From fa4812a1bd2d74ae87bfe2eab79ed95cf1fb232d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 21 Nov 2022 20:52:06 +0000 Subject: chore: autopublish 2022-11-21T20:52:06Z --- public/404.html | 4 ++-- public/404/index.html | 4 ++-- public/_gatsby/slices/_gatsby-scripts-1.html | 4 ++-- public/chunk-map.json | 2 +- public/component---src-pages-index-tsx-e59db967ec99f8e86048.js | 2 ++ public/component---src-pages-index-tsx-e59db967ec99f8e86048.js.map | 1 + public/index.html | 6 +++--- public/page-data/app-data.json | 2 +- public/webpack-runtime-e52898bfba80906f74b6.js | 2 ++ public/webpack-runtime-e52898bfba80906f74b6.js.map | 1 + public/webpack.stats.json | 2 +- 11 files changed, 18 insertions(+), 12 deletions(-) create mode 100644 public/component---src-pages-index-tsx-e59db967ec99f8e86048.js create mode 100644 public/component---src-pages-index-tsx-e59db967ec99f8e86048.js.map create mode 100644 public/webpack-runtime-e52898bfba80906f74b6.js create mode 100644 public/webpack-runtime-e52898bfba80906f74b6.js.map diff --git a/public/404.html b/public/404.html index fe68f8e..720fb41 100644 --- a/public/404.html +++ b/public/404.html @@ -18,6 +18,6 @@ data-styled.g4[id="Content-sc-1487q2e-0"]{content:"ckEhu,"}/*!sc*/ - \ No newline at end of file + \ No newline at end of file diff --git a/public/404/index.html b/public/404/index.html index 8d78a2d..922e868 100644 --- a/public/404/index.html +++ b/public/404/index.html @@ -18,6 +18,6 @@ data-styled.g4[id="Content-sc-1487q2e-0"]{content:"ckEhu,"}/*!sc*/ - \ No newline at end of file + \ No newline at end of file diff --git a/public/_gatsby/slices/_gatsby-scripts-1.html b/public/_gatsby/slices/_gatsby-scripts-1.html index 120196c..3cd4f55 100644 --- a/public/_gatsby/slices/_gatsby-scripts-1.html +++ b/public/_gatsby/slices/_gatsby-scripts-1.html @@ -2,6 +2,6 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/public/chunk-map.json b/public/chunk-map.json index 535641d..0f02b7a 100644 --- a/public/chunk-map.json +++ b/public/chunk-map.json @@ -1 +1 @@ -{"app":["/app-b863c76cb1053852e93f.js"],"component---src-pages-404-tsx":["/component---src-pages-404-tsx-2c0679d9093097de4278.js"],"component---src-pages-index-tsx":["/component---src-pages-index-tsx-ed567871985ee70bf7f2.js"]} \ No newline at end of file +{"app":["/app-b863c76cb1053852e93f.js"],"component---src-pages-404-tsx":["/component---src-pages-404-tsx-2c0679d9093097de4278.js"],"component---src-pages-index-tsx":["/component---src-pages-index-tsx-e59db967ec99f8e86048.js"]} \ No newline at end of file diff --git a/public/component---src-pages-index-tsx-e59db967ec99f8e86048.js b/public/component---src-pages-index-tsx-e59db967ec99f8e86048.js new file mode 100644 index 0000000..0359ef3 --- /dev/null +++ b/public/component---src-pages-index-tsx-e59db967ec99f8e86048.js @@ -0,0 +1,2 @@ +"use strict";(self.webpackChunksubmelon_tech=self.webpackChunksubmelon_tech||[]).push([[691],{3723:function(e,t,r){r.d(t,{L:function(){return h},M:function(){return E},P:function(){return w},S:function(){return _},_:function(){return i},a:function(){return o},b:function(){return s},g:function(){return d},h:function(){return c}});var n=r(7294),a=(r(2369),r(5697)),l=r.n(a);function o(){return o=Object.assign?Object.assign.bind():function(e){for(var t=1;t=0||(a[r]=e[r]);return a}const c=()=>"undefined"!=typeof HTMLImageElement&&"loading"in HTMLImageElement.prototype;function s(e,t,r,n,a){return void 0===a&&(a={}),o({},r,{loading:n,shouldLoad:e,"data-main-image":"",style:o({},a,{opacity:t?1:0})})}function d(e,t,r,n,a,l,i,c){const s={};l&&(s.backgroundColor=l,"fixed"===r?(s.width=n,s.height=a,s.backgroundColor=l,s.position="relative"):("constrained"===r||"fullWidth"===r)&&(s.position="absolute",s.top=0,s.left=0,s.bottom=0,s.right=0)),i&&(s.objectFit=i),c&&(s.objectPosition=c);const d=o({},e,{"aria-hidden":!0,"data-placeholder-image":"",style:o({opacity:t?0:1,transition:"opacity 500ms linear"},s)});return d}const u=["children"],p=function(e){let{layout:t,width:r,height:a}=e;return"fullWidth"===t?n.createElement("div",{"aria-hidden":!0,style:{paddingTop:a/r*100+"%"}}):"constrained"===t?n.createElement("div",{style:{maxWidth:r,display:"block"}},n.createElement("img",{alt:"",role:"presentation","aria-hidden":"true",src:"data:image/svg+xml;charset=utf-8,%3Csvg height='"+a+"' width='"+r+"' xmlns='http://www.w3.org/2000/svg' version='1.1'%3E%3C/svg%3E",style:{maxWidth:"100%",display:"block",position:"static"}})):null},h=function(e){let{children:t}=e,r=i(e,u);return n.createElement(n.Fragment,null,n.createElement(p,o({},r)),t,null)},m=["src","srcSet","loading","alt","shouldLoad"],g=["fallback","sources","shouldLoad"],f=function(e){let{src:t,srcSet:r,loading:a,alt:l="",shouldLoad:c}=e,s=i(e,m);return n.createElement("img",o({},s,{decoding:"async",loading:a,src:c?t:void 0,"data-src":c?void 0:t,srcSet:c?r:void 0,"data-srcset":c?void 0:r,alt:l}))},v=function(e){let{fallback:t,sources:r=[],shouldLoad:a=!0}=e,l=i(e,g);const c=l.sizes||(null==t?void 0:t.sizes),s=n.createElement(f,o({},l,t,{sizes:c,shouldLoad:a}));return r.length?n.createElement("picture",null,r.map((e=>{let{media:t,srcSet:r,type:l}=e;return n.createElement("source",{key:t+"-"+l+"-"+r,type:l,media:t,srcSet:a?r:void 0,"data-srcset":a?void 0:r,sizes:c})})),s):s};var y;f.propTypes={src:a.string.isRequired,alt:a.string.isRequired,sizes:a.string,srcSet:a.string,shouldLoad:a.bool},v.displayName="Picture",v.propTypes={alt:a.string.isRequired,shouldLoad:a.bool,fallback:a.exact({src:a.string.isRequired,srcSet:a.string,sizes:a.string}),sources:a.arrayOf(a.oneOfType([a.exact({media:a.string.isRequired,type:a.string,sizes:a.string,srcSet:a.string.isRequired}),a.exact({media:a.string,type:a.string.isRequired,sizes:a.string,srcSet:a.string.isRequired})]))};const b=["fallback"],w=function(e){let{fallback:t}=e,r=i(e,b);return t?n.createElement(v,o({},r,{fallback:{src:t},"aria-hidden":!0,alt:""})):n.createElement("div",o({},r))};w.displayName="Placeholder",w.propTypes={fallback:a.string,sources:null==(y=v.propTypes)?void 0:y.sources,alt:function(e,t,r){return e[t]?new Error("Invalid prop `"+t+"` supplied to `"+r+"`. Validation failed."):null}};const E=function(e){return n.createElement(n.Fragment,null,n.createElement(v,o({},e)),n.createElement("noscript",null,n.createElement(v,o({},e,{shouldLoad:!0}))))};E.displayName="MainImage",E.propTypes=v.propTypes;const x=function(e,t,r){for(var n=arguments.length,a=new Array(n>3?n-3:0),o=3;oJSON.stringify(a.images)),[a.images]);u&&(d=u);const T=function(e,t,r){let n="";return"fullWidth"===e&&(n=''),"constrained"===e&&(n='
"),n}(y,f,v);return(0,n.useEffect)((()=>{I||(I=Promise.all([r.e(774),r.e(223)]).then(r.bind(r,8223)).then((e=>{let{renderImageToString:t,swapPlaceholderImage:r}=e;return O=t,{renderImageToString:t,swapPlaceholderImage:r}})));const e=k.current.querySelector("[data-gatsby-image-ssr]");if(e&&c())return e.complete?(null==p||p({wasCached:!0}),null==h||h({wasCached:!0}),setTimeout((()=>{e.removeAttribute("data-gatsby-image-ssr")}),0)):(null==p||p({wasCached:!0}),e.addEventListener("load",(function t(){e.removeEventListener("load",t),null==h||h({wasCached:!0}),setTimeout((()=>{e.removeAttribute("data-gatsby-image-ssr")}),0)}))),void S.add(j);if(O&&S.has(j))return;let t,n;return I.then((e=>{let{renderImageToString:r,swapPlaceholderImage:i}=e;k.current&&(k.current.innerHTML=r(o({isLoading:!0,isLoaded:S.has(j),image:a},g)),S.has(j)||(t=requestAnimationFrame((()=>{k.current&&(n=i(k.current,j,S,l,p,h,m))}))))})),()=>{t&&cancelAnimationFrame(t),n&&n()}}),[a]),(0,n.useLayoutEffect)((()=>{S.has(j)&&O&&(k.current.innerHTML=O(o({isLoading:S.has(j),isLoaded:S.has(j),image:a},g)),null==p||p({wasCached:!0}),null==h||h({wasCached:!0}))}),[a]),(0,n.createElement)(t,o({},x,{style:o({},w,l,{backgroundColor:s}),className:E+(d?" "+d:""),ref:k,dangerouslySetInnerHTML:{__html:T},suppressHydrationWarning:!0}))},T=(0,n.memo)((function(e){return e.image?(0,n.createElement)(j,e):null}));T.propTypes=k,T.displayName="GatsbyImage";const N=["src","__imageData","__error","width","height","aspectRatio","tracedSVGOptions","placeholder","formats","quality","transformOptions","jpgOptions","pngOptions","webpOptions","avifOptions","blurredOptions","breakpoints","outputPixelDensities"],z=function(e,t){for(var r=arguments.length,n=new Array(r>2?r-2:0),a=2;a{if(void 0!==e.layout&&!H.has(e.layout))return new Error("Invalid value "+e.layout+'" provided for prop "layout". Defaulting to "constrained". Valid values are "fixed", "fullWidth" or "constrained".')}},_=(M=T,function(e){let{src:t,__imageData:r,__error:a}=e,l=i(e,N);return a&&console.warn(a),r?n.createElement(M,o({image:r},l)):(console.warn("Image not loaded",t),null)});var M;_.displayName="StaticImage",_.propTypes=P},2369:function(e){const t=(e,t)=>{if("string"!=typeof e&&!Array.isArray(e))throw new TypeError("Expected the input to be `string | string[]`");t=Object.assign({pascalCase:!1},t);if(e=Array.isArray(e)?e.map((e=>e.trim())).filter((e=>e.length)).join("-"):e.trim(),0===e.length)return"";if(1===e.length)return t.pascalCase?e.toUpperCase():e.toLowerCase();return e!==e.toLowerCase()&&(e=(e=>{let t=!1,r=!1,n=!1;for(let a=0;at.toUpperCase())).replace(/\d+(\w|$)/g,(e=>e.toUpperCase())),r=e,t.pascalCase?r.charAt(0).toUpperCase()+r.slice(1):r;var r};e.exports=t,e.exports.default=t},1895:function(e,t,r){var n=r(7294),a=r(1693);t.Z=e=>{let{children:t,...r}=e;return n.createElement(a.gp,{theme:{link:!0}},n.createElement(a.Jo,r,t))}},4690:function(e,t,r){r.d(t,{F:function(){return a}});var n=r(7294);function a(){const e="The official website of Kevin Hoerr, developer of websites.";return n.createElement(n.Fragment,null,n.createElement("meta",{name:"twitter:description",content:e}),n.createElement("meta",{name:"twitter:title",content:"Kevin J Hoerr "}),n.createElement("meta",{name:"twitter:creator",content:"Kevin J Hoerr"}),n.createElement("meta",{name:"twitter:card",content:"summary"}),n.createElement("meta",{property:"og:type",content:"website"}),n.createElement("meta",{property:"og:description",content:e}),n.createElement("meta",{property:"og:title",content:"Kevin J Hoerr "}),n.createElement("meta",{name:"description",content:e}),n.createElement("title",null,"Kevin J Hoerr "))}},6432:function(e,t,r){r.r(t),r.d(t,{Head:function(){return p.F},default:function(){return h}});var n=r(7294),a=r(3723),l=r(9583),o=r(1895),i=r(1693);const c=["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"];function s(e){var t,r;return null!==(t=null===(r=e.toString().match(/.{1,2}/g))||void 0===r?void 0:r.map((e=>c[parseInt(e)])).join(""))&&void 0!==t?t:""}var d=e=>{let{timestamp:t}=e;return n.createElement(i.$_,null,n.createElement("span",null,"©2022 kjhoerr@https://submelon.dev/:",function(e){const t=new Date(1e3*e);return[t.getUTCFullYear(),t.getUTCMonth(),t.getUTCDate(),t.getUTCHours(),t.getUTCMinutes()].map(s).join(".")+"-0"}(parseInt(t))))},u=r(4405),p=r(4690);var h=()=>n.createElement("main",null,n.createElement(u.Pd.Provider,{value:{size:"20",style:{marginBottom:"-4px"}}},n.createElement(i.VY,null,n.createElement("div",null,n.createElement(a.S,{src:"../images/main.png",alt:"Picture of Kevin Hoerr",placeholder:"tracedSVG",layout:"fixed",width:350,height:350,__imageData:r(3741)})),n.createElement(i.ti,null,"Hello!"),n.createElement(i.gp,null,n.createElement("p",null,"I'm a computer science and math graduate from Millersville University. I work as an IT consultant and specialize in development operations and systems validation for web applications."),n.createElement("p",null,"My most recent projects have been focused on full-stack development. I use Kubernetes for orchestration and NextJS for the front-end. For back-end development, I have built services enabled by Java with Spring Boot, Quarkus, and rust+actix-web with a GraphQL serving public API."),n.createElement("p",null,"I run a personal Kubernetes cluster at home using MicroOS and k3d. I have also run multiple clusters via DigitalOcean with deployments dedicated for hosting git projects, CI/CD, and code coverage. Since then all projects have been moved to GitHub."),n.createElement("em",null,"- Kevin H.")),n.createElement(o.Z,{href:"https://cybr.es/@kjhoerr",rel:"me","aria-label":"My Mastodon account"},n.createElement(l.WJp,null)," @kjhoerr@cybr.es"),n.createElement(o.Z,{href:"https://github.com/kjhoerr",rel:"me","aria-label":"My GitHub account with my most active personal projects"},n.createElement(l.hJX,null)," kjhoerr on GitHub")),n.createElement(d,{timestamp:"1669057338"})))},1693:function(e,t,r){r.d(t,{Jo:function(){return a},gp:function(){return l},ti:function(){return o},VY:function(){return i},$_:function(){return c}});var n=r(2788),a=n.default.a.withConfig({displayName:"BlockAnchor",componentId:"sc-1teltef-0"})(["padding:8px;width:328px;display:block;text-align:center;-webkit-text-decoration:none;text-decoration:none;color:#666;&:visited,&:active{padding:8px;width:328px;display:block;text-align:center;-webkit-text-decoration:none;text-decoration:none;color:#666;}"]),l=n.default.div.withConfig({displayName:"BlockBody",componentId:"sc-40egxv-0"})(["& + &{margin-top:3px;}background-color:#fff;border:1px #000 solid;border-left:3px #000 solid;border-right:3px #000 solid;padding:",";& > ","{&:hover{background-color:#ddd;color:#222;}}&:last-child,&:last-child > ","{border-bottom-left-radius:18px;border-bottom-right-radius:18px;}"],(e=>e.theme.link?"0":"4px 8px"),a,a),o=n.default.div.withConfig({displayName:"BlockHeader",componentId:"sc-ntmdvi-0"})(["background-color:#000;width:100%;text-align:center;color:#fff;font-size:36px;font-weight:bold;margin-top:3px;padding-top:4px;"]),i=n.default.div.withConfig({displayName:"Content",componentId:"sc-1487q2e-0"})(["width:350px;margin:0px auto;margin-bottom:120px;padding-top:136px;"]),c=n.default.div.withConfig({displayName:"Footer",componentId:"sc-zowffk-0"})(["width:100%;position:fixed;left:0px;bottom:0px;text-align:center;font-size:12px;span{background-color:#e1e1e1;}"])},4405:function(e,t,r){r.d(t,{w_:function(){return s},Pd:function(){return l}});var n=r(7294),a={color:void 0,size:void 0,className:void 0,style:void 0,attr:void 0},l=n.createContext&&n.createContext(a),o=function(){return o=Object.assign||function(e){for(var t,r=1,n=arguments.length;r\n placeholder?: \"tracedSVG\" | \"dominantColor\" | \"blurred\" | \"none\"\n tracedSVGOptions?: Record\n width?: number\n height?: number\n aspectRatio?: number\n sizes?: string\n quality?: number\n transformOptions?: {\n fit?: Fit\n cropFocus?: number | string\n duotone?: {\n highlight: string\n shadow: string\n opacity?: number\n }\n grayscale?: boolean\n rotate?: number\n trim?: number\n }\n jpgOptions?: Record\n pngOptions?: Record\n webpOptions?: Record\n avifOptions?: Record\n blurredOptions?: { width?: number; toFormat?: ImageFormat }\n breakpoints?: Array\n outputPixelDensities?: Array\n backgroundColor?: string\n}\n\nexport interface IImageSizeArgs {\n width?: number\n height?: number\n layout?: Layout\n filename: string\n outputPixelDensities?: Array\n breakpoints?: Array\n fit?: Fit\n reporter?: IReporter\n sourceMetadata: { width: number; height: number }\n}\n\nexport interface IImageSizes {\n sizes: Array\n presentationWidth: number\n presentationHeight: number\n aspectRatio: number\n unscaledWidth: number\n}\n\nexport interface IImage {\n src: string\n width: number\n height: number\n format: ImageFormat\n}\n\nexport interface IGatsbyImageHelperArgs {\n pluginName: string\n generateImageSource: (\n filename: string,\n width: number,\n height: number,\n format: ImageFormat,\n fit?: Fit,\n options?: Record\n ) => IImage\n layout?: Layout\n formats?: Array\n filename: string\n placeholderURL?: string\n width?: number\n height?: number\n sizes?: string\n reporter?: IReporter\n sourceMetadata?: { width: number; height: number; format: ImageFormat }\n fit?: Fit\n options?: Record\n breakpoints?: Array\n backgroundColor?: string\n aspectRatio?: number\n}\n\nconst warn = (message: string): void => console.warn(message)\n\nconst sortNumeric = (a: number, b: number): number => a - b\n\nexport const getSizes = (width: number, layout: Layout): string | undefined => {\n switch (layout) {\n // If screen is wider than the max size, image width is the max size,\n // otherwise it's the width of the screen\n case `constrained`:\n return `(min-width: ${width}px) ${width}px, 100vw`\n\n // Image is always the same width, whatever the size of the screen\n case `fixed`:\n return `${width}px`\n\n // Image is always the width of the screen\n case `fullWidth`:\n return `100vw`\n\n default:\n return undefined\n }\n}\n\nexport const getSrcSet = (images: Array): string =>\n images.map(image => `${image.src} ${image.width}w`).join(`,\\n`)\n\nexport function formatFromFilename(filename: string): ImageFormat | undefined {\n const dot = filename.lastIndexOf(`.`)\n if (dot !== -1) {\n const ext = filename.slice(dot + 1)\n if (ext === `jpeg`) {\n return `jpg`\n }\n if (ext.length === 3 || ext.length === 4) {\n return ext as ImageFormat\n }\n }\n return undefined\n}\n\nexport function setDefaultDimensions(\n args: IGatsbyImageHelperArgs\n): IGatsbyImageHelperArgs {\n let {\n layout = `constrained`,\n width,\n height,\n sourceMetadata,\n breakpoints,\n aspectRatio,\n formats = [`auto`, `webp`],\n } = args\n formats = formats.map(format => format.toLowerCase() as ImageFormat)\n layout = camelCase(layout) as Layout\n\n if (width && height) {\n return { ...args, formats, layout, aspectRatio: width / height }\n }\n if (sourceMetadata.width && sourceMetadata.height && !aspectRatio) {\n aspectRatio = sourceMetadata.width / sourceMetadata.height\n }\n\n if (layout === `fullWidth`) {\n width = width || sourceMetadata.width || breakpoints[breakpoints.length - 1]\n height = height || Math.round(width / (aspectRatio || DEFAULT_ASPECT_RATIO))\n } else {\n if (!width) {\n if (height && aspectRatio) {\n width = height * aspectRatio\n } else if (sourceMetadata.width) {\n width = sourceMetadata.width\n } else if (height) {\n width = Math.round(height / DEFAULT_ASPECT_RATIO)\n } else {\n width = DEFAULT_FIXED_WIDTH\n }\n }\n\n if (aspectRatio && !height) {\n height = Math.round(width / aspectRatio)\n } else if (!aspectRatio) {\n aspectRatio = width / height\n }\n }\n return { ...args, width, height, aspectRatio, layout, formats }\n}\n\n/**\n * Use this for getting an image for the blurred placeholder. This ensures the\n * aspect ratio and crop match the main image\n */\nexport function getLowResolutionImageURL(\n args: IGatsbyImageHelperArgs,\n width = 20\n): string {\n args = setDefaultDimensions(args)\n const { generateImageSource, filename, aspectRatio } = args\n return generateImageSource(\n filename,\n width,\n Math.round(width / aspectRatio),\n args.sourceMetadata.format || `jpg`,\n args.fit,\n args.options\n )?.src\n}\n\nexport function generateImageData(\n args: IGatsbyImageHelperArgs\n): IGatsbyImageData {\n args = setDefaultDimensions(args)\n\n let {\n pluginName,\n sourceMetadata,\n generateImageSource,\n layout,\n fit,\n options,\n width,\n height,\n filename,\n reporter = { warn },\n backgroundColor,\n placeholderURL,\n } = args\n\n if (!pluginName) {\n reporter.warn(\n `[gatsby-plugin-image] \"generateImageData\" was not passed a plugin name`\n )\n }\n\n if (typeof generateImageSource !== `function`) {\n throw new Error(`generateImageSource must be a function`)\n }\n\n if (!sourceMetadata || (!sourceMetadata.width && !sourceMetadata.height)) {\n // No metadata means we let the CDN handle max size etc, aspect ratio etc\n sourceMetadata = {\n width,\n height,\n format: sourceMetadata?.format || formatFromFilename(filename) || `auto`,\n }\n } else if (!sourceMetadata.format) {\n sourceMetadata.format = formatFromFilename(filename)\n }\n\n const formats = new Set(args.formats)\n\n if (formats.size === 0 || formats.has(`auto`) || formats.has(``)) {\n formats.delete(`auto`)\n formats.delete(``)\n formats.add(sourceMetadata.format)\n }\n\n if (formats.has(`jpg`) && formats.has(`png`)) {\n reporter.warn(\n `[${pluginName}] Specifying both 'jpg' and 'png' formats is not supported. Using 'auto' instead`\n )\n if (sourceMetadata.format === `jpg`) {\n formats.delete(`png`)\n } else {\n formats.delete(`jpg`)\n }\n }\n\n const imageSizes = calculateImageSizes({ ...args, sourceMetadata })\n\n const result: IGatsbyImageData[\"images\"] = {\n sources: [],\n }\n\n let sizes = args.sizes\n if (!sizes) {\n sizes = getSizes(imageSizes.presentationWidth, layout)\n }\n\n formats.forEach(format => {\n const images = imageSizes.sizes\n .map(size => {\n const imageSrc = generateImageSource(\n filename,\n size,\n Math.round(size / imageSizes.aspectRatio),\n format,\n fit,\n options\n )\n if (\n !imageSrc?.width ||\n !imageSrc.height ||\n !imageSrc.src ||\n !imageSrc.format\n ) {\n reporter.warn(\n `[${pluginName}] The resolver for image ${filename} returned an invalid value.`\n )\n return undefined\n }\n return imageSrc\n })\n .filter(Boolean)\n\n if (format === `jpg` || format === `png` || format === `auto`) {\n const unscaled =\n images.find(img => img.width === imageSizes.unscaledWidth) || images[0]\n\n if (unscaled) {\n result.fallback = {\n src: unscaled.src,\n srcSet: getSrcSet(images),\n sizes,\n }\n }\n } else {\n result.sources?.push({\n srcSet: getSrcSet(images),\n sizes,\n type: `image/${format}`,\n })\n }\n })\n\n const imageProps: Partial = {\n images: result,\n layout,\n backgroundColor,\n }\n\n if (placeholderURL) {\n imageProps.placeholder = { fallback: placeholderURL }\n }\n\n switch (layout) {\n case `fixed`:\n imageProps.width = imageSizes.presentationWidth\n imageProps.height = imageSizes.presentationHeight\n break\n\n case `fullWidth`:\n imageProps.width = 1\n imageProps.height = 1 / imageSizes.aspectRatio\n break\n\n case `constrained`:\n imageProps.width = args.width || imageSizes.presentationWidth || 1\n imageProps.height = (imageProps.width || 1) / imageSizes.aspectRatio\n }\n\n return imageProps as IGatsbyImageData\n}\n\nconst dedupeAndSortDensities = (values: Array): Array =>\n Array.from(new Set([1, ...values])).sort(sortNumeric)\n\nexport function calculateImageSizes(args: IImageSizeArgs): IImageSizes {\n const {\n width,\n height,\n filename,\n layout = `constrained`,\n sourceMetadata: imgDimensions,\n reporter = { warn },\n breakpoints = DEFAULT_BREAKPOINTS,\n } = args\n\n // check that all dimensions provided are positive\n const userDimensions = { width, height }\n const erroneousUserDimensions = Object.entries(userDimensions).filter(\n ([_, size]) => typeof size === `number` && size < 1\n )\n if (erroneousUserDimensions.length) {\n throw new Error(\n `Specified dimensions for images must be positive numbers (> 0). Problem dimensions you have are ${erroneousUserDimensions\n .map(dim => dim.join(`: `))\n .join(`, `)}`\n )\n }\n\n if (layout === `fixed`) {\n return fixedImageSizes(args)\n } else if (layout === `constrained`) {\n return responsiveImageSizes(args)\n } else if (layout === `fullWidth`) {\n return responsiveImageSizes({ breakpoints, ...args })\n } else {\n reporter.warn(\n `No valid layout was provided for the image at ${filename}. Valid image layouts are fixed, fullWidth, and constrained. Found ${layout}`\n )\n return {\n sizes: [imgDimensions.width],\n presentationWidth: imgDimensions.width,\n presentationHeight: imgDimensions.height,\n aspectRatio: imgDimensions.width / imgDimensions.height,\n unscaledWidth: imgDimensions.width,\n }\n }\n}\nexport function fixedImageSizes({\n filename,\n sourceMetadata: imgDimensions,\n width,\n height,\n fit = `cover`,\n outputPixelDensities = DEFAULT_PIXEL_DENSITIES,\n reporter = { warn },\n}: IImageSizeArgs): IImageSizes {\n let aspectRatio = imgDimensions.width / imgDimensions.height\n // Sort, dedupe and ensure there's a 1\n const densities = dedupeAndSortDensities(outputPixelDensities)\n\n // If both are provided then we need to check the fit\n if (width && height) {\n const calculated = getDimensionsAndAspectRatio(imgDimensions, {\n width,\n height,\n fit,\n })\n width = calculated.width\n height = calculated.height\n aspectRatio = calculated.aspectRatio\n }\n\n if (!width) {\n if (!height) {\n width = DEFAULT_FIXED_WIDTH\n } else {\n width = Math.round(height * aspectRatio)\n }\n } else if (!height) {\n height = Math.round(width / aspectRatio)\n }\n\n const originalWidth = width // will use this for presentationWidth, don't want to lose it\n const isTopSizeOverriden =\n imgDimensions.width < width || imgDimensions.height < (height as number)\n\n // If the image is smaller than requested, warn the user that it's being processed as such\n // print out this message with the necessary information before we overwrite it for sizing\n if (isTopSizeOverriden) {\n const fixedDimension = imgDimensions.width < width ? `width` : `height`\n reporter.warn(`\nThe requested ${fixedDimension} \"${\n fixedDimension === `width` ? width : height\n }px\" for the image ${filename} was larger than the actual image ${fixedDimension} of ${\n imgDimensions[fixedDimension]\n }px. If possible, replace the current image with a larger one.`)\n\n if (fixedDimension === `width`) {\n width = imgDimensions.width\n height = Math.round(width / aspectRatio)\n } else {\n height = imgDimensions.height\n width = height * aspectRatio\n }\n }\n\n const sizes = densities\n .filter(size => size >= 1) // remove smaller densities because fixed images don't need them\n .map(density => Math.round(density * (width as number)))\n .filter(size => size <= imgDimensions.width)\n\n return {\n sizes,\n aspectRatio,\n presentationWidth: originalWidth,\n presentationHeight: Math.round(originalWidth / aspectRatio),\n unscaledWidth: width,\n }\n}\n\nexport function responsiveImageSizes({\n sourceMetadata: imgDimensions,\n width,\n height,\n fit = `cover`,\n outputPixelDensities = DEFAULT_PIXEL_DENSITIES,\n breakpoints,\n layout,\n}: IImageSizeArgs): IImageSizes {\n let sizes\n let aspectRatio = imgDimensions.width / imgDimensions.height\n // Sort, dedupe and ensure there's a 1\n const densities = dedupeAndSortDensities(outputPixelDensities)\n\n // If both are provided then we need to check the fit\n if (width && height) {\n const calculated = getDimensionsAndAspectRatio(imgDimensions, {\n width,\n height,\n fit,\n })\n width = calculated.width\n height = calculated.height\n aspectRatio = calculated.aspectRatio\n }\n\n // Case 1: width of height were passed in, make sure it isn't larger than the actual image\n width = width && Math.min(width, imgDimensions.width)\n height = height && Math.min(height, imgDimensions.height)\n\n // Case 2: neither width or height were passed in, use default size\n if (!width && !height) {\n width = Math.min(DEFAULT_FLUID_WIDTH, imgDimensions.width)\n height = width / aspectRatio\n }\n\n // if it still hasn't been found, calculate width from the derived height.\n // TS isn't smart enough to realise the type for height has been narrowed here\n if (!width) {\n width = (height as number) * aspectRatio\n }\n\n const originalWidth = width\n const isTopSizeOverriden =\n imgDimensions.width < width || imgDimensions.height < (height as number)\n if (isTopSizeOverriden) {\n width = imgDimensions.width\n height = imgDimensions.height\n }\n\n width = Math.round(width)\n\n if (breakpoints?.length > 0) {\n sizes = breakpoints.filter(size => size <= imgDimensions.width)\n\n // If a larger breakpoint has been filtered-out, add the actual image width instead\n if (\n sizes.length < breakpoints.length &&\n !sizes.includes(imgDimensions.width)\n ) {\n sizes.push(imgDimensions.width)\n }\n } else {\n sizes = densities.map(density => Math.round(density * (width as number)))\n sizes = sizes.filter(size => size <= imgDimensions.width)\n }\n\n // ensure that the size passed in is included in the final output\n if (layout === `constrained` && !sizes.includes(width)) {\n sizes.push(width)\n }\n sizes = sizes.sort(sortNumeric)\n return {\n sizes,\n aspectRatio,\n presentationWidth: originalWidth,\n presentationHeight: Math.round(originalWidth / aspectRatio),\n unscaledWidth: width,\n }\n}\n\nexport function getDimensionsAndAspectRatio(\n dimensions,\n options\n): { width: number; height: number; aspectRatio: number } {\n // Calculate the eventual width/height of the image.\n const imageAspectRatio = dimensions.width / dimensions.height\n\n let width = options.width\n let height = options.height\n\n switch (options.fit) {\n case `fill`: {\n width = options.width ? options.width : dimensions.width\n height = options.height ? options.height : dimensions.height\n break\n }\n case `inside`: {\n const widthOption = options.width\n ? options.width\n : Number.MAX_SAFE_INTEGER\n const heightOption = options.height\n ? options.height\n : Number.MAX_SAFE_INTEGER\n\n width = Math.min(widthOption, Math.round(heightOption * imageAspectRatio))\n height = Math.min(\n heightOption,\n Math.round(widthOption / imageAspectRatio)\n )\n break\n }\n case `outside`: {\n const widthOption = options.width ? options.width : 0\n const heightOption = options.height ? options.height : 0\n\n width = Math.max(widthOption, Math.round(heightOption * imageAspectRatio))\n height = Math.max(\n heightOption,\n Math.round(widthOption / imageAspectRatio)\n )\n break\n }\n\n default: {\n if (options.width && !options.height) {\n width = options.width\n height = Math.round(options.width / imageAspectRatio)\n }\n\n if (options.height && !options.width) {\n width = Math.round(options.height * imageAspectRatio)\n height = options.height\n }\n }\n }\n\n return {\n width,\n height,\n aspectRatio: width / height,\n }\n}\n","/* global GATSBY___IMAGE */\nimport { generateImageData, EVERY_BREAKPOINT } from \"../image-utils\"\nimport type { CSSProperties, HTMLAttributes, ImgHTMLAttributes } from \"react\"\nimport type { Node } from \"gatsby\"\nimport type { PlaceholderProps } from \"./placeholder\"\nimport type { MainImageProps } from \"./main-image\"\nimport type { IGatsbyImageData } from \"./gatsby-image.browser\"\nimport type {\n IGatsbyImageHelperArgs,\n Layout,\n IImage,\n ImageFormat,\n} from \"../image-utils\"\n\n// Native lazy-loading support: https://addyosmani.com/blog/lazy-loading/\nexport const hasNativeLazyLoadSupport = (): boolean =>\n typeof HTMLImageElement !== `undefined` &&\n `loading` in HTMLImageElement.prototype\n\nexport function gatsbyImageIsInstalled(): boolean {\n return typeof GATSBY___IMAGE !== `undefined` && GATSBY___IMAGE\n}\n\nexport type IGatsbyImageDataParent = T & {\n gatsbyImageData: IGatsbyImageData\n}\nexport type IGatsbyImageParent = T & {\n gatsbyImage: IGatsbyImageData\n}\nexport type FileNode = Partial & {\n childImageSharp?: IGatsbyImageDataParent>\n}\n\nconst isGatsbyImageData = (\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n node: IGatsbyImageData | any\n): node is IGatsbyImageData =>\n // 🦆 check for a deep prop to be sure this is a valid gatsbyImageData object\n Boolean(node?.images?.fallback?.src)\n\nconst isGatsbyImageDataParent = (\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n node: IGatsbyImageDataParent | any\n): node is IGatsbyImageDataParent => Boolean(node?.gatsbyImageData)\n\nconst isGatsbyImageParent = (\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n node: IGatsbyImageParent | any\n): node is IGatsbyImageParent => Boolean(node?.gatsbyImage)\n\nexport type ImageDataLike =\n | FileNode\n | IGatsbyImageDataParent\n | IGatsbyImageParent\n | IGatsbyImageData\n\nexport const getImage = (\n node: ImageDataLike | null\n): IGatsbyImageData | undefined => {\n // This checks both for gatsbyImageData and gatsbyImage\n if (isGatsbyImageData(node)) {\n return node\n }\n // gatsbyImageData GraphQL field\n if (isGatsbyImageDataParent(node)) {\n return node.gatsbyImageData\n }\n // gatsbyImage GraphQL field for Gatsby's Image CDN service\n if (isGatsbyImageParent(node)) {\n return node.gatsbyImage\n }\n return node?.childImageSharp?.gatsbyImageData\n}\n\nexport const getSrc = (node: ImageDataLike): string | undefined =>\n getImage(node)?.images?.fallback?.src\n\nexport const getSrcSet = (node: ImageDataLike): string | undefined =>\n getImage(node)?.images?.fallback?.srcSet\n\nexport function getWrapperProps(\n width: number,\n height: number,\n layout: Layout\n): Pick, \"className\" | \"style\"> & {\n \"data-gatsby-image-wrapper\": string\n} {\n const wrapperStyle: CSSProperties = {}\n\n let className = `gatsby-image-wrapper`\n\n // If the plugin isn't installed we need to apply the styles inline\n if (!gatsbyImageIsInstalled()) {\n wrapperStyle.position = `relative`\n wrapperStyle.overflow = `hidden`\n }\n\n if (layout === `fixed`) {\n wrapperStyle.width = width\n wrapperStyle.height = height\n } else if (layout === `constrained`) {\n if (!gatsbyImageIsInstalled()) {\n wrapperStyle.display = `inline-block`\n wrapperStyle.verticalAlign = `top`\n }\n className = `gatsby-image-wrapper gatsby-image-wrapper-constrained`\n }\n\n return {\n className,\n \"data-gatsby-image-wrapper\": ``,\n style: wrapperStyle,\n }\n}\n\nexport interface IUrlBuilderArgs {\n width: number\n height: number\n baseUrl: string\n format: ImageFormat\n options: OptionsType\n}\nexport interface IGetImageDataArgs> {\n baseUrl: string\n /**\n * For constrained and fixed images, the size of the image element\n */\n width?: number\n height?: number\n /**\n * If available, pass the source image width and height\n */\n sourceWidth?: number\n sourceHeight?: number\n /**\n * If only one dimension is passed, then this will be used to calculate the other.\n */\n aspectRatio?: number\n layout?: Layout\n /**\n * Returns a URL based on the passed arguments. Should be a pure function\n */\n urlBuilder: (args: IUrlBuilderArgs) => string\n\n /**\n * Should be a data URI\n */\n p