diff --git a/404.html b/404.html index c448d5ad0..d026c55c5 100644 --- a/404.html +++ b/404.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

- - + + \ No newline at end of file diff --git a/assets/js/06608fa3.0264dabc.js b/assets/js/06608fa3.0264dabc.js new file mode 100644 index 000000000..6c79b3be9 --- /dev/null +++ b/assets/js/06608fa3.0264dabc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[7601],{4469:e=>{e.exports=JSON.parse('{"name":"docusaurus-plugin-content-blog","id":"default"}')}}]); \ No newline at end of file diff --git a/assets/js/1776fc83.0cbe1638.js b/assets/js/1776fc83.0cbe1638.js new file mode 100644 index 000000000..b36495d23 --- /dev/null +++ b/assets/js/1776fc83.0cbe1638.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[6326],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>g});var a=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=a.createContext({}),p=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},d="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=p(n),u=i,g=d["".concat(s,".").concat(u)]||d[u]||m[u]||r;return n?a.createElement(g,o(o({ref:t},c),{},{components:n})):a.createElement(g,o({ref:t},c))}));function g(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,o=new Array(r);o[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[d]="string"==typeof e?e:i,o[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>m,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var a=n(7462),i=(n(7294),n(3905));const r={label:"JPEG-XL",sidebar_position:7},o="JPEG-XL",l={unversionedId:"images/JXL",id:"images/JXL",title:"JPEG-XL",description:"This section is in need of contributions. If you believe you can help, please see our Contribution Guide to get started as a contributor!",source:"@site/docs/images/JXL.md",sourceDirName:"images",slug:"/images/JXL",permalink:"/docs/images/JXL",draft:!1,editUrl:"https://github.com/av1-community-contributors/codec-wiki/tree/main/docs/images/JXL.md",tags:[],version:"current",sidebarPosition:7,frontMatter:{label:"JPEG-XL",sidebar_position:7},sidebar:"tutorialSidebar",previous:{title:"AVIF",permalink:"/docs/images/AVIF"},next:{title:"x264",permalink:"/docs/encoders/x264"}},s={},p=[{value:"Usage",id:"usage",level:2},{value:"Decoding",id:"decoding",level:3},{value:"Encoding",id:"encoding",level:3},{value:"Distance and quality",id:"distance-and-quality",level:4},{value:"Effort",id:"effort",level:4},{value:"Performance Checklist",id:"performance-checklist",level:2}],c={toc:p},d="wrapper";function m(e){let{components:t,...n}=e;return(0,i.kt)(d,(0,a.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"jpeg-xl"},"JPEG-XL"),(0,i.kt)("admonition",{title:"Help Wanted",type:"warning"},(0,i.kt)("p",{parentName:"admonition"},"This section is in need of contributions. If you believe you can help, please see our ",(0,i.kt)("a",{parentName:"p",href:"/docs/contribution-guide"},"Contribution Guide")," to get started as a contributor!")),(0,i.kt)("p",null,"JPEG-XL (JXL) is a compression format for images that was developed by the Joint Photographic Experts Group (JPEG) in 2020. It is designed to provide improved compression efficiency compared to the traditional ",(0,i.kt)("a",{parentName:"p",href:"/docs/images/JPEG"},"JPEG")," format, while still maintaining image quality. JPEG-XL uses a combination of techniques such as perceptual color encoding, advanced entropy coding, and a new image prediction method to achieve its improved compression performance. It also has a lossless JPEG recompression mode, where an existing JPEG file can be turned into a JXL that can be decoded for a bit-for-bit exact replica of the original JPEG."),(0,i.kt)("h2",{id:"usage"},"Usage"),(0,i.kt)("p",null,"While it has support by many image viewers, editors, and other software, such as GIMP, Krita, Safari, ImageMagick, and many more, the most complete set of tools for encoding, manipulating, and decoding ",(0,i.kt)("inlineCode",{parentName:"p"},".jxl")," files is libjxl, the reference library for the format."),(0,i.kt)("h3",{id:"decoding"},"Decoding"),(0,i.kt)("p",null,"Decoding a ",(0,i.kt)("inlineCode",{parentName:"p"},".jxl")," image is straightforward with libjxl's decoder, ",(0,i.kt)("inlineCode",{parentName:"p"},"djxl"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"djxl example.jxl example.png\n")),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"djxl")," can decode to pixels via pipes, png, apng for animated jxl, jpg, ppm, and pfm."),(0,i.kt)("p",null,"By default, if the ",(0,i.kt)("inlineCode",{parentName:"p"},".jxl")," file was encoded with lossless jpeg recompression, ",(0,i.kt)("inlineCode",{parentName:"p"},"djxl")," will rebuild the exact jpeg file that was originally compressed. To avoid this, and create a new jpeg file:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"djxl -j example.jxl example.jpg\n")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Keep in mind this is now a lossy process as ",(0,i.kt)("inlineCode",{parentName:"strong"},"djxl")," will decode to pixels, then encode a new ",(0,i.kt)("inlineCode",{parentName:"strong"},".jpg")," with those pixels.")),(0,i.kt)("h3",{id:"encoding"},"Encoding"),(0,i.kt)("p",null,"libjxl's encoder ",(0,i.kt)("inlineCode",{parentName:"p"},"cjxl")," has more options to play around with. It takes a few primary arguments, distance (",(0,i.kt)("inlineCode",{parentName:"p"},"-d"),"), quality (",(0,i.kt)("inlineCode",{parentName:"p"},"-q"),"), and effort (",(0,i.kt)("inlineCode",{parentName:"p"},"-e"),")."),(0,i.kt)("h4",{id:"distance-and-quality"},"Distance and quality"),(0,i.kt)("p",null,"Distance and quality are two ways of specifying ",(0,i.kt)("em",{parentName:"p"},"how much loss")," you are willing to tolerate, and as such, they are mutually exclusive, as they pull the same levers under the hood."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Distance is designed to map to how 'close' one must be to the source to notice any loss. It is represented as a scale between 0.0 & 25.0. 0.0 is ",(0,i.kt)("strong",{parentName:"li"},"mathematically lossless"),", every pixel will have the exact same value as the source. 1.0 is designed to be ",(0,i.kt)("strong",{parentName:"li"},"visually lossless"),", look the same at a normal viewing distance, and higher values have more loss."),(0,i.kt)("li",{parentName:"ul"},"Quality is designed to roughly map to ",(0,i.kt)("a",{parentName:"li",href:"/docs/images/JPEG"},"JPEG"),"'s quality argument. A range 0-100, where 100 is ",(0,i.kt)("strong",{parentName:"li"},"mathematically lossless"),", 90 is intended to be ",(0,i.kt)("strong",{parentName:"li"},"visually lossless"),", and 0 is almost unrecognizable as the original image.")),(0,i.kt)("h4",{id:"effort"},"Effort"),(0,i.kt)("p",null,"Effort is similar to ",(0,i.kt)("inlineCode",{parentName:"p"},"cpu-used")," in video encoding. It specifies the amount of effort the encoder will make in order to get the smallest file size it can. It takes the form of a range 1-9, where higher numbers will spend more resources to get diminishing returns in terms of smaller size, while lower values do the opposite, leaving file size on the table for faster encoding."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"cjxl -e 9 -d 0.3 example.png example.jxl\n")),(0,i.kt)("p",null,"Encoding with effort 9 and distance 0.3"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"cjxl example.jpg example.jxl\n")),(0,i.kt)("p",null,"This, by default uses lossless JPEG compression."),(0,i.kt)("h2",{id:"performance-checklist"},"Performance Checklist"),(0,i.kt)("p",null,"Lossless? ",(0,i.kt)("em",{parentName:"p"},"Yes")),(0,i.kt)("p",null,"Lossy? ",(0,i.kt)("em",{parentName:"p"},"Yes")),(0,i.kt)("p",null,"Supported Bit Depths:\n",(0,i.kt)("em",{parentName:"p"},"Up to 32 BPC")),(0,i.kt)("p",null,"HDR/Wide Gamut? ",(0,i.kt)("em",{parentName:"p"},"Yes")),(0,i.kt)("p",null,"Animation? ",(0,i.kt)("em",{parentName:"p"},"Yes")),(0,i.kt)("p",null,"Transparency? ",(0,i.kt)("em",{parentName:"p"},"Yes")),(0,i.kt)("p",null,"Progressive Decode? ",(0,i.kt)("em",{parentName:"p"},"Yes")),(0,i.kt)("p",null,"Royalty Free? ",(0,i.kt)("em",{parentName:"p"},"Yes")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1776fc83.db2049f7.js b/assets/js/1776fc83.db2049f7.js deleted file mode 100644 index e5686651d..000000000 --- a/assets/js/1776fc83.db2049f7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[6326],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>f});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),p=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},l=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),u=p(r),d=o,f=u["".concat(s,".").concat(d)]||u[d]||m[d]||i;return r?n.createElement(f,a(a({ref:t},l),{},{components:r})):n.createElement(f,a({ref:t},l))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=d;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[u]="string"==typeof e?e:o,a[1]=c;for(var p=2;p{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>m,frontMatter:()=>i,metadata:()=>c,toc:()=>p});var n=r(7462),o=(r(7294),r(3905));const i={label:"JPEG-XL",sidebar_position:7},a="JPEG-XL",c={unversionedId:"images/JXL",id:"images/JXL",title:"JPEG-XL",description:"This section is in need of contributions. If you believe you can help, please see our Contribution Guide to get started as a contributor!",source:"@site/docs/images/JXL.md",sourceDirName:"images",slug:"/images/JXL",permalink:"/docs/images/JXL",draft:!1,editUrl:"https://github.com/av1-community-contributors/codec-wiki/tree/main/docs/images/JXL.md",tags:[],version:"current",sidebarPosition:7,frontMatter:{label:"JPEG-XL",sidebar_position:7},sidebar:"tutorialSidebar",previous:{title:"AVIF",permalink:"/docs/images/AVIF"},next:{title:"x264",permalink:"/docs/encoders/x264"}},s={},p=[{value:"Performance Checklist",id:"performance-checklist",level:2}],l={toc:p},u="wrapper";function m(e){let{components:t,...r}=e;return(0,o.kt)(u,(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"jpeg-xl"},"JPEG-XL"),(0,o.kt)("admonition",{title:"Help Wanted",type:"warning"},(0,o.kt)("p",{parentName:"admonition"},"This section is in need of contributions. If you believe you can help, please see our ",(0,o.kt)("a",{parentName:"p",href:"/docs/contribution-guide"},"Contribution Guide")," to get started as a contributor!")),(0,o.kt)("p",null,"JPEG-XL is a compression format for images that was developed by the Joint Photographic Experts Group (JPEG) in 2020. It is designed to provide improved compression efficiency compared to the traditional ",(0,o.kt)("a",{parentName:"p",href:"/docs/images/JPEG"},"JPEG")," format, while still maintaining image quality. JPEG-XL uses a combination of techniques such as perceptual color encoding, advanced entropy coding, and a new image prediction method to achieve its improved compression performance."),(0,o.kt)("h2",{id:"performance-checklist"},"Performance Checklist"),(0,o.kt)("p",null,"Lossless? ",(0,o.kt)("em",{parentName:"p"},"Yes")),(0,o.kt)("p",null,"Lossy? ",(0,o.kt)("em",{parentName:"p"},"Yes")),(0,o.kt)("p",null,"Supported Bit Depths:\n",(0,o.kt)("em",{parentName:"p"},"Up to 32 BPC")),(0,o.kt)("p",null,"HDR/Wide Gamut? ",(0,o.kt)("em",{parentName:"p"},"Yes")),(0,o.kt)("p",null,"Animation? ",(0,o.kt)("em",{parentName:"p"},"Yes")),(0,o.kt)("p",null,"Transparency? ",(0,o.kt)("em",{parentName:"p"},"Yes")),(0,o.kt)("p",null,"Progressive Decode? ",(0,o.kt)("em",{parentName:"p"},"Yes")),(0,o.kt)("p",null,"Royalty Free? ",(0,o.kt)("em",{parentName:"p"},"Yes")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/19839cd1.1e966039.js b/assets/js/19839cd1.1e966039.js new file mode 100644 index 000000000..8f2b2e230 --- /dev/null +++ b/assets/js/19839cd1.1e966039.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[3958],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var o=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=o.createContext({}),c=function(e){var t=o.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=c(e.components);return o.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},m=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=c(n),m=r,f=u["".concat(l,".").concat(m)]||u[m]||d[m]||a;return n?o.createElement(f,i(i({ref:t},p),{},{components:n})):o.createElement(f,i({ref:t},p))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,i=new Array(a);i[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:r,i[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>c});var o=n(7462),r=(n(7294),n(3905));const a={label:"FLAC",sidebar_position:7},i="FLAC",s={unversionedId:"audio/FLAC",id:"audio/FLAC",title:"FLAC",description:"This section is in need of contributions. If you believe you can help, please see our Contribution Guide to get started as a contributor!",source:"@site/docs/audio/FLAC.md",sourceDirName:"audio",slug:"/audio/FLAC",permalink:"/docs/audio/FLAC",draft:!1,editUrl:"https://github.com/av1-community-contributors/codec-wiki/tree/main/docs/audio/FLAC.md",tags:[],version:"current",sidebarPosition:7,frontMatter:{label:"FLAC",sidebar_position:7},sidebar:"tutorialSidebar",previous:{title:"Speex",permalink:"/docs/audio/Speex"},next:{title:"WavPack",permalink:"/docs/audio/WavPack"}},l={},c=[{value:"Software support",id:"software-support",level:2},{value:"WAV to FLAC using FFmpeg:",id:"wav-to-flac-using-ffmpeg",level:3},{value:"WAV to FLAC using FLAC command-line tool:",id:"wav-to-flac-using-flac-command-line-tool",level:3}],p={toc:c},u="wrapper";function d(e){let{components:t,...n}=e;return(0,r.kt)(u,(0,o.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"flac"},"FLAC"),(0,r.kt)("admonition",{title:"Help Wanted",type:"warning"},(0,r.kt)("p",{parentName:"admonition"},"This section is in need of contributions. If you believe you can help, please see our ",(0,r.kt)("a",{parentName:"p",href:"/docs/contribution-guide"},"Contribution Guide")," to get started as a contributor!")),(0,r.kt)("p",null,"FLAC (Free Lossless Audio Coding) is an open-source lossless audio codec with widespread support & compatibility released in 2001. It represents the most efficent lossless audio format in common use today."),(0,r.kt)("p",null,"FLAC is commonly contained in a ogg container with either a ",(0,r.kt)("inlineCode",{parentName:"p"},".flac")," or ",(0,r.kt)("inlineCode",{parentName:"p"},".ogg")," extension. It can less commonly be used within a matroska container (",(0,r.kt)("inlineCode",{parentName:"p"},".mkv")," or ",(0,r.kt)("inlineCode",{parentName:"p"},".mka"),") for mixing with a video stream."),(0,r.kt)("h2",{id:"software-support"},"Software support"),(0,r.kt)("p",null,"FLAC is supported by the majority of web browsers and media players in common use as of 2023."),(0,r.kt)("h3",{id:"wav-to-flac-using-ffmpeg"},"WAV to FLAC using ",(0,r.kt)("a",{parentName:"h3",href:"/docs/utilities/ffmpeg"},"FFmpeg"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"ffmpeg -i example.wav -c:a flac example.flac\n")),(0,r.kt)("h3",{id:"wav-to-flac-using-flac-command-line-tool"},"WAV to FLAC using FLAC command-line tool:"),(0,r.kt)("p",null,"You can include an argument of a number 0-8 to specify the compression effort, 0 being fastest and 8 having the highest compression."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"flac example.wav -8 -o example.flac\n")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/19839cd1.76168225.js b/assets/js/19839cd1.76168225.js deleted file mode 100644 index 94080fa5a..000000000 --- a/assets/js/19839cd1.76168225.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[3958],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>b});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var u=n.createContext({}),s=function(e){var t=n.useContext(u),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},p=function(e){var t=s(e.components);return n.createElement(u.Provider,{value:t},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,u=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),l=s(r),f=o,b=l["".concat(u,".").concat(f)]||l[f]||d[f]||i;return r?n.createElement(b,a(a({ref:t},p),{},{components:r})):n.createElement(b,a({ref:t},p))}));function b(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=f;var c={};for(var u in t)hasOwnProperty.call(t,u)&&(c[u]=t[u]);c.originalType=e,c[l]="string"==typeof e?e:o,a[1]=c;for(var s=2;s{r.r(t),r.d(t,{assets:()=>u,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>c,toc:()=>s});var n=r(7462),o=(r(7294),r(3905));const i={label:"FLAC",sidebar_position:7},a="FLAC",c={unversionedId:"audio/FLAC",id:"audio/FLAC",title:"FLAC",description:"This section is in need of contributions. If you believe you can help, please see our Contribution Guide to get started as a contributor!",source:"@site/docs/audio/FLAC.md",sourceDirName:"audio",slug:"/audio/FLAC",permalink:"/docs/audio/FLAC",draft:!1,editUrl:"https://github.com/av1-community-contributors/codec-wiki/tree/main/docs/audio/FLAC.md",tags:[],version:"current",sidebarPosition:7,frontMatter:{label:"FLAC",sidebar_position:7},sidebar:"tutorialSidebar",previous:{title:"Speex",permalink:"/docs/audio/Speex"},next:{title:"WavPack",permalink:"/docs/audio/WavPack"}},u={},s=[],p={toc:s},l="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(l,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"flac"},"FLAC"),(0,o.kt)("admonition",{title:"Help Wanted",type:"warning"},(0,o.kt)("p",{parentName:"admonition"},"This section is in need of contributions. If you believe you can help, please see our ",(0,o.kt)("a",{parentName:"p",href:"/docs/contribution-guide"},"Contribution Guide")," to get started as a contributor!")),(0,o.kt)("p",null,"FLAC is an open-source lossless audio codec with widespread support & compatibility."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/3494e53a.8d763d6c.js b/assets/js/3494e53a.8d763d6c.js deleted file mode 100644 index 6c4a7eb12..000000000 --- a/assets/js/3494e53a.8d763d6c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[370],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>f});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},l=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=p(r),d=o,f=u["".concat(c,".").concat(d)]||u[d]||m[d]||i;return r?n.createElement(f,a(a({ref:t},l),{},{components:r})):n.createElement(f,a({ref:t},l))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:o,a[1]=s;for(var p=2;p{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>m,frontMatter:()=>i,metadata:()=>s,toc:()=>p});var n=r(7462),o=(r(7294),r(3905));const i={label:"WebP",sidebar_position:4},a="WebP",s={unversionedId:"images/WebP",id:"images/WebP",title:"WebP",description:"This section is in need of contributions. If you believe you can help, please see our Contribution Guide to get started as a contributor!",source:"@site/docs/images/WebP.md",sourceDirName:"images",slug:"/images/WebP",permalink:"/docs/images/WebP",draft:!1,editUrl:"https://github.com/av1-community-contributors/codec-wiki/tree/main/docs/images/WebP.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{label:"WebP",sidebar_position:4},sidebar:"tutorialSidebar",previous:{title:"HEIC",permalink:"/docs/images/HEIC"},next:{title:"JPEG 2000",permalink:"/docs/images/JPEG2000"}},c={},p=[{value:"Performance Checklist",id:"performance-checklist",level:2}],l={toc:p},u="wrapper";function m(e){let{components:t,...r}=e;return(0,o.kt)(u,(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"webp"},"WebP"),(0,o.kt)("admonition",{title:"Help Wanted",type:"warning"},(0,o.kt)("p",{parentName:"admonition"},"This section is in need of contributions. If you believe you can help, please see our ",(0,o.kt)("a",{parentName:"p",href:"/docs/contribution-guide"},"Contribution Guide")," to get started as a contributor!")),(0,o.kt)("p",null,'WebP is a free image file format first released by Google in 2010. It consists of 2 primary "modes" of operation. A lossy mode derived from the ',(0,o.kt)("a",{parentName:"p",href:"/docs/video/VP8"},"VP8")," video codec, and a novel lossless mode added in 2011."),(0,o.kt)("h2",{id:"performance-checklist"},"Performance Checklist"),(0,o.kt)("p",null,"Lossless? ",(0,o.kt)("em",{parentName:"p"},"Yes")),(0,o.kt)("p",null,"Lossy? ",(0,o.kt)("em",{parentName:"p"},"Yes")),(0,o.kt)("p",null,"Supported Bit Depth:\n",(0,o.kt)("em",{parentName:"p"},"8 BPC")),(0,o.kt)("p",null,"HDR/Wide Gamut? ",(0,o.kt)("em",{parentName:"p"},"No")),(0,o.kt)("p",null,"Animation? ",(0,o.kt)("em",{parentName:"p"},"Yes")),(0,o.kt)("p",null,"Transparency? ",(0,o.kt)("em",{parentName:"p"},"Yes")),(0,o.kt)("p",null,"Progressive Decode? ",(0,o.kt)("em",{parentName:"p"},"No")),(0,o.kt)("p",null,"Royalty Free? ",(0,o.kt)("em",{parentName:"p"},"Yes")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/3494e53a.fe7bea70.js b/assets/js/3494e53a.fe7bea70.js new file mode 100644 index 000000000..dcb9d35cc --- /dev/null +++ b/assets/js/3494e53a.fe7bea70.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[370],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>b});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),p=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},c=function(e){var t=p(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),u=p(n),m=o,b=u["".concat(l,".").concat(m)]||u[m]||d[m]||i;return n?r.createElement(b,a(a({ref:t},c),{},{components:n})):r.createElement(b,a({ref:t},c))}));function b(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:o,a[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>p});var r=n(7462),o=(n(7294),n(3905));const i={label:"WebP",sidebar_position:4},a="WebP",s={unversionedId:"images/WebP",id:"images/WebP",title:"WebP",description:"This section is in need of contributions. If you believe you can help, please see our Contribution Guide to get started as a contributor!",source:"@site/docs/images/WebP.md",sourceDirName:"images",slug:"/images/WebP",permalink:"/docs/images/WebP",draft:!1,editUrl:"https://github.com/av1-community-contributors/codec-wiki/tree/main/docs/images/WebP.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{label:"WebP",sidebar_position:4},sidebar:"tutorialSidebar",previous:{title:"HEIC",permalink:"/docs/images/HEIC"},next:{title:"JPEG 2000",permalink:"/docs/images/JPEG2000"}},l={},p=[{value:"Encoding",id:"encoding",level:2},{value:"Using libwebp",id:"using-libwebp",level:3},{value:"Performance Checklist",id:"performance-checklist",level:2}],c={toc:p},u="wrapper";function d(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"webp"},"WebP"),(0,o.kt)("admonition",{title:"Help Wanted",type:"warning"},(0,o.kt)("p",{parentName:"admonition"},"This section is in need of contributions. If you believe you can help, please see our ",(0,o.kt)("a",{parentName:"p",href:"/docs/contribution-guide"},"Contribution Guide")," to get started as a contributor!")),(0,o.kt)("p",null,'WebP is a free image file format first released by Google in 2010. It consists of 2 primary "modes" of operation. A lossy mode derived from the ',(0,o.kt)("a",{parentName:"p",href:"/docs/video/VP8"},"VP8")," video codec, and a novel lossless mode added in 2011."),(0,o.kt)("h2",{id:"encoding"},"Encoding"),(0,o.kt)("h3",{id:"using-libwebp"},"Using libwebp"),(0,o.kt)("p",null,"libwebp supports WebP, JPEG, PNG, PNM (PGM, PPM, PAM), TIFF as input formats, and a quality (",(0,o.kt)("inlineCode",{parentName:"p"},"-q"),") value between 0 (lowest quality, smallest file) and 100 (highest quality, largest file). Should you need the lossless mode, you need to instead use a ",(0,o.kt)("inlineCode",{parentName:"p"},"-z")," argument, with values representing the effort used between 0 (fastest encode, largest file) and 9 (slowest encode, smallest file)."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"cwebp example.png -q 75 -o example.webp\n")),(0,o.kt)("h2",{id:"performance-checklist"},"Performance Checklist"),(0,o.kt)("p",null,"Lossless? ",(0,o.kt)("em",{parentName:"p"},"Yes")),(0,o.kt)("p",null,"Lossy? ",(0,o.kt)("em",{parentName:"p"},"Yes")),(0,o.kt)("p",null,"Supported Bit Depth:\n",(0,o.kt)("em",{parentName:"p"},"8 BPC")),(0,o.kt)("p",null,"HDR/Wide Gamut? ",(0,o.kt)("em",{parentName:"p"},"No")),(0,o.kt)("p",null,"Animation? ",(0,o.kt)("em",{parentName:"p"},"Yes")),(0,o.kt)("p",null,"Transparency? ",(0,o.kt)("em",{parentName:"p"},"Yes")),(0,o.kt)("p",null,"Progressive Decode? ",(0,o.kt)("em",{parentName:"p"},"No")),(0,o.kt)("p",null,"Royalty Free? ",(0,o.kt)("em",{parentName:"p"},"Yes")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/39634027.231831df.js b/assets/js/39634027.231831df.js deleted file mode 100644 index 8a3aacce7..000000000 --- a/assets/js/39634027.231831df.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[4100],{5745:e=>{e.exports=JSON.parse('{"name":"docusaurus-plugin-content-pages","id":"default"}')}}]); \ No newline at end of file diff --git a/assets/js/59641f86.29ad1f11.js b/assets/js/59641f86.29ad1f11.js new file mode 100644 index 000000000..6126feaeb --- /dev/null +++ b/assets/js/59641f86.29ad1f11.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[3312],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>m});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var d=n.createContext({}),l=function(e){var t=n.useContext(d),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(d.Provider,{value:t},e.children)},s="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,d=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),s=l(r),f=o,m=s["".concat(d,".").concat(f)]||s[f]||u[f]||i;return r?n.createElement(m,a(a({ref:t},p),{},{components:r})):n.createElement(m,a({ref:t},p))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=f;var c={};for(var d in t)hasOwnProperty.call(t,d)&&(c[d]=t[d]);c.originalType=e,c[s]="string"==typeof e?e:o,a[1]=c;for(var l=2;l{r.r(t),r.d(t,{assets:()=>d,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var n=r(7462),o=(r(7294),r(3905));const i={label:"Theora",sidebar_position:9},a="Theora",c={unversionedId:"video/Theora",id:"video/Theora",title:"Theora",description:"This section is in need of contributions. If you believe you can help, please see our Contribution Guide to get started as a contributor!",source:"@site/docs/video/Theora.md",sourceDirName:"video",slug:"/video/Theora",permalink:"/docs/video/Theora",draft:!1,editUrl:"https://github.com/av1-community-contributors/codec-wiki/tree/main/docs/video/Theora.md",tags:[],version:"current",sidebarPosition:9,frontMatter:{label:"Theora",sidebar_position:9},sidebar:"tutorialSidebar",previous:{title:"VC-1",permalink:"/docs/video/VC-1"},next:{title:"FFV1",permalink:"/docs/video/FFV1"}},d={},l=[{value:"Encoding",id:"encoding",level:2}],p={toc:l},s="wrapper";function u(e){let{components:t,...r}=e;return(0,o.kt)(s,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"theora"},"Theora"),(0,o.kt)("admonition",{title:"Help Wanted",type:"warning"},(0,o.kt)("p",{parentName:"admonition"},"This section is in need of contributions. If you believe you can help, please see our ",(0,o.kt)("a",{parentName:"p",href:"/docs/contribution-guide"},"Contribution Guide")," to get started as a contributor!")),(0,o.kt)("p",null,"Theora is a legacy video codec first released in 2004. It is derived from VP3, part of the same family of codecs that formed ",(0,o.kt)("a",{parentName:"p",href:"/docs/video/VP8"},"VP8"),", ",(0,o.kt)("a",{parentName:"p",href:"/docs/video/VP9"},"VP9")," and ",(0,o.kt)("a",{parentName:"p",href:"/docs/video/AV1"},"AV1"),"."),(0,o.kt)("h2",{id:"encoding"},"Encoding"),(0,o.kt)("p",null,"Theora is frequently contained within a ogg (",(0,o.kt)("inlineCode",{parentName:"p"},".ogg")," or ",(0,o.kt)("inlineCode",{parentName:"p"},".ogv"),") container with ",(0,o.kt)("a",{parentName:"p",href:"/docs/audio/Vorbis"},"vorbis")," audio."),(0,o.kt)("p",null,"To be filled."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/59641f86.5b478d95.js b/assets/js/59641f86.5b478d95.js deleted file mode 100644 index bc3a1ba08..000000000 --- a/assets/js/59641f86.5b478d95.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[3312],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>b});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),u=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},l=function(e){var t=u(e.components);return n.createElement(s.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),p=u(r),f=o,b=p["".concat(s,".").concat(f)]||p[f]||d[f]||i;return r?n.createElement(b,a(a({ref:t},l),{},{components:r})):n.createElement(b,a({ref:t},l))}));function b(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=f;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[p]="string"==typeof e?e:o,a[1]=c;for(var u=2;u{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>c,toc:()=>u});var n=r(7462),o=(r(7294),r(3905));const i={label:"Theora",sidebar_position:9},a="Theora",c={unversionedId:"video/Theora",id:"video/Theora",title:"Theora",description:"This section is in need of contributions. If you believe you can help, please see our Contribution Guide to get started as a contributor!",source:"@site/docs/video/Theora.md",sourceDirName:"video",slug:"/video/Theora",permalink:"/docs/video/Theora",draft:!1,editUrl:"https://github.com/av1-community-contributors/codec-wiki/tree/main/docs/video/Theora.md",tags:[],version:"current",sidebarPosition:9,frontMatter:{label:"Theora",sidebar_position:9},sidebar:"tutorialSidebar",previous:{title:"VC-1",permalink:"/docs/video/VC-1"},next:{title:"FFV1",permalink:"/docs/video/FFV1"}},s={},u=[],l={toc:u},p="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(p,(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"theora"},"Theora"),(0,o.kt)("admonition",{title:"Help Wanted",type:"warning"},(0,o.kt)("p",{parentName:"admonition"},"This section is in need of contributions. If you believe you can help, please see our ",(0,o.kt)("a",{parentName:"p",href:"/docs/contribution-guide"},"Contribution Guide")," to get started as a contributor!")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/608061a6.d75443b3.js b/assets/js/608061a6.41c28a06.js similarity index 97% rename from assets/js/608061a6.d75443b3.js rename to assets/js/608061a6.41c28a06.js index f6d90a92d..8d23b97e8 100644 --- a/assets/js/608061a6.d75443b3.js +++ b/assets/js/608061a6.41c28a06.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[9967],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>g});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},d=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},p=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),u=l(n),p=o,g=u["".concat(c,".").concat(p)]||u[p]||m[p]||i;return n?r.createElement(g,a(a({ref:t},d),{},{components:n})):r.createElement(g,a({ref:t},d))}));function g(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=p;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:o,a[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>m,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var r=n(7462),o=(n(7294),n(3905));const i={title:"Embedding the Un-Embeddable: Dissecting discord.nfp.is, stolen.shoes & Others",description:"Revealing the secrets of those websites that allow you to embed entire movies, AV1, and videos over 500MB on Discord.",slug:"embedding-the-un-embeddable",authors:[{name:"Simulping",title:"Maintainer / Encoder",url:"https://github.com/Simulping",image_url:"https://avatars.githubusercontent.com/u/12994794?v=4"}],tags:["video","discord"],image:"/img/discord-embed-blog-image.webp",hide_table_of_contents:!1},a=void 0,s={permalink:"/blog/embedding-the-un-embeddable",source:"@site/blog/2023-10-29-embedding-the-un-embeddable.md",title:"Embedding the Un-Embeddable: Dissecting discord.nfp.is, stolen.shoes & Others",description:"Revealing the secrets of those websites that allow you to embed entire movies, AV1, and videos over 500MB on Discord.",date:"2023-10-29T00:00:00.000Z",formattedDate:"October 29, 2023",tags:[{label:"video",permalink:"/blog/tags/video"},{label:"discord",permalink:"/blog/tags/discord"}],readingTime:8.91,hasTruncateMarker:!0,authors:[{name:"Simulping",title:"Maintainer / Encoder",url:"https://github.com/Simulping",image_url:"https://avatars.githubusercontent.com/u/12994794?v=4",imageURL:"https://avatars.githubusercontent.com/u/12994794?v=4"}],frontMatter:{title:"Embedding the Un-Embeddable: Dissecting discord.nfp.is, stolen.shoes & Others",description:"Revealing the secrets of those websites that allow you to embed entire movies, AV1, and videos over 500MB on Discord.",slug:"embedding-the-un-embeddable",authors:[{name:"Simulping",title:"Maintainer / Encoder",url:"https://github.com/Simulping",image_url:"https://avatars.githubusercontent.com/u/12994794?v=4",imageURL:"https://avatars.githubusercontent.com/u/12994794?v=4"}],tags:["video","discord"],image:"/img/discord-embed-blog-image.webp",hide_table_of_contents:!1},nextItem:{title:"AV1 Encoding for Dummies",permalink:"/blog/av1-encoding-for-dummies"}},c={authorsImageUrls:[void 0]},l=[{value:"A Scenario",id:"a-scenario",level:2}],d={toc:l},u="wrapper";function m(e){let{components:t,...i}=e;return(0,o.kt)(u,(0,r.Z)({},d,i,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("admonition",{title:"Copyright Disclosure",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"The Codec Wiki unequivocally condemns any form of piracy, including the unauthorized distribution of copyrighted content. This blog post is intended to educate & inform. You may not use the tools discussed to infringe upon the intellectual property rights of content creators without serious legal risk. We encourage our readers to respect copyright laws & use the tools we discuss here appropriately.")),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"Feature image",src:n(5477).Z,width:"1920",height:"1080"}),"\n",(0,o.kt)("strong",{parentName:"p"},'A 567.14 MB, 12 min 11 s, 2K (2,048 x 858), VP9 + Opus, 6.51 Mbps average, Blender short film "Cosmos Laundromat"')),(0,o.kt)("h2",{id:"a-scenario"},"A Scenario"),(0,o.kt)("p",null,"While chatting in your favorite Discord servers & group chats, you may see a friend send a weird link. You might even consider it suspicious on first glance. It is a video featuring an image of a movie poster with a play button that is almost begging to be clicked. Naturally, you click it."))}m.isMDXComponent=!0},5477:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/discord-embed-blog-image-2bcaf4f73f5fa33664328756753f3041.webp"}}]); \ No newline at end of file +"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[9967],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>g});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},d=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},p=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),u=l(n),p=o,g=u["".concat(c,".").concat(p)]||u[p]||m[p]||i;return n?r.createElement(g,a(a({ref:t},d),{},{components:n})):r.createElement(g,a({ref:t},d))}));function g(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=p;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:o,a[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>m,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var r=n(7462),o=(n(7294),n(3905));const i={title:"Embedding the Un-Embeddable: Dissecting discord.nfp.is, stolen.shoes & Others",description:"Revealing the secrets of those websites that allow you to embed entire movies, AV1, and videos over 500MB on Discord.",slug:"embedding-the-un-embeddable",authors:[{name:"Simulping",title:"Maintainer / Encoder",url:"https://github.com/Simulping",image_url:"https://avatars.githubusercontent.com/u/12994794?v=4"}],tags:["video","discord"],image:"/img/discord-embed-blog-image.webp",hide_table_of_contents:!1},a=void 0,s={permalink:"/blog/embedding-the-un-embeddable",source:"@site/blog/2023-10-29-embedding-the-un-embeddable.md",title:"Embedding the Un-Embeddable: Dissecting discord.nfp.is, stolen.shoes & Others",description:"Revealing the secrets of those websites that allow you to embed entire movies, AV1, and videos over 500MB on Discord.",date:"2023-10-29T00:00:00.000Z",formattedDate:"October 29, 2023",tags:[{label:"video",permalink:"/blog/tags/video"},{label:"discord",permalink:"/blog/tags/discord"}],readingTime:8.91,hasTruncateMarker:!0,authors:[{name:"Simulping",title:"Maintainer / Encoder",url:"https://github.com/Simulping",image_url:"https://avatars.githubusercontent.com/u/12994794?v=4",imageURL:"https://avatars.githubusercontent.com/u/12994794?v=4"}],frontMatter:{title:"Embedding the Un-Embeddable: Dissecting discord.nfp.is, stolen.shoes & Others",description:"Revealing the secrets of those websites that allow you to embed entire movies, AV1, and videos over 500MB on Discord.",slug:"embedding-the-un-embeddable",authors:[{name:"Simulping",title:"Maintainer / Encoder",url:"https://github.com/Simulping",image_url:"https://avatars.githubusercontent.com/u/12994794?v=4",imageURL:"https://avatars.githubusercontent.com/u/12994794?v=4"}],tags:["video","discord"],image:"/img/discord-embed-blog-image.webp",hide_table_of_contents:!1},nextItem:{title:"AV1 Encoding for Dummies",permalink:"/blog/av1-encoding-for-dummies"}},c={authorsImageUrls:[void 0]},l=[{value:"A Scenario",id:"a-scenario",level:2}],d={toc:l},u="wrapper";function m(e){let{components:t,...i}=e;return(0,o.kt)(u,(0,r.Z)({},d,i,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("admonition",{title:"Copyright Disclosure",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"The Codec Wiki unequivocally condemns any form of piracy, including the unauthorized distribution of copyrighted content. This blog post is intended to educate & inform. You may not use the tools discussed to infringe upon the intellectual property rights of content creators without serious legal risk. We encourage our readers to respect copyright laws & use the tools we discuss here appropriately.")),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"Feature image",src:n(3093).Z,width:"1920",height:"1080"}),"\n",(0,o.kt)("strong",{parentName:"p"},'A 567.14 MB, 12 min 11 s, 2K (2,048 x 858), VP9 + Opus, 6.51 Mbps average, Blender short film "Cosmos Laundromat"')),(0,o.kt)("h2",{id:"a-scenario"},"A Scenario"),(0,o.kt)("p",null,"While chatting in your favorite Discord servers & group chats, you may see a friend send a weird link. You might even consider it suspicious on first glance. It is a video featuring an image of a movie poster with a play button that is almost begging to be clicked. Naturally, you click it."))}m.isMDXComponent=!0},3093:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/discord-embed-blog-image-2bcaf4f73f5fa33664328756753f3041.webp"}}]); \ No newline at end of file diff --git a/assets/js/60e1ac2d.642d5cf9.js b/assets/js/60e1ac2d.323bcb16.js similarity index 99% rename from assets/js/60e1ac2d.642d5cf9.js rename to assets/js/60e1ac2d.323bcb16.js index fba582120..988656802 100644 --- a/assets/js/60e1ac2d.642d5cf9.js +++ b/assets/js/60e1ac2d.323bcb16.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[5581],{3905:(e,t,a)=>{a.d(t,{Zo:()=>m,kt:()=>h});var n=a(7294);function i(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function r(e){for(var t=1;t=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var s=n.createContext({}),p=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):r(r({},t),e)),a},m=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},c=n.forwardRef((function(e,t){var a=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,m=l(e,["components","mdxType","originalType","parentName"]),u=p(a),c=i,h=u["".concat(s,".").concat(c)]||u[c]||d[c]||o;return a?n.createElement(h,r(r({ref:t},m),{},{components:a})):n.createElement(h,r({ref:t},m))}));function h(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=a.length,r=new Array(o);r[0]=c;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[u]="string"==typeof e?e:i,r[1]=l;for(var p=2;p{a.r(t),a.d(t,{assets:()=>s,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>l,toc:()=>p});var n=a(7462),i=(a(7294),a(3905));const o={title:"AV1 Encoding for Dummies",description:"This guide will show you how to encode in AV1 the *right* and *optimal* way.",slug:"av1-encoding-for-dummies",authors:[{name:"Simulping",title:"Maintainer / Encoder",url:"https://github.com/Simulping",image_url:"https://avatars.githubusercontent.com/u/12994794?v=4"},{name:"Gianni Rosato",title:"Maintainer",url:"https://github.com/gianni-rosato",image_url:"https://avatars.githubusercontent.com/u/35711760?v=4"}],tags:["video","compression"],image:"/img/compare-guide.webp",hide_table_of_contents:!1},r=void 0,l={permalink:"/blog/av1-encoding-for-dummies",source:"@site/blog/2023-09-03-av1-for-dummies.md",title:"AV1 Encoding for Dummies",description:"This guide will show you how to encode in AV1 the *right* and *optimal* way.",date:"2023-09-03T00:00:00.000Z",formattedDate:"September 3, 2023",tags:[{label:"video",permalink:"/blog/tags/video"},{label:"compression",permalink:"/blog/tags/compression"}],readingTime:15.145,hasTruncateMarker:!0,authors:[{name:"Simulping",title:"Maintainer / Encoder",url:"https://github.com/Simulping",image_url:"https://avatars.githubusercontent.com/u/12994794?v=4",imageURL:"https://avatars.githubusercontent.com/u/12994794?v=4"},{name:"Gianni Rosato",title:"Maintainer",url:"https://github.com/gianni-rosato",image_url:"https://avatars.githubusercontent.com/u/35711760?v=4",imageURL:"https://avatars.githubusercontent.com/u/35711760?v=4"}],frontMatter:{title:"AV1 Encoding for Dummies",description:"This guide will show you how to encode in AV1 the *right* and *optimal* way.",slug:"av1-encoding-for-dummies",authors:[{name:"Simulping",title:"Maintainer / Encoder",url:"https://github.com/Simulping",image_url:"https://avatars.githubusercontent.com/u/12994794?v=4",imageURL:"https://avatars.githubusercontent.com/u/12994794?v=4"},{name:"Gianni Rosato",title:"Maintainer",url:"https://github.com/gianni-rosato",image_url:"https://avatars.githubusercontent.com/u/35711760?v=4",imageURL:"https://avatars.githubusercontent.com/u/35711760?v=4"}],tags:["video","compression"],image:"/img/compare-guide.webp",hide_table_of_contents:!1},prevItem:{title:"Embedding the Un-Embeddable: Dissecting discord.nfp.is, stolen.shoes & Others",permalink:"/blog/embedding-the-un-embeddable"},nextItem:{title:"Site Optimization by Reducing Image Load on the Web",permalink:"/blog/site-optimization"}},s={authorsImageUrls:[void 0,void 0]},p=[{value:"Installing the Tools",id:"installing-the-tools",level:2},{value:"Microsoft Windows",id:"microsoft-windows",level:3},{value:"macOS",id:"macos",level:3},{value:"Linux",id:"linux",level:3},{value:"The Easy Ways",id:"the-easy-ways",level:4},{value:"The Compiling Route",id:"the-compiling-route",level:4},{value:"Ubuntu",id:"ubuntu",level:5},{value:"Arch",id:"arch",level:5},{value:"Compiling aom-av1-lavish",id:"compiling-aom-av1-lavish",level:4},{value:"Encoding",id:"encoding",level:2},{value:"Merging Everything",id:"merging-everything",level:2},{value:"Tips & Tricks",id:"tips--tricks",level:2},{value:"Final Thoughts",id:"final-thoughts",level:2}],m={toc:p},u="wrapper";function d(e){let{components:t,...o}=e;return(0,i.kt)(u,(0,n.Z)({},m,o,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"This guide will show you how to encode in AV1 the ",(0,i.kt)("em",{parentName:"p"},"right")," and ",(0,i.kt)("em",{parentName:"p"},"optimal")," way. Yes, you using standalone ",(0,i.kt)("inlineCode",{parentName:"p"},"libaom"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"libsvtav1"),", and ",(0,i.kt)("inlineCode",{parentName:"p"},"librav1e")," from FFmpeg or even piping ",(0,i.kt)("inlineCode",{parentName:"p"},"yuv4mpeg")," into ",(0,i.kt)("strong",{parentName:"p"},"mainline")," aomenc are all unoptimal."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"Compare",src:a(8804).Z,width:"1045",height:"588"})),(0,i.kt)("p",null,"In this guide, we'll be installing Av1an for chunked encoding and infinite threading, because the current state of AV1 encoders, except for ",(0,i.kt)("a",{parentName:"p",href:"https://wiki.x266.mov/docs/encoders/SVT-AV1"},"SVT-AV1"),", unfortunately lacks threading and will only use very low amount of cores, which hampers speeds. The only caveat to this approach is ",(0,i.kt)("strong",{parentName:"p"},"RAM consumption"),", encoding 2160p (4K) with ",(0,i.kt)("a",{parentName:"p",href:"https://wiki.x266.mov/docs/encoders/aomenc"},"aomenc")," with 4 workers could take upwards of ",(0,i.kt)("strong",{parentName:"p"},"16GB")," of RAM! So do keep this in mind."),(0,i.kt)("h2",{id:"installing-the-tools"},"Installing the Tools"),(0,i.kt)("h3",{id:"microsoft-windows"},"Microsoft Windows"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"The GUI Way:")),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Install ",(0,i.kt)("a",{parentName:"li",href:"https://github.com/n00mkrad/nmkoder"},"NMKODER")," which is a GUI front-end to av1an with all dependencies installed."),(0,i.kt)("li",{parentName:"ol"},"You're done, you can skip to the encoding part")),(0,i.kt)("admonition",{title:"Almost abandonware",type:"warning"},(0,i.kt)("p",{parentName:"admonition"},"Since Nmkoder already ships everything by default and its last release was 29th March 2022. You need to manually update all encoders and tools to get better encoding speeds. Missing out on updates will result in your encodes being sub-optimal.")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"The Automated Way:")),(0,i.kt)("p",null,"There is now a batch script for automating the install process, which can be found ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/Hishiro64/av1an-win-script"},"here"),". The instructions are in the README file."),(0,i.kt)("admonition",{type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"The script will download outdated version encoders and tools such as ",(0,i.kt)("inlineCode",{parentName:"p"},"aom-av1-psy")," and MKVToolNix v76.0, if you are fine with these you can proceed.")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"The Manual Way:")),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"Install ",(0,i.kt)("strong",{parentName:"p"},"Python 3.10.x, this will change so consult from the")," ",(0,i.kt)("a",{parentName:"p",href:"http://www.vapoursynth.com/doc/installation.html"},"Vapoursynth website")," ",(0,i.kt)("strong",{parentName:"p"},"if you're reading this from the future")," from ",(0,i.kt)("a",{parentName:"p",href:"https://www.python.org/downloads/windows/"},"here"),' and select "Windows Installer 64-bit". Upon installation check the tick for adding Python to PATH like so\n',(0,i.kt)("img",{alt:"Python PATH",src:a(7843).Z,width:"672",height:"417"}),")")),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"Download and install Vapoursynth from ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/vapoursynth/vapoursynth/releases"},"here"),' and select "VapourSynth64-RXX.exe"')),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"Open the terminal and type ",(0,i.kt)("inlineCode",{parentName:"p"},"vsrepo.py install lsmas ffms2")," to install some plugins for Av1an to work.")),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"Download MKVToolNix from ",(0,i.kt)("a",{parentName:"p",href:"https://mkvtoolnix.download/downloads.html#windows"},"here"),', select "mkvtoolnix-64bit-XX.X.X-setup.exe", and install ',(0,i.kt)("strong",{parentName:"p"},"(Also available on winget!)"))),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"Download Av1an from ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/master-of-zen/Av1an/releases"},"here"),' (SELECT LATEST AND CLICK THE "ASSETS" DROPDOWN)')),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"Download ",(0,i.kt)("strong",{parentName:"p"},"shared libraries")," FFmpeg from ",(0,i.kt)("a",{parentName:"p",href:"https://www.gyan.dev/ffmpeg/builds"},"gyan.dev"))),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"Download a pre-built fork of Aomenc (",(0,i.kt)("a",{parentName:"p",href:"https://github.com/Clybius/aom-av1-lavish/tree/Endless_Merging"},"aom-av1-lavish"),") which has neat stuff such as sane defaults, new tunes, optimizations, etc. This can be downloaded for Windows ",(0,i.kt)("a",{parentName:"p",href:"https://autumn.revolt.chat/attachments/download/-2EiZW1edcT9anApFZ1PJBEber-pJ6z02NiQBjbr28"},"here")," ",(0,i.kt)("em",{parentName:"p"},"(Current as of Sept 6, 2023)")),(0,i.kt)("admonition",{parentName:"li",type:"info"},(0,i.kt)("p",{parentName:"admonition"},"If you opt to compile aomenc yourself, you can view the instructions on how to do that ",(0,i.kt)("a",{parentName:"p",href:"https://wiki.x266.mov/docs/encoders/aomenc/#installation"},"here"),"."))),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"Move Av1an, FFmpeg ",(0,i.kt)("strong",{parentName:"p"},"(Including the FFmpeg DLLs)"),", and aomenc to somewhere preferable, eg ",(0,i.kt)("inlineCode",{parentName:"p"},"C:\\Encoding"),".")),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"Add the folder ",(0,i.kt)("strong",{parentName:"p"},"AND MKVTOOLNIX INSTALLATION FOLDER")," to the ",(0,i.kt)("a",{parentName:"p",href:"https://www.maketecheasier.com/what-is-the-windows-path/"},"Windows PATH environment"),"."))),(0,i.kt)("h3",{id:"macos"},"macOS"),(0,i.kt)("p",null,(0,i.kt)("em",{parentName:"p"},"written by gb82 (Gianni Rosato)")),(0,i.kt)("p",null,"macOS is very similar to Linux, although there aren't any GUI tools for AV1 encoding that I can comfortably recommend."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Homebrew + Macports for Av1an + rav1e:"),"\n",(0,i.kt)("em",{parentName:"p"},"Note that some commands may have to be run with ",(0,i.kt)("inlineCode",{parentName:"em"},"sudo"),", which I won't explicitly include for security reasons.")),(0,i.kt)("p",null,"Installing the Homebrew package manager is a well documented process at this point:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"\n')),(0,i.kt)("p",null,"As is installing MacPorts. Install the relevent ",(0,i.kt)("inlineCode",{parentName:"p"},".pkg")," for your macOS version from the MacPorts Project website:\n",(0,i.kt)("a",{parentName:"p",href:"https://www.macports.org/install.php"},"www.macports.org/install.php")),(0,i.kt)("p",null,"Now, you can run the following commands:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"brew update && brew upgrade\nbrew install rav1e aom mkvtoolnix ffmpeg\n# Usually you must run MacPorts commands for package installations as root\nport upgrade outdated\nport install av1an\n")),(0,i.kt)("p",null,"This is the easiest way to get everything set up & working to produce AV1 video with ",(0,i.kt)("inlineCode",{parentName:"p"},"rav1e")," or mainline ",(0,i.kt)("inlineCode",{parentName:"p"},"aomenc")," & Av1an. You can check that things are installed by running the following commands & parsing their output:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"% av1an --version\nav1an 0.4.1-unstable (rev e10880d) (Release)\n\n* Compiler\n rustc 1.70.0 (LLVM 16.0)\n\n* Target Triple\n aarch64-apple-darwin\n\n* Date Info\n Commit Date: 2023-06-25\n\n* VapourSynth Plugins\n systems.innocent.lsmas : Not found\n com.vapoursynth.ffms2 : Not found\n")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'% rav1e --version | grep "release" -C 1 \nrav1e 0.6.6 () (release)\nrustc 1.69.0 (84c898d65 2023-04-16) (built from a source tarball) aarch64-apple-darwin\n')),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'% aomenc --help | grep "AOMedia" -C 3\n\nIncluded encoders:\n\n av1 - AOMedia Project AV1 Encoder 3.6.1 (default)\n\n Use --codec to switch to a non-default encoder.\n')),(0,i.kt)("p",null,"Notice ",(0,i.kt)("inlineCode",{parentName:"p"},"systems.innocent.lsmas : Not found")," in the Av1an output. This means you won't be able to use the lsmash chunking method through vapoursynth & may instead have to rely on hybrid chunking, through ",(0,i.kt)("inlineCode",{parentName:"p"},"-m hybrid"),". This is slower & takes up disk space while encoding, but still works. A sample Av1an command with this basic installation may look like this:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'av1an -i "input" -y --resume --verbose --split-method av-scenechange -m hybrid -c mkvmerge -e rav1e --force -v " --tiles 8 -s 4 --quantizer 80 --no-scene-detection" --photon-noise 7 --chroma-noise --pix-format yuv420p10le -w 8 -o "output.mkv"\n')),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Building From Source")),(0,i.kt)("p",null,"If you want lsmash support, aom-av1-lavish instead of mainline, or anything else that isn't covered by the more basic installation, you'll have to compile from source. Things are very similar to Linux, with a few oddities:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"macOS sometimes doesn't have a ",(0,i.kt)("inlineCode",{parentName:"li"},"/usr/local/bin")," by default. You can fix this by doing ",(0,i.kt)("inlineCode",{parentName:"li"},"mkdir /usr/local/bin"),"."),(0,i.kt)("li",{parentName:"ul"},"Homebrew installs ",(0,i.kt)("em",{parentName:"li"},"everything")," in its own directory structure. If you're building things from source that rely on libraries from vapoursynth, zimg, lsmash, etc, make sure to copy them from ",(0,i.kt)("inlineCode",{parentName:"li"},"/opt/homebrew/lib")," to ",(0,i.kt)("inlineCode",{parentName:"li"},"/usr/local/lib"),". Finding them is a matter of ",(0,i.kt)("inlineCode",{parentName:"li"},'ls | grep "keyword"')," & copying what looks reasonable to be associated with the tool you're using."),(0,i.kt)("li",{parentName:"ul"},"Building most things from source will have instructions for ","*","nix which work for both macOS & Linux. Even if it says Linux, there's a good chance it'll work on macOS as well, & it is always worth trying Linux build instructions on Mac. I won't be going through building every encoding tool & dependency from source, as it is generally much more intuitive than Windows, but building Av1an is worth detailing here just as an example.")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'brew install git rust nasm\ngit clone https://github.com/master-of-zen/Av1an\ncd Av1an\nRUSTFLAGS="-C target-cpu=native" cargo build --release\ncd .. && cd target/release\ncp av1an /usr/local/bin\n')),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"More Difficult: Building aom-av1-lavish from Source")),(0,i.kt)("p",null,"If you want to make the most out of your hardware & eke out every last drop of quality, it may be worth building aom-av1-lavish from source. The first step is to clone it from the Endless Merging branch:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"git clone https://github.com/Clybius/aom-av1-lavish -b Endless_Merging\ncd aom-av1-lavish\n")),(0,i.kt)("p",null,"Now, you need to make some manual changes to the source code until Clybius merges ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/Clybius/aom-av1-lavish/pull/1/files"},"this commit"),"."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Add the line ",(0,i.kt)("inlineCode",{parentName:"li"},'#include "aq_variance.h"')," at line 19 in ",(0,i.kt)("inlineCode",{parentName:"li"},"av1/encoder/encodeframe_utils.c")),(0,i.kt)("li",{parentName:"ul"},"Comment out line 2546 in ",(0,i.kt)("inlineCode",{parentName:"li"},"av1/encoder/speed_features.c"),". This line is ",(0,i.kt)("inlineCode",{parentName:"li"},"const int qindex_thresh_cdef_sf_s1_s3_l2[2] = { 92, 48 };")," & becomes ",(0,i.kt)("inlineCode",{parentName:"li"},"// const int qindex_thresh_cdef_sf_s1_s3_l2[2] = { 92, 48 };"),".")),(0,i.kt)("p",null,"Now you can continue to build according to the Linux instructions below. Obviously you'll need cmake, which you can install with homebrew along with any other tools you may need. While still in the ",(0,i.kt)("inlineCode",{parentName:"p"},"aom-av1-lavish")," directory:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'mkdir -p aom_build && cd aom_build\ncmake .. -DBUILD_SHARED_LIBS=0 -DENABLE_DOCS=0 -DCONFIG_TUNE_BUTTERAUGLI=0 -DCONFIG_TUNE_VMAF=0 -DCONFIG_AV1_DECODER=0 -DENABLE_TESTS=0 -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-flto -O3 -march=native" -DCMAKE_C_FLAGS="-flto -O3 -march=native -pipe -fno-plt" -DCMAKE_LD_FLAGS="-flto -O3 -march=native"\nmake -j$(nproc)\n# This may need to be run as root:\nmake install\n')),(0,i.kt)("p",null,"Now you can run ",(0,i.kt)("inlineCode",{parentName:"p"},'aomenc --help | grep "AOMedia" -C 3')," to see if lavish installed. If you're getting the same output as above, you may need to copy the ",(0,i.kt)("inlineCode",{parentName:"p"},"aomenc")," executable to ",(0,i.kt)("inlineCode",{parentName:"p"},"/opt/local/bin"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"/usr/local/bin"),", & ",(0,i.kt)("inlineCode",{parentName:"p"},"/opt/homebrew/bin")," if you already installed mainline aomenc. Running the version info command again, the correct output should look something like this:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"% aomenc --help | grep AOMedia -C 3\n\nIncluded encoders:\n\n av1 - AOMedia Project AV1 Encoder Psy v3.6.0 (default)\n\n Use --codec to switch to a non-default encoder.\n")),(0,i.kt)("p",null,"Notice how it says ",(0,i.kt)("inlineCode",{parentName:"p"},"AOMedia Project AV1 Encoder Psy")," instead of ",(0,i.kt)("inlineCode",{parentName:"p"},"AOMedia Project AV1 Encoder"),". You should be all set after this to start using aom-av1-lavish & following the current parameter meta as outlined below."),(0,i.kt)("h3",{id:"linux"},"Linux"),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"Yet again, try using Arch. It's way easier.")),(0,i.kt)("h4",{id:"the-easy-ways"},"The Easy Ways"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Install ",(0,i.kt)("a",{parentName:"li",href:"https://github.com/gianni-rosato/aviator"},"Aviator")," (",(0,i.kt)("a",{parentName:"li",href:"https://wiki.x266.mov/docs/encoders/SVT-AV1"},"SVT-AV1")," + ",(0,i.kt)("a",{parentName:"li",href:"https://wiki.x266.mov/docs/utilities/FFmpeg"},"FFmpeg"),") or ",(0,i.kt)("a",{parentName:"li",href:"https://giannirosato.com/blog/post/aviator-1/"},"rAV1ator")," basically same thing but ",(0,i.kt)("a",{parentName:"li",href:"https://wiki.x266.mov/docs/utilities/av1an.md"},"Av1an")," + ",(0,i.kt)("a",{parentName:"li",href:"https://wiki.x266.mov/docs/encoders/rav1e"},"rav1e"),". Both are only available as ",(0,i.kt)("a",{parentName:"li",href:"https://beta.flathub.org/apps/net.natesales.Aviator"},"Flatpaks"),". Keep in mind Aviator ships with ",(0,i.kt)("strong",{parentName:"li"},"SVT-AV1")," and rAV1ator with ",(0,i.kt)("strong",{parentName:"li"},"rav1e")," instead of aomenc/AOM-AV1, which I will not be covering here."),(0,i.kt)("li",{parentName:"ul"},"Install ",(0,i.kt)("a",{parentName:"li",href:"https://wiki.x266.mov/docs/utilities/rav1ator-cli"},"rav1ator-cli"),", a TUI for using Av1an meant to be easy to use. Much more flexible than the GUI options & can work with a number of encoders. See ",(0,i.kt)("a",{parentName:"li",href:"https://wiki.x266.mov/docs/utilities/rav1ator-cli/#installation"},"this page")," for more info.")),(0,i.kt)("h4",{id:"the-compiling-route"},"The Compiling Route"),(0,i.kt)("h5",{id:"ubuntu"},"Ubuntu"),(0,i.kt)("p",null,"The guide below is targeted towards 22.04, packages and other things may be different on other versions. First Install Rust via ",(0,i.kt)("inlineCode",{parentName:"p"},"rustup")," first, as apt version of Rust is severely outdated, then you can continue."),(0,i.kt)("p",null,"Install dependencies:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"sudo apt install wget python unzip unrar build-essential meson autoconf automake libtool git nasm yasm python3-dev python3-pip cython3 libass-dev libqt5websockets5-dev libfftw3-dev libtesseract-dev ffmpeg libavcodec-dev libavformat-dev libswscale-dev libavutil-dev libswresample-dev libmediainfo-dev mkvtoolnix mediainfo perl nasm yasm git cmake libavutil-dev libavcodec-dev libavformat-dev libavdevice-dev libavfilter-dev libswscale-dev libswresample-dev libpostproc-dev llvm libclang-dev libssl-dev\n")),(0,i.kt)("p",null,"Install l-smash:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'git clone https://github.com/l-smash/l-smash.git\ncd l-smash\n./configure --enable-shared --extra-cflags="-march=native"\nmake -j$(nproc)\nsudo make install\n')),(0,i.kt)("p",null,"Install zimg:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"git clone --recursive https://github.com/sekrit-twc/zimg.git\ncd zimg\n./autogen.sh\n./configure\nmake -j$(nproc)\nsudo make install\n")),(0,i.kt)("p",null,"Install ImageMagick:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"git clone https://github.com/ImageMagick/ImageMagick\ncd ImageMagick\n./configure\nmake -j$(nproc)\nsudo make install\n")),(0,i.kt)("p",null,"Install Vapoursynth R63:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'wget https://github.com/vapoursynth/vapoursynth/archive/refs/tags/R63.zip\nunzip R63.zip\ncd vapoursynth-R63\n./autogen.sh\n./configure CFLAGS="-march=native" CXXFLAGS="-march=native" --libdir=/usr/lib\nmake -j$(nproc)\nsudo make install\nsudo mkdir /usr/lib/vapoursynth\nsudo ldconfig\n')),(0,i.kt)("p",null,"The plugin directory will be located in ",(0,i.kt)("inlineCode",{parentName:"p"},"/usr/lib/vapoursynth"),"."),(0,i.kt)("p",null,"Install L-SMASH-Works Vapoursynth Plugin:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'git clone https://github.com/AkarinVS/L-SMASH-Works -b ffmpeg-4.5\ncd L-SMASH-Works/VapourSynth && mkdir build && cd build\nmeson .. --optimization=3 --default-library=static -Db_lto=true -Dc_args="-march=native" -Dcpp_args="-march=native"\nninja -j$(nproc)\nsudo cp libvslsmashsource.so /usr/lib/vapoursynth/\n')),(0,i.kt)("admonition",{type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"L-SMASH-Works doesn't work on ",(0,i.kt)("strong",{parentName:"p"},"aarch64"),", it is recommended to use other plugins instead.")),(0,i.kt)("p",null,"Install FFMS2 Vapoursynth Plugin:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'git clone https://github.com/FFMS/ffms2\ncd ffms2\n./autogen.sh\n./configure CFLAGS="-O3 -march=native" CXXFLAGS="-O3 -march=native"\nmake -j$(nproc)\nsudo cp src/core/.libs/libffms2.so src/core/.libs/libffms2.so.5 src/core/.libs/libffms2.so.5.0.0 /usr/lib/vapoursynth\n')),(0,i.kt)("p",null,"Install Av1an:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'git clone https://github.com/master-of-zen/Av1an\ncd Av1an\nRUSTFLAGS="-C target-cpu=native" cargo build --release\nsudo cp target/release/av1an /usr/local/bin\n')),(0,i.kt)("p",null,"When there's no errors, proceed to compiling ",(0,i.kt)("inlineCode",{parentName:"p"},"aom-av1-lavish"),"."),(0,i.kt)("h5",{id:"arch"},"Arch"),(0,i.kt)("p",null,"Install dependencies:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"sudo pacman -S vapoursynth ffmpeg av1an mkvtoolnix-gui git perl cmake ninja meson nasm vapoursynth-plugin-lsmashsource ffms2\n")),(0,i.kt)("p",null,"you're done, proceed."),(0,i.kt)("h4",{id:"compiling-aom-av1-lavish"},"Compiling aom-av1-lavish"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'git clone https://github.com/Clybius/aom-av1-lavish -b Endless_Merging\ncd aom-av1-lavish && mkdir -p aom_build && cd aom_build\ncmake .. -DBUILD_SHARED_LIBS=0 -DENABLE_DOCS=0 -DCONFIG_TUNE_BUTTERAUGLI=0 -DCONFIG_TUNE_VMAF=0 -DCONFIG_AV1_DECODER=0 -DENABLE_TESTS=0 -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-flto -O3 -march=native" -DCMAKE_C_FLAGS="-flto -O3 -march=native -pipe -fno-plt"\nmake -j$(nproc)\nsudo make install\n')),(0,i.kt)("h2",{id:"encoding"},"Encoding"),(0,i.kt)("p",null,"The moment you've all been waiting for, let's just get into it. Here's an example ",(0,i.kt)("em",{parentName:"p"},"recommended")," parameter as of now (09/03/23) ","[MM/DD/YY]",":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'av1an -x 300 -i input.mkv -w 4 -e aom -c mkvmerge --resume -m lsmash --photon-noise=10 --set-thread-affinity=2 --verbose -a " -an " -f " -an " -v " --bit-depth=10 --cpu-used=4 --end-usage=q --cq-level=24 --threads=2 --tile-columns=0 --tile-rows=0 --lag-in-frames=64 --tune-content=psy --tune=ssim --enable-keyframe-filtering=1 --disable-kf --kf-max-dist=9999 --enable-qm=1 --deltaq-mode=0 --aq-mode=0 --quant-b-adapt=1 --enable-fwd-kf=0 --arnr-strength=1 --sb-size=dynamic --enable-dnl-denoising=0 " -o "output.mkv"\n')),(0,i.kt)("admonition",{title:"Parameter Meta",type:"info"},(0,i.kt)("p",{parentName:"admonition"},"It is strongly recommended to join the ",(0,i.kt)("a",{parentName:"p",href:"https://discord.gg/vpREHAvYvh"},"AV1 Discord server")," to get the latest updates on what to use and which to set, as it's the only easily reachable place for everything AV1 & encoding tips in general.")),(0,i.kt)("p",null,"Now let's dissect it one-by-one"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Av1an parameters:")),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"-i")," Input.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"-x 300")," Sets scene split length to 300 frames, you can increase it for more quality at the tradeoff of video seekability.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"-w 4"),' Specifies the amount of "workers" or amount of encoders working on the video.')),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--verbose")," Sets logging to verbose.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--resume")," Resumes the encode even when you haven't encoded yet. I strongly recommend leaving this if you resume a lot since you can accidentally delete your whole progress (There's no delete confirmation feature.. yet) if you \"resumed\" without the parameter in place.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"-e aom")," Specifies we're using aomenc encoder which should be the default option.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"-c mkvmerge")," Specifies we're using mkvmerge (MKVToolNix) to concatenate the parts when done, you can specify with ffmpeg if you want to but this is the best method.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"-m lsmash")," Specifies we're using l-smash (Vapoursynth plugin) to split the videos, this is also the best method because ffms2 causes video lag (Tested a year ago, might change now) and other methods just suck (Slow and not worth it, learned the hard way). You can attempt to use ffms2 when inputting VC-1 videos as it is not possible with l-smash (Or convert it to lossless with x264 qp 0).")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},'-f " -an "')," ",(0,i.kt)("inlineCode",{parentName:"p"},"-f")," Stands for ffmpeg parameters, ",(0,i.kt)("inlineCode",{parentName:"p"},"-an")," is to remove all audio since its better to encode and merge it separately. To crop use ",(0,i.kt)("inlineCode",{parentName:"p"},'-f " -an -vf crop=1920:800 "')," for example to crop the video to 1920x800.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},'-v " "')," Is where you put the encoder's parameters in.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},'-a " -an "')," FFmpeg audio encoding options, we're removing it cause we can always add it later. But if you want to, you can also encode directly. Here's an example for encoding to Opus using libopus assuming stereo: ",(0,i.kt)("inlineCode",{parentName:"p"},'-a " -c:a libopus -b:a 128k "'),".")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--photon-noise=10")," AV1 grain synthesis, which is a technique where the encoder puts fake grain in so it looks more natural and potentially hiding video artifacts (cause grain is hard to encode and explodes bitrate usage because of their randomness), 5-8 for almost none to little grain, 10-14 for medium, 15+ heavy, 20+ extremely heavy, 30+ for extremely grainy 90s live action films.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--set-thread-affinity=2")," Pins the thread to the encoder, aligns with ",(0,i.kt)("inlineCode",{parentName:"p"},"--threads=2")," in the encoder parameter so set them accordingly."))),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"aomenc parameters:")),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--bit-depth=10")," We're using 10bit because it makes the video smaller and reduces ",(0,i.kt)("a",{parentName:"p",href:"https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Video_codecs#contouring"},"banding"),".")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--cpu-used=4")," This is the preset which ranges from 0-9, you can go to 3 if you want more efficiency, 2 if you have a lot of time, 4 is the sweet spot, and 6 if you want speed. Don't go above 6 (Worst efficiency) or even 0 (It would take WEEKS to finish).")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--end-usage=q --cq-level=24")," This specifies that we are going to use a knockoff version of CRF level similar to x264/x265 encoders, in this case CRF 24.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--threads=2")," Sets the amount of threads the encoder can use, aligns with ",(0,i.kt)("inlineCode",{parentName:"p"},"--set-thread-affinity")," in Av1an.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--tile-columns=0 --tile-rows=0")," This is the tiles options, where the encoder splits the videos into tiles to encode faster, see the image below (Yellow lines):"),(0,i.kt)("picture",null,(0,i.kt)("source",{srcset:"https://raw.githubusercontent.com/av1-community-contributors/images/main/tiling_av1.avif?token=GHSAT0AAAAAACEZPDXIZARY5MGSTJW4SI22ZHY636A",type:"image/avif"}),(0,i.kt)("img",{src:"https://autumn.revolt.chat/attachments/HwhZjoDsdzLZsJM2mjzX7lEDmJn1xcYNdrQqmOxPYW/tiling_av1.jpeg",alt:"Tiling",width:"1280",height:"768",loading:"lazy"})))),(0,i.kt)("admonition",{title:"Tile usage",type:"note"},(0,i.kt)("p",{parentName:"admonition"},"Do NOT use tiles for 1080p and below, use 1 ",(0,i.kt)("inlineCode",{parentName:"p"},"tile-columns")," at 1440p (2K), 2 ",(0,i.kt)("inlineCode",{parentName:"p"},"tile-columns")," and 1 ",(0,i.kt)("inlineCode",{parentName:"p"},"tile-rows")," for 2160p (4K)")),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--lag-in-frames=64")," Knockoff of x264/x265 ",(0,i.kt)("a",{parentName:"p",href:"https://en.wikipedia.org/wiki/Group_of_pictures"},"Group of Pictures")," (GOP), makes the encoder look into future frames for better compression decision making, do not go over 64 as it is pretty much useless.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--aq-mode")," adaptive quantization mode, 0 is better most of the time")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--tune-content=psy --tune=ssim")," As the name suggests they are tunes that affect the video output, for the better, and for the worst"))),(0,i.kt)("admonition",{title:"Tunes to use",type:"info"},(0,i.kt)("p",{parentName:"admonition"},"Set ",(0,i.kt)("inlineCode",{parentName:"p"},"tune-content")," to ",(0,i.kt)("inlineCode",{parentName:"p"},"animation")," if you're encoding above ",(0,i.kt)("inlineCode",{parentName:"p"},"cq-level=30")," A.K.A lower quality, despite it's name\nSet ",(0,i.kt)("inlineCode",{parentName:"p"},"tune-content")," to ",(0,i.kt)("inlineCode",{parentName:"p"},"psy")," for everything else, ",(0,i.kt)("strong",{parentName:"p"},"do not use if you encode above ",(0,i.kt)("inlineCode",{parentName:"strong"},"cq-level=30")),"\nFor ",(0,i.kt)("inlineCode",{parentName:"p"},"tune"),", this is a bit tricky. For now, the meta seems to be ",(0,i.kt)("inlineCode",{parentName:"p"},"ssim"),", but back then it was ",(0,i.kt)("inlineCode",{parentName:"p"},"lavish")," which is considered THE best tune because it's based on ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/google/butteraugli"},"butteraugli"),". Now it's fallen behind because its more blurry than ",(0,i.kt)("inlineCode",{parentName:"p"},"ssim"),", and before that it was ",(0,i.kt)("inlineCode",{parentName:"p"},"butteraugli"),", and then ",(0,i.kt)("inlineCode",{parentName:"p"},"ipq_vmaf_psy"),", and finally just ",(0,i.kt)("inlineCode",{parentName:"p"},"ipq"),".\nIf you use any of the VMAF tunes, ",(0,i.kt)("strong",{parentName:"p"},"you need to specify ",(0,i.kt)("inlineCode",{parentName:"strong"},"--vmaf-model-path=")," to where you put it"),".")),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--enable-keyframe-filtering=1")," We're setting it to 1 because of compatibility reasons, 2 is more efficient but there are seeking issues and FFmpeg for some reason can't input it.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--sb-size=dynamic")," Allows the encoder to use 128x128 block partitioning besides 64x64 which gives an efficiency boost, ignore it.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--deltaq-mode")," set to 0 because its just better.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--arnr-strength=1")," Controls how strong the filtering will be, 1 is good for 3D Pixar CGI-like and 2D animation, use 4 if you're doing live action content. Using maximum at higher bitrates would just result in a blurry mess.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--disable-kf --enable-fwd-kf=0")," We're disabling keyframes cause ",(0,i.kt)("strong",{parentName:"p"},"Av1an already did scene detection, so we wont have to."),". And it speeds things up.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--kf-max-dist=9999")," Maximum keyframe interval, we're setting it at the highest possible value since av1an's scene detection keyframe interval is already 240 by default")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--enable-chroma-deltaq=1 --enable-qm=1 --quant-b-adapt=1")," Parameters that give you free efficiency boost.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--enable-dnl-denoising=0")," Disables the encoder's built-in denoising technique when grain synthesis is enabled, you can optionally set it to 1 when you have a pretty noisy video since it works quite well."))),(0,i.kt)("admonition",{title:"Concatenation Error on Linux",type:"info"},(0,i.kt)("p",{parentName:"admonition"},"Run ",(0,i.kt)("inlineCode",{parentName:"p"},"ulimit -n 200000"),", resume, and it should concatenate just fine. If it still errors, head to the encode directory > encode, and run ",(0,i.kt)("inlineCode",{parentName:"p"},"mkvmerge @../options.json"))),(0,i.kt)("h2",{id:"merging-everything"},"Merging Everything"),(0,i.kt)("p",null,"Once you're done just encode your audio using ffmpeg (or just passthrough it), subtitles should be carried along with your video output, and merge them in MKVToolNix! Don't want Matroska files? That's fine, you can use FFmpeg or MP4Box to output into ",(0,i.kt)("inlineCode",{parentName:"p"},"mp4"),", just keep in mind that PGS/SUP/VOBSUB subtitles are not supported and Opus audio support is still experimental."),(0,i.kt)("h2",{id:"tips--tricks"},"Tips & Tricks"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--denoise-noise-level=10")," Alternative to ",(0,i.kt)("inlineCode",{parentName:"p"},"photon-noise"),", slower than photon-noise and is the OG grain synthesis method, performs okay and just serves as an alternative. Don't attempt to use it at high values (>12) since it creates noticeable grain patterns.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--arnr-maxframes")," to set max reference frames that will be used to filter the encode, higher values would make the video blurrier at high fidelity but look better at lower bitrates.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--butteraugli-resize-factor=2")," if you use any of the butteraugli-based tunes (lavish, butteraugli) to speed it up without much losses and ",(0,i.kt)("inlineCode",{parentName:"p"},"--butteraugli-intensity-target=250")," to match the content light level."))),(0,i.kt)("h2",{id:"final-thoughts"},"Final Thoughts"),(0,i.kt)("p",null,'Encoding has always been about experimentation for the best, there is really no "One size fits all" for encoding content, as they differ from scene complexity, how it\'s captured (2D/Real life), film grain, dark scenes, etc. So experiment away for your specific type of content!'),(0,i.kt)("blockquote",null,(0,i.kt)("p",{parentName:"blockquote"},(0,i.kt)("strong",{parentName:"p"},"Guide originally hosted on ",(0,i.kt)("a",{parentName:"strong",href:"https://rentry.co/AV1"},"https://rentry.co/AV1"),", rewrite and migration by Simulping."))))}d.isMDXComponent=!0},8804:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/compare-guide-6feb966fbd9d73be4a3097c41691c4ad.webp"},7843:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/python-path-a89fc4fe6c6eb4c2ea0a7610dd2cf09a.webp"}}]); \ No newline at end of file +"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[5581],{3905:(e,t,a)=>{a.d(t,{Zo:()=>m,kt:()=>h});var n=a(7294);function i(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function r(e){for(var t=1;t=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var s=n.createContext({}),p=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):r(r({},t),e)),a},m=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},c=n.forwardRef((function(e,t){var a=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,m=l(e,["components","mdxType","originalType","parentName"]),u=p(a),c=i,h=u["".concat(s,".").concat(c)]||u[c]||d[c]||o;return a?n.createElement(h,r(r({ref:t},m),{},{components:a})):n.createElement(h,r({ref:t},m))}));function h(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=a.length,r=new Array(o);r[0]=c;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[u]="string"==typeof e?e:i,r[1]=l;for(var p=2;p{a.r(t),a.d(t,{assets:()=>s,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>l,toc:()=>p});var n=a(7462),i=(a(7294),a(3905));const o={title:"AV1 Encoding for Dummies",description:"This guide will show you how to encode in AV1 the *right* and *optimal* way.",slug:"av1-encoding-for-dummies",authors:[{name:"Simulping",title:"Maintainer / Encoder",url:"https://github.com/Simulping",image_url:"https://avatars.githubusercontent.com/u/12994794?v=4"},{name:"Gianni Rosato",title:"Maintainer",url:"https://github.com/gianni-rosato",image_url:"https://avatars.githubusercontent.com/u/35711760?v=4"}],tags:["video","compression"],image:"/img/compare-guide.webp",hide_table_of_contents:!1},r=void 0,l={permalink:"/blog/av1-encoding-for-dummies",source:"@site/blog/2023-09-03-av1-for-dummies.md",title:"AV1 Encoding for Dummies",description:"This guide will show you how to encode in AV1 the *right* and *optimal* way.",date:"2023-09-03T00:00:00.000Z",formattedDate:"September 3, 2023",tags:[{label:"video",permalink:"/blog/tags/video"},{label:"compression",permalink:"/blog/tags/compression"}],readingTime:15.145,hasTruncateMarker:!0,authors:[{name:"Simulping",title:"Maintainer / Encoder",url:"https://github.com/Simulping",image_url:"https://avatars.githubusercontent.com/u/12994794?v=4",imageURL:"https://avatars.githubusercontent.com/u/12994794?v=4"},{name:"Gianni Rosato",title:"Maintainer",url:"https://github.com/gianni-rosato",image_url:"https://avatars.githubusercontent.com/u/35711760?v=4",imageURL:"https://avatars.githubusercontent.com/u/35711760?v=4"}],frontMatter:{title:"AV1 Encoding for Dummies",description:"This guide will show you how to encode in AV1 the *right* and *optimal* way.",slug:"av1-encoding-for-dummies",authors:[{name:"Simulping",title:"Maintainer / Encoder",url:"https://github.com/Simulping",image_url:"https://avatars.githubusercontent.com/u/12994794?v=4",imageURL:"https://avatars.githubusercontent.com/u/12994794?v=4"},{name:"Gianni Rosato",title:"Maintainer",url:"https://github.com/gianni-rosato",image_url:"https://avatars.githubusercontent.com/u/35711760?v=4",imageURL:"https://avatars.githubusercontent.com/u/35711760?v=4"}],tags:["video","compression"],image:"/img/compare-guide.webp",hide_table_of_contents:!1},prevItem:{title:"Embedding the Un-Embeddable: Dissecting discord.nfp.is, stolen.shoes & Others",permalink:"/blog/embedding-the-un-embeddable"},nextItem:{title:"Site Optimization by Reducing Image Load on the Web",permalink:"/blog/site-optimization"}},s={authorsImageUrls:[void 0,void 0]},p=[{value:"Installing the Tools",id:"installing-the-tools",level:2},{value:"Microsoft Windows",id:"microsoft-windows",level:3},{value:"macOS",id:"macos",level:3},{value:"Linux",id:"linux",level:3},{value:"The Easy Ways",id:"the-easy-ways",level:4},{value:"The Compiling Route",id:"the-compiling-route",level:4},{value:"Ubuntu",id:"ubuntu",level:5},{value:"Arch",id:"arch",level:5},{value:"Compiling aom-av1-lavish",id:"compiling-aom-av1-lavish",level:4},{value:"Encoding",id:"encoding",level:2},{value:"Merging Everything",id:"merging-everything",level:2},{value:"Tips & Tricks",id:"tips--tricks",level:2},{value:"Final Thoughts",id:"final-thoughts",level:2}],m={toc:p},u="wrapper";function d(e){let{components:t,...o}=e;return(0,i.kt)(u,(0,n.Z)({},m,o,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"This guide will show you how to encode in AV1 the ",(0,i.kt)("em",{parentName:"p"},"right")," and ",(0,i.kt)("em",{parentName:"p"},"optimal")," way. Yes, you using standalone ",(0,i.kt)("inlineCode",{parentName:"p"},"libaom"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"libsvtav1"),", and ",(0,i.kt)("inlineCode",{parentName:"p"},"librav1e")," from FFmpeg or even piping ",(0,i.kt)("inlineCode",{parentName:"p"},"yuv4mpeg")," into ",(0,i.kt)("strong",{parentName:"p"},"mainline")," aomenc are all unoptimal."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"Compare",src:a(9081).Z,width:"1045",height:"588"})),(0,i.kt)("p",null,"In this guide, we'll be installing Av1an for chunked encoding and infinite threading, because the current state of AV1 encoders, except for ",(0,i.kt)("a",{parentName:"p",href:"https://wiki.x266.mov/docs/encoders/SVT-AV1"},"SVT-AV1"),", unfortunately lacks threading and will only use very low amount of cores, which hampers speeds. The only caveat to this approach is ",(0,i.kt)("strong",{parentName:"p"},"RAM consumption"),", encoding 2160p (4K) with ",(0,i.kt)("a",{parentName:"p",href:"https://wiki.x266.mov/docs/encoders/aomenc"},"aomenc")," with 4 workers could take upwards of ",(0,i.kt)("strong",{parentName:"p"},"16GB")," of RAM! So do keep this in mind."),(0,i.kt)("h2",{id:"installing-the-tools"},"Installing the Tools"),(0,i.kt)("h3",{id:"microsoft-windows"},"Microsoft Windows"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"The GUI Way:")),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Install ",(0,i.kt)("a",{parentName:"li",href:"https://github.com/n00mkrad/nmkoder"},"NMKODER")," which is a GUI front-end to av1an with all dependencies installed."),(0,i.kt)("li",{parentName:"ol"},"You're done, you can skip to the encoding part")),(0,i.kt)("admonition",{title:"Almost abandonware",type:"warning"},(0,i.kt)("p",{parentName:"admonition"},"Since Nmkoder already ships everything by default and its last release was 29th March 2022. You need to manually update all encoders and tools to get better encoding speeds. Missing out on updates will result in your encodes being sub-optimal.")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"The Automated Way:")),(0,i.kt)("p",null,"There is now a batch script for automating the install process, which can be found ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/Hishiro64/av1an-win-script"},"here"),". The instructions are in the README file."),(0,i.kt)("admonition",{type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"The script will download outdated version encoders and tools such as ",(0,i.kt)("inlineCode",{parentName:"p"},"aom-av1-psy")," and MKVToolNix v76.0, if you are fine with these you can proceed.")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"The Manual Way:")),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"Install ",(0,i.kt)("strong",{parentName:"p"},"Python 3.10.x, this will change so consult from the")," ",(0,i.kt)("a",{parentName:"p",href:"http://www.vapoursynth.com/doc/installation.html"},"Vapoursynth website")," ",(0,i.kt)("strong",{parentName:"p"},"if you're reading this from the future")," from ",(0,i.kt)("a",{parentName:"p",href:"https://www.python.org/downloads/windows/"},"here"),' and select "Windows Installer 64-bit". Upon installation check the tick for adding Python to PATH like so\n',(0,i.kt)("img",{alt:"Python PATH",src:a(5900).Z,width:"672",height:"417"}),")")),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"Download and install Vapoursynth from ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/vapoursynth/vapoursynth/releases"},"here"),' and select "VapourSynth64-RXX.exe"')),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"Open the terminal and type ",(0,i.kt)("inlineCode",{parentName:"p"},"vsrepo.py install lsmas ffms2")," to install some plugins for Av1an to work.")),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"Download MKVToolNix from ",(0,i.kt)("a",{parentName:"p",href:"https://mkvtoolnix.download/downloads.html#windows"},"here"),', select "mkvtoolnix-64bit-XX.X.X-setup.exe", and install ',(0,i.kt)("strong",{parentName:"p"},"(Also available on winget!)"))),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"Download Av1an from ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/master-of-zen/Av1an/releases"},"here"),' (SELECT LATEST AND CLICK THE "ASSETS" DROPDOWN)')),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"Download ",(0,i.kt)("strong",{parentName:"p"},"shared libraries")," FFmpeg from ",(0,i.kt)("a",{parentName:"p",href:"https://www.gyan.dev/ffmpeg/builds"},"gyan.dev"))),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"Download a pre-built fork of Aomenc (",(0,i.kt)("a",{parentName:"p",href:"https://github.com/Clybius/aom-av1-lavish/tree/Endless_Merging"},"aom-av1-lavish"),") which has neat stuff such as sane defaults, new tunes, optimizations, etc. This can be downloaded for Windows ",(0,i.kt)("a",{parentName:"p",href:"https://autumn.revolt.chat/attachments/download/-2EiZW1edcT9anApFZ1PJBEber-pJ6z02NiQBjbr28"},"here")," ",(0,i.kt)("em",{parentName:"p"},"(Current as of Sept 6, 2023)")),(0,i.kt)("admonition",{parentName:"li",type:"info"},(0,i.kt)("p",{parentName:"admonition"},"If you opt to compile aomenc yourself, you can view the instructions on how to do that ",(0,i.kt)("a",{parentName:"p",href:"https://wiki.x266.mov/docs/encoders/aomenc/#installation"},"here"),"."))),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"Move Av1an, FFmpeg ",(0,i.kt)("strong",{parentName:"p"},"(Including the FFmpeg DLLs)"),", and aomenc to somewhere preferable, eg ",(0,i.kt)("inlineCode",{parentName:"p"},"C:\\Encoding"),".")),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"Add the folder ",(0,i.kt)("strong",{parentName:"p"},"AND MKVTOOLNIX INSTALLATION FOLDER")," to the ",(0,i.kt)("a",{parentName:"p",href:"https://www.maketecheasier.com/what-is-the-windows-path/"},"Windows PATH environment"),"."))),(0,i.kt)("h3",{id:"macos"},"macOS"),(0,i.kt)("p",null,(0,i.kt)("em",{parentName:"p"},"written by gb82 (Gianni Rosato)")),(0,i.kt)("p",null,"macOS is very similar to Linux, although there aren't any GUI tools for AV1 encoding that I can comfortably recommend."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Homebrew + Macports for Av1an + rav1e:"),"\n",(0,i.kt)("em",{parentName:"p"},"Note that some commands may have to be run with ",(0,i.kt)("inlineCode",{parentName:"em"},"sudo"),", which I won't explicitly include for security reasons.")),(0,i.kt)("p",null,"Installing the Homebrew package manager is a well documented process at this point:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"\n')),(0,i.kt)("p",null,"As is installing MacPorts. Install the relevent ",(0,i.kt)("inlineCode",{parentName:"p"},".pkg")," for your macOS version from the MacPorts Project website:\n",(0,i.kt)("a",{parentName:"p",href:"https://www.macports.org/install.php"},"www.macports.org/install.php")),(0,i.kt)("p",null,"Now, you can run the following commands:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"brew update && brew upgrade\nbrew install rav1e aom mkvtoolnix ffmpeg\n# Usually you must run MacPorts commands for package installations as root\nport upgrade outdated\nport install av1an\n")),(0,i.kt)("p",null,"This is the easiest way to get everything set up & working to produce AV1 video with ",(0,i.kt)("inlineCode",{parentName:"p"},"rav1e")," or mainline ",(0,i.kt)("inlineCode",{parentName:"p"},"aomenc")," & Av1an. You can check that things are installed by running the following commands & parsing their output:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"% av1an --version\nav1an 0.4.1-unstable (rev e10880d) (Release)\n\n* Compiler\n rustc 1.70.0 (LLVM 16.0)\n\n* Target Triple\n aarch64-apple-darwin\n\n* Date Info\n Commit Date: 2023-06-25\n\n* VapourSynth Plugins\n systems.innocent.lsmas : Not found\n com.vapoursynth.ffms2 : Not found\n")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'% rav1e --version | grep "release" -C 1 \nrav1e 0.6.6 () (release)\nrustc 1.69.0 (84c898d65 2023-04-16) (built from a source tarball) aarch64-apple-darwin\n')),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'% aomenc --help | grep "AOMedia" -C 3\n\nIncluded encoders:\n\n av1 - AOMedia Project AV1 Encoder 3.6.1 (default)\n\n Use --codec to switch to a non-default encoder.\n')),(0,i.kt)("p",null,"Notice ",(0,i.kt)("inlineCode",{parentName:"p"},"systems.innocent.lsmas : Not found")," in the Av1an output. This means you won't be able to use the lsmash chunking method through vapoursynth & may instead have to rely on hybrid chunking, through ",(0,i.kt)("inlineCode",{parentName:"p"},"-m hybrid"),". This is slower & takes up disk space while encoding, but still works. A sample Av1an command with this basic installation may look like this:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'av1an -i "input" -y --resume --verbose --split-method av-scenechange -m hybrid -c mkvmerge -e rav1e --force -v " --tiles 8 -s 4 --quantizer 80 --no-scene-detection" --photon-noise 7 --chroma-noise --pix-format yuv420p10le -w 8 -o "output.mkv"\n')),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Building From Source")),(0,i.kt)("p",null,"If you want lsmash support, aom-av1-lavish instead of mainline, or anything else that isn't covered by the more basic installation, you'll have to compile from source. Things are very similar to Linux, with a few oddities:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"macOS sometimes doesn't have a ",(0,i.kt)("inlineCode",{parentName:"li"},"/usr/local/bin")," by default. You can fix this by doing ",(0,i.kt)("inlineCode",{parentName:"li"},"mkdir /usr/local/bin"),"."),(0,i.kt)("li",{parentName:"ul"},"Homebrew installs ",(0,i.kt)("em",{parentName:"li"},"everything")," in its own directory structure. If you're building things from source that rely on libraries from vapoursynth, zimg, lsmash, etc, make sure to copy them from ",(0,i.kt)("inlineCode",{parentName:"li"},"/opt/homebrew/lib")," to ",(0,i.kt)("inlineCode",{parentName:"li"},"/usr/local/lib"),". Finding them is a matter of ",(0,i.kt)("inlineCode",{parentName:"li"},'ls | grep "keyword"')," & copying what looks reasonable to be associated with the tool you're using."),(0,i.kt)("li",{parentName:"ul"},"Building most things from source will have instructions for ","*","nix which work for both macOS & Linux. Even if it says Linux, there's a good chance it'll work on macOS as well, & it is always worth trying Linux build instructions on Mac. I won't be going through building every encoding tool & dependency from source, as it is generally much more intuitive than Windows, but building Av1an is worth detailing here just as an example.")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'brew install git rust nasm\ngit clone https://github.com/master-of-zen/Av1an\ncd Av1an\nRUSTFLAGS="-C target-cpu=native" cargo build --release\ncd .. && cd target/release\ncp av1an /usr/local/bin\n')),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"More Difficult: Building aom-av1-lavish from Source")),(0,i.kt)("p",null,"If you want to make the most out of your hardware & eke out every last drop of quality, it may be worth building aom-av1-lavish from source. The first step is to clone it from the Endless Merging branch:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"git clone https://github.com/Clybius/aom-av1-lavish -b Endless_Merging\ncd aom-av1-lavish\n")),(0,i.kt)("p",null,"Now, you need to make some manual changes to the source code until Clybius merges ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/Clybius/aom-av1-lavish/pull/1/files"},"this commit"),"."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Add the line ",(0,i.kt)("inlineCode",{parentName:"li"},'#include "aq_variance.h"')," at line 19 in ",(0,i.kt)("inlineCode",{parentName:"li"},"av1/encoder/encodeframe_utils.c")),(0,i.kt)("li",{parentName:"ul"},"Comment out line 2546 in ",(0,i.kt)("inlineCode",{parentName:"li"},"av1/encoder/speed_features.c"),". This line is ",(0,i.kt)("inlineCode",{parentName:"li"},"const int qindex_thresh_cdef_sf_s1_s3_l2[2] = { 92, 48 };")," & becomes ",(0,i.kt)("inlineCode",{parentName:"li"},"// const int qindex_thresh_cdef_sf_s1_s3_l2[2] = { 92, 48 };"),".")),(0,i.kt)("p",null,"Now you can continue to build according to the Linux instructions below. Obviously you'll need cmake, which you can install with homebrew along with any other tools you may need. While still in the ",(0,i.kt)("inlineCode",{parentName:"p"},"aom-av1-lavish")," directory:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'mkdir -p aom_build && cd aom_build\ncmake .. -DBUILD_SHARED_LIBS=0 -DENABLE_DOCS=0 -DCONFIG_TUNE_BUTTERAUGLI=0 -DCONFIG_TUNE_VMAF=0 -DCONFIG_AV1_DECODER=0 -DENABLE_TESTS=0 -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-flto -O3 -march=native" -DCMAKE_C_FLAGS="-flto -O3 -march=native -pipe -fno-plt" -DCMAKE_LD_FLAGS="-flto -O3 -march=native"\nmake -j$(nproc)\n# This may need to be run as root:\nmake install\n')),(0,i.kt)("p",null,"Now you can run ",(0,i.kt)("inlineCode",{parentName:"p"},'aomenc --help | grep "AOMedia" -C 3')," to see if lavish installed. If you're getting the same output as above, you may need to copy the ",(0,i.kt)("inlineCode",{parentName:"p"},"aomenc")," executable to ",(0,i.kt)("inlineCode",{parentName:"p"},"/opt/local/bin"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"/usr/local/bin"),", & ",(0,i.kt)("inlineCode",{parentName:"p"},"/opt/homebrew/bin")," if you already installed mainline aomenc. Running the version info command again, the correct output should look something like this:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"% aomenc --help | grep AOMedia -C 3\n\nIncluded encoders:\n\n av1 - AOMedia Project AV1 Encoder Psy v3.6.0 (default)\n\n Use --codec to switch to a non-default encoder.\n")),(0,i.kt)("p",null,"Notice how it says ",(0,i.kt)("inlineCode",{parentName:"p"},"AOMedia Project AV1 Encoder Psy")," instead of ",(0,i.kt)("inlineCode",{parentName:"p"},"AOMedia Project AV1 Encoder"),". You should be all set after this to start using aom-av1-lavish & following the current parameter meta as outlined below."),(0,i.kt)("h3",{id:"linux"},"Linux"),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"Yet again, try using Arch. It's way easier.")),(0,i.kt)("h4",{id:"the-easy-ways"},"The Easy Ways"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Install ",(0,i.kt)("a",{parentName:"li",href:"https://github.com/gianni-rosato/aviator"},"Aviator")," (",(0,i.kt)("a",{parentName:"li",href:"https://wiki.x266.mov/docs/encoders/SVT-AV1"},"SVT-AV1")," + ",(0,i.kt)("a",{parentName:"li",href:"https://wiki.x266.mov/docs/utilities/FFmpeg"},"FFmpeg"),") or ",(0,i.kt)("a",{parentName:"li",href:"https://giannirosato.com/blog/post/aviator-1/"},"rAV1ator")," basically same thing but ",(0,i.kt)("a",{parentName:"li",href:"https://wiki.x266.mov/docs/utilities/av1an.md"},"Av1an")," + ",(0,i.kt)("a",{parentName:"li",href:"https://wiki.x266.mov/docs/encoders/rav1e"},"rav1e"),". Both are only available as ",(0,i.kt)("a",{parentName:"li",href:"https://beta.flathub.org/apps/net.natesales.Aviator"},"Flatpaks"),". Keep in mind Aviator ships with ",(0,i.kt)("strong",{parentName:"li"},"SVT-AV1")," and rAV1ator with ",(0,i.kt)("strong",{parentName:"li"},"rav1e")," instead of aomenc/AOM-AV1, which I will not be covering here."),(0,i.kt)("li",{parentName:"ul"},"Install ",(0,i.kt)("a",{parentName:"li",href:"https://wiki.x266.mov/docs/utilities/rav1ator-cli"},"rav1ator-cli"),", a TUI for using Av1an meant to be easy to use. Much more flexible than the GUI options & can work with a number of encoders. See ",(0,i.kt)("a",{parentName:"li",href:"https://wiki.x266.mov/docs/utilities/rav1ator-cli/#installation"},"this page")," for more info.")),(0,i.kt)("h4",{id:"the-compiling-route"},"The Compiling Route"),(0,i.kt)("h5",{id:"ubuntu"},"Ubuntu"),(0,i.kt)("p",null,"The guide below is targeted towards 22.04, packages and other things may be different on other versions. First Install Rust via ",(0,i.kt)("inlineCode",{parentName:"p"},"rustup")," first, as apt version of Rust is severely outdated, then you can continue."),(0,i.kt)("p",null,"Install dependencies:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"sudo apt install wget python unzip unrar build-essential meson autoconf automake libtool git nasm yasm python3-dev python3-pip cython3 libass-dev libqt5websockets5-dev libfftw3-dev libtesseract-dev ffmpeg libavcodec-dev libavformat-dev libswscale-dev libavutil-dev libswresample-dev libmediainfo-dev mkvtoolnix mediainfo perl nasm yasm git cmake libavutil-dev libavcodec-dev libavformat-dev libavdevice-dev libavfilter-dev libswscale-dev libswresample-dev libpostproc-dev llvm libclang-dev libssl-dev\n")),(0,i.kt)("p",null,"Install l-smash:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'git clone https://github.com/l-smash/l-smash.git\ncd l-smash\n./configure --enable-shared --extra-cflags="-march=native"\nmake -j$(nproc)\nsudo make install\n')),(0,i.kt)("p",null,"Install zimg:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"git clone --recursive https://github.com/sekrit-twc/zimg.git\ncd zimg\n./autogen.sh\n./configure\nmake -j$(nproc)\nsudo make install\n")),(0,i.kt)("p",null,"Install ImageMagick:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"git clone https://github.com/ImageMagick/ImageMagick\ncd ImageMagick\n./configure\nmake -j$(nproc)\nsudo make install\n")),(0,i.kt)("p",null,"Install Vapoursynth R63:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'wget https://github.com/vapoursynth/vapoursynth/archive/refs/tags/R63.zip\nunzip R63.zip\ncd vapoursynth-R63\n./autogen.sh\n./configure CFLAGS="-march=native" CXXFLAGS="-march=native" --libdir=/usr/lib\nmake -j$(nproc)\nsudo make install\nsudo mkdir /usr/lib/vapoursynth\nsudo ldconfig\n')),(0,i.kt)("p",null,"The plugin directory will be located in ",(0,i.kt)("inlineCode",{parentName:"p"},"/usr/lib/vapoursynth"),"."),(0,i.kt)("p",null,"Install L-SMASH-Works Vapoursynth Plugin:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'git clone https://github.com/AkarinVS/L-SMASH-Works -b ffmpeg-4.5\ncd L-SMASH-Works/VapourSynth && mkdir build && cd build\nmeson .. --optimization=3 --default-library=static -Db_lto=true -Dc_args="-march=native" -Dcpp_args="-march=native"\nninja -j$(nproc)\nsudo cp libvslsmashsource.so /usr/lib/vapoursynth/\n')),(0,i.kt)("admonition",{type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"L-SMASH-Works doesn't work on ",(0,i.kt)("strong",{parentName:"p"},"aarch64"),", it is recommended to use other plugins instead.")),(0,i.kt)("p",null,"Install FFMS2 Vapoursynth Plugin:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'git clone https://github.com/FFMS/ffms2\ncd ffms2\n./autogen.sh\n./configure CFLAGS="-O3 -march=native" CXXFLAGS="-O3 -march=native"\nmake -j$(nproc)\nsudo cp src/core/.libs/libffms2.so src/core/.libs/libffms2.so.5 src/core/.libs/libffms2.so.5.0.0 /usr/lib/vapoursynth\n')),(0,i.kt)("p",null,"Install Av1an:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'git clone https://github.com/master-of-zen/Av1an\ncd Av1an\nRUSTFLAGS="-C target-cpu=native" cargo build --release\nsudo cp target/release/av1an /usr/local/bin\n')),(0,i.kt)("p",null,"When there's no errors, proceed to compiling ",(0,i.kt)("inlineCode",{parentName:"p"},"aom-av1-lavish"),"."),(0,i.kt)("h5",{id:"arch"},"Arch"),(0,i.kt)("p",null,"Install dependencies:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"sudo pacman -S vapoursynth ffmpeg av1an mkvtoolnix-gui git perl cmake ninja meson nasm vapoursynth-plugin-lsmashsource ffms2\n")),(0,i.kt)("p",null,"you're done, proceed."),(0,i.kt)("h4",{id:"compiling-aom-av1-lavish"},"Compiling aom-av1-lavish"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'git clone https://github.com/Clybius/aom-av1-lavish -b Endless_Merging\ncd aom-av1-lavish && mkdir -p aom_build && cd aom_build\ncmake .. -DBUILD_SHARED_LIBS=0 -DENABLE_DOCS=0 -DCONFIG_TUNE_BUTTERAUGLI=0 -DCONFIG_TUNE_VMAF=0 -DCONFIG_AV1_DECODER=0 -DENABLE_TESTS=0 -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-flto -O3 -march=native" -DCMAKE_C_FLAGS="-flto -O3 -march=native -pipe -fno-plt"\nmake -j$(nproc)\nsudo make install\n')),(0,i.kt)("h2",{id:"encoding"},"Encoding"),(0,i.kt)("p",null,"The moment you've all been waiting for, let's just get into it. Here's an example ",(0,i.kt)("em",{parentName:"p"},"recommended")," parameter as of now (09/03/23) ","[MM/DD/YY]",":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'av1an -x 300 -i input.mkv -w 4 -e aom -c mkvmerge --resume -m lsmash --photon-noise=10 --set-thread-affinity=2 --verbose -a " -an " -f " -an " -v " --bit-depth=10 --cpu-used=4 --end-usage=q --cq-level=24 --threads=2 --tile-columns=0 --tile-rows=0 --lag-in-frames=64 --tune-content=psy --tune=ssim --enable-keyframe-filtering=1 --disable-kf --kf-max-dist=9999 --enable-qm=1 --deltaq-mode=0 --aq-mode=0 --quant-b-adapt=1 --enable-fwd-kf=0 --arnr-strength=1 --sb-size=dynamic --enable-dnl-denoising=0 " -o "output.mkv"\n')),(0,i.kt)("admonition",{title:"Parameter Meta",type:"info"},(0,i.kt)("p",{parentName:"admonition"},"It is strongly recommended to join the ",(0,i.kt)("a",{parentName:"p",href:"https://discord.gg/vpREHAvYvh"},"AV1 Discord server")," to get the latest updates on what to use and which to set, as it's the only easily reachable place for everything AV1 & encoding tips in general.")),(0,i.kt)("p",null,"Now let's dissect it one-by-one"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Av1an parameters:")),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"-i")," Input.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"-x 300")," Sets scene split length to 300 frames, you can increase it for more quality at the tradeoff of video seekability.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"-w 4"),' Specifies the amount of "workers" or amount of encoders working on the video.')),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--verbose")," Sets logging to verbose.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--resume")," Resumes the encode even when you haven't encoded yet. I strongly recommend leaving this if you resume a lot since you can accidentally delete your whole progress (There's no delete confirmation feature.. yet) if you \"resumed\" without the parameter in place.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"-e aom")," Specifies we're using aomenc encoder which should be the default option.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"-c mkvmerge")," Specifies we're using mkvmerge (MKVToolNix) to concatenate the parts when done, you can specify with ffmpeg if you want to but this is the best method.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"-m lsmash")," Specifies we're using l-smash (Vapoursynth plugin) to split the videos, this is also the best method because ffms2 causes video lag (Tested a year ago, might change now) and other methods just suck (Slow and not worth it, learned the hard way). You can attempt to use ffms2 when inputting VC-1 videos as it is not possible with l-smash (Or convert it to lossless with x264 qp 0).")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},'-f " -an "')," ",(0,i.kt)("inlineCode",{parentName:"p"},"-f")," Stands for ffmpeg parameters, ",(0,i.kt)("inlineCode",{parentName:"p"},"-an")," is to remove all audio since its better to encode and merge it separately. To crop use ",(0,i.kt)("inlineCode",{parentName:"p"},'-f " -an -vf crop=1920:800 "')," for example to crop the video to 1920x800.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},'-v " "')," Is where you put the encoder's parameters in.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},'-a " -an "')," FFmpeg audio encoding options, we're removing it cause we can always add it later. But if you want to, you can also encode directly. Here's an example for encoding to Opus using libopus assuming stereo: ",(0,i.kt)("inlineCode",{parentName:"p"},'-a " -c:a libopus -b:a 128k "'),".")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--photon-noise=10")," AV1 grain synthesis, which is a technique where the encoder puts fake grain in so it looks more natural and potentially hiding video artifacts (cause grain is hard to encode and explodes bitrate usage because of their randomness), 5-8 for almost none to little grain, 10-14 for medium, 15+ heavy, 20+ extremely heavy, 30+ for extremely grainy 90s live action films.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--set-thread-affinity=2")," Pins the thread to the encoder, aligns with ",(0,i.kt)("inlineCode",{parentName:"p"},"--threads=2")," in the encoder parameter so set them accordingly."))),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"aomenc parameters:")),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--bit-depth=10")," We're using 10bit because it makes the video smaller and reduces ",(0,i.kt)("a",{parentName:"p",href:"https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Video_codecs#contouring"},"banding"),".")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--cpu-used=4")," This is the preset which ranges from 0-9, you can go to 3 if you want more efficiency, 2 if you have a lot of time, 4 is the sweet spot, and 6 if you want speed. Don't go above 6 (Worst efficiency) or even 0 (It would take WEEKS to finish).")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--end-usage=q --cq-level=24")," This specifies that we are going to use a knockoff version of CRF level similar to x264/x265 encoders, in this case CRF 24.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--threads=2")," Sets the amount of threads the encoder can use, aligns with ",(0,i.kt)("inlineCode",{parentName:"p"},"--set-thread-affinity")," in Av1an.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--tile-columns=0 --tile-rows=0")," This is the tiles options, where the encoder splits the videos into tiles to encode faster, see the image below (Yellow lines):"),(0,i.kt)("picture",null,(0,i.kt)("source",{srcset:"https://raw.githubusercontent.com/av1-community-contributors/images/main/tiling_av1.avif?token=GHSAT0AAAAAACEZPDXIZARY5MGSTJW4SI22ZHY636A",type:"image/avif"}),(0,i.kt)("img",{src:"https://autumn.revolt.chat/attachments/HwhZjoDsdzLZsJM2mjzX7lEDmJn1xcYNdrQqmOxPYW/tiling_av1.jpeg",alt:"Tiling",width:"1280",height:"768",loading:"lazy"})))),(0,i.kt)("admonition",{title:"Tile usage",type:"note"},(0,i.kt)("p",{parentName:"admonition"},"Do NOT use tiles for 1080p and below, use 1 ",(0,i.kt)("inlineCode",{parentName:"p"},"tile-columns")," at 1440p (2K), 2 ",(0,i.kt)("inlineCode",{parentName:"p"},"tile-columns")," and 1 ",(0,i.kt)("inlineCode",{parentName:"p"},"tile-rows")," for 2160p (4K)")),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--lag-in-frames=64")," Knockoff of x264/x265 ",(0,i.kt)("a",{parentName:"p",href:"https://en.wikipedia.org/wiki/Group_of_pictures"},"Group of Pictures")," (GOP), makes the encoder look into future frames for better compression decision making, do not go over 64 as it is pretty much useless.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--aq-mode")," adaptive quantization mode, 0 is better most of the time")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--tune-content=psy --tune=ssim")," As the name suggests they are tunes that affect the video output, for the better, and for the worst"))),(0,i.kt)("admonition",{title:"Tunes to use",type:"info"},(0,i.kt)("p",{parentName:"admonition"},"Set ",(0,i.kt)("inlineCode",{parentName:"p"},"tune-content")," to ",(0,i.kt)("inlineCode",{parentName:"p"},"animation")," if you're encoding above ",(0,i.kt)("inlineCode",{parentName:"p"},"cq-level=30")," A.K.A lower quality, despite it's name\nSet ",(0,i.kt)("inlineCode",{parentName:"p"},"tune-content")," to ",(0,i.kt)("inlineCode",{parentName:"p"},"psy")," for everything else, ",(0,i.kt)("strong",{parentName:"p"},"do not use if you encode above ",(0,i.kt)("inlineCode",{parentName:"strong"},"cq-level=30")),"\nFor ",(0,i.kt)("inlineCode",{parentName:"p"},"tune"),", this is a bit tricky. For now, the meta seems to be ",(0,i.kt)("inlineCode",{parentName:"p"},"ssim"),", but back then it was ",(0,i.kt)("inlineCode",{parentName:"p"},"lavish")," which is considered THE best tune because it's based on ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/google/butteraugli"},"butteraugli"),". Now it's fallen behind because its more blurry than ",(0,i.kt)("inlineCode",{parentName:"p"},"ssim"),", and before that it was ",(0,i.kt)("inlineCode",{parentName:"p"},"butteraugli"),", and then ",(0,i.kt)("inlineCode",{parentName:"p"},"ipq_vmaf_psy"),", and finally just ",(0,i.kt)("inlineCode",{parentName:"p"},"ipq"),".\nIf you use any of the VMAF tunes, ",(0,i.kt)("strong",{parentName:"p"},"you need to specify ",(0,i.kt)("inlineCode",{parentName:"strong"},"--vmaf-model-path=")," to where you put it"),".")),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--enable-keyframe-filtering=1")," We're setting it to 1 because of compatibility reasons, 2 is more efficient but there are seeking issues and FFmpeg for some reason can't input it.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--sb-size=dynamic")," Allows the encoder to use 128x128 block partitioning besides 64x64 which gives an efficiency boost, ignore it.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--deltaq-mode")," set to 0 because its just better.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--arnr-strength=1")," Controls how strong the filtering will be, 1 is good for 3D Pixar CGI-like and 2D animation, use 4 if you're doing live action content. Using maximum at higher bitrates would just result in a blurry mess.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--disable-kf --enable-fwd-kf=0")," We're disabling keyframes cause ",(0,i.kt)("strong",{parentName:"p"},"Av1an already did scene detection, so we wont have to."),". And it speeds things up.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--kf-max-dist=9999")," Maximum keyframe interval, we're setting it at the highest possible value since av1an's scene detection keyframe interval is already 240 by default")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--enable-chroma-deltaq=1 --enable-qm=1 --quant-b-adapt=1")," Parameters that give you free efficiency boost.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--enable-dnl-denoising=0")," Disables the encoder's built-in denoising technique when grain synthesis is enabled, you can optionally set it to 1 when you have a pretty noisy video since it works quite well."))),(0,i.kt)("admonition",{title:"Concatenation Error on Linux",type:"info"},(0,i.kt)("p",{parentName:"admonition"},"Run ",(0,i.kt)("inlineCode",{parentName:"p"},"ulimit -n 200000"),", resume, and it should concatenate just fine. If it still errors, head to the encode directory > encode, and run ",(0,i.kt)("inlineCode",{parentName:"p"},"mkvmerge @../options.json"))),(0,i.kt)("h2",{id:"merging-everything"},"Merging Everything"),(0,i.kt)("p",null,"Once you're done just encode your audio using ffmpeg (or just passthrough it), subtitles should be carried along with your video output, and merge them in MKVToolNix! Don't want Matroska files? That's fine, you can use FFmpeg or MP4Box to output into ",(0,i.kt)("inlineCode",{parentName:"p"},"mp4"),", just keep in mind that PGS/SUP/VOBSUB subtitles are not supported and Opus audio support is still experimental."),(0,i.kt)("h2",{id:"tips--tricks"},"Tips & Tricks"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--denoise-noise-level=10")," Alternative to ",(0,i.kt)("inlineCode",{parentName:"p"},"photon-noise"),", slower than photon-noise and is the OG grain synthesis method, performs okay and just serves as an alternative. Don't attempt to use it at high values (>12) since it creates noticeable grain patterns.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--arnr-maxframes")," to set max reference frames that will be used to filter the encode, higher values would make the video blurrier at high fidelity but look better at lower bitrates.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"--butteraugli-resize-factor=2")," if you use any of the butteraugli-based tunes (lavish, butteraugli) to speed it up without much losses and ",(0,i.kt)("inlineCode",{parentName:"p"},"--butteraugli-intensity-target=250")," to match the content light level."))),(0,i.kt)("h2",{id:"final-thoughts"},"Final Thoughts"),(0,i.kt)("p",null,'Encoding has always been about experimentation for the best, there is really no "One size fits all" for encoding content, as they differ from scene complexity, how it\'s captured (2D/Real life), film grain, dark scenes, etc. So experiment away for your specific type of content!'),(0,i.kt)("blockquote",null,(0,i.kt)("p",{parentName:"blockquote"},(0,i.kt)("strong",{parentName:"p"},"Guide originally hosted on ",(0,i.kt)("a",{parentName:"strong",href:"https://rentry.co/AV1"},"https://rentry.co/AV1"),", rewrite and migration by Simulping."))))}d.isMDXComponent=!0},9081:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/compare-guide-6feb966fbd9d73be4a3097c41691c4ad.webp"},5900:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/python-path-a89fc4fe6c6eb4c2ea0a7610dd2cf09a.webp"}}]); \ No newline at end of file diff --git a/assets/js/239a6b34.0eb2ad08.js b/assets/js/695eb979.b9f6b8c1.js similarity index 65% rename from assets/js/239a6b34.0eb2ad08.js rename to assets/js/695eb979.b9f6b8c1.js index 8147854e0..2c2f0b123 100644 --- a/assets/js/239a6b34.0eb2ad08.js +++ b/assets/js/695eb979.b9f6b8c1.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[6643],{3769:e=>{e.exports=JSON.parse('{"name":"docusaurus-plugin-content-docs","id":"default"}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[1809],{3769:e=>{e.exports=JSON.parse('{"name":"docusaurus-plugin-content-docs","id":"default"}')}}]); \ No newline at end of file diff --git a/assets/js/6bdd9a40.56f3b23d.js b/assets/js/6bdd9a40.56f3b23d.js new file mode 100644 index 000000000..c974deef9 --- /dev/null +++ b/assets/js/6bdd9a40.56f3b23d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[60],{5745:e=>{e.exports=JSON.parse('{"name":"docusaurus-plugin-content-pages","id":"default"}')}}]); \ No newline at end of file diff --git a/assets/js/89809f85.d242abfe.js b/assets/js/89809f85.363353a9.js similarity index 86% rename from assets/js/89809f85.d242abfe.js rename to assets/js/89809f85.363353a9.js index a6c890786..0db289652 100644 --- a/assets/js/89809f85.d242abfe.js +++ b/assets/js/89809f85.363353a9.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[9578],{3905:(e,t,i)=>{i.d(t,{Zo:()=>h,kt:()=>u});var o=i(7294);function a(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}function n(e,t){var i=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),i.push.apply(i,o)}return i}function s(e){for(var t=1;t=0||(a[i]=e[i]);return a}(e,t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,i)&&(a[i]=e[i])}return a}var l=o.createContext({}),d=function(e){var t=o.useContext(l),i=t;return e&&(i="function"==typeof e?e(t):s(s({},t),e)),i},h=function(e){var t=d(e.components);return o.createElement(l.Provider,{value:t},e.children)},p="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},m=o.forwardRef((function(e,t){var i=e.components,a=e.mdxType,n=e.originalType,l=e.parentName,h=r(e,["components","mdxType","originalType","parentName"]),p=d(i),m=a,u=p["".concat(l,".").concat(m)]||p[m]||c[m]||n;return i?o.createElement(u,s(s({ref:t},h),{},{components:i})):o.createElement(u,s({ref:t},h))}));function u(e,t){var i=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var n=i.length,s=new Array(n);s[0]=m;var r={};for(var l in t)hasOwnProperty.call(t,l)&&(r[l]=t[l]);r.originalType=e,r[p]="string"==typeof e?e:a,s[1]=r;for(var d=2;d{i.r(t),i.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>c,frontMatter:()=>n,metadata:()=>r,toc:()=>d});var o=i(7462),a=(i(7294),i(3905));const n={title:"Embedding the Un-Embeddable: Dissecting discord.nfp.is, stolen.shoes & Others",description:"Revealing the secrets of those websites that allow you to embed entire movies, AV1, and videos over 500MB on Discord.",slug:"embedding-the-un-embeddable",authors:[{name:"Simulping",title:"Maintainer / Encoder",url:"https://github.com/Simulping",image_url:"https://avatars.githubusercontent.com/u/12994794?v=4"}],tags:["video","discord"],image:"/img/discord-embed-blog-image.webp",hide_table_of_contents:!1},s=void 0,r={permalink:"/blog/embedding-the-un-embeddable",source:"@site/blog/2023-10-29-embedding-the-un-embeddable.md",title:"Embedding the Un-Embeddable: Dissecting discord.nfp.is, stolen.shoes & Others",description:"Revealing the secrets of those websites that allow you to embed entire movies, AV1, and videos over 500MB on Discord.",date:"2023-10-29T00:00:00.000Z",formattedDate:"October 29, 2023",tags:[{label:"video",permalink:"/blog/tags/video"},{label:"discord",permalink:"/blog/tags/discord"}],readingTime:8.91,hasTruncateMarker:!0,authors:[{name:"Simulping",title:"Maintainer / Encoder",url:"https://github.com/Simulping",image_url:"https://avatars.githubusercontent.com/u/12994794?v=4",imageURL:"https://avatars.githubusercontent.com/u/12994794?v=4"}],frontMatter:{title:"Embedding the Un-Embeddable: Dissecting discord.nfp.is, stolen.shoes & Others",description:"Revealing the secrets of those websites that allow you to embed entire movies, AV1, and videos over 500MB on Discord.",slug:"embedding-the-un-embeddable",authors:[{name:"Simulping",title:"Maintainer / Encoder",url:"https://github.com/Simulping",image_url:"https://avatars.githubusercontent.com/u/12994794?v=4",imageURL:"https://avatars.githubusercontent.com/u/12994794?v=4"}],tags:["video","discord"],image:"/img/discord-embed-blog-image.webp",hide_table_of_contents:!1},nextItem:{title:"AV1 Encoding for Dummies",permalink:"/blog/av1-encoding-for-dummies"}},l={authorsImageUrls:[void 0]},d=[{value:"A Scenario",id:"a-scenario",level:2},{value:"How it Works",id:"how-it-works",level:2},{value:"The Website's End",id:"the-websites-end",level:3},{value:"Discord's End",id:"discords-end",level:3},{value:"Strengths & Limitations",id:"strengths--limitations",level:2},{value:"Strengths",id:"strengths",level:4},{value:"Limitations",id:"limitations",level:4},{value:"Differences between Sites",id:"differences-between-sites",level:2},{value:"The Lore",id:"the-lore",level:2},{value:"Dwayne",id:"dwayne",level:3},{value:"Discovery",id:"discovery",level:3},{value:"The Experiments & Interactive Site",id:"the-experiments--interactive-site",level:3},{value:"Virality",id:"virality",level:3},{value:"Closing",id:"closing",level:2}],h={toc:d},p="wrapper";function c(e){let{components:t,...n}=e;return(0,a.kt)(p,(0,o.Z)({},h,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("admonition",{title:"Copyright Disclosure",type:"caution"},(0,a.kt)("p",{parentName:"admonition"},"The Codec Wiki unequivocally condemns any form of piracy, including the unauthorized distribution of copyrighted content. This blog post is intended to educate & inform. You may not use the tools discussed to infringe upon the intellectual property rights of content creators without serious legal risk. We encourage our readers to respect copyright laws & use the tools we discuss here appropriately.")),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"Feature image",src:i(5477).Z,width:"1920",height:"1080"}),"\n",(0,a.kt)("strong",{parentName:"p"},'A 567.14 MB, 12 min 11 s, 2K (2,048 x 858), VP9 + Opus, 6.51 Mbps average, Blender short film "Cosmos Laundromat"')),(0,a.kt)("h2",{id:"a-scenario"},"A Scenario"),(0,a.kt)("p",null,"While chatting in your favorite Discord servers & group chats, you may see a friend send a weird link. You might even consider it suspicious on first glance. It is a video featuring an image of a movie poster with a play button that is almost begging to be clicked. Naturally, you click it."),(0,a.kt)("p",null,"It loads for a second, and to your surprise it is a full-length, 90-minute (sometimes even two hour)-long unauthorized copy of a movie. If you don't know exactly what is going on, you probably sit there dumbfounded as a pixel perfect HD movie plays back. You may have expected a stereotypically muddy, blocky, laggy shitpost, but this has defied your expectations."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"stolen.shoes",src:i(2588).Z,width:"1088",height:"318"})),(0,a.kt)("p",null,"The truth is, there are ",(0,a.kt)("em",{parentName:"p"},"multiple")," site that do this. Currently, there are five at the time of writing. Below is a list the ones I am currently familiar with:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://stolen.shoes"},"https://stolen.shoes")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://discord.nfp.is"},"https://discord.nfp.is")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://embeds.video"},"https://embeds.video")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://x266.mov/discord-embed"},"https://x266.mov/discord-embed")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://autocompressor.net/av1"},"https://autocompressor.net/av1"))),(0,a.kt)("p",null,"The big question is, ",(0,a.kt)("strong",{parentName:"p"},"how do they work?")," Let's get to dissecting."),(0,a.kt)("h2",{id:"how-it-works"},"How it Works"),(0,a.kt)("p",null,"The entire scheme is actually very simple, as it is all just HTML meta tags (If you are familiar with web development, this is all a walk in the park)."),(0,a.kt)("p",null,"The technology's inner working can be divided into two distinct parts. First, let's see how it works on the website's end."),(0,a.kt)("h3",{id:"the-websites-end"},"The Website's End"),(0,a.kt)("p",null,"If you view each website's source, you will find this specific line in each one but they may have a different order:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-html"},'\n\n\n\n\n')),(0,a.kt)("p",null,"These are the ",(0,a.kt)("inlineCode",{parentName:"p"},"head")," parts of HTML, which dictate metadata for the document itself such as what the website title/name is, cosmetic embed, defining the site's icon, etc. They are usually found in between the ",(0,a.kt)("inlineCode",{parentName:"p"},"")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"")," tags. Here's an example of a static HTML site serving one specific video:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-html"},'\n\n\n \n \n some embed site\n \n \n \n \n \n\n\n

Hi

\n

Just your friendly neighborhood video embed site

\n \n\n')),(0,a.kt)("br",null),"These interactive sites usually deploy a live script, like a Javascript framework. Examples are NodeJS, ExpressJS, Svelte, etc. These are used to parse video and thumbnails realtime so they can be embedded on Discord (or potentially other platforms).",(0,a.kt)("h3",{id:"discords-end"},"Discord's End"),(0,a.kt)("p",null,'Traditionally, Discord\'s media embedder will impose it\'s own video embed size limit (50 MiB) when a user sends a direct video link as usual. But in this case Discord will embed the thumbnail first, not the video. You could say the link "tricks" Discord by showing a "false face" first.'),(0,a.kt)("h2",{id:"strengths--limitations"},"Strengths & Limitations"),(0,a.kt)("p",null,"After a combination of countless hours of observation, rigorous testing throughout the period of a year, and conversations with the sites' creators, the current strengths & limitations of this exploit are enumerated below."),(0,a.kt)("h4",{id:"strengths"},"Strengths"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"You can embed non-web compatible codecs such as ",(0,a.kt)("a",{parentName:"li",href:"https://wiki.x266.mov/docs/video/HEVC"},"HEVC")," in ",(0,a.kt)("a",{parentName:"li",href:"https://wiki.x266.mov/docs/introduction/terminology#mp4--m4v"},"MP4/MOV"),", but the user must be using a compatible browser. ",(0,a.kt)("a",{parentName:"li",href:"https://thorium.rocks"},"Thorium")," or Safari version 13 or greater will work for HEVC playback."),(0,a.kt)("li",{parentName:"ul"},"There is no maximum size. You could embed a video the size of a raw Bluray, although I do not condone this unless you have the necessary legal permissions to do so or you're uploading a Creative Commons licensed movie like Big Buck Bunny while adhering to the restrictions of the applicable Creative Commons license. This also means you can send high bitrate gaming clips to your friends without any restrictions, assuming you already have a place to upload them.")),(0,a.kt)("h4",{id:"limitations"},"Limitations"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"You can only use ",(0,a.kt)("a",{parentName:"li",href:"https://simple.wikipedia.org/wiki/Hotlinking"},"hotlinks"),", which means direct linking to the video itself ending in the appropriate file extension such as ",(0,a.kt)("inlineCode",{parentName:"li"},".mp4"),". Cloud services like Google Drive or OneDrive will not work for storage."),(0,a.kt)("li",{parentName:"ul"},"You cannot use Discord's CDN (cdn.discordapp.com) as the video source. I assume this is because of Discord's proxy blocking embeds over 50 MiB, but ",(0,a.kt)("strong",{parentName:"li"},"only discord.nfp.is can do this"),", as it ",(0,a.kt)("strong",{parentName:"li"},"proxies cdn.discordapp.com")," itself."),(0,a.kt)("li",{parentName:"ul"},"You cannot embed videos in any resolutions higher than 3840 x 2160, Discord imposes a hard limit for this on all video after it was discovered that some videos could play normally but then be maliciously scaled to ridiculous resolutions during playback to crash Discord.")),(0,a.kt)("h2",{id:"differences-between-sites"},"Differences between Sites"),(0,a.kt)("p",null,"As mentioned before, there are five known sites at the time of writing. They all serve the same function, but one may interest you more than another due to slight differences in features & functionality."),(0,a.kt)("p",null,"Here are the sites, each with one noteworthy special benefit:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://stolen.shoes"},"https://stolen.shoes")," - Recognition, as it is the OG."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://discord.nfp.is"},"https://discord.nfp.is")," - You can use Discord CDN as video source."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://embeds.video"},"https://embeds.video")," - Immediately input video source into the URL (",(0,a.kt)("inlineCode",{parentName:"li"},"https://embeds.video/https://example.com/v/video.mp4"),")"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://x266.mov/discord-embed"},"https://x266.mov/discord-embed")," - Attractive domain, simple layout."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://autocompressor.net/av1"},"https://autocompressor.net/av1")," - Lots of info dump, pretty advanced features.")),(0,a.kt)("p",null,"That concludes the technical overview! Next, let's cover the history of this exploit."),(0,a.kt)("h2",{id:"the-lore"},"The Lore"),(0,a.kt)("h3",{id:"dwayne"},"Dwayne"),(0,a.kt)("p",null,"In around April of 2022, a Reddit user going by the name of u/CreativeGamer03 ",(0,a.kt)("a",{parentName:"p",href:"https://www.reddit.com/r/discordapp/comments/u96kky/someone_sent_this_in_the_memes_channel_and_bruh"},"posted a video on r/discordapp"),' of a link where a GIF of Dwayne "The Rock" Johnson plays caption with "Is this a GIF or is it a video?" When played, a low-quality music video of Rick Astley\'s "Never Gonna Give You Up" plays.'),(0,a.kt)("p",null,"The link used is now unfortunately ",(0,a.kt)("a",{parentName:"p",href:"https://archuser.de/the-rock"},"removed"),"."),(0,a.kt)("h3",{id:"discovery"},"Discovery"),(0,a.kt)("p",null,"On 23rd June 2022, a Discord user ",(0,a.kt)("em",{parentName:"p"},"Clybius")," on the AV1 Community server asked people for ",(0,a.kt)("a",{parentName:"p",href:"https://wiki.x266.mov/docs/video/VP9"},"VP9")," or ",(0,a.kt)("a",{parentName:"p",href:"https://wiki.x266.mov/docs/video/AVC"},"H.264")," videos that were over 100 MB in size. At the time the current 500 MB nitro tier did not exist. They then decided to use a 59 minute 1080p sample video of nature scenery from around the world with a thumbnail featuring a GIF of a waterfall to test the exploit. It worked."),(0,a.kt)("p",null,"He tried shortly afterward with ",(0,a.kt)("a",{parentName:"p",href:"https://wiki.x266.mov/docs/video/AV1"},"AV1"),". Eureka, it also worked:"),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"AV1",src:i(3952).Z,width:"497",height:"421"})),(0,a.kt)("p",null,"Clybius confirmed that this could be patched if discovered. He cites having had the idea from the Dwayne Johnson example above, but forgetting about it for a couple of months. So, it seems this entire concept stemmed from a silly rickroll."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"Dwayne",src:i(1354).Z,width:"1108",height:"98"})),(0,a.kt)("h3",{id:"the-experiments--interactive-site"},"The Experiments & Interactive Site"),(0,a.kt)("p",null,"After the discovery of AV1 embedding, experimentation brought about the discovery that ",(0,a.kt)("em",{parentName:"p"},"any")," video codec will work as long as the user can decode/play the codec and the container/extension is an MP4, MOV, or WebM. These are all traditionally web-compatible containers. If you're interested in learning about containers, please see the ",(0,a.kt)("a",{parentName:"p",href:"https://wiki.x266.mov/docs/introduction/terminology#container"},"Containers")," section on the ",(0,a.kt)("a",{parentName:"p",href:"https://wiki.x266.mov/docs/introduction/terminology"},"Terminology")," page."),(0,a.kt)("p",null,"This applies to HEVC, ProRes, ",(0,a.kt)("a",{parentName:"p",href:"https://wiki.x266.mov/docs/audio/AAC#xhe-aac"},"xHE-AAC"),", and other bizarre codecs that are rarely seen on the Web."),(0,a.kt)("p",null,"While experimentating, Clybius converted one their idle domains ",(0,a.kt)("inlineCode",{parentName:"p"},"stolen.shoes")," into an interactive embedder that provided a textbox for a video URL, a thumbnail URL, a width value, & a height value for the desired video. This would be the first website for Discord embedding."),(0,a.kt)("h3",{id:"virality"},"Virality"),(0,a.kt)("p",null,"It's not long before people outside of the AV1 Community discovered ",(0,a.kt)("inlineCode",{parentName:"p"},"stolen.shoes"),", and its popularity increased rapidly. Its use usually involved the illicit distribution of full-length, unauthorized copies of movies; this sometimes happened very shortly after some movies were released. There were a couple notable instances of this happenening that caused quite the stir online each time."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'The first instance featured the DreamWorks sequel of "Puss in Boots (2011)", "Puss in Boots: The Last Wish (2022)". A 1080p video sourced from a streaming site was the first wake up call that attracted attention to the existence of these embed sites. This example used ',(0,a.kt)("inlineCode",{parentName:"li"},"stolen.shoes"),".")),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"puss",src:i(2588).Z,width:"1088",height:"318"})),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'The second instance was when highly-anticipated animated film "The Super Mario Bros. Movie (2023)" produced by Illumination, Universal Studios, and Nintendo was spread around Discord. It was first spotted as a Cam (A camera recording by someone in theaters), then as it went out on streaming services a different link appeared but spread faster and with upgraded 1080p quality. Both used ',(0,a.kt)("inlineCode",{parentName:"li"},"stolen.shoes")," as the embed site.")),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"mario",src:i(1147).Z,width:"1307",height:"335"})),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'The third instance is very recent as of the day this was posted. A streaming-service sourced "Five Nights at Freddy\'s (2023)" was spread around since the movie released both in theaters and streaming service (Peacock) day one, and it gained steam extremely fast as most people had not seen it yet. Currently, this illegal novelty is gaining ',(0,a.kt)("a",{parentName:"li",href:"https://www.reddit.com/r/discordapp/comments/17hx45y/is_discordnfp_an_ip_grabber/"},"hundreds of upvotes within the r/discordapp subreddit"),". The copy seems to be a compressed 720p encode. This example used ",(0,a.kt)("inlineCode",{parentName:"li"},"discord.nfp.is"),".")),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"fnaf",src:i(5430).Z,width:"1044",height:"409"})),(0,a.kt)("p",null,"Note the ones listed here are the ones that I saw become extremely popular. There may be lesser known links that have been spread around privately or just did not cause enough noise for me to notice. Some less popular examples I've noticed, featuring more illicit copyrighted content distribution: "),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Top Gun Maverick (2022)"),(0,a.kt)("li",{parentName:"ul"},"The SpongeBob trilogy (2005/2015/2020)"),(0,a.kt)("li",{parentName:"ul"},"Spider-Man: Across the Spider-Verse (2023)")),(0,a.kt)("h2",{id:"closing"},"Closing"),(0,a.kt)("p",null,"The ability to embed unusually large videos on Discord has enabled both positive and negative use cases. On the one hand, it allows high-quality content to be shared easily among friends. However, it has also facilitated mass copyright infringement by empowering virtually anyone with a Discord accound to freely spread pirated movies."),(0,a.kt)("p",null,"While this is fascinating from a technical perspective, embedding techniques like these tread a fine ethical line. As with anything, it is important to be mindful of how our actions affect others, and I should remind everyone that content creators deserve to be compensated for their work. As users, we should support them by accessing their content via legitimate platforms."),(0,a.kt)("p",null,"It is hard to say how long this exploit will continue to be usable. Instead of enabling piracy, which may cause Discord to be more likely to patch this exploit if they see it as a serious threat, let's instead use these capabilities responsibly to share our own creations, gaming highlights, and other media which we can share legally. Given some thoughtfulness, perhaps we can find a fair balance between respecting copyright law and appeasing Discord's sensibilities while allowing some creative flexibility on the platform."),(0,a.kt)("p",null,"Thank you for reading this blog post, I hope you learned something!"))}c.isMDXComponent=!0},3952:(e,t,i)=>{i.d(t,{Z:()=>o});const o=i.p+"assets/images/clybius-av1-28dcfefe8d58784301332b8119d2e926.webp"},1354:(e,t,i)=>{i.d(t,{Z:()=>o});const o=i.p+"assets/images/clybius-dwayne-15341f187cb8e7dbfd5c4ee00451eabd.webp"},5477:(e,t,i)=>{i.d(t,{Z:()=>o});const o=i.p+"assets/images/discord-embed-blog-image-2bcaf4f73f5fa33664328756753f3041.webp"},5430:(e,t,i)=>{i.d(t,{Z:()=>o});const o=i.p+"assets/images/discordnfpis-fnaf-dab5b24a63605605e7c7882d20a992a3.webp"},1147:(e,t,i)=>{i.d(t,{Z:()=>o});const o=i.p+"assets/images/stolenshoes-mario-6de3b4071d4c09064d7323fec40530f4.webp"},2588:(e,t,i)=>{i.d(t,{Z:()=>o});const o=i.p+"assets/images/stolenshoes-puss-842a1f9165b7571d293a74be89da25c2.webp"}}]); \ No newline at end of file +"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[9578],{3905:(e,t,i)=>{i.d(t,{Zo:()=>h,kt:()=>u});var o=i(7294);function a(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}function n(e,t){var i=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),i.push.apply(i,o)}return i}function s(e){for(var t=1;t=0||(a[i]=e[i]);return a}(e,t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,i)&&(a[i]=e[i])}return a}var l=o.createContext({}),d=function(e){var t=o.useContext(l),i=t;return e&&(i="function"==typeof e?e(t):s(s({},t),e)),i},h=function(e){var t=d(e.components);return o.createElement(l.Provider,{value:t},e.children)},p="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},m=o.forwardRef((function(e,t){var i=e.components,a=e.mdxType,n=e.originalType,l=e.parentName,h=r(e,["components","mdxType","originalType","parentName"]),p=d(i),m=a,u=p["".concat(l,".").concat(m)]||p[m]||c[m]||n;return i?o.createElement(u,s(s({ref:t},h),{},{components:i})):o.createElement(u,s({ref:t},h))}));function u(e,t){var i=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var n=i.length,s=new Array(n);s[0]=m;var r={};for(var l in t)hasOwnProperty.call(t,l)&&(r[l]=t[l]);r.originalType=e,r[p]="string"==typeof e?e:a,s[1]=r;for(var d=2;d{i.r(t),i.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>c,frontMatter:()=>n,metadata:()=>r,toc:()=>d});var o=i(7462),a=(i(7294),i(3905));const n={title:"Embedding the Un-Embeddable: Dissecting discord.nfp.is, stolen.shoes & Others",description:"Revealing the secrets of those websites that allow you to embed entire movies, AV1, and videos over 500MB on Discord.",slug:"embedding-the-un-embeddable",authors:[{name:"Simulping",title:"Maintainer / Encoder",url:"https://github.com/Simulping",image_url:"https://avatars.githubusercontent.com/u/12994794?v=4"}],tags:["video","discord"],image:"/img/discord-embed-blog-image.webp",hide_table_of_contents:!1},s=void 0,r={permalink:"/blog/embedding-the-un-embeddable",source:"@site/blog/2023-10-29-embedding-the-un-embeddable.md",title:"Embedding the Un-Embeddable: Dissecting discord.nfp.is, stolen.shoes & Others",description:"Revealing the secrets of those websites that allow you to embed entire movies, AV1, and videos over 500MB on Discord.",date:"2023-10-29T00:00:00.000Z",formattedDate:"October 29, 2023",tags:[{label:"video",permalink:"/blog/tags/video"},{label:"discord",permalink:"/blog/tags/discord"}],readingTime:8.91,hasTruncateMarker:!0,authors:[{name:"Simulping",title:"Maintainer / Encoder",url:"https://github.com/Simulping",image_url:"https://avatars.githubusercontent.com/u/12994794?v=4",imageURL:"https://avatars.githubusercontent.com/u/12994794?v=4"}],frontMatter:{title:"Embedding the Un-Embeddable: Dissecting discord.nfp.is, stolen.shoes & Others",description:"Revealing the secrets of those websites that allow you to embed entire movies, AV1, and videos over 500MB on Discord.",slug:"embedding-the-un-embeddable",authors:[{name:"Simulping",title:"Maintainer / Encoder",url:"https://github.com/Simulping",image_url:"https://avatars.githubusercontent.com/u/12994794?v=4",imageURL:"https://avatars.githubusercontent.com/u/12994794?v=4"}],tags:["video","discord"],image:"/img/discord-embed-blog-image.webp",hide_table_of_contents:!1},nextItem:{title:"AV1 Encoding for Dummies",permalink:"/blog/av1-encoding-for-dummies"}},l={authorsImageUrls:[void 0]},d=[{value:"A Scenario",id:"a-scenario",level:2},{value:"How it Works",id:"how-it-works",level:2},{value:"The Website's End",id:"the-websites-end",level:3},{value:"Discord's End",id:"discords-end",level:3},{value:"Strengths & Limitations",id:"strengths--limitations",level:2},{value:"Strengths",id:"strengths",level:4},{value:"Limitations",id:"limitations",level:4},{value:"Differences between Sites",id:"differences-between-sites",level:2},{value:"The Lore",id:"the-lore",level:2},{value:"Dwayne",id:"dwayne",level:3},{value:"Discovery",id:"discovery",level:3},{value:"The Experiments & Interactive Site",id:"the-experiments--interactive-site",level:3},{value:"Virality",id:"virality",level:3},{value:"Closing",id:"closing",level:2}],h={toc:d},p="wrapper";function c(e){let{components:t,...n}=e;return(0,a.kt)(p,(0,o.Z)({},h,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("admonition",{title:"Copyright Disclosure",type:"caution"},(0,a.kt)("p",{parentName:"admonition"},"The Codec Wiki unequivocally condemns any form of piracy, including the unauthorized distribution of copyrighted content. This blog post is intended to educate & inform. You may not use the tools discussed to infringe upon the intellectual property rights of content creators without serious legal risk. We encourage our readers to respect copyright laws & use the tools we discuss here appropriately.")),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"Feature image",src:i(3093).Z,width:"1920",height:"1080"}),"\n",(0,a.kt)("strong",{parentName:"p"},'A 567.14 MB, 12 min 11 s, 2K (2,048 x 858), VP9 + Opus, 6.51 Mbps average, Blender short film "Cosmos Laundromat"')),(0,a.kt)("h2",{id:"a-scenario"},"A Scenario"),(0,a.kt)("p",null,"While chatting in your favorite Discord servers & group chats, you may see a friend send a weird link. You might even consider it suspicious on first glance. It is a video featuring an image of a movie poster with a play button that is almost begging to be clicked. Naturally, you click it."),(0,a.kt)("p",null,"It loads for a second, and to your surprise it is a full-length, 90-minute (sometimes even two hour)-long unauthorized copy of a movie. If you don't know exactly what is going on, you probably sit there dumbfounded as a pixel perfect HD movie plays back. You may have expected a stereotypically muddy, blocky, laggy shitpost, but this has defied your expectations."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"stolen.shoes",src:i(8449).Z,width:"1088",height:"318"})),(0,a.kt)("p",null,"The truth is, there are ",(0,a.kt)("em",{parentName:"p"},"multiple")," site that do this. Currently, there are five at the time of writing. Below is a list the ones I am currently familiar with:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://stolen.shoes"},"https://stolen.shoes")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://discord.nfp.is"},"https://discord.nfp.is")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://embeds.video"},"https://embeds.video")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://x266.mov/discord-embed"},"https://x266.mov/discord-embed")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://autocompressor.net/av1"},"https://autocompressor.net/av1"))),(0,a.kt)("p",null,"The big question is, ",(0,a.kt)("strong",{parentName:"p"},"how do they work?")," Let's get to dissecting."),(0,a.kt)("h2",{id:"how-it-works"},"How it Works"),(0,a.kt)("p",null,"The entire scheme is actually very simple, as it is all just HTML meta tags (If you are familiar with web development, this is all a walk in the park)."),(0,a.kt)("p",null,"The technology's inner working can be divided into two distinct parts. First, let's see how it works on the website's end."),(0,a.kt)("h3",{id:"the-websites-end"},"The Website's End"),(0,a.kt)("p",null,"If you view each website's source, you will find this specific line in each one but they may have a different order:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-html"},'\n\n\n\n\n')),(0,a.kt)("p",null,"These are the ",(0,a.kt)("inlineCode",{parentName:"p"},"head")," parts of HTML, which dictate metadata for the document itself such as what the website title/name is, cosmetic embed, defining the site's icon, etc. They are usually found in between the ",(0,a.kt)("inlineCode",{parentName:"p"},"")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"")," tags. Here's an example of a static HTML site serving one specific video:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-html"},'\n\n\n \n \n some embed site\n \n \n \n \n \n\n\n

Hi

\n

Just your friendly neighborhood video embed site

\n \n\n')),(0,a.kt)("br",null),"These interactive sites usually deploy a live script, like a Javascript framework. Examples are NodeJS, ExpressJS, Svelte, etc. These are used to parse video and thumbnails realtime so they can be embedded on Discord (or potentially other platforms).",(0,a.kt)("h3",{id:"discords-end"},"Discord's End"),(0,a.kt)("p",null,'Traditionally, Discord\'s media embedder will impose it\'s own video embed size limit (50 MiB) when a user sends a direct video link as usual. But in this case Discord will embed the thumbnail first, not the video. You could say the link "tricks" Discord by showing a "false face" first.'),(0,a.kt)("h2",{id:"strengths--limitations"},"Strengths & Limitations"),(0,a.kt)("p",null,"After a combination of countless hours of observation, rigorous testing throughout the period of a year, and conversations with the sites' creators, the current strengths & limitations of this exploit are enumerated below."),(0,a.kt)("h4",{id:"strengths"},"Strengths"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"You can embed non-web compatible codecs such as ",(0,a.kt)("a",{parentName:"li",href:"https://wiki.x266.mov/docs/video/HEVC"},"HEVC")," in ",(0,a.kt)("a",{parentName:"li",href:"https://wiki.x266.mov/docs/introduction/terminology#mp4--m4v"},"MP4/MOV"),", but the user must be using a compatible browser. ",(0,a.kt)("a",{parentName:"li",href:"https://thorium.rocks"},"Thorium")," or Safari version 13 or greater will work for HEVC playback."),(0,a.kt)("li",{parentName:"ul"},"There is no maximum size. You could embed a video the size of a raw Bluray, although I do not condone this unless you have the necessary legal permissions to do so or you're uploading a Creative Commons licensed movie like Big Buck Bunny while adhering to the restrictions of the applicable Creative Commons license. This also means you can send high bitrate gaming clips to your friends without any restrictions, assuming you already have a place to upload them.")),(0,a.kt)("h4",{id:"limitations"},"Limitations"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"You can only use ",(0,a.kt)("a",{parentName:"li",href:"https://simple.wikipedia.org/wiki/Hotlinking"},"hotlinks"),", which means direct linking to the video itself ending in the appropriate file extension such as ",(0,a.kt)("inlineCode",{parentName:"li"},".mp4"),". Cloud services like Google Drive or OneDrive will not work for storage."),(0,a.kt)("li",{parentName:"ul"},"You cannot use Discord's CDN (cdn.discordapp.com) as the video source. I assume this is because of Discord's proxy blocking embeds over 50 MiB, but ",(0,a.kt)("strong",{parentName:"li"},"only discord.nfp.is can do this"),", as it ",(0,a.kt)("strong",{parentName:"li"},"proxies cdn.discordapp.com")," itself."),(0,a.kt)("li",{parentName:"ul"},"You cannot embed videos in any resolutions higher than 3840 x 2160, Discord imposes a hard limit for this on all video after it was discovered that some videos could play normally but then be maliciously scaled to ridiculous resolutions during playback to crash Discord.")),(0,a.kt)("h2",{id:"differences-between-sites"},"Differences between Sites"),(0,a.kt)("p",null,"As mentioned before, there are five known sites at the time of writing. They all serve the same function, but one may interest you more than another due to slight differences in features & functionality."),(0,a.kt)("p",null,"Here are the sites, each with one noteworthy special benefit:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://stolen.shoes"},"https://stolen.shoes")," - Recognition, as it is the OG."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://discord.nfp.is"},"https://discord.nfp.is")," - You can use Discord CDN as video source."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://embeds.video"},"https://embeds.video")," - Immediately input video source into the URL (",(0,a.kt)("inlineCode",{parentName:"li"},"https://embeds.video/https://example.com/v/video.mp4"),")"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://x266.mov/discord-embed"},"https://x266.mov/discord-embed")," - Attractive domain, simple layout."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://autocompressor.net/av1"},"https://autocompressor.net/av1")," - Lots of info dump, pretty advanced features.")),(0,a.kt)("p",null,"That concludes the technical overview! Next, let's cover the history of this exploit."),(0,a.kt)("h2",{id:"the-lore"},"The Lore"),(0,a.kt)("h3",{id:"dwayne"},"Dwayne"),(0,a.kt)("p",null,"In around April of 2022, a Reddit user going by the name of u/CreativeGamer03 ",(0,a.kt)("a",{parentName:"p",href:"https://www.reddit.com/r/discordapp/comments/u96kky/someone_sent_this_in_the_memes_channel_and_bruh"},"posted a video on r/discordapp"),' of a link where a GIF of Dwayne "The Rock" Johnson plays caption with "Is this a GIF or is it a video?" When played, a low-quality music video of Rick Astley\'s "Never Gonna Give You Up" plays.'),(0,a.kt)("p",null,"The link used is now unfortunately ",(0,a.kt)("a",{parentName:"p",href:"https://archuser.de/the-rock"},"removed"),"."),(0,a.kt)("h3",{id:"discovery"},"Discovery"),(0,a.kt)("p",null,"On 23rd June 2022, a Discord user ",(0,a.kt)("em",{parentName:"p"},"Clybius")," on the AV1 Community server asked people for ",(0,a.kt)("a",{parentName:"p",href:"https://wiki.x266.mov/docs/video/VP9"},"VP9")," or ",(0,a.kt)("a",{parentName:"p",href:"https://wiki.x266.mov/docs/video/AVC"},"H.264")," videos that were over 100 MB in size. At the time the current 500 MB nitro tier did not exist. They then decided to use a 59 minute 1080p sample video of nature scenery from around the world with a thumbnail featuring a GIF of a waterfall to test the exploit. It worked."),(0,a.kt)("p",null,"He tried shortly afterward with ",(0,a.kt)("a",{parentName:"p",href:"https://wiki.x266.mov/docs/video/AV1"},"AV1"),". Eureka, it also worked:"),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"AV1",src:i(2194).Z,width:"497",height:"421"})),(0,a.kt)("p",null,"Clybius confirmed that this could be patched if discovered. He cites having had the idea from the Dwayne Johnson example above, but forgetting about it for a couple of months. So, it seems this entire concept stemmed from a silly rickroll."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"Dwayne",src:i(1828).Z,width:"1108",height:"98"})),(0,a.kt)("h3",{id:"the-experiments--interactive-site"},"The Experiments & Interactive Site"),(0,a.kt)("p",null,"After the discovery of AV1 embedding, experimentation brought about the discovery that ",(0,a.kt)("em",{parentName:"p"},"any")," video codec will work as long as the user can decode/play the codec and the container/extension is an MP4, MOV, or WebM. These are all traditionally web-compatible containers. If you're interested in learning about containers, please see the ",(0,a.kt)("a",{parentName:"p",href:"https://wiki.x266.mov/docs/introduction/terminology#container"},"Containers")," section on the ",(0,a.kt)("a",{parentName:"p",href:"https://wiki.x266.mov/docs/introduction/terminology"},"Terminology")," page."),(0,a.kt)("p",null,"This applies to HEVC, ProRes, ",(0,a.kt)("a",{parentName:"p",href:"https://wiki.x266.mov/docs/audio/AAC#xhe-aac"},"xHE-AAC"),", and other bizarre codecs that are rarely seen on the Web."),(0,a.kt)("p",null,"While experimentating, Clybius converted one their idle domains ",(0,a.kt)("inlineCode",{parentName:"p"},"stolen.shoes")," into an interactive embedder that provided a textbox for a video URL, a thumbnail URL, a width value, & a height value for the desired video. This would be the first website for Discord embedding."),(0,a.kt)("h3",{id:"virality"},"Virality"),(0,a.kt)("p",null,"It's not long before people outside of the AV1 Community discovered ",(0,a.kt)("inlineCode",{parentName:"p"},"stolen.shoes"),", and its popularity increased rapidly. Its use usually involved the illicit distribution of full-length, unauthorized copies of movies; this sometimes happened very shortly after some movies were released. There were a couple notable instances of this happenening that caused quite the stir online each time."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'The first instance featured the DreamWorks sequel of "Puss in Boots (2011)", "Puss in Boots: The Last Wish (2022)". A 1080p video sourced from a streaming site was the first wake up call that attracted attention to the existence of these embed sites. This example used ',(0,a.kt)("inlineCode",{parentName:"li"},"stolen.shoes"),".")),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"puss",src:i(8449).Z,width:"1088",height:"318"})),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'The second instance was when highly-anticipated animated film "The Super Mario Bros. Movie (2023)" produced by Illumination, Universal Studios, and Nintendo was spread around Discord. It was first spotted as a Cam (A camera recording by someone in theaters), then as it went out on streaming services a different link appeared but spread faster and with upgraded 1080p quality. Both used ',(0,a.kt)("inlineCode",{parentName:"li"},"stolen.shoes")," as the embed site.")),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"mario",src:i(3643).Z,width:"1307",height:"335"})),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'The third instance is very recent as of the day this was posted. A streaming-service sourced "Five Nights at Freddy\'s (2023)" was spread around since the movie released both in theaters and streaming service (Peacock) day one, and it gained steam extremely fast as most people had not seen it yet. Currently, this illegal novelty is gaining ',(0,a.kt)("a",{parentName:"li",href:"https://www.reddit.com/r/discordapp/comments/17hx45y/is_discordnfp_an_ip_grabber/"},"hundreds of upvotes within the r/discordapp subreddit"),". The copy seems to be a compressed 720p encode. This example used ",(0,a.kt)("inlineCode",{parentName:"li"},"discord.nfp.is"),".")),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"fnaf",src:i(314).Z,width:"1044",height:"409"})),(0,a.kt)("p",null,"Note the ones listed here are the ones that I saw become extremely popular. There may be lesser known links that have been spread around privately or just did not cause enough noise for me to notice. Some less popular examples I've noticed, featuring more illicit copyrighted content distribution: "),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Top Gun Maverick (2022)"),(0,a.kt)("li",{parentName:"ul"},"The SpongeBob trilogy (2005/2015/2020)"),(0,a.kt)("li",{parentName:"ul"},"Spider-Man: Across the Spider-Verse (2023)")),(0,a.kt)("h2",{id:"closing"},"Closing"),(0,a.kt)("p",null,"The ability to embed unusually large videos on Discord has enabled both positive and negative use cases. On the one hand, it allows high-quality content to be shared easily among friends. However, it has also facilitated mass copyright infringement by empowering virtually anyone with a Discord accound to freely spread pirated movies."),(0,a.kt)("p",null,"While this is fascinating from a technical perspective, embedding techniques like these tread a fine ethical line. As with anything, it is important to be mindful of how our actions affect others, and I should remind everyone that content creators deserve to be compensated for their work. As users, we should support them by accessing their content via legitimate platforms."),(0,a.kt)("p",null,"It is hard to say how long this exploit will continue to be usable. Instead of enabling piracy, which may cause Discord to be more likely to patch this exploit if they see it as a serious threat, let's instead use these capabilities responsibly to share our own creations, gaming highlights, and other media which we can share legally. Given some thoughtfulness, perhaps we can find a fair balance between respecting copyright law and appeasing Discord's sensibilities while allowing some creative flexibility on the platform."),(0,a.kt)("p",null,"Thank you for reading this blog post, I hope you learned something!"))}c.isMDXComponent=!0},2194:(e,t,i)=>{i.d(t,{Z:()=>o});const o=i.p+"assets/images/clybius-av1-28dcfefe8d58784301332b8119d2e926.webp"},1828:(e,t,i)=>{i.d(t,{Z:()=>o});const o=i.p+"assets/images/clybius-dwayne-15341f187cb8e7dbfd5c4ee00451eabd.webp"},3093:(e,t,i)=>{i.d(t,{Z:()=>o});const o=i.p+"assets/images/discord-embed-blog-image-2bcaf4f73f5fa33664328756753f3041.webp"},314:(e,t,i)=>{i.d(t,{Z:()=>o});const o=i.p+"assets/images/discordnfpis-fnaf-dab5b24a63605605e7c7882d20a992a3.webp"},3643:(e,t,i)=>{i.d(t,{Z:()=>o});const o=i.p+"assets/images/stolenshoes-mario-6de3b4071d4c09064d7323fec40530f4.webp"},8449:(e,t,i)=>{i.d(t,{Z:()=>o});const o=i.p+"assets/images/stolenshoes-puss-842a1f9165b7571d293a74be89da25c2.webp"}}]); \ No newline at end of file diff --git a/assets/js/9b6fb453.b34e50bc.js b/assets/js/9b6fb453.b34e50bc.js deleted file mode 100644 index 88d7c1cc0..000000000 --- a/assets/js/9b6fb453.b34e50bc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[130],{4469:e=>{e.exports=JSON.parse('{"name":"docusaurus-plugin-content-blog","id":"default"}')}}]); \ No newline at end of file diff --git a/assets/js/b4470a6f.32de82f1.js b/assets/js/b4470a6f.85539aa9.js similarity index 95% rename from assets/js/b4470a6f.32de82f1.js rename to assets/js/b4470a6f.85539aa9.js index edb56ce90..858104fdb 100644 --- a/assets/js/b4470a6f.32de82f1.js +++ b/assets/js/b4470a6f.85539aa9.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[9596],{3905:(e,t,i)=>{i.d(t,{Zo:()=>m,kt:()=>u});var a=i(7294);function o(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}function n(e,t){var i=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),i.push.apply(i,a)}return i}function s(e){for(var t=1;t=0||(o[i]=e[i]);return o}(e,t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,i)&&(o[i]=e[i])}return o}var l=a.createContext({}),p=function(e){var t=a.useContext(l),i=t;return e&&(i="function"==typeof e?e(t):s(s({},t),e)),i},m=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},c="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},g=a.forwardRef((function(e,t){var i=e.components,o=e.mdxType,n=e.originalType,l=e.parentName,m=r(e,["components","mdxType","originalType","parentName"]),c=p(i),g=o,u=c["".concat(l,".").concat(g)]||c[g]||h[g]||n;return i?a.createElement(u,s(s({ref:t},m),{},{components:i})):a.createElement(u,s({ref:t},m))}));function u(e,t){var i=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var n=i.length,s=new Array(n);s[0]=g;var r={};for(var l in t)hasOwnProperty.call(t,l)&&(r[l]=t[l]);r.originalType=e,r[c]="string"==typeof e?e:o,s[1]=r;for(var p=2;p{i.r(t),i.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>h,frontMatter:()=>n,metadata:()=>r,toc:()=>p});var a=i(7462),o=(i(7294),i(3905));const n={title:"Site Optimization by Reducing Image Load on the Web",description:"A big part of understanding any multimedia codec technology is knowing the application for such technology. For images, a big use case is web delivery.",slug:"site-optimization",authors:[{name:"RootAtKali",title:"Autocompressor Founder / CEO",image_url:"https://cdn.discordapp.com/avatars/456553041902960660/e57850912e0cd8dd62cb20439e0b36ea.jpg"},{name:"Gianni Rosato",title:"Maintainer",url:"https://github.com/gianni-rosato",image_url:"https://avatars.githubusercontent.com/u/35711760?v=4"}],tags:["image","web","compression"],image:"/img/_DSC8466-smaller.jpg",hide_table_of_contents:!1},s=void 0,r={permalink:"/blog/site-optimization",source:"@site/blog/2023-07-21-site-optimization.md",title:"Site Optimization by Reducing Image Load on the Web",description:"A big part of understanding any multimedia codec technology is knowing the application for such technology. For images, a big use case is web delivery.",date:"2023-07-21T00:00:00.000Z",formattedDate:"July 21, 2023",tags:[{label:"image",permalink:"/blog/tags/image"},{label:"web",permalink:"/blog/tags/web"},{label:"compression",permalink:"/blog/tags/compression"}],readingTime:9.255,hasTruncateMarker:!0,authors:[{name:"RootAtKali",title:"Autocompressor Founder / CEO",image_url:"https://cdn.discordapp.com/avatars/456553041902960660/e57850912e0cd8dd62cb20439e0b36ea.jpg",imageURL:"https://cdn.discordapp.com/avatars/456553041902960660/e57850912e0cd8dd62cb20439e0b36ea.jpg"},{name:"Gianni Rosato",title:"Maintainer",url:"https://github.com/gianni-rosato",image_url:"https://avatars.githubusercontent.com/u/35711760?v=4",imageURL:"https://avatars.githubusercontent.com/u/35711760?v=4"}],frontMatter:{title:"Site Optimization by Reducing Image Load on the Web",description:"A big part of understanding any multimedia codec technology is knowing the application for such technology. For images, a big use case is web delivery.",slug:"site-optimization",authors:[{name:"RootAtKali",title:"Autocompressor Founder / CEO",image_url:"https://cdn.discordapp.com/avatars/456553041902960660/e57850912e0cd8dd62cb20439e0b36ea.jpg",imageURL:"https://cdn.discordapp.com/avatars/456553041902960660/e57850912e0cd8dd62cb20439e0b36ea.jpg"},{name:"Gianni Rosato",title:"Maintainer",url:"https://github.com/gianni-rosato",image_url:"https://avatars.githubusercontent.com/u/35711760?v=4",imageURL:"https://avatars.githubusercontent.com/u/35711760?v=4"}],tags:["image","web","compression"],image:"/img/_DSC8466-smaller.jpg",hide_table_of_contents:!1},prevItem:{title:"AV1 Encoding for Dummies",permalink:"/blog/av1-encoding-for-dummies"}},l={authorsImageUrls:[void 0,void 0]},p=[{value:"Fire & Forget",id:"fire--forget",level:2},{value:"Massive Improvement",id:"massive-improvement",level:2},{value:"Lazy Loading",id:"lazy-loading",level:3},{value:"New Codecs",id:"new-codecs",level:2},{value:"Fallbacks",id:"fallbacks",level:3},{value:"Compression Efficacy",id:"compression-efficacy",level:3},{value:"Responsive Images",id:"responsive-images",level:2}],m={toc:p},c="wrapper";function h(e){let{components:t,...n}=e;return(0,o.kt)(c,(0,a.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"A big part of understanding any multimedia codec technology is knowing the application for such technology."),(0,o.kt)("p",null,"For images, a big use case is web delivery. Compared to other multimedia, images are incredibly popular on the Web & knowing how to serve them properly can be a massive boon to your website's traffic as well as less of a headache for users on slower connections or who are under bandwidth constraints. The most disappointing part is that images are often poorly done on the web; all too frequently will you run into a site serving massive photographic PNGs for no reason, or photography sites serving photographs fresh out of the editing software with no thought put into their final delivery. A little effort, patience, & knowledge will go a long way toward improving the user experience for individuals using your site, & this article will illustrate some of the basics."),(0,o.kt)("admonition",{type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"These instructions are for ",(0,o.kt)("em",{parentName:"p"},"photographic")," images; other kinds of images, like non-photographic, artwork, pixel art, etc. should likely be handled differently.")),(0,o.kt)("admonition",{type:"warning"},(0,o.kt)("p",{parentName:"admonition"},"Many images won't load properly unless your browser supports JXL, AVIF, & proper ICCv2 color management. This is for demonstration purposes only & shouldn't represent an actual common website experience. If you're curious anyway, the following browsers can display the contents of this page perfectly:"),(0,o.kt)("ul",{parentName:"admonition"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://thorium.rocks/"},"Thorium")," | ",(0,o.kt)("em",{parentName:"li"},"Linux, ",(0,o.kt)("a",{parentName:"em",href:"https://github.com/Alex313031/Thorium-Special/releases"},"macOS"),", ",(0,o.kt)("a",{parentName:"em",href:"https://github.com/Alex313031/thorium/releases/"},"Windows"),", ",(0,o.kt)("a",{parentName:"em",href:"https://github.com/Alex313031/Thorium-Special/releases"},"Android"))),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://www.waterfox.net/"},"Waterfox")," | ",(0,o.kt)("em",{parentName:"li"},(0,o.kt)("a",{parentName:"em",href:"https://flathub.org/apps/net.waterfox.waterfox"},"Linux"),", ",(0,o.kt)("a",{parentName:"em",href:"https://www.waterfox.net/download/"},"macOS"),", ",(0,o.kt)("a",{parentName:"em",href:"https://www.waterfox.net/download/"},"Windows"))),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://thorium.rocks/mercury"},"Mercury")," | ",(0,o.kt)("em",{parentName:"li"},(0,o.kt)("a",{parentName:"em",href:"https://github.com/Alex313031/Mercury/releases"},"Linux"),", ",(0,o.kt)("a",{parentName:"em",href:"https://github.com/Alex313031/Mercury/releases"},"Windows"))))),(0,o.kt)("h2",{id:"fire--forget"},"Fire & Forget"),(0,o.kt)("p",null,"First, we'll illustrate what ",(0,o.kt)("em",{parentName:"p"},"not")," to do, which is fortunately not incredibly difficult to avoid. Taking an image straight out of your editing software at a massive size will often bloat the size & resolution to something that isn't generally usable for a website regardless of the codec you're using & its quality per bit. It can be argued there are specific use cases that demand incredible resolution & fidelity coexist on the Web, but we won't be covering those here. Here's an example of a bloated image:"),(0,o.kt)("p",null,(0,o.kt)("em",{parentName:"p"},"exported straight from Darktable at JPEG q90, with no scaling")),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"bloated_jpeg",src:i(3372).Z,width:"5470",height:"3656"})),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"2.2 MB")),(0,o.kt)("h2",{id:"massive-improvement"},"Massive Improvement"),(0,o.kt)("p",null,"The easiest way to have a large improvement without doing much work is to simply resize the image before serving it. Even if you exported a lossy JPEG, resizing should remove a lot of artifacts. The way to perceive a worst-case for an image's size on a site is to inspect the image element's width & height, which should give us an estimate of how large we should make our image. Any larger than this value is unreasonable since we're overfilling the element's size for no reason & the image is being scaled down anyway."),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"box-size-mac",src:i(6819).Z}),"\n",(0,o.kt)("em",{parentName:"p"},"Inspect Element in Firefox. The Mac used to take this screenshot has a relatively high display resolution of 2560x1664. Because Macs scale things differently, we're probably going to want to double the horizontal resolution here.")),(0,o.kt)("p",null,"The width is the most important value here, so our new image is going to be exported with a width of 1699 pixels. This new image, encoded at JPEG q90 with ",(0,o.kt)("inlineCode",{parentName:"p"},"cjpegli"),", looks like this:"),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"smaller_jpeg",src:i(4642).Z,width:"1699",height:"1136"})),(0,o.kt)("p",null,"Obviously, there's lost fidelity compared to the original, but considering this is ",(0,o.kt)("em",{parentName:"p"},"so much smaller"),", it is worth the trade-off for many. It is also worth noting we are using an improved jpeg encoder in the form of ",(0,o.kt)("inlineCode",{parentName:"p"},"cjpegli"),", although that is secondary to the resize. If it doesn't look as good as you want it to, you can always scale the resolution up a bit, though currently, it looks plenty passable for its size."),(0,o.kt)("p",null,"2.2 MB -> ",(0,o.kt)("strong",{parentName:"p"},"233 kB")),(0,o.kt)("h3",{id:"lazy-loading"},"Lazy Loading"),(0,o.kt)("p",null,"A bonus tip is to add the ",(0,o.kt)("inlineCode",{parentName:"p"},'loading="lazy"')," attribute to your picture tag to allow the image to load only when scrolled to by a user. This doesn't save bandwidth, but it improves the user experience by loading images further down the page only when necessary. An example may look like this:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-html"},'\n alt text\n \n')),(0,o.kt)("h2",{id:"new-codecs"},"New Codecs"),(0,o.kt)("p",null,"If you desire further improvement, it may be time to consider using a newer codec like ",(0,o.kt)("a",{parentName:"p",href:"/docs/images/AVIF"},"AVIF")," or ",(0,o.kt)("a",{parentName:"p",href:"/docs/images/JXL"},"JPEG-XL"),". These options will compress far more effectively than JPEG, with the only trade-off being browser support. We're not going to consider ",(0,o.kt)("a",{parentName:"p",href:"/docs/images/WebP"},"WebP")," or ",(0,o.kt)("a",{parentName:"p",href:"/docs/images/HEIC"},"HEIC"),", since WebP is not competitive enough with JPEG for photographic imagery (often being worse) & HEIC has been superseded by AVIF - which sees greater support anyhow - & is not royalty free, effectively preventing widespread Web adoption forever. Again, we're just considering ",(0,o.kt)("em",{parentName:"p"},"lossy")," compression for ",(0,o.kt)("em",{parentName:"p"},"photographic")," images; it is a different story with WebP elsewhere, as it performs well on non-photographic content & is almost always better than PNG for 8-bit lossless compression. So, we are left with JXL & AVIF for now."),(0,o.kt)("h3",{id:"fallbacks"},"Fallbacks"),(0,o.kt)("p",null,"AVIF sees widespread support, but JPEG-XL isn't quite there yet with Web support as Google continues to push AVIF (it is debatable if it ever will be outside the Apple ecosystem). Even with AVIF, adoption isn't remotely close to JPEG, so it is worth providing a fallback. This can look like the following example:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-html"},'\n \n \n \n alt text\n \n')),(0,o.kt)("p",null,"Here is a JXL falling back to an AVIF falling back to a WebP falling back to a JPEG. Pretty intense to have this many fallbacks unless you're really after the ultimate compression ratio, but it is certainly an option. AVIF & JPEG alone will probably be enough for most."),(0,o.kt)("h3",{id:"compression-efficacy"},"Compression Efficacy"),(0,o.kt)("p",null,"Let's look at how our image examples compare to the original with our new codec selection. We'll be aiming for high visual fidelity, so around the same quality as our initial JPEG encoded with ",(0,o.kt)("inlineCode",{parentName:"p"},"cjpegli")," (which scores ~",(0,o.kt)("inlineCode",{parentName:"p"},"83.01")," with the ",(0,o.kt)("a",{parentName:"p",href:"/docs/metrics/SSIMULACRA2"},"SSIMULACRA2")," visual fidelity metric)."),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"smaller_jxl",src:i(3086).Z})),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"137.0 kB")," ",(0,o.kt)("em",{parentName:"p"},"JPEG-XL image, encoded with ",(0,o.kt)("inlineCode",{parentName:"em"},"cjxl lossless.png out.jxl -d 1.49 -e 9"),". Score: ~",(0,o.kt)("inlineCode",{parentName:"em"},"83.04"))," ",(0,o.kt)("em",{parentName:"p"},"3.06s user time")),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"smaller_avif",src:i(6309).Z})),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"124.8 kB")," ",(0,o.kt)("em",{parentName:"p"},"AVIF image, encoded with ",(0,o.kt)("inlineCode",{parentName:"em"},"avifenc -c aom -s 4 -j 8 -d 10 -y 444 --min 1 --max 63 -a end-usage=q -a cq-level=16 -a tune=ssim lossless.png out.avif"),". Score: ~",(0,o.kt)("inlineCode",{parentName:"em"},"83.03"))," ",(0,o.kt)("em",{parentName:"p"},"7.54s user time")),(0,o.kt)("p",null,"JXL also supports lossless transcoding of JPEG images. This means every pixel is identical, the image just has a smaller filesize than the original JPEG; if you can use JXL, you can transcode existing JPEGs losslessly on your site & save some bandwidth that way. The JPEG transcode below gives a higher SSIMULACRA2 score than the original for some reason, but I'll chalk that up to a decoding inconsistency between how the ",(0,o.kt)("inlineCode",{parentName:"p"},"ssimulacra2")," program decodes JPEG & JXL. Either way, the scores are fairly close."),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"smaller_jxl_jpeg-recomp",src:i(8545).Z})),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"189.4 kB")," ",(0,o.kt)("em",{parentName:"p"},"JPEG-XL image from JPEG, encoded with ",(0,o.kt)("inlineCode",{parentName:"em"},"cjxl input.jpg input-recomp.jxl -d 0.0 -e 9 --brotli_effort=11"),". Score: ~",(0,o.kt)("inlineCode",{parentName:"em"},"84.92")," (???)")," ",(0,o.kt)("em",{parentName:"p"},"0.67s user time")),(0,o.kt)("p",null,"The final trick we can use, while not a new codec at all, still increases quality per bit. Encoding an XYB JPEG with ",(0,o.kt)("inlineCode",{parentName:"p"},"cjpegli")," encodes with the perceptual XYB colorspace using an ICC profile to modify the original JPEG colors, avoiding JPEG's normal YCbCr which isn't perceptually optimized for the human visual system. Using XYB, we can afford identical quality with less bitrate than normal JPEG. This has universal compatibility, but not every application understands how to handle the XYB color profile (although color-managed modern browsers should be fine)."),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"smaller_jpeg_xyb",src:i(2282).Z,width:"1699",height:"1136"})),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"208.3 kB")," ",(0,o.kt)("em",{parentName:"p"},"XYB JPEG, encoded with ",(0,o.kt)("inlineCode",{parentName:"em"},"cjpegli lossless.png out.jpg --xyb -d 1.155"),". Score: ~",(0,o.kt)("inlineCode",{parentName:"em"},"83.04"))," ",(0,o.kt)("em",{parentName:"p"},"0.10s user time")),(0,o.kt)("p",null,"In this particular instance, AVIF seems to be the overall winner. This isn't always the case due to JXL's superiority at higher fidelity & with more detailed images, but according to SSIMULACRA2, AVIF has the best quality per bit with this image. You can use your own eyes to further clarify your choice, though. It is worth mentioning that as these were encoded from a 16-bit source PNG, the JXL image is the only one that maintains the full original bit depth, & AVIF isn't fast to encode."),(0,o.kt)("h2",{id:"responsive-images"},"Responsive Images"),(0,o.kt)("p",null,"Displaying an image that is too large for a viewport is a waste of bandwidth, & displaying an image that's too small for the viewport leaves fidelity to be desired. Luckily, we have the ",(0,o.kt)("a",{parentName:"p",href:"https://ausi.github.io/respimagelint/"},"Responsive Image Linter")," that can help us figure out which image sizes we should be using."),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"responsive_image_linter",src:i(6294).Z})),(0,o.kt)("p",null,"In our fire & forget example, we see that we are serving an image that is far too large. We already know that, but now we can see that given various viewport sizes we could be serving images that have respective widths of 270px, 958px, 1350px, 1660px, & 1916px to optimize for delivery to a variety of different devices. Here's how we'd write that in HTML:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-html"},'\n\u2003\u2003\n\u2003\u2003\n\u2003\u2003alt text\n\n')),(0,o.kt)("p",null,"It is worth noting that this example above & the example below aren't perfect implementations of a responsive image given the conditions of this site, but the general concept still applies. Some things to note:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"srcset")," = the images available to your browser to serve, & their respective widths"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"sizes")," = the conditions given to the browser explaining under what conditions should it serve which image"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"(min-width: XXXpx) YYYpx")," = Given the viewport is at least XXX wide, serve an image of YYY horizontal resolution. The browser will pick an image from srcset that is CSS pixels ","*"," display scaling."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"calc(100vw - 24px)")," = Usually preceded by a (min-width) condition. Specifies a value the browser should calculate on its own to pick the closest option from the srcset. Let's say we have ",(0,o.kt)("inlineCode",{parentName:"li"},"(min-width: 997px) calc(75vw - 257px)"),". This means given the viewport is at least 997px wide, calculate 0.75 ","*"," the current viewport resolution - 257 to find the closest image in the srcset to fit the number of pixel specified.")),(0,o.kt)("picture",null,"\u2003\u2003",(0,o.kt)("source",{type:"image/jxl",srcset:"https://raw.githubusercontent.com/av1-community-contributors/codec-wiki/deployment/img/img_size/img_270.jxl 270w, https://raw.githubusercontent.com/av1-community-contributors/codec-wiki/deployment/img/img_size/img_958.jxl 958w, https://raw.githubusercontent.com/av1-community-contributors/codec-wiki/deployment/img/img_size/img_1350.jxl 1350w, https://raw.githubusercontent.com/av1-community-contributors/codec-wiki/deployment/img/img_size/img_1660.jxl 1660w, https://raw.githubusercontent.com/av1-community-contributors/codec-wiki/deployment/img/img_size/img_1916.jxl 1916w",sizes:"(min-width: 2000px) 1916px, (min-width: 1700px) 1660px, (min-width: 1400px) 1350px, (min-width: 1000px) 958px, calc(100vw - 24px)"}),"\u2003\u2003",(0,o.kt)("source",{type:"image/avif",srcset:"https://raw.githubusercontent.com/av1-community-contributors/codec-wiki/deployment/img/img_size/img_270.avif 270w, https://raw.githubusercontent.com/av1-community-contributors/codec-wiki/deployment/img/img_size/img_958.avif 958w, https://raw.githubusercontent.com/av1-community-contributors/codec-wiki/deployment/img/img_size/img_1350.avif 1350w, https://raw.githubusercontent.com/av1-community-contributors/codec-wiki/deployment/img/img_size/img_1660.avif 1660w, https://raw.githubusercontent.com/av1-community-contributors/codec-wiki/deployment/img/img_size/img_1916.avif 1916w",sizes:"(min-width: 2000px) 1916px, (min-width: 1700px) 1660px, (min-width: 1400px) 1350px, (min-width: 1000px) 958px, calc(100vw - 24px)"}),"\u2003\u2003",(0,o.kt)("img",{loading:"lazy",width:"1699",height:"1136",alt:"alt text",srcset:"https://raw.githubusercontent.com/av1-community-contributors/codec-wiki/deployment/img/img_size/img_270.jpg 270w, https://raw.githubusercontent.com/av1-community-contributors/codec-wiki/deployment/img/img_size/img_958.jpg 958w, https://raw.githubusercontent.com/av1-community-contributors/codec-wiki/deployment/img/img_size/img_1350.jpg 1350w, https://raw.githubusercontent.com/av1-community-contributors/codec-wiki/deployment/img/img_size/img_1660.jpg 1660w, https://raw.githubusercontent.com/av1-community-contributors/codec-wiki/deployment/img/img_size/img_1916.jpg 1916w",sizes:"(min-width: 2000px) 1916px, (min-width: 1700px) 1660px, (min-width: 1400px) 1350px, (min-width: 1000px) 958px, calc(100vw - 24px)",src:"https://raw.githubusercontent.com/av1-community-contributors/codec-wiki/deployment/img/_DSC8466-smaller.jpg"})),(0,o.kt)("p",null,"That's all! Massive thanks to Auto-Rez Media Technologies for the inspiration behind this article & explicit permission to use their ",(0,o.kt)("a",{parentName:"p",href:"https://autocompressor.net/blog/reduce-image-load"},"Reduce Your Page's Image Load")," blog post when writing this entry. I have ",(0,o.kt)("a",{parentName:"p",href:"https://autumn.revolt.chat/attachments/GtFGuwNfeRdcwUN0MWzhDCAiiadWOk88XXC3pQv6RI"},"confirmed")," with their leadership that this wiki entry can be safely licensed under CC BY-SA 4.0."))}h.isMDXComponent=!0},8545:(e,t,i)=>{i.d(t,{Z:()=>a});const a=i.p+"assets/images/_DSC8466-smaller-recomp-f3af6d54a8c1c62cda0c2d3ba048e1fc.jxl"},2282:(e,t,i)=>{i.d(t,{Z:()=>a});const a=i.p+"assets/images/_DSC8466-smaller-xyb-0372077e225cf7b460ec9238bb2a65f9.jpg"},6309:(e,t,i)=>{i.d(t,{Z:()=>a});const a=i.p+"assets/images/_DSC8466-smaller-452ed8f5a33da727be398450e7e580a3.avif"},4642:(e,t,i)=>{i.d(t,{Z:()=>a});const a=i.p+"assets/images/_DSC8466-smaller-48eaf650a417558ea976bf40eee82f67.jpg"},3086:(e,t,i)=>{i.d(t,{Z:()=>a});const a=i.p+"assets/images/_DSC8466-smaller-492a0639fb771671738062a57b2015a2.jxl"},3372:(e,t,i)=>{i.d(t,{Z:()=>a});const a=i.p+"assets/images/_DSC8466-d51a7e87bed86d101412ba728ebc6be2.jpg"},6819:(e,t,i)=>{i.d(t,{Z:()=>a});const a=i.p+"assets/images/box-size-mac-f49e702b0cb4a531f65283ad604d4b4c.avif"},6294:(e,t,i)=>{i.d(t,{Z:()=>a});const a=i.p+"assets/images/responsive_image_linter-178eb56c12557c53a2b129dd75925fe9.avif"}}]); \ No newline at end of file +"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[9596],{3905:(e,t,i)=>{i.d(t,{Zo:()=>m,kt:()=>u});var a=i(7294);function o(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}function n(e,t){var i=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),i.push.apply(i,a)}return i}function s(e){for(var t=1;t=0||(o[i]=e[i]);return o}(e,t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,i)&&(o[i]=e[i])}return o}var l=a.createContext({}),p=function(e){var t=a.useContext(l),i=t;return e&&(i="function"==typeof e?e(t):s(s({},t),e)),i},m=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},c="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},g=a.forwardRef((function(e,t){var i=e.components,o=e.mdxType,n=e.originalType,l=e.parentName,m=r(e,["components","mdxType","originalType","parentName"]),c=p(i),g=o,u=c["".concat(l,".").concat(g)]||c[g]||h[g]||n;return i?a.createElement(u,s(s({ref:t},m),{},{components:i})):a.createElement(u,s({ref:t},m))}));function u(e,t){var i=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var n=i.length,s=new Array(n);s[0]=g;var r={};for(var l in t)hasOwnProperty.call(t,l)&&(r[l]=t[l]);r.originalType=e,r[c]="string"==typeof e?e:o,s[1]=r;for(var p=2;p{i.r(t),i.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>h,frontMatter:()=>n,metadata:()=>r,toc:()=>p});var a=i(7462),o=(i(7294),i(3905));const n={title:"Site Optimization by Reducing Image Load on the Web",description:"A big part of understanding any multimedia codec technology is knowing the application for such technology. For images, a big use case is web delivery.",slug:"site-optimization",authors:[{name:"RootAtKali",title:"Autocompressor Founder / CEO",image_url:"https://cdn.discordapp.com/avatars/456553041902960660/e57850912e0cd8dd62cb20439e0b36ea.jpg"},{name:"Gianni Rosato",title:"Maintainer",url:"https://github.com/gianni-rosato",image_url:"https://avatars.githubusercontent.com/u/35711760?v=4"}],tags:["image","web","compression"],image:"/img/_DSC8466-smaller.jpg",hide_table_of_contents:!1},s=void 0,r={permalink:"/blog/site-optimization",source:"@site/blog/2023-07-21-site-optimization.md",title:"Site Optimization by Reducing Image Load on the Web",description:"A big part of understanding any multimedia codec technology is knowing the application for such technology. For images, a big use case is web delivery.",date:"2023-07-21T00:00:00.000Z",formattedDate:"July 21, 2023",tags:[{label:"image",permalink:"/blog/tags/image"},{label:"web",permalink:"/blog/tags/web"},{label:"compression",permalink:"/blog/tags/compression"}],readingTime:9.255,hasTruncateMarker:!0,authors:[{name:"RootAtKali",title:"Autocompressor Founder / CEO",image_url:"https://cdn.discordapp.com/avatars/456553041902960660/e57850912e0cd8dd62cb20439e0b36ea.jpg",imageURL:"https://cdn.discordapp.com/avatars/456553041902960660/e57850912e0cd8dd62cb20439e0b36ea.jpg"},{name:"Gianni Rosato",title:"Maintainer",url:"https://github.com/gianni-rosato",image_url:"https://avatars.githubusercontent.com/u/35711760?v=4",imageURL:"https://avatars.githubusercontent.com/u/35711760?v=4"}],frontMatter:{title:"Site Optimization by Reducing Image Load on the Web",description:"A big part of understanding any multimedia codec technology is knowing the application for such technology. For images, a big use case is web delivery.",slug:"site-optimization",authors:[{name:"RootAtKali",title:"Autocompressor Founder / CEO",image_url:"https://cdn.discordapp.com/avatars/456553041902960660/e57850912e0cd8dd62cb20439e0b36ea.jpg",imageURL:"https://cdn.discordapp.com/avatars/456553041902960660/e57850912e0cd8dd62cb20439e0b36ea.jpg"},{name:"Gianni Rosato",title:"Maintainer",url:"https://github.com/gianni-rosato",image_url:"https://avatars.githubusercontent.com/u/35711760?v=4",imageURL:"https://avatars.githubusercontent.com/u/35711760?v=4"}],tags:["image","web","compression"],image:"/img/_DSC8466-smaller.jpg",hide_table_of_contents:!1},prevItem:{title:"AV1 Encoding for Dummies",permalink:"/blog/av1-encoding-for-dummies"}},l={authorsImageUrls:[void 0,void 0]},p=[{value:"Fire & Forget",id:"fire--forget",level:2},{value:"Massive Improvement",id:"massive-improvement",level:2},{value:"Lazy Loading",id:"lazy-loading",level:3},{value:"New Codecs",id:"new-codecs",level:2},{value:"Fallbacks",id:"fallbacks",level:3},{value:"Compression Efficacy",id:"compression-efficacy",level:3},{value:"Responsive Images",id:"responsive-images",level:2}],m={toc:p},c="wrapper";function h(e){let{components:t,...n}=e;return(0,o.kt)(c,(0,a.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"A big part of understanding any multimedia codec technology is knowing the application for such technology."),(0,o.kt)("p",null,"For images, a big use case is web delivery. Compared to other multimedia, images are incredibly popular on the Web & knowing how to serve them properly can be a massive boon to your website's traffic as well as less of a headache for users on slower connections or who are under bandwidth constraints. The most disappointing part is that images are often poorly done on the web; all too frequently will you run into a site serving massive photographic PNGs for no reason, or photography sites serving photographs fresh out of the editing software with no thought put into their final delivery. A little effort, patience, & knowledge will go a long way toward improving the user experience for individuals using your site, & this article will illustrate some of the basics."),(0,o.kt)("admonition",{type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"These instructions are for ",(0,o.kt)("em",{parentName:"p"},"photographic")," images; other kinds of images, like non-photographic, artwork, pixel art, etc. should likely be handled differently.")),(0,o.kt)("admonition",{type:"warning"},(0,o.kt)("p",{parentName:"admonition"},"Many images won't load properly unless your browser supports JXL, AVIF, & proper ICCv2 color management. This is for demonstration purposes only & shouldn't represent an actual common website experience. If you're curious anyway, the following browsers can display the contents of this page perfectly:"),(0,o.kt)("ul",{parentName:"admonition"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://thorium.rocks/"},"Thorium")," | ",(0,o.kt)("em",{parentName:"li"},"Linux, ",(0,o.kt)("a",{parentName:"em",href:"https://github.com/Alex313031/Thorium-Special/releases"},"macOS"),", ",(0,o.kt)("a",{parentName:"em",href:"https://github.com/Alex313031/thorium/releases/"},"Windows"),", ",(0,o.kt)("a",{parentName:"em",href:"https://github.com/Alex313031/Thorium-Special/releases"},"Android"))),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://www.waterfox.net/"},"Waterfox")," | ",(0,o.kt)("em",{parentName:"li"},(0,o.kt)("a",{parentName:"em",href:"https://flathub.org/apps/net.waterfox.waterfox"},"Linux"),", ",(0,o.kt)("a",{parentName:"em",href:"https://www.waterfox.net/download/"},"macOS"),", ",(0,o.kt)("a",{parentName:"em",href:"https://www.waterfox.net/download/"},"Windows"))),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://thorium.rocks/mercury"},"Mercury")," | ",(0,o.kt)("em",{parentName:"li"},(0,o.kt)("a",{parentName:"em",href:"https://github.com/Alex313031/Mercury/releases"},"Linux"),", ",(0,o.kt)("a",{parentName:"em",href:"https://github.com/Alex313031/Mercury/releases"},"Windows"))))),(0,o.kt)("h2",{id:"fire--forget"},"Fire & Forget"),(0,o.kt)("p",null,"First, we'll illustrate what ",(0,o.kt)("em",{parentName:"p"},"not")," to do, which is fortunately not incredibly difficult to avoid. Taking an image straight out of your editing software at a massive size will often bloat the size & resolution to something that isn't generally usable for a website regardless of the codec you're using & its quality per bit. It can be argued there are specific use cases that demand incredible resolution & fidelity coexist on the Web, but we won't be covering those here. Here's an example of a bloated image:"),(0,o.kt)("p",null,(0,o.kt)("em",{parentName:"p"},"exported straight from Darktable at JPEG q90, with no scaling")),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"bloated_jpeg",src:i(6039).Z,width:"5470",height:"3656"})),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"2.2 MB")),(0,o.kt)("h2",{id:"massive-improvement"},"Massive Improvement"),(0,o.kt)("p",null,"The easiest way to have a large improvement without doing much work is to simply resize the image before serving it. Even if you exported a lossy JPEG, resizing should remove a lot of artifacts. The way to perceive a worst-case for an image's size on a site is to inspect the image element's width & height, which should give us an estimate of how large we should make our image. Any larger than this value is unreasonable since we're overfilling the element's size for no reason & the image is being scaled down anyway."),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"box-size-mac",src:i(6440).Z}),"\n",(0,o.kt)("em",{parentName:"p"},"Inspect Element in Firefox. The Mac used to take this screenshot has a relatively high display resolution of 2560x1664. Because Macs scale things differently, we're probably going to want to double the horizontal resolution here.")),(0,o.kt)("p",null,"The width is the most important value here, so our new image is going to be exported with a width of 1699 pixels. This new image, encoded at JPEG q90 with ",(0,o.kt)("inlineCode",{parentName:"p"},"cjpegli"),", looks like this:"),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"smaller_jpeg",src:i(2918).Z,width:"1699",height:"1136"})),(0,o.kt)("p",null,"Obviously, there's lost fidelity compared to the original, but considering this is ",(0,o.kt)("em",{parentName:"p"},"so much smaller"),", it is worth the trade-off for many. It is also worth noting we are using an improved jpeg encoder in the form of ",(0,o.kt)("inlineCode",{parentName:"p"},"cjpegli"),", although that is secondary to the resize. If it doesn't look as good as you want it to, you can always scale the resolution up a bit, though currently, it looks plenty passable for its size."),(0,o.kt)("p",null,"2.2 MB -> ",(0,o.kt)("strong",{parentName:"p"},"233 kB")),(0,o.kt)("h3",{id:"lazy-loading"},"Lazy Loading"),(0,o.kt)("p",null,"A bonus tip is to add the ",(0,o.kt)("inlineCode",{parentName:"p"},'loading="lazy"')," attribute to your picture tag to allow the image to load only when scrolled to by a user. This doesn't save bandwidth, but it improves the user experience by loading images further down the page only when necessary. An example may look like this:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-html"},'\n alt text\n \n')),(0,o.kt)("h2",{id:"new-codecs"},"New Codecs"),(0,o.kt)("p",null,"If you desire further improvement, it may be time to consider using a newer codec like ",(0,o.kt)("a",{parentName:"p",href:"/docs/images/AVIF"},"AVIF")," or ",(0,o.kt)("a",{parentName:"p",href:"/docs/images/JXL"},"JPEG-XL"),". These options will compress far more effectively than JPEG, with the only trade-off being browser support. We're not going to consider ",(0,o.kt)("a",{parentName:"p",href:"/docs/images/WebP"},"WebP")," or ",(0,o.kt)("a",{parentName:"p",href:"/docs/images/HEIC"},"HEIC"),", since WebP is not competitive enough with JPEG for photographic imagery (often being worse) & HEIC has been superseded by AVIF - which sees greater support anyhow - & is not royalty free, effectively preventing widespread Web adoption forever. Again, we're just considering ",(0,o.kt)("em",{parentName:"p"},"lossy")," compression for ",(0,o.kt)("em",{parentName:"p"},"photographic")," images; it is a different story with WebP elsewhere, as it performs well on non-photographic content & is almost always better than PNG for 8-bit lossless compression. So, we are left with JXL & AVIF for now."),(0,o.kt)("h3",{id:"fallbacks"},"Fallbacks"),(0,o.kt)("p",null,"AVIF sees widespread support, but JPEG-XL isn't quite there yet with Web support as Google continues to push AVIF (it is debatable if it ever will be outside the Apple ecosystem). Even with AVIF, adoption isn't remotely close to JPEG, so it is worth providing a fallback. This can look like the following example:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-html"},'\n \n \n \n alt text\n \n')),(0,o.kt)("p",null,"Here is a JXL falling back to an AVIF falling back to a WebP falling back to a JPEG. Pretty intense to have this many fallbacks unless you're really after the ultimate compression ratio, but it is certainly an option. AVIF & JPEG alone will probably be enough for most."),(0,o.kt)("h3",{id:"compression-efficacy"},"Compression Efficacy"),(0,o.kt)("p",null,"Let's look at how our image examples compare to the original with our new codec selection. We'll be aiming for high visual fidelity, so around the same quality as our initial JPEG encoded with ",(0,o.kt)("inlineCode",{parentName:"p"},"cjpegli")," (which scores ~",(0,o.kt)("inlineCode",{parentName:"p"},"83.01")," with the ",(0,o.kt)("a",{parentName:"p",href:"/docs/metrics/SSIMULACRA2"},"SSIMULACRA2")," visual fidelity metric)."),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"smaller_jxl",src:i(8559).Z})),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"137.0 kB")," ",(0,o.kt)("em",{parentName:"p"},"JPEG-XL image, encoded with ",(0,o.kt)("inlineCode",{parentName:"em"},"cjxl lossless.png out.jxl -d 1.49 -e 9"),". Score: ~",(0,o.kt)("inlineCode",{parentName:"em"},"83.04"))," ",(0,o.kt)("em",{parentName:"p"},"3.06s user time")),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"smaller_avif",src:i(9593).Z})),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"124.8 kB")," ",(0,o.kt)("em",{parentName:"p"},"AVIF image, encoded with ",(0,o.kt)("inlineCode",{parentName:"em"},"avifenc -c aom -s 4 -j 8 -d 10 -y 444 --min 1 --max 63 -a end-usage=q -a cq-level=16 -a tune=ssim lossless.png out.avif"),". Score: ~",(0,o.kt)("inlineCode",{parentName:"em"},"83.03"))," ",(0,o.kt)("em",{parentName:"p"},"7.54s user time")),(0,o.kt)("p",null,"JXL also supports lossless transcoding of JPEG images. This means every pixel is identical, the image just has a smaller filesize than the original JPEG; if you can use JXL, you can transcode existing JPEGs losslessly on your site & save some bandwidth that way. The JPEG transcode below gives a higher SSIMULACRA2 score than the original for some reason, but I'll chalk that up to a decoding inconsistency between how the ",(0,o.kt)("inlineCode",{parentName:"p"},"ssimulacra2")," program decodes JPEG & JXL. Either way, the scores are fairly close."),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"smaller_jxl_jpeg-recomp",src:i(8657).Z})),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"189.4 kB")," ",(0,o.kt)("em",{parentName:"p"},"JPEG-XL image from JPEG, encoded with ",(0,o.kt)("inlineCode",{parentName:"em"},"cjxl input.jpg input-recomp.jxl -d 0.0 -e 9 --brotli_effort=11"),". Score: ~",(0,o.kt)("inlineCode",{parentName:"em"},"84.92")," (???)")," ",(0,o.kt)("em",{parentName:"p"},"0.67s user time")),(0,o.kt)("p",null,"The final trick we can use, while not a new codec at all, still increases quality per bit. Encoding an XYB JPEG with ",(0,o.kt)("inlineCode",{parentName:"p"},"cjpegli")," encodes with the perceptual XYB colorspace using an ICC profile to modify the original JPEG colors, avoiding JPEG's normal YCbCr which isn't perceptually optimized for the human visual system. Using XYB, we can afford identical quality with less bitrate than normal JPEG. This has universal compatibility, but not every application understands how to handle the XYB color profile (although color-managed modern browsers should be fine)."),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"smaller_jpeg_xyb",src:i(4837).Z,width:"1699",height:"1136"})),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"208.3 kB")," ",(0,o.kt)("em",{parentName:"p"},"XYB JPEG, encoded with ",(0,o.kt)("inlineCode",{parentName:"em"},"cjpegli lossless.png out.jpg --xyb -d 1.155"),". Score: ~",(0,o.kt)("inlineCode",{parentName:"em"},"83.04"))," ",(0,o.kt)("em",{parentName:"p"},"0.10s user time")),(0,o.kt)("p",null,"In this particular instance, AVIF seems to be the overall winner. This isn't always the case due to JXL's superiority at higher fidelity & with more detailed images, but according to SSIMULACRA2, AVIF has the best quality per bit with this image. You can use your own eyes to further clarify your choice, though. It is worth mentioning that as these were encoded from a 16-bit source PNG, the JXL image is the only one that maintains the full original bit depth, & AVIF isn't fast to encode."),(0,o.kt)("h2",{id:"responsive-images"},"Responsive Images"),(0,o.kt)("p",null,"Displaying an image that is too large for a viewport is a waste of bandwidth, & displaying an image that's too small for the viewport leaves fidelity to be desired. Luckily, we have the ",(0,o.kt)("a",{parentName:"p",href:"https://ausi.github.io/respimagelint/"},"Responsive Image Linter")," that can help us figure out which image sizes we should be using."),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"responsive_image_linter",src:i(1778).Z})),(0,o.kt)("p",null,"In our fire & forget example, we see that we are serving an image that is far too large. We already know that, but now we can see that given various viewport sizes we could be serving images that have respective widths of 270px, 958px, 1350px, 1660px, & 1916px to optimize for delivery to a variety of different devices. Here's how we'd write that in HTML:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-html"},'\n\u2003\u2003\n\u2003\u2003\n\u2003\u2003alt text\n\n')),(0,o.kt)("p",null,"It is worth noting that this example above & the example below aren't perfect implementations of a responsive image given the conditions of this site, but the general concept still applies. Some things to note:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"srcset")," = the images available to your browser to serve, & their respective widths"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"sizes")," = the conditions given to the browser explaining under what conditions should it serve which image"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"(min-width: XXXpx) YYYpx")," = Given the viewport is at least XXX wide, serve an image of YYY horizontal resolution. The browser will pick an image from srcset that is CSS pixels ","*"," display scaling."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"calc(100vw - 24px)")," = Usually preceded by a (min-width) condition. Specifies a value the browser should calculate on its own to pick the closest option from the srcset. Let's say we have ",(0,o.kt)("inlineCode",{parentName:"li"},"(min-width: 997px) calc(75vw - 257px)"),". This means given the viewport is at least 997px wide, calculate 0.75 ","*"," the current viewport resolution - 257 to find the closest image in the srcset to fit the number of pixel specified.")),(0,o.kt)("picture",null,"\u2003\u2003",(0,o.kt)("source",{type:"image/jxl",srcset:"https://raw.githubusercontent.com/av1-community-contributors/codec-wiki/deployment/img/img_size/img_270.jxl 270w, https://raw.githubusercontent.com/av1-community-contributors/codec-wiki/deployment/img/img_size/img_958.jxl 958w, https://raw.githubusercontent.com/av1-community-contributors/codec-wiki/deployment/img/img_size/img_1350.jxl 1350w, https://raw.githubusercontent.com/av1-community-contributors/codec-wiki/deployment/img/img_size/img_1660.jxl 1660w, https://raw.githubusercontent.com/av1-community-contributors/codec-wiki/deployment/img/img_size/img_1916.jxl 1916w",sizes:"(min-width: 2000px) 1916px, (min-width: 1700px) 1660px, (min-width: 1400px) 1350px, (min-width: 1000px) 958px, calc(100vw - 24px)"}),"\u2003\u2003",(0,o.kt)("source",{type:"image/avif",srcset:"https://raw.githubusercontent.com/av1-community-contributors/codec-wiki/deployment/img/img_size/img_270.avif 270w, https://raw.githubusercontent.com/av1-community-contributors/codec-wiki/deployment/img/img_size/img_958.avif 958w, https://raw.githubusercontent.com/av1-community-contributors/codec-wiki/deployment/img/img_size/img_1350.avif 1350w, https://raw.githubusercontent.com/av1-community-contributors/codec-wiki/deployment/img/img_size/img_1660.avif 1660w, https://raw.githubusercontent.com/av1-community-contributors/codec-wiki/deployment/img/img_size/img_1916.avif 1916w",sizes:"(min-width: 2000px) 1916px, (min-width: 1700px) 1660px, (min-width: 1400px) 1350px, (min-width: 1000px) 958px, calc(100vw - 24px)"}),"\u2003\u2003",(0,o.kt)("img",{loading:"lazy",width:"1699",height:"1136",alt:"alt text",srcset:"https://raw.githubusercontent.com/av1-community-contributors/codec-wiki/deployment/img/img_size/img_270.jpg 270w, https://raw.githubusercontent.com/av1-community-contributors/codec-wiki/deployment/img/img_size/img_958.jpg 958w, https://raw.githubusercontent.com/av1-community-contributors/codec-wiki/deployment/img/img_size/img_1350.jpg 1350w, https://raw.githubusercontent.com/av1-community-contributors/codec-wiki/deployment/img/img_size/img_1660.jpg 1660w, https://raw.githubusercontent.com/av1-community-contributors/codec-wiki/deployment/img/img_size/img_1916.jpg 1916w",sizes:"(min-width: 2000px) 1916px, (min-width: 1700px) 1660px, (min-width: 1400px) 1350px, (min-width: 1000px) 958px, calc(100vw - 24px)",src:"https://raw.githubusercontent.com/av1-community-contributors/codec-wiki/deployment/img/_DSC8466-smaller.jpg"})),(0,o.kt)("p",null,"That's all! Massive thanks to Auto-Rez Media Technologies for the inspiration behind this article & explicit permission to use their ",(0,o.kt)("a",{parentName:"p",href:"https://autocompressor.net/blog/reduce-image-load"},"Reduce Your Page's Image Load")," blog post when writing this entry. I have ",(0,o.kt)("a",{parentName:"p",href:"https://autumn.revolt.chat/attachments/GtFGuwNfeRdcwUN0MWzhDCAiiadWOk88XXC3pQv6RI"},"confirmed")," with their leadership that this wiki entry can be safely licensed under CC BY-SA 4.0."))}h.isMDXComponent=!0},8657:(e,t,i)=>{i.d(t,{Z:()=>a});const a=i.p+"assets/images/_DSC8466-smaller-recomp-f3af6d54a8c1c62cda0c2d3ba048e1fc.jxl"},4837:(e,t,i)=>{i.d(t,{Z:()=>a});const a=i.p+"assets/images/_DSC8466-smaller-xyb-0372077e225cf7b460ec9238bb2a65f9.jpg"},9593:(e,t,i)=>{i.d(t,{Z:()=>a});const a=i.p+"assets/images/_DSC8466-smaller-452ed8f5a33da727be398450e7e580a3.avif"},2918:(e,t,i)=>{i.d(t,{Z:()=>a});const a=i.p+"assets/images/_DSC8466-smaller-48eaf650a417558ea976bf40eee82f67.jpg"},8559:(e,t,i)=>{i.d(t,{Z:()=>a});const a=i.p+"assets/images/_DSC8466-smaller-492a0639fb771671738062a57b2015a2.jxl"},6039:(e,t,i)=>{i.d(t,{Z:()=>a});const a=i.p+"assets/images/_DSC8466-d51a7e87bed86d101412ba728ebc6be2.jpg"},6440:(e,t,i)=>{i.d(t,{Z:()=>a});const a=i.p+"assets/images/box-size-mac-f49e702b0cb4a531f65283ad604d4b4c.avif"},1778:(e,t,i)=>{i.d(t,{Z:()=>a});const a=i.p+"assets/images/responsive_image_linter-178eb56c12557c53a2b129dd75925fe9.avif"}}]); \ No newline at end of file diff --git a/assets/js/b9f079c2.4b4eff1e.js b/assets/js/b9f079c2.4b4eff1e.js new file mode 100644 index 000000000..17cff628c --- /dev/null +++ b/assets/js/b9f079c2.4b4eff1e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[5226],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>m});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var d=r.createContext({}),p=function(e){var t=r.useContext(d),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(d.Provider,{value:t},e.children)},s="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,d=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),s=p(n),f=o,m=s["".concat(d,".").concat(f)]||s[f]||u[f]||i;return n?r.createElement(m,a(a({ref:t},l),{},{components:n})):r.createElement(m,a({ref:t},l))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=f;var c={};for(var d in t)hasOwnProperty.call(t,d)&&(c[d]=t[d]);c.originalType=e,c[s]="string"==typeof e?e:o,a[1]=c;for(var p=2;p{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>c,toc:()=>p});var r=n(7462),o=(n(7294),n(3905));const i={label:"VC-1",sidebar_position:8},a="VC-1",c={unversionedId:"video/VC-1",id:"video/VC-1",title:"VC-1",description:"This section is in need of contributions. If you believe you can help, please see our Contribution Guide to get started as a contributor!",source:"@site/docs/video/VC-1.md",sourceDirName:"video",slug:"/video/VC-1",permalink:"/docs/video/VC-1",draft:!1,editUrl:"https://github.com/av1-community-contributors/codec-wiki/tree/main/docs/video/VC-1.md",tags:[],version:"current",sidebarPosition:8,frontMatter:{label:"VC-1",sidebar_position:8},sidebar:"tutorialSidebar",previous:{title:"AVS3",permalink:"/docs/video/AVS3"},next:{title:"Theora",permalink:"/docs/video/Theora"}},d={},p=[{value:"Encoding",id:"encoding",level:2},{value:"Decoding",id:"decoding",level:2}],l={toc:p},s="wrapper";function u(e){let{components:t,...n}=e;return(0,o.kt)(s,(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"vc-1"},"VC-1"),(0,o.kt)("admonition",{title:"Help Wanted",type:"warning"},(0,o.kt)("p",{parentName:"admonition"},"This section is in need of contributions. If you believe you can help, please see our ",(0,o.kt)("a",{parentName:"p",href:"/docs/contribution-guide"},"Contribution Guide")," to get started as a contributor!")),(0,o.kt)("p",null,"VC-1 is video codec created by Microsoft and released in 2006. It largely aimed to compete with ",(0,o.kt)("a",{parentName:"p",href:"/docs/video/AVC"},"AVC"),"."),(0,o.kt)("h2",{id:"encoding"},"Encoding"),(0,o.kt)("p",null,"VC-1 can be contained in ",(0,o.kt)("inlineCode",{parentName:"p"},".mp4"),", ",(0,o.kt)("inlineCode",{parentName:"p"},".mkv"),", and ",(0,o.kt)("inlineCode",{parentName:"p"},".avi")," containers.\nTo be filled"),(0,o.kt)("h2",{id:"decoding"},"Decoding"),(0,o.kt)("p",null,"VC-1 can be decoded by ",(0,o.kt)("a",{parentName:"p",href:"/docs/utilities/ffmpeg"},"FFmpeg"),", ",(0,o.kt)("a",{parentName:"p",href:"/docs/video-players"},"VLC"),", ",(0,o.kt)("a",{parentName:"p",href:"/docs/video-players"},"MPV"),", and any device that supports blu-ray."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b9f079c2.a2888097.js b/assets/js/b9f079c2.a2888097.js deleted file mode 100644 index 520060d60..000000000 --- a/assets/js/b9f079c2.a2888097.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[5226],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>b});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),u=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},l=function(e){var t=u(e.components);return n.createElement(s.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),p=u(r),f=o,b=p["".concat(s,".").concat(f)]||p[f]||d[f]||i;return r?n.createElement(b,a(a({ref:t},l),{},{components:r})):n.createElement(b,a({ref:t},l))}));function b(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=f;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[p]="string"==typeof e?e:o,a[1]=c;for(var u=2;u{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>c,toc:()=>u});var n=r(7462),o=(r(7294),r(3905));const i={label:"VC-1",sidebar_position:8},a="VC-1",c={unversionedId:"video/VC-1",id:"video/VC-1",title:"VC-1",description:"This section is in need of contributions. If you believe you can help, please see our Contribution Guide to get started as a contributor!",source:"@site/docs/video/VC-1.md",sourceDirName:"video",slug:"/video/VC-1",permalink:"/docs/video/VC-1",draft:!1,editUrl:"https://github.com/av1-community-contributors/codec-wiki/tree/main/docs/video/VC-1.md",tags:[],version:"current",sidebarPosition:8,frontMatter:{label:"VC-1",sidebar_position:8},sidebar:"tutorialSidebar",previous:{title:"AVS3",permalink:"/docs/video/AVS3"},next:{title:"Theora",permalink:"/docs/video/Theora"}},s={},u=[],l={toc:u},p="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(p,(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"vc-1"},"VC-1"),(0,o.kt)("admonition",{title:"Help Wanted",type:"warning"},(0,o.kt)("p",{parentName:"admonition"},"This section is in need of contributions. If you believe you can help, please see our ",(0,o.kt)("a",{parentName:"p",href:"/docs/contribution-guide"},"Contribution Guide")," to get started as a contributor!")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/bc8b8418.1c9d40a8.js b/assets/js/bc8b8418.1c9d40a8.js deleted file mode 100644 index c19dd0a19..000000000 --- a/assets/js/bc8b8418.1c9d40a8.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[4704],{3905:(e,t,a)=>{a.d(t,{Zo:()=>d,kt:()=>h});var i=a(7294);function o(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function r(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,i)}return a}function n(e){for(var t=1;t=0||(o[a]=e[a]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(o[a]=e[a])}return o}var l=i.createContext({}),c=function(e){var t=i.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):n(n({},t),e)),a},d=function(e){var t=c(e.components);return i.createElement(l.Provider,{value:t},e.children)},m="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},p=i.forwardRef((function(e,t){var a=e.components,o=e.mdxType,r=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),m=c(a),p=o,h=m["".concat(l,".").concat(p)]||m[p]||u[p]||r;return a?i.createElement(h,n(n({ref:t},d),{},{components:a})):i.createElement(h,n({ref:t},d))}));function h(e,t){var a=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=a.length,n=new Array(r);n[0]=p;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[m]="string"==typeof e?e:o,n[1]=s;for(var c=2;c{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>n,default:()=>u,frontMatter:()=>r,metadata:()=>s,toc:()=>c});var i=a(7462),o=(a(7294),a(3905));const r={title:"Terminology",sidebar_position:2},n="Terminology",s={unversionedId:"introduction/terminology",id:"introduction/terminology",title:"Terminology",description:"When learning about encoding technology, it is important to understand the vast terminology that is often used to describe concepts that are often not very complex to understand.",source:"@site/docs/introduction/terminology.md",sourceDirName:"introduction",slug:"/introduction/terminology",permalink:"/docs/introduction/terminology",draft:!1,editUrl:"https://github.com/av1-community-contributors/codec-wiki/tree/main/docs/introduction/terminology.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{title:"Terminology",sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Prologue",permalink:"/docs/introduction/prologue"},next:{title:"Spotting Video Artifacts",permalink:"/docs/introduction/video-artifacts"}},l={},c=[{value:"Bitstream",id:"bitstream",level:2},{value:"Elementary stream",id:"elementary-stream",level:2},{value:"Muxing",id:"muxing",level:2},{value:"Codec",id:"codec",level:2},{value:"Filter",id:"filter",level:2},{value:"Muxer/Demuxer",id:"muxerdemuxer",level:2},{value:"Bitstream filter",id:"bitstream-filter",level:2},{value:"Container",id:"container",level:2},{value:"MP4 / M4V",id:"mp4--m4v",level:4},{value:"MOV",id:"mov",level:4},{value:"MKV / MKA / MKS / MK3D",id:"mkv--mka--mks--mk3d",level:4},{value:"WebM",id:"webm",level:4},{value:"Transcoding",id:"transcoding",level:2},{value:"RDO",id:"rdo",level:2},{value:"Perceputal / Psychovisual / Psychoacoustic",id:"perceputal--psychovisual--psychoacoustic",level:2},{value:"Discrete Cosine Transform (DCT)",id:"discrete-cosine-transform-dct",level:2}],d={toc:c},m="wrapper";function u(e){let{components:t,...a}=e;return(0,o.kt)(m,(0,i.Z)({},d,a,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"terminology"},"Terminology"),(0,o.kt)("p",null,"When learning about encoding technology, it is important to understand the vast terminology that is often used to describe concepts that are often not very complex to understand."),(0,o.kt)("h2",{id:"bitstream"},"Bitstream"),(0,o.kt)("p",null,"A ",(0,o.kt)("em",{parentName:"p"},"bitstream")," or ",(0,o.kt)("em",{parentName:"p"},"bit stream")," is a media file, the kind that is played in a media player. It consists of a ",(0,o.kt)("a",{parentName:"p",href:"#container"},"container")," wrapping multiple ",(0,o.kt)("a",{parentName:"p",href:"#elementary-stream"},"elementary streams")),(0,o.kt)("h2",{id:"elementary-stream"},"Elementary stream"),(0,o.kt)("p",null,"An elementary stream is an audio, video, or subtitle track. Basically, it's the compressed data you want to ",(0,o.kt)("a",{parentName:"p",href:"#muxing"},"mux")," into the container."),(0,o.kt)("h2",{id:"muxing"},"Muxing"),(0,o.kt)("p",null,"Putting elementary streams into a container, which preserves them without making any changes to the data."),(0,o.kt)("h2",{id:"codec"},"Codec"),(0,o.kt)("p",null,"A codec (",(0,o.kt)("strong",{parentName:"p"},"co"),"der/",(0,o.kt)("strong",{parentName:"p"},"dec"),"oder) is the piece of code that actually encodes the data you put in. It takes as input and produces as output an elementary stream. More information is provided ",(0,o.kt)("a",{parentName:"p",href:"/docs/introduction/prologue/#what-is-a-codec"},"in the prologue"),"."),(0,o.kt)("h2",{id:"filter"},"Filter"),(0,o.kt)("p",null,"A filter is a piece of code you can apply to the data to make something about it different, for instance sharpening, removing artifacts, shakiness, denoising, scaling, overlay, etc."),(0,o.kt)("h2",{id:"muxerdemuxer"},"Muxer/Demuxer"),(0,o.kt)("p",null,"The pieces of code that ",(0,o.kt)("a",{parentName:"p",href:"#muxing"},"mux")," or do the reverse, getting elementary streams from the container."),(0,o.kt)("h2",{id:"bitstream-filter"},"Bitstream filter"),(0,o.kt)("p",null,"A bitstream filter is a filter that is directly applied to the ",(0,o.kt)("a",{parentName:"p",href:"#bitstream"},"bitstream")," in order to change something about the container, for instance, convert frame types, or corrupt some packets."),(0,o.kt)("h2",{id:"container"},"Container"),(0,o.kt)("p",null,"A container is a format for putting one or more elementary streams into one file, which is then called a ",(0,o.kt)("a",{parentName:"p",href:"#bitstream"},"bitstream"),"."),(0,o.kt)("p",null,'A video container is a digital file format that holds video and audio data, as well as additional information such as subtitles, metadata, and chapter markers. It acts as a "wrapper" that packages all these elements into a single file that can be played on various devices and software platforms. Think of it like a container you might use to transport goods - the video and audio data are like the items being transported, while the container itself provides a structure and organization for the contents.'),(0,o.kt)("p",null,"Some kinds of containers:"),(0,o.kt)("h4",{id:"mp4--m4v"},"MP4 / M4V"),(0,o.kt)("p",null,"This is likely the most common container you've encountered, & has near universal compatibility. Has a limited maximum amount of streams. The supported video codecs are ",(0,o.kt)("a",{parentName:"p",href:"/docs/video/AVC"},"H.264"),", ",(0,o.kt)("a",{parentName:"p",href:"/docs/video/HEVC"},"H.265"),", ",(0,o.kt)("a",{parentName:"p",href:"/docs/video/VVC"},"H.266"),", DivX, Xvid, ",(0,o.kt)("a",{parentName:"p",href:"/docs/video/VP9"},"VP9")," (Unofficial, hacky), and ",(0,o.kt)("a",{parentName:"p",href:"/docs/video/AV1"},"AV1")," (Unofficial, hacky). For audio codecs it's many of the various flavors of ",(0,o.kt)("a",{parentName:"p",href:"/docs/audio/AAC"},"AAC"),", ",(0,o.kt)("a",{parentName:"p",href:"/docs/audio/MP3"},"MP3"),", ",(0,o.kt)("a",{parentName:"p",href:"/docs/audio/FLAC"},"FLAC")," (Unofficial), ",(0,o.kt)("a",{parentName:"p",href:"/docs/audio/Opus"},"Opus")," (Unofficial, hacky). For subtitles only MPEG-4 Timed Text (TTXT) is supported."),(0,o.kt)("p",null,"The best tool to work with this container is MP4Box, but FFmpeg also works."),(0,o.kt)("h4",{id:"mov"},"MOV"),(0,o.kt)("p",null,"Similar to MP4, but less supported. Made with Apple Quicktime in mind, supports ProRes."),(0,o.kt)("h4",{id:"mkv--mka--mks--mk3d"},"MKV / MKA / MKS / MK3D"),(0,o.kt)("p",null,"Also known as Matroska, allows an unlimited amount of video/audio/subtitle streams and any codec that probably still exists in Area 51, you can put literally anything in there and it won't even care, MPEG-2/DivX/H.266/Theora/Thor/RealVideo/MJPEG/AVS3/AMR-WB, you name it. All around best container for working with if you have the choice."),(0,o.kt)("h4",{id:"webm"},"WebM"),(0,o.kt)("p",null,"A container made with web streaming in mind. WebM is stripped-down MKV that only allows free & open source codecs such as VP8, VP9 & AV1 for video, Vorbis & Opus for audio, and ",(0,o.kt)("a",{parentName:"p",href:"/docs/subtitles/webvtt"},"WebVTT")," for subtitles."),(0,o.kt)("h2",{id:"transcoding"},"Transcoding"),(0,o.kt)("p",null,"Taking an elementary stream & converting it to another format, lossless or lossy, using an encoder of some kind. For example, if I convert a lossless ",(0,o.kt)("a",{parentName:"p",href:"/docs/video/FFV1"},"FFV1")," video to lossy AV1 using an encoder, let's say ",(0,o.kt)("a",{parentName:"p",href:"/docs/encoders/rav1e"},"rav1e"),", I have ",(0,o.kt)("em",{parentName:"p"},"transcoded")," this lossless video to AV1. Transcoding doesn't have anything to do with the container."),(0,o.kt)("h2",{id:"rdo"},"RDO"),(0,o.kt)("p",null,"RDO, or Rate-Distortion Optimization, is a technique used to find the best trade-off between the bit rate & the quality of lossily encoded content. RDO can be metric-based, optimizing to score well on metrics like ",(0,o.kt)("a",{parentName:"p",href:"/docs/metrics/PSNR"},"PSNR")," or ",(0,o.kt)("a",{parentName:"p",href:"/docs/metrics/SSIM"},"SSIM"),"."),(0,o.kt)("h2",{id:"perceputal--psychovisual--psychoacoustic"},"Perceputal / Psychovisual / Psychoacoustic"),(0,o.kt)("p",null,'"Psychovisual quality" (for videos), "Psychoacoustic quality" (for audio), or "perceptual quality" is a term used to describe the perception of quality of a distorted video by the human visual system. The goal of any multimedia codec is to minimize data while maintaining perceived quality, and optimizing around human perception theoretically yields the best performance even within a limited set of coding techniques (like when using an older codec). Our model of human perception continues to evolve, and there is currently no such thing as a perfect model of the human visual system available. The current best available options in the form of metrics appear to be ',(0,o.kt)("a",{parentName:"p",href:"/docs/metrics/SSIMULACRA2"},"SSIMULACRA2")," & ",(0,o.kt)("a",{parentName:"p",href:"/docs/metrics/butteraugli"},"Butteraugli"),"."),(0,o.kt)("h2",{id:"discrete-cosine-transform-dct"},"Discrete Cosine Transform (DCT)"),(0,o.kt)("p",null,"The Discrete Cosine Transform is a mathematical transformation that can transform discrete data into the frequency domain. This discrete data could be pixels in an image/video compression block or data points recorded temporally representing an audio recording. This algorithm is a particularly good choice for image, video, music, & speech compression because it has high energy compaction relative to our understanding of images & their perceptual quality. High energy compaction means the DCT is able to represent a signal with a small number of significant coefficients, in this case mainly in the lower frequencies."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/bc8b8418.997835b3.js b/assets/js/bc8b8418.997835b3.js new file mode 100644 index 000000000..d5b558fef --- /dev/null +++ b/assets/js/bc8b8418.997835b3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[4704],{3905:(e,t,a)=>{a.d(t,{Zo:()=>d,kt:()=>h});var o=a(7294);function i(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function r(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,o)}return a}function n(e){for(var t=1;t=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var l=o.createContext({}),c=function(e){var t=o.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):n(n({},t),e)),a},d=function(e){var t=c(e.components);return o.createElement(l.Provider,{value:t},e.children)},m="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},p=o.forwardRef((function(e,t){var a=e.components,i=e.mdxType,r=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),m=c(a),p=i,h=m["".concat(l,".").concat(p)]||m[p]||u[p]||r;return a?o.createElement(h,n(n({ref:t},d),{},{components:a})):o.createElement(h,n({ref:t},d))}));function h(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=a.length,n=new Array(r);n[0]=p;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[m]="string"==typeof e?e:i,n[1]=s;for(var c=2;c{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>n,default:()=>u,frontMatter:()=>r,metadata:()=>s,toc:()=>c});var o=a(7462),i=(a(7294),a(3905));const r={title:"Terminology",sidebar_position:2},n="Terminology",s={unversionedId:"introduction/terminology",id:"introduction/terminology",title:"Terminology",description:"When learning about encoding technology, it is important to understand the vast terminology that is often used to describe concepts that are often not very complex to understand.",source:"@site/docs/introduction/terminology.md",sourceDirName:"introduction",slug:"/introduction/terminology",permalink:"/docs/introduction/terminology",draft:!1,editUrl:"https://github.com/av1-community-contributors/codec-wiki/tree/main/docs/introduction/terminology.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{title:"Terminology",sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Prologue",permalink:"/docs/introduction/prologue"},next:{title:"Spotting Video Artifacts",permalink:"/docs/introduction/video-artifacts"}},l={},c=[{value:"Bitstream",id:"bitstream",level:2},{value:"Lossy / Lossless",id:"lossy--lossless",level:2},{value:"Elementary stream",id:"elementary-stream",level:2},{value:"Muxing",id:"muxing",level:2},{value:"Codec",id:"codec",level:2},{value:"Filter",id:"filter",level:2},{value:"Muxer/Demuxer",id:"muxerdemuxer",level:2},{value:"Bitstream filter",id:"bitstream-filter",level:2},{value:"Container",id:"container",level:2},{value:"MP4 / M4V",id:"mp4--m4v",level:4},{value:"MOV",id:"mov",level:4},{value:"MKV / MKA / MKS / MK3D",id:"mkv--mka--mks--mk3d",level:4},{value:"WebM",id:"webm",level:4},{value:"Transcoding",id:"transcoding",level:2},{value:"RDO",id:"rdo",level:2},{value:"Perceputal / Psychovisual / Psychoacoustic",id:"perceputal--psychovisual--psychoacoustic",level:2},{value:"Discrete Cosine Transform (DCT)",id:"discrete-cosine-transform-dct",level:2}],d={toc:c},m="wrapper";function u(e){let{components:t,...a}=e;return(0,i.kt)(m,(0,o.Z)({},d,a,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"terminology"},"Terminology"),(0,i.kt)("p",null,"When learning about encoding technology, it is important to understand the vast terminology that is often used to describe concepts that are often not very complex to understand."),(0,i.kt)("h2",{id:"bitstream"},"Bitstream"),(0,i.kt)("p",null,"A ",(0,i.kt)("em",{parentName:"p"},"bitstream")," or ",(0,i.kt)("em",{parentName:"p"},"bit stream")," is a media file, the kind that is played in a media player. It consists of a ",(0,i.kt)("a",{parentName:"p",href:"#container"},"container")," wrapping multiple ",(0,i.kt)("a",{parentName:"p",href:"#elementary-stream"},"elementary streams")),(0,i.kt)("h2",{id:"lossy--lossless"},"Lossy / Lossless"),(0,i.kt)("p",null,(0,i.kt)("em",{parentName:"p"},"Lossy")," encoding throws out some of the detail to achieve a smaller size. Often, this is an acceptable trade-off, but if you need a perfect recreation of the data, you need ",(0,i.kt)("em",{parentName:"p"},"lossless")," encoding."),(0,i.kt)("h2",{id:"elementary-stream"},"Elementary stream"),(0,i.kt)("p",null,"An elementary stream is an audio, video, or subtitle track. Basically, it's the compressed data you want to ",(0,i.kt)("a",{parentName:"p",href:"#muxing"},"mux")," into the container."),(0,i.kt)("h2",{id:"muxing"},"Muxing"),(0,i.kt)("p",null,"Putting elementary streams into a container, which preserves them without making any changes to the data."),(0,i.kt)("h2",{id:"codec"},"Codec"),(0,i.kt)("p",null,"A codec (",(0,i.kt)("strong",{parentName:"p"},"co"),"der/",(0,i.kt)("strong",{parentName:"p"},"dec"),"oder) is the piece of code that actually encodes the data you put in. It takes as input and produces as output an elementary stream. More information is provided ",(0,i.kt)("a",{parentName:"p",href:"/docs/introduction/prologue/#what-is-a-codec"},"in the prologue"),"."),(0,i.kt)("h2",{id:"filter"},"Filter"),(0,i.kt)("p",null,"A filter is a piece of code you can apply to the data to make something about it different, for instance sharpening, removing artifacts, shakiness, denoising, scaling, overlay, etc."),(0,i.kt)("h2",{id:"muxerdemuxer"},"Muxer/Demuxer"),(0,i.kt)("p",null,"The pieces of code that ",(0,i.kt)("a",{parentName:"p",href:"#muxing"},"mux")," or do the reverse, getting elementary streams from the container."),(0,i.kt)("h2",{id:"bitstream-filter"},"Bitstream filter"),(0,i.kt)("p",null,"A bitstream filter is a filter that is directly applied to the ",(0,i.kt)("a",{parentName:"p",href:"#bitstream"},"bitstream")," in order to change something about the container, for instance, convert frame types, or corrupt some packets."),(0,i.kt)("h2",{id:"container"},"Container"),(0,i.kt)("p",null,"A container is a format for putting one or more elementary streams into one file, which is then called a ",(0,i.kt)("a",{parentName:"p",href:"#bitstream"},"bitstream"),"."),(0,i.kt)("p",null,'A video container is a digital file format that holds video and audio data, as well as additional information such as subtitles, metadata, and chapter markers. It acts as a "wrapper" that packages all these elements into a single file that can be played on various devices and software platforms. Think of it like a container you might use to transport goods - the video and audio data are like the items being transported, while the container itself provides a structure and organization for the contents.'),(0,i.kt)("p",null,"Some kinds of containers:"),(0,i.kt)("h4",{id:"mp4--m4v"},"MP4 / M4V"),(0,i.kt)("p",null,"This is likely the most common container you've encountered, & has near universal compatibility. Has a limited maximum amount of streams. The supported video codecs are ",(0,i.kt)("a",{parentName:"p",href:"/docs/video/AVC"},"H.264"),", ",(0,i.kt)("a",{parentName:"p",href:"/docs/video/HEVC"},"H.265"),", ",(0,i.kt)("a",{parentName:"p",href:"/docs/video/VVC"},"H.266"),", DivX, Xvid, ",(0,i.kt)("a",{parentName:"p",href:"/docs/video/VP9"},"VP9")," (Unofficial, hacky), and ",(0,i.kt)("a",{parentName:"p",href:"/docs/video/AV1"},"AV1")," (Unofficial, hacky). For audio codecs it's many of the various flavors of ",(0,i.kt)("a",{parentName:"p",href:"/docs/audio/AAC"},"AAC"),", ",(0,i.kt)("a",{parentName:"p",href:"/docs/audio/MP3"},"MP3"),", ",(0,i.kt)("a",{parentName:"p",href:"/docs/audio/FLAC"},"FLAC")," (Unofficial), ",(0,i.kt)("a",{parentName:"p",href:"/docs/audio/Opus"},"Opus")," (Unofficial, hacky). For subtitles only MPEG-4 Timed Text (TTXT) is supported."),(0,i.kt)("p",null,"The best tool to work with this container is MP4Box, but FFmpeg also works."),(0,i.kt)("h4",{id:"mov"},"MOV"),(0,i.kt)("p",null,"Similar to MP4, but less supported. Made with Apple Quicktime in mind, supports ProRes."),(0,i.kt)("h4",{id:"mkv--mka--mks--mk3d"},"MKV / MKA / MKS / MK3D"),(0,i.kt)("p",null,"Also known as Matroska, allows an unlimited amount of video/audio/subtitle streams and any codec that probably still exists in Area 51, you can put literally anything in there and it won't even care, MPEG-2/DivX/H.266/Theora/Thor/RealVideo/MJPEG/AVS3/AMR-WB, you name it. All around best container for working with if you have the choice."),(0,i.kt)("h4",{id:"webm"},"WebM"),(0,i.kt)("p",null,"A container made with web streaming in mind. WebM is stripped-down MKV that only allows free & open source codecs such as VP8, VP9 & AV1 for video, Vorbis & Opus for audio, and ",(0,i.kt)("a",{parentName:"p",href:"/docs/subtitles/webvtt"},"WebVTT")," for subtitles."),(0,i.kt)("h2",{id:"transcoding"},"Transcoding"),(0,i.kt)("p",null,"Taking an elementary stream & converting it to another format, lossless or lossy, using an encoder of some kind. For example, if I convert a lossless ",(0,i.kt)("a",{parentName:"p",href:"/docs/video/FFV1"},"FFV1")," video to lossy AV1 using an encoder, let's say ",(0,i.kt)("a",{parentName:"p",href:"/docs/encoders/rav1e"},"rav1e"),", I have ",(0,i.kt)("em",{parentName:"p"},"transcoded")," this lossless video to AV1. Transcoding doesn't have anything to do with the container."),(0,i.kt)("h2",{id:"rdo"},"RDO"),(0,i.kt)("p",null,"RDO, or Rate-Distortion Optimization, is a technique used to find the best trade-off between the bit rate & the quality of lossily encoded content. RDO can be metric-based, optimizing to score well on metrics like ",(0,i.kt)("a",{parentName:"p",href:"/docs/metrics/PSNR"},"PSNR")," or ",(0,i.kt)("a",{parentName:"p",href:"/docs/metrics/SSIM"},"SSIM"),"."),(0,i.kt)("h2",{id:"perceputal--psychovisual--psychoacoustic"},"Perceputal / Psychovisual / Psychoacoustic"),(0,i.kt)("p",null,'"Psychovisual quality" (for videos), "Psychoacoustic quality" (for audio), or "perceptual quality" is a term used to describe the perception of quality of a distorted video by the human visual system. The goal of any multimedia codec is to minimize data while maintaining perceived quality, and optimizing around human perception theoretically yields the best performance even within a limited set of coding techniques (like when using an older codec). Our model of human perception continues to evolve, and there is currently no such thing as a perfect model of the human visual system available. The current best available options in the form of metrics appear to be ',(0,i.kt)("a",{parentName:"p",href:"/docs/metrics/SSIMULACRA2"},"SSIMULACRA2")," & ",(0,i.kt)("a",{parentName:"p",href:"/docs/metrics/butteraugli"},"Butteraugli"),"."),(0,i.kt)("h2",{id:"discrete-cosine-transform-dct"},"Discrete Cosine Transform (DCT)"),(0,i.kt)("p",null,"The Discrete Cosine Transform is a mathematical transformation that can transform discrete data into the frequency domain. This discrete data could be pixels in an image/video compression block or data points recorded temporally representing an audio recording. This algorithm is a particularly good choice for image, video, music, & speech compression because it has high energy compaction relative to our understanding of images & their perceptual quality. High energy compaction means the DCT is able to represent a signal with a small number of significant coefficients, in this case mainly in the lower frequencies."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/d6f42046.fc467dc5.js b/assets/js/d6f42046.08bc8401.js similarity index 67% rename from assets/js/d6f42046.fc467dc5.js rename to assets/js/d6f42046.08bc8401.js index d4c7bbf30..e89c4ee0a 100644 --- a/assets/js/d6f42046.fc467dc5.js +++ b/assets/js/d6f42046.08bc8401.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[1280],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>f});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},l=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=p(r),d=a,f=u["".concat(c,".").concat(d)]||u[d]||m[d]||o;return r?n.createElement(f,i(i({ref:t},l),{},{components:r})):n.createElement(f,i({ref:t},l))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:a,i[1]=s;for(var p=2;p{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>m,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var n=r(7462),a=(r(7294),r(3905));const o={label:"PNG",sidebar_position:2},i="PNG",s={unversionedId:"images/PNG",id:"images/PNG",title:"PNG",description:"This section is in need of contributions. If you believe you can help, please see our Contribution Guide to get started as a contributor!",source:"@site/docs/images/PNG.md",sourceDirName:"images",slug:"/images/PNG",permalink:"/docs/images/PNG",draft:!1,editUrl:"https://github.com/av1-community-contributors/codec-wiki/tree/main/docs/images/PNG.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{label:"PNG",sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"JPEG",permalink:"/docs/images/JPEG"},next:{title:"GIF",permalink:"/docs/images/GIF"}},c={},p=[{value:"Performance Checklist",id:"performance-checklist",level:2}],l={toc:p},u="wrapper";function m(e){let{components:t,...r}=e;return(0,a.kt)(u,(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"png"},"PNG"),(0,a.kt)("admonition",{title:"Help Wanted",type:"warning"},(0,a.kt)("p",{parentName:"admonition"},"This section is in need of contributions. If you believe you can help, please see our ",(0,a.kt)("a",{parentName:"p",href:"/docs/contribution-guide"},"Contribution Guide")," to get started as a contributor!")),(0,a.kt)("p",null,"Portable Network Graphics (PNG) is a free lossless image file format released in 1996. It was ceated as an alternative to ",(0,a.kt)("a",{parentName:"p",href:"/docs/images/GIF"},"GIF"),", which was at the time a proprietary format."),(0,a.kt)("h2",{id:"performance-checklist"},"Performance Checklist"),(0,a.kt)("p",null,"Lossless? ",(0,a.kt)("em",{parentName:"p"},"Yes")),(0,a.kt)("p",null,"Lossy? ",(0,a.kt)("em",{parentName:"p"},"No")),(0,a.kt)("p",null,"Supported Bit Depths:\n",(0,a.kt)("em",{parentName:"p"},"8 BPC, 16 BPC")),(0,a.kt)("p",null,"HDR/Wide Gamut? ",(0,a.kt)("em",{parentName:"p"},"Yes")),(0,a.kt)("p",null,"Animation? ",(0,a.kt)("em",{parentName:"p"},"Yes")),(0,a.kt)("p",null,"Transparency? ",(0,a.kt)("em",{parentName:"p"},"Yes")),(0,a.kt)("p",null,"Progressive Decode? ",(0,a.kt)("em",{parentName:"p"},"Kinda")),(0,a.kt)("p",null,"Royalty Free? ",(0,a.kt)("em",{parentName:"p"},"Yes")))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[1280],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>f});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),c=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},l=function(e){var t=c(e.components);return n.createElement(p.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=c(r),d=a,f=u["".concat(p,".").concat(d)]||u[d]||m[d]||o;return r?n.createElement(f,i(i({ref:t},l),{},{components:r})):n.createElement(f,i({ref:t},l))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=d;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[u]="string"==typeof e?e:a,i[1]=s;for(var c=2;c{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>m,frontMatter:()=>o,metadata:()=>s,toc:()=>c});var n=r(7462),a=(r(7294),r(3905));const o={label:"PNG",sidebar_position:2},i="PNG",s={unversionedId:"images/PNG",id:"images/PNG",title:"PNG",description:"This section is in need of contributions. If you believe you can help, please see our Contribution Guide to get started as a contributor!",source:"@site/docs/images/PNG.md",sourceDirName:"images",slug:"/images/PNG",permalink:"/docs/images/PNG",draft:!1,editUrl:"https://github.com/av1-community-contributors/codec-wiki/tree/main/docs/images/PNG.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{label:"PNG",sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"JPEG",permalink:"/docs/images/JPEG"},next:{title:"GIF",permalink:"/docs/images/GIF"}},p={},c=[{value:"Performance Checklist",id:"performance-checklist",level:2}],l={toc:c},u="wrapper";function m(e){let{components:t,...r}=e;return(0,a.kt)(u,(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"png"},"PNG"),(0,a.kt)("admonition",{title:"Help Wanted",type:"warning"},(0,a.kt)("p",{parentName:"admonition"},"This section is in need of contributions. If you believe you can help, please see our ",(0,a.kt)("a",{parentName:"p",href:"/docs/contribution-guide"},"Contribution Guide")," to get started as a contributor!")),(0,a.kt)("p",null,"Portable Network Graphics (PNG) is a free lossless image file format released in 1996. It was ceated as an alternative to ",(0,a.kt)("a",{parentName:"p",href:"/docs/images/GIF"},"GIF"),", which was at the time a proprietary format. It gained animation support similar to GIF with the release of APNG in 2008, which is now supported by all popular web browsers."),(0,a.kt)("h2",{id:"performance-checklist"},"Performance Checklist"),(0,a.kt)("p",null,"Lossless? ",(0,a.kt)("em",{parentName:"p"},"Yes")),(0,a.kt)("p",null,"Lossy? ",(0,a.kt)("em",{parentName:"p"},"No")),(0,a.kt)("p",null,"Supported Bit Depths:\n",(0,a.kt)("em",{parentName:"p"},"8 BPC, 16 BPC")),(0,a.kt)("p",null,"HDR/Wide Gamut? ",(0,a.kt)("em",{parentName:"p"},"Yes")),(0,a.kt)("p",null,"Animation? ",(0,a.kt)("em",{parentName:"p"},"Yes")),(0,a.kt)("p",null,"Transparency? ",(0,a.kt)("em",{parentName:"p"},"Yes")),(0,a.kt)("p",null,"Progressive Decode? ",(0,a.kt)("em",{parentName:"p"},"Kinda")),(0,a.kt)("p",null,"Royalty Free? ",(0,a.kt)("em",{parentName:"p"},"Yes")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/main.8c9ed1a3.js b/assets/js/main.8c9ed1a3.js deleted file mode 100644 index 9c2934ccb..000000000 --- a/assets/js/main.8c9ed1a3.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! For license information please see main.8c9ed1a3.js.LICENSE.txt */ -(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[179],{723:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(7294),a=n(7462),o=n(8356),i=n.n(o),l=n(6887);const s={"01a85c17":[()=>Promise.all([n.e(532),n.e(4013)]).then(n.bind(n,1223)),"@theme/BlogTagsListPage",1223],"03398248":[()=>n.e(3283).then(n.bind(n,7876)),"@site/docs/video/HEVC.md",7876],"087cb829":[()=>n.e(6899).then(n.bind(n,661)),"@site/docs/filtering/dehalo.md",661],"0cc695c5":[()=>n.e(2768).then(n.bind(n,639)),"@site/docs/images/JPEG2000.md",639],"0e272b0d":[()=>n.e(9140).then(n.bind(n,6412)),"@site/docs/encoders/vpxenc.md",6412],"0f8cca8e":[()=>n.e(909).then(n.bind(n,7875)),"@site/docs/terms-of-use.md",7875],"13d564a8":[()=>n.e(3146).then(n.bind(n,8508)),"@site/docs/encoders/rav1e.md",8508],"146621ac":[()=>n.e(1164).then(n.bind(n,1101)),"@site/docs/data/brotli.md",1101],"16a2ecb1":[()=>n.e(1810).then(n.bind(n,2601)),"@site/docs/encoders/VTM.md",2601],"170db0a5":[()=>n.e(6301).then(n.bind(n,5449)),"@site/docs/video/AVS3.md",5449],"1776fc83":[()=>n.e(6326).then(n.bind(n,8222)),"@site/docs/images/JXL.md",8222],17896441:[()=>Promise.all([n.e(532),n.e(1506),n.e(7918)]).then(n.bind(n,8945)),"@theme/DocItem",8945],"180751f5":[()=>n.e(6627).then(n.t.bind(n,1438,19)),"~blog/default/blog-tags-image-bfd-list.json",1438],"18c4b02f":[()=>n.e(1777).then(n.bind(n,3167)),"@site/docs/metrics/SSIMULACRA2.md",3167],"195e296c":[()=>n.e(6117).then(n.bind(n,7019)),"@site/docs/images/JPEG.md",7019],"19839cd1":[()=>n.e(3958).then(n.bind(n,1383)),"@site/docs/audio/FLAC.md",1383],"1b4147b1":[()=>n.e(5715).then(n.bind(n,6506)),"@site/docs/utilities/Aviator.md",6506],"1be78505":[()=>Promise.all([n.e(532),n.e(9514)]).then(n.bind(n,9963)),"@theme/DocPage",9963],"1cb05ddd":[()=>n.e(3899).then(n.bind(n,7396)),"@site/docs/utilities/hdr10plus_tool.md",7396],"1cb64385":[()=>n.e(774).then(n.bind(n,1651)),"@site/docs/utilities/mp4box.md",1651],"1d129381":[()=>n.e(5302).then(n.bind(n,8140)),"@site/docs/utilities/FFMetrics.md",8140],"1f391b9e":[()=>Promise.all([n.e(532),n.e(1506),n.e(3085)]).then(n.bind(n,4247)),"@theme/MDXPage",4247],22091897:[()=>n.e(4828).then(n.bind(n,482)),"@site/docs/encoders/Kvazaar.md",482],"236b5e64":[()=>n.e(4591).then(n.bind(n,3075)),"@site/docs/data/xz.md",3075],"239a6b34":[()=>n.e(6643).then(n.t.bind(n,3769,19)),"/Users/giannim2/git-cloning/codec-wiki/.docusaurus/docusaurus-plugin-content-docs/default/plugin-route-context-module-100.json",3769],"2c0077b9":[()=>n.e(9612).then(n.bind(n,257)),"@site/docs/introduction/psychovisual.md",257],"2d568f8b":[()=>n.e(6242).then(n.bind(n,4256)),"@site/docs/metrics/VMAF.md",4256],"311c973b":[()=>n.e(1056).then(n.bind(n,1396)),"@site/docs/encoders/uvg266.md",1396],"319244b6":[()=>n.e(1221).then(n.t.bind(n,9742,19)),"~blog/default/blog-tags-compression-c1f.json",9742],"333f9c20":[()=>n.e(1727).then(n.bind(n,2231)),"@site/docs/utilities/nmkoder.md",2231],"33b5e57c":[()=>n.e(3128).then(n.bind(n,6807)),"@site/docs/metrics/SSIM.md",6807],"3494e53a":[()=>n.e(370).then(n.bind(n,9302)),"@site/docs/images/WebP.md",9302],"350130fb":[()=>n.e(9211).then(n.bind(n,7069)),"@site/docs/audio/Dolby.md",7069],"393be207":[()=>n.e(7414).then(n.bind(n,3123)),"@site/src/pages/markdown-page.md",3123],39634027:[()=>n.e(4100).then(n.t.bind(n,5745,19)),"/Users/giannim2/git-cloning/codec-wiki/.docusaurus/docusaurus-plugin-content-pages/default/plugin-route-context-module-100.json",5745],"3ca2a0fe":[()=>n.e(9768).then(n.bind(n,8042)),"@site/docs/introduction/high-dynamic-range.md",8042],"43f4d598":[()=>n.e(9087).then(n.bind(n,7191)),"@site/docs/video/FFV1.md",7191],"44ae7035":[()=>n.e(5888).then(n.bind(n,3065)),"@site/docs/images/HEIC.md",3065],"46e4c4c4":[()=>n.e(1034).then(n.bind(n,8290)),"@site/docs/encoders/VVenC.md",8290],"4b506820":[()=>n.e(837).then(n.bind(n,3376)),"@site/docs/utilities/MKVToolNix.md",3376],"4d465a8d":[()=>n.e(4503).then(n.bind(n,8917)),"@site/docs/utilities/ffmpeg.md",8917],"4edf0cfc":[()=>n.e(7473).then(n.bind(n,101)),"@site/docs/utilities/rAV1ator.md",101],"4f425cbc":[()=>n.e(8007).then(n.bind(n,1009)),"@site/docs/subtitles/SRT.md",1009],"50cc20ba":[()=>n.e(6997).then(n.bind(n,5579)),"@site/docs/encoders/SVT-HEVC.md",5579],"548450a9":[()=>n.e(9510).then(n.bind(n,8214)),"@site/docs/images/AVIF.md",8214],"56ac595f":[()=>Promise.all([n.e(532),n.e(7363)]).then(n.bind(n,1010)),"@site/docs/utilities/av1an.md",1010],"56ad2297":[()=>n.e(5663).then(n.bind(n,5490)),"@site/docs/video/AV1.md",5490],"5730e896":[()=>n.e(4478).then(n.bind(n,7108)),"@site/docs/audio/Vorbis.md",7108],"59641f86":[()=>n.e(3312).then(n.bind(n,7671)),"@site/docs/video/Theora.md",7671],"5dfd82d3":[()=>n.e(1062).then(n.bind(n,8634)),"@site/docs/encoders/x265.md",8634],"5e9f5e1a":[()=>Promise.resolve().then(n.bind(n,6809)),"@generated/docusaurus.config",6809],"608061a6":[()=>n.e(9967).then(n.bind(n,7892)),"@site/blog/2023-10-29-embedding-the-un-embeddable.md?truncated=true",7892],"60e1ac2d":[()=>n.e(5581).then(n.bind(n,5650)),"@site/blog/2023-09-03-av1-for-dummies.md",5650],"68409bcb":[()=>n.e(6976).then(n.bind(n,995)),"@site/docs/data/zstd.md",995],"6875c492":[()=>Promise.all([n.e(532),n.e(1506),n.e(2529),n.e(8610)]).then(n.bind(n,1714)),"@theme/BlogTagsPostsPage",1714],"68768e4f":[()=>n.e(5676).then(n.bind(n,6433)),"@site/docs/encoders/HM.md",6433],"6be474c2":[()=>n.e(1157).then(n.bind(n,3296)),"@site/docs/video/VP9.md",3296],"6ed27c39":[()=>n.e(3241).then(n.bind(n,543)),"@site/docs/metrics/butteraugli.md",543],"6f58bdf2":[()=>n.e(1444).then(n.bind(n,64)),"@site/docs/utilities/dovi_tool.md",64],"7015859e":[()=>n.e(5496).then(n.bind(n,4754)),"@site/docs/data/bzip2.md",4754],"71e8630b":[()=>n.e(1015).then(n.bind(n,6669)),"@site/docs/encoders/Aurora1.md",6669],"729fe1da":[()=>n.e(3173).then(n.bind(n,7527)),"@site/docs/encoders/SVT-VP9.md",7527],74450489:[()=>n.e(489).then(n.t.bind(n,9159,19)),"~blog/default/blog-tags-web-0e7.json",9159],"7574d07a":[()=>n.e(17).then(n.bind(n,9685)),"@site/docs/encoders/AVM.md",9685],"7680a4d5":[()=>n.e(1746).then(n.bind(n,7931)),"@site/docs/utilities/eac3to.md",7931],"7d044f50":[()=>n.e(2565).then(n.t.bind(n,6704,19)),"~blog/default/blog-tags-video-835-list.json",6704],"7dc56e97":[()=>n.e(8039).then(n.bind(n,6665)),"@site/docs/video/prores.md",6665],"7ec778da":[()=>n.e(9112).then(n.t.bind(n,3759,19)),"~blog/default/blog-tags-video-835.json",3759],"7ecaa93b":[()=>n.e(819).then(n.bind(n,8797)),"@site/docs/filtering/denoise.md",8797],"8112becb":[()=>n.e(6335).then(n.bind(n,8641)),"@site/blog/2023-07-21-site-optimization.md?truncated=true",8641],"814f3328":[()=>n.e(2535).then(n.t.bind(n,5641,19)),"~blog/default/blog-post-list-prop-default.json",5641],"8634481e":[()=>n.e(5795).then(n.bind(n,5986)),"@site/docs/filtering/intro.md",5986],"871a984d":[()=>n.e(5474).then(n.bind(n,7903)),"@site/docs/images/GIF.md",7903],"87861d43":[()=>n.e(3722).then(n.bind(n,328)),"@site/docs/video-players.md",328],"89809f85":[()=>n.e(9578).then(n.bind(n,2414)),"@site/blog/2023-10-29-embedding-the-un-embeddable.md",2414],"8a31ca28":[()=>Promise.all([n.e(532),n.e(4445)]).then(n.bind(n,5468)),"@site/docs/utilities/rav1ator-cli.md",5468],"8c5da4da":[()=>n.e(1923).then(n.bind(n,8006)),"@site/docs/privacy-policy.md",8006],"91a1632f":[()=>n.e(6896).then(n.bind(n,4731)),"@site/docs/subtitles/webvtt.md",4731],92404733:[()=>n.e(8971).then(n.bind(n,9296)),"@site/blog/2023-09-03-av1-for-dummies.md?truncated=true",9296],"935f2afb":[()=>n.e(53).then(n.t.bind(n,1109,19)),"~docs/default/version-current-metadata-prop-751.json",1109],"96daa04a":[()=>n.e(8685).then(n.bind(n,317)),"@site/docs/introduction/prologue.md",317],"96f54850":[()=>n.e(3681).then(n.bind(n,2820)),"@site/docs/video/VVC.md",2820],"9b0d9acc":[()=>n.e(3677).then(n.bind(n,2294)),"@site/docs/metrics/PSNR.md",2294],"9b4bf0ad":[()=>n.e(537).then(n.bind(n,5078)),"@site/docs/filtering/deinterlace.md",5078],"9b6fb453":[()=>n.e(130).then(n.t.bind(n,4469,19)),"/Users/giannim2/git-cloning/codec-wiki/.docusaurus/docusaurus-plugin-content-blog/default/plugin-route-context-module-100.json",4469],"9e4087bc":[()=>n.e(3608).then(n.bind(n,3169)),"@theme/BlogArchivePage",3169],a5eab855:[()=>n.e(8833).then(n.bind(n,5973)),"@site/docs/utilities/YUView.md",5973],a6aa9e1f:[()=>Promise.all([n.e(532),n.e(1506),n.e(2529),n.e(3089)]).then(n.bind(n,46)),"@theme/BlogListPage",46],a7023ddc:[()=>n.e(1713).then(n.t.bind(n,3457,19)),"~blog/default/blog-tags-tags-4c2.json",3457],abb705c2:[()=>n.e(1586).then(n.bind(n,8980)),"@site/docs/data/gzip.md",8980],ad895e75:[()=>n.e(4288).then(n.bind(n,3581)),"@site/docs/FAQ.md",3581],aea4c9a8:[()=>n.e(6031).then(n.bind(n,9482)),"@site/docs/filtering/detelecine.md",9482],b059735e:[()=>n.e(5893).then(n.t.bind(n,7288,19)),"~blog/default/blog-tags-web-0e7-list.json",7288],b0d95fb7:[()=>n.e(7671).then(n.bind(n,9955)),"@site/docs/contribution-guide.md",9955],b2b675dd:[()=>n.e(533).then(n.t.bind(n,8017,19)),"~blog/default/blog-c06.json",8017],b2f554cd:[()=>n.e(1477).then(n.t.bind(n,10,19)),"~blog/default/blog-archive-80c.json",10],b31956d8:[()=>n.e(3599).then(n.bind(n,8958)),"@site/docs/encoders/x264.md",8958],b41a2a88:[()=>n.e(2759).then(n.bind(n,4734)),"@site/docs/video/AVC.md",4734],b4470a6f:[()=>n.e(9596).then(n.bind(n,7282)),"@site/blog/2023-07-21-site-optimization.md",7282],b994ae50:[()=>n.e(4416).then(n.bind(n,1550)),"@site/docs/audio/Speex.md",1550],b9f079c2:[()=>n.e(5226).then(n.bind(n,9746)),"@site/docs/video/VC-1.md",9746],bc8b8418:[()=>n.e(4704).then(n.bind(n,1322)),"@site/docs/introduction/terminology.md",1322],bda40bca:[()=>n.e(918).then(n.bind(n,2203)),"@site/docs/filtering/vapoursynth.md",2203],c177ddec:[()=>n.e(9060).then(n.bind(n,4901)),"@site/docs/encoders/aomenc.md",4901],c4f5d8e4:[()=>Promise.all([n.e(532),n.e(4195)]).then(n.bind(n,9294)),"@site/src/pages/index.js",9294],c8fc782b:[()=>n.e(5335).then(n.bind(n,505)),"@site/docs/video/utvideo.md",505],c9a80c62:[()=>n.e(6492).then(n.bind(n,936)),"@site/docs/audio/Opus.md",936],ccc49370:[()=>Promise.all([n.e(532),n.e(1506),n.e(2529),n.e(6103)]).then(n.bind(n,5203)),"@theme/BlogPostPage",5203],cce01883:[()=>n.e(1606).then(n.bind(n,9092)),"@site/docs/audio/AAC.md",9092],cd1d8cd3:[()=>n.e(4002).then(n.bind(n,7014)),"@site/docs/filtering/deband.md",7014],d083b8d3:[()=>n.e(3155).then(n.bind(n,9053)),"@site/docs/audio/MP3.md",9053],d2946d3d:[()=>n.e(2875).then(n.bind(n,2438)),"@site/docs/data/7z.md",2438],d3fe2180:[()=>n.e(1820).then(n.bind(n,9151)),"@site/docs/audio/WavPack.md",9151],d4833a76:[()=>n.e(5601).then(n.bind(n,477)),"@site/docs/video/VP8.md",477],d6f42046:[()=>n.e(1280).then(n.bind(n,4563)),"@site/docs/images/PNG.md",4563],d92a3c43:[()=>n.e(2798).then(n.bind(n,8016)),"@site/docs/resources.md",8016],ddf1125a:[()=>n.e(3586).then(n.bind(n,8722)),"@site/docs/data/zip.md",8722],e6fe0126:[()=>n.e(7777).then(n.t.bind(n,7033,19)),"~blog/default/blog-tags-image-bfd.json",7033],e80106d6:[()=>n.e(3686).then(n.t.bind(n,5812,19)),"~blog/default/blog-tags-compression-c1f-list.json",5812],ec2b09d3:[()=>n.e(3416).then(n.bind(n,8816)),"@site/docs/encoders/SVT-AV1.md",8816],f0f157d6:[()=>n.e(3950).then(n.t.bind(n,1473,19)),"~blog/default/blog-tags-discord-ee6.json",1473],f4173e2a:[()=>n.e(5463).then(n.bind(n,3319)),"@site/docs/data/zpaq.md",3319],f594c766:[()=>n.e(8606).then(n.bind(n,5721)),"@site/docs/encoders/JM.md",5721],f98cc194:[()=>n.e(2902).then(n.bind(n,5198)),"@site/docs/introduction/video-artifacts.md",5198],fdae8881:[()=>n.e(1361).then(n.t.bind(n,7962,19)),"~blog/default/blog-tags-discord-ee6-list.json",7962]};function c(e){let{error:t,retry:n,pastDelay:a}=e;return t?r.createElement("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"}},r.createElement("p",null,String(t)),r.createElement("div",null,r.createElement("button",{type:"button",onClick:n},"Retry"))):a?r.createElement("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"}},r.createElement("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb"},r.createElement("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2"},r.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},r.createElement("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),r.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},r.createElement("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),r.createElement("circle",{cx:"22",cy:"22",r:"8"},r.createElement("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"}))))):null}var u=n(9670),d=n(226);function p(e,t){if("*"===e)return i()({loading:c,loader:()=>n.e(4972).then(n.bind(n,4972)),modules:["@theme/NotFound"],webpack:()=>[4972],render(e,t){const n=e.default;return r.createElement(d.z,{value:{plugin:{name:"native",id:"default"}}},r.createElement(n,t))}});const o=l[`${e}-${t}`],p={},f=[],m=[],h=(0,u.Z)(o);return Object.entries(h).forEach((e=>{let[t,n]=e;const r=s[n];r&&(p[t]=r[0],f.push(r[1]),m.push(r[2]))})),i().Map({loading:c,loader:p,modules:f,webpack:()=>m,render(t,n){const i=JSON.parse(JSON.stringify(o));Object.entries(t).forEach((t=>{let[n,r]=t;const a=r.default;if(!a)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof a&&"function"!=typeof a||Object.keys(r).filter((e=>"default"!==e)).forEach((e=>{a[e]=r[e]}));let o=i;const l=n.split(".");l.slice(0,-1).forEach((e=>{o=o[e]})),o[l[l.length-1]]=a}));const l=i.__comp;delete i.__comp;const s=i.__context;return delete i.__context,r.createElement(d.z,{value:s},r.createElement(l,(0,a.Z)({},i,n)))}})}const f=[{path:"/blog",component:p("/blog","c20"),exact:!0},{path:"/blog/archive",component:p("/blog/archive","6b5"),exact:!0},{path:"/blog/av1-encoding-for-dummies",component:p("/blog/av1-encoding-for-dummies","392"),exact:!0},{path:"/blog/embedding-the-un-embeddable",component:p("/blog/embedding-the-un-embeddable","b43"),exact:!0},{path:"/blog/site-optimization",component:p("/blog/site-optimization","f0b"),exact:!0},{path:"/blog/tags",component:p("/blog/tags","b03"),exact:!0},{path:"/blog/tags/compression",component:p("/blog/tags/compression","42b"),exact:!0},{path:"/blog/tags/discord",component:p("/blog/tags/discord","51e"),exact:!0},{path:"/blog/tags/image",component:p("/blog/tags/image","aa3"),exact:!0},{path:"/blog/tags/video",component:p("/blog/tags/video","ad3"),exact:!0},{path:"/blog/tags/web",component:p("/blog/tags/web","567"),exact:!0},{path:"/markdown-page",component:p("/markdown-page","6b7"),exact:!0},{path:"/docs",component:p("/docs","b6f"),routes:[{path:"/docs/audio/AAC",component:p("/docs/audio/AAC","49c"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/audio/Dolby",component:p("/docs/audio/Dolby","6dc"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/audio/FLAC",component:p("/docs/audio/FLAC","a15"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/audio/MP3",component:p("/docs/audio/MP3","8a9"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/audio/Opus",component:p("/docs/audio/Opus","d03"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/audio/Speex",component:p("/docs/audio/Speex","bbf"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/audio/Vorbis",component:p("/docs/audio/Vorbis","ac2"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/audio/WavPack",component:p("/docs/audio/WavPack","c24"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/contribution-guide",component:p("/docs/contribution-guide","daa"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/data/7z",component:p("/docs/data/7z","9ea"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/data/brotli",component:p("/docs/data/brotli","780"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/data/bzip2",component:p("/docs/data/bzip2","bd1"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/data/gzip",component:p("/docs/data/gzip","0b5"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/data/xz",component:p("/docs/data/xz","f99"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/data/zip",component:p("/docs/data/zip","818"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/data/zpaq",component:p("/docs/data/zpaq","c01"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/data/zstd",component:p("/docs/data/zstd","b64"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/encoders/aomenc",component:p("/docs/encoders/aomenc","3cb"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/encoders/Aurora1",component:p("/docs/encoders/Aurora1","ebf"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/encoders/AVM",component:p("/docs/encoders/AVM","702"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/encoders/HM",component:p("/docs/encoders/HM","ee8"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/encoders/JM",component:p("/docs/encoders/JM","0c9"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/encoders/Kvazaar",component:p("/docs/encoders/Kvazaar","d86"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/encoders/rav1e",component:p("/docs/encoders/rav1e","75b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/encoders/SVT-AV1",component:p("/docs/encoders/SVT-AV1","081"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/encoders/SVT-HEVC",component:p("/docs/encoders/SVT-HEVC","435"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/encoders/SVT-VP9",component:p("/docs/encoders/SVT-VP9","314"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/encoders/uvg266",component:p("/docs/encoders/uvg266","274"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/encoders/vpxenc",component:p("/docs/encoders/vpxenc","3df"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/encoders/VTM",component:p("/docs/encoders/VTM","336"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/encoders/VVenC",component:p("/docs/encoders/VVenC","384"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/encoders/x264",component:p("/docs/encoders/x264","cdd"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/encoders/x265",component:p("/docs/encoders/x265","25a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/FAQ",component:p("/docs/FAQ","cb6"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/filtering/deband",component:p("/docs/filtering/deband","d0a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/filtering/dehalo",component:p("/docs/filtering/dehalo","910"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/filtering/deinterlace",component:p("/docs/filtering/deinterlace","162"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/filtering/denoise",component:p("/docs/filtering/denoise","d49"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/filtering/detelecine",component:p("/docs/filtering/detelecine","fbd"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/filtering/intro",component:p("/docs/filtering/intro","755"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/filtering/vapoursynth",component:p("/docs/filtering/vapoursynth","23f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/images/AVIF",component:p("/docs/images/AVIF","1c2"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/images/GIF",component:p("/docs/images/GIF","25a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/images/HEIC",component:p("/docs/images/HEIC","641"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/images/JPEG",component:p("/docs/images/JPEG","c9a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/images/JPEG2000",component:p("/docs/images/JPEG2000","c35"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/images/JXL",component:p("/docs/images/JXL","b86"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/images/PNG",component:p("/docs/images/PNG","50f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/images/WebP",component:p("/docs/images/WebP","237"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/introduction/high-dynamic-range",component:p("/docs/introduction/high-dynamic-range","fa6"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/introduction/prologue",component:p("/docs/introduction/prologue","70d"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/introduction/psychovisual",component:p("/docs/introduction/psychovisual","7a5"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/introduction/terminology",component:p("/docs/introduction/terminology","3a8"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/introduction/video-artifacts",component:p("/docs/introduction/video-artifacts","01e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/metrics/butteraugli",component:p("/docs/metrics/butteraugli","671"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/metrics/PSNR",component:p("/docs/metrics/PSNR","271"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/metrics/SSIM",component:p("/docs/metrics/SSIM","a7d"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/metrics/SSIMULACRA2",component:p("/docs/metrics/SSIMULACRA2","f08"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/metrics/VMAF",component:p("/docs/metrics/VMAF","7aa"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/privacy-policy",component:p("/docs/privacy-policy","5f4"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/resources",component:p("/docs/resources","8be"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/subtitles/SRT",component:p("/docs/subtitles/SRT","039"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/subtitles/webvtt",component:p("/docs/subtitles/webvtt","729"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/terms-of-use",component:p("/docs/terms-of-use","514"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/utilities/av1an",component:p("/docs/utilities/av1an","e85"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/utilities/Aviator",component:p("/docs/utilities/Aviator","a6f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/utilities/dovi_tool",component:p("/docs/utilities/dovi_tool","60e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/utilities/eac3to",component:p("/docs/utilities/eac3to","cb7"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/utilities/FFMetrics",component:p("/docs/utilities/FFMetrics","f62"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/utilities/ffmpeg",component:p("/docs/utilities/ffmpeg","80a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/utilities/hdr10plus_tool",component:p("/docs/utilities/hdr10plus_tool","427"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/utilities/MKVToolNix",component:p("/docs/utilities/MKVToolNix","970"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/utilities/mp4box",component:p("/docs/utilities/mp4box","fae"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/utilities/nmkoder",component:p("/docs/utilities/nmkoder","900"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/utilities/rAV1ator",component:p("/docs/utilities/rAV1ator","380"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/utilities/rav1ator-cli",component:p("/docs/utilities/rav1ator-cli","ffb"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/utilities/YUView",component:p("/docs/utilities/YUView","6c5"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/video-players",component:p("/docs/video-players","0d0"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/video/AV1",component:p("/docs/video/AV1","0ad"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/video/AVC",component:p("/docs/video/AVC","19c"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/video/AVS3",component:p("/docs/video/AVS3","d0b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/video/FFV1",component:p("/docs/video/FFV1","57b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/video/HEVC",component:p("/docs/video/HEVC","533"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/video/prores",component:p("/docs/video/prores","6e5"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/video/Theora",component:p("/docs/video/Theora","0a4"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/video/utvideo",component:p("/docs/video/utvideo","0fc"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/video/VC-1",component:p("/docs/video/VC-1","185"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/video/VP8",component:p("/docs/video/VP8","89f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/video/VP9",component:p("/docs/video/VP9","8ea"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/video/VVC",component:p("/docs/video/VVC","8eb"),exact:!0,sidebar:"tutorialSidebar"}]},{path:"/",component:p("/","231"),exact:!0},{path:"*",component:p("*")}]},8934:(e,t,n)=>{"use strict";n.d(t,{_:()=>a,t:()=>o});var r=n(7294);const a=r.createContext(!1);function o(e){let{children:t}=e;const[n,o]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{o(!0)}),[]),r.createElement(a.Provider,{value:n},t)}},7221:(e,t,n)=>{"use strict";var r=n(7294),a=n(3935),o=n(3727),i=n(405),l=n(412);const s=[n(2497),n(3310),n(8320),n(2295)];var c=n(723),u=n(6550),d=n(8790);function p(e){let{children:t}=e;return r.createElement(r.Fragment,null,t)}var f=n(7462),m=n(5742),h=n(2263),g=n(4996),b=n(6668),v=n(1944),y=n(4711),w=n(9727),k=n(3320),S=n(8780),E=n(197);function x(){const{i18n:{defaultLocale:e,localeConfigs:t}}=(0,h.Z)(),n=(0,y.l)();return r.createElement(m.Z,null,Object.entries(t).map((e=>{let[t,{htmlLang:a}]=e;return r.createElement("link",{key:t,rel:"alternate",href:n.createUrl({locale:t,fullyQualified:!0}),hrefLang:a})})),r.createElement("link",{rel:"alternate",href:n.createUrl({locale:e,fullyQualified:!0}),hrefLang:"x-default"}))}function _(e){let{permalink:t}=e;const{siteConfig:{url:n}}=(0,h.Z)(),a=function(){const{siteConfig:{url:e,baseUrl:t,trailingSlash:n}}=(0,h.Z)(),{pathname:r}=(0,u.TH)();return e+(0,S.applyTrailingSlash)((0,g.Z)(r),{trailingSlash:n,baseUrl:t})}(),o=t?`${n}${t}`:a;return r.createElement(m.Z,null,r.createElement("meta",{property:"og:url",content:o}),r.createElement("link",{rel:"canonical",href:o}))}function C(){const{i18n:{currentLocale:e}}=(0,h.Z)(),{metadata:t,image:n}=(0,b.L)();return r.createElement(r.Fragment,null,r.createElement(m.Z,null,r.createElement("meta",{name:"twitter:card",content:"summary_large_image"}),r.createElement("body",{className:w.h})),n&&r.createElement(v.d,{image:n}),r.createElement(_,null),r.createElement(x,null),r.createElement(E.Z,{tag:k.HX,locale:e}),r.createElement(m.Z,null,t.map(((e,t)=>r.createElement("meta",(0,f.Z)({key:t},e))))))}const T=new Map;function A(e){if(T.has(e.pathname))return{...e,pathname:T.get(e.pathname)};if((0,d.f)(c.Z,e.pathname).some((e=>{let{route:t}=e;return!0===t.exact})))return T.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return T.set(e.pathname,t),{...e,pathname:t}}var L=n(8934),P=n(8940);function R(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r{const r=t.default?.[e]??t[e];return r?.(...n)}));return()=>a.forEach((e=>e?.()))}const N=function(e){let{children:t,location:n,previousLocation:a}=e;return(0,r.useLayoutEffect)((()=>{a!==n&&(!function(e){let{location:t,previousLocation:n}=e;if(!n)return;const r=t.pathname===n.pathname,a=t.hash===n.hash,o=t.search===n.search;if(r&&a&&!o)return;const{hash:i}=t;if(i){const e=decodeURIComponent(i.substring(1)),t=document.getElementById(e);t?.scrollIntoView()}else window.scrollTo(0,0)}({location:n,previousLocation:a}),R("onRouteDidUpdate",{previousLocation:a,location:n}))}),[a,n]),t};function O(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,d.f)(c.Z,e))).flat();return Promise.all(t.map((e=>e.route.component.preload?.())))}class I extends r.Component{previousLocation;routeUpdateCleanupCb;constructor(e){super(e),this.previousLocation=null,this.routeUpdateCleanupCb=l.Z.canUseDOM?R("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,t){if(e.location===this.props.location)return t.nextRouteHasLoaded;const n=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=R("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),O(n.pathname).then((()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})})).catch((e=>{console.warn(e),window.location.reload()})),!1}render(){const{children:e,location:t}=this.props;return r.createElement(N,{previousLocation:this.previousLocation,location:t},r.createElement(u.AW,{location:t,render:()=>e}))}}const D=I,M="__docusaurus-base-url-issue-banner-container",F="__docusaurus-base-url-issue-banner",B="__docusaurus-base-url-issue-banner-suggestion-container",j="__DOCUSAURUS_INSERT_BASEURL_BANNER";function z(e){return`\nwindow['${j}'] = true;\n\ndocument.addEventListener('DOMContentLoaded', maybeInsertBanner);\n\nfunction maybeInsertBanner() {\n var shouldInsert = window['${j}'];\n shouldInsert && insertBanner();\n}\n\nfunction insertBanner() {\n var bannerContainer = document.getElementById('${M}');\n if (!bannerContainer) {\n return;\n }\n var bannerHtml = ${JSON.stringify(function(e){return`\n
\n

Your Docusaurus site did not load properly.

\n

A very common reason is a wrong site baseUrl configuration.

\n

Current configured baseUrl = ${e} ${"/"===e?" (default value)":""}

\n

We suggest trying baseUrl =

\n
\n`}(e)).replace(/{window[j]=!1}),[]),r.createElement(r.Fragment,null,!l.Z.canUseDOM&&r.createElement(m.Z,null,r.createElement("script",null,z(e))),r.createElement("div",{id:M}))}function V(){const{siteConfig:{baseUrl:e,baseUrlIssueBanner:t}}=(0,h.Z)(),{pathname:n}=(0,u.TH)();return t&&n===e?r.createElement(U,null):null}function $(){const{siteConfig:{favicon:e,title:t,noIndex:n},i18n:{currentLocale:a,localeConfigs:o}}=(0,h.Z)(),i=(0,g.Z)(e),{htmlLang:l,direction:s}=o[a];return r.createElement(m.Z,null,r.createElement("html",{lang:l,dir:s}),r.createElement("title",null,t),r.createElement("meta",{property:"og:title",content:t}),r.createElement("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"}),n&&r.createElement("meta",{name:"robots",content:"noindex, nofollow"}),e&&r.createElement("link",{rel:"icon",href:i}))}var H=n(4763),G=n(2389);function q(){const e=(0,G.Z)();return r.createElement(m.Z,null,r.createElement("html",{"data-has-hydrated":e}))}function Z(){const e=(0,d.H)(c.Z),t=(0,u.TH)();return r.createElement(H.Z,null,r.createElement(P.M,null,r.createElement(L.t,null,r.createElement(p,null,r.createElement($,null),r.createElement(C,null),r.createElement(V,null),r.createElement(D,{location:A(t)},e)),r.createElement(q,null))))}var W=n(6887);const Y=function(e){try{return document.createElement("link").relList.supports(e)}catch{return!1}}("prefetch")?function(e){return new Promise(((t,n)=>{if("undefined"==typeof document)return void n();const r=document.createElement("link");r.setAttribute("rel","prefetch"),r.setAttribute("href",e),r.onload=()=>t(),r.onerror=()=>n();const a=document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode;a?.appendChild(r)}))}:function(e){return new Promise(((t,n)=>{const r=new XMLHttpRequest;r.open("GET",e,!0),r.withCredentials=!0,r.onload=()=>{200===r.status?t():n()},r.send(null)}))};var K=n(9670);const X=new Set,Q=new Set,J=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,ee={prefetch(e){if(!(e=>!J()&&!Q.has(e)&&!X.has(e))(e))return!1;X.add(e);const t=(0,d.f)(c.Z,e).flatMap((e=>{return t=e.route.path,Object.entries(W).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,K.Z)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?Y(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!J()&&!Q.has(e))(e)&&(Q.add(e),O(e))},te=Object.freeze(ee);if(l.Z.canUseDOM){window.docusaurus=te;const e=a.hydrate;O(window.location.pathname).then((()=>{e(r.createElement(i.B6,null,r.createElement(o.VK,null,r.createElement(Z,null))),document.getElementById("__docusaurus"))}))}},8940:(e,t,n)=>{"use strict";n.d(t,{_:()=>u,M:()=>d});var r=n(7294),a=n(6809);const o=JSON.parse('{"docusaurus-plugin-content-docs":{"default":{"path":"/docs","versions":[{"name":"current","label":"Next","isLast":true,"path":"/docs","mainDocId":"introduction/prologue","docs":[{"id":"audio/AAC","path":"/docs/audio/AAC","sidebar":"tutorialSidebar"},{"id":"audio/Dolby","path":"/docs/audio/Dolby","sidebar":"tutorialSidebar"},{"id":"audio/FLAC","path":"/docs/audio/FLAC","sidebar":"tutorialSidebar"},{"id":"audio/MP3","path":"/docs/audio/MP3","sidebar":"tutorialSidebar"},{"id":"audio/Opus","path":"/docs/audio/Opus","sidebar":"tutorialSidebar"},{"id":"audio/Speex","path":"/docs/audio/Speex","sidebar":"tutorialSidebar"},{"id":"audio/Vorbis","path":"/docs/audio/Vorbis","sidebar":"tutorialSidebar"},{"id":"audio/WavPack","path":"/docs/audio/WavPack","sidebar":"tutorialSidebar"},{"id":"contribution-guide","path":"/docs/contribution-guide","sidebar":"tutorialSidebar"},{"id":"data/7z","path":"/docs/data/7z","sidebar":"tutorialSidebar"},{"id":"data/brotli","path":"/docs/data/brotli","sidebar":"tutorialSidebar"},{"id":"data/bzip2","path":"/docs/data/bzip2","sidebar":"tutorialSidebar"},{"id":"data/gzip","path":"/docs/data/gzip","sidebar":"tutorialSidebar"},{"id":"data/xz","path":"/docs/data/xz","sidebar":"tutorialSidebar"},{"id":"data/zip","path":"/docs/data/zip","sidebar":"tutorialSidebar"},{"id":"data/zpaq","path":"/docs/data/zpaq","sidebar":"tutorialSidebar"},{"id":"data/zstd","path":"/docs/data/zstd","sidebar":"tutorialSidebar"},{"id":"encoders/aomenc","path":"/docs/encoders/aomenc","sidebar":"tutorialSidebar"},{"id":"encoders/Aurora1","path":"/docs/encoders/Aurora1","sidebar":"tutorialSidebar"},{"id":"encoders/AVM","path":"/docs/encoders/AVM","sidebar":"tutorialSidebar"},{"id":"encoders/HM","path":"/docs/encoders/HM","sidebar":"tutorialSidebar"},{"id":"encoders/JM","path":"/docs/encoders/JM","sidebar":"tutorialSidebar"},{"id":"encoders/Kvazaar","path":"/docs/encoders/Kvazaar","sidebar":"tutorialSidebar"},{"id":"encoders/rav1e","path":"/docs/encoders/rav1e","sidebar":"tutorialSidebar"},{"id":"encoders/SVT-AV1","path":"/docs/encoders/SVT-AV1","sidebar":"tutorialSidebar"},{"id":"encoders/SVT-HEVC","path":"/docs/encoders/SVT-HEVC","sidebar":"tutorialSidebar"},{"id":"encoders/SVT-VP9","path":"/docs/encoders/SVT-VP9","sidebar":"tutorialSidebar"},{"id":"encoders/uvg266","path":"/docs/encoders/uvg266","sidebar":"tutorialSidebar"},{"id":"encoders/vpxenc","path":"/docs/encoders/vpxenc","sidebar":"tutorialSidebar"},{"id":"encoders/VTM","path":"/docs/encoders/VTM","sidebar":"tutorialSidebar"},{"id":"encoders/VVenC","path":"/docs/encoders/VVenC","sidebar":"tutorialSidebar"},{"id":"encoders/x264","path":"/docs/encoders/x264","sidebar":"tutorialSidebar"},{"id":"encoders/x265","path":"/docs/encoders/x265","sidebar":"tutorialSidebar"},{"id":"FAQ","path":"/docs/FAQ","sidebar":"tutorialSidebar"},{"id":"filtering/deband","path":"/docs/filtering/deband","sidebar":"tutorialSidebar"},{"id":"filtering/dehalo","path":"/docs/filtering/dehalo","sidebar":"tutorialSidebar"},{"id":"filtering/deinterlace","path":"/docs/filtering/deinterlace","sidebar":"tutorialSidebar"},{"id":"filtering/denoise","path":"/docs/filtering/denoise","sidebar":"tutorialSidebar"},{"id":"filtering/detelecine","path":"/docs/filtering/detelecine","sidebar":"tutorialSidebar"},{"id":"filtering/intro","path":"/docs/filtering/intro","sidebar":"tutorialSidebar"},{"id":"filtering/vapoursynth","path":"/docs/filtering/vapoursynth","sidebar":"tutorialSidebar"},{"id":"images/AVIF","path":"/docs/images/AVIF","sidebar":"tutorialSidebar"},{"id":"images/GIF","path":"/docs/images/GIF","sidebar":"tutorialSidebar"},{"id":"images/HEIC","path":"/docs/images/HEIC","sidebar":"tutorialSidebar"},{"id":"images/JPEG","path":"/docs/images/JPEG","sidebar":"tutorialSidebar"},{"id":"images/JPEG2000","path":"/docs/images/JPEG2000","sidebar":"tutorialSidebar"},{"id":"images/JXL","path":"/docs/images/JXL","sidebar":"tutorialSidebar"},{"id":"images/PNG","path":"/docs/images/PNG","sidebar":"tutorialSidebar"},{"id":"images/WebP","path":"/docs/images/WebP","sidebar":"tutorialSidebar"},{"id":"introduction/high-dynamic-range","path":"/docs/introduction/high-dynamic-range","sidebar":"tutorialSidebar"},{"id":"introduction/prologue","path":"/docs/introduction/prologue","sidebar":"tutorialSidebar"},{"id":"introduction/psychovisual","path":"/docs/introduction/psychovisual","sidebar":"tutorialSidebar"},{"id":"introduction/terminology","path":"/docs/introduction/terminology","sidebar":"tutorialSidebar"},{"id":"introduction/video-artifacts","path":"/docs/introduction/video-artifacts","sidebar":"tutorialSidebar"},{"id":"metrics/butteraugli","path":"/docs/metrics/butteraugli","sidebar":"tutorialSidebar"},{"id":"metrics/PSNR","path":"/docs/metrics/PSNR","sidebar":"tutorialSidebar"},{"id":"metrics/SSIM","path":"/docs/metrics/SSIM","sidebar":"tutorialSidebar"},{"id":"metrics/SSIMULACRA2","path":"/docs/metrics/SSIMULACRA2","sidebar":"tutorialSidebar"},{"id":"metrics/VMAF","path":"/docs/metrics/VMAF","sidebar":"tutorialSidebar"},{"id":"privacy-policy","path":"/docs/privacy-policy","sidebar":"tutorialSidebar"},{"id":"resources","path":"/docs/resources","sidebar":"tutorialSidebar"},{"id":"subtitles/SRT","path":"/docs/subtitles/SRT","sidebar":"tutorialSidebar"},{"id":"subtitles/webvtt","path":"/docs/subtitles/webvtt","sidebar":"tutorialSidebar"},{"id":"terms-of-use","path":"/docs/terms-of-use","sidebar":"tutorialSidebar"},{"id":"utilities/av1an","path":"/docs/utilities/av1an","sidebar":"tutorialSidebar"},{"id":"utilities/Aviator","path":"/docs/utilities/Aviator","sidebar":"tutorialSidebar"},{"id":"utilities/dovi_tool","path":"/docs/utilities/dovi_tool","sidebar":"tutorialSidebar"},{"id":"utilities/eac3to","path":"/docs/utilities/eac3to","sidebar":"tutorialSidebar"},{"id":"utilities/FFMetrics","path":"/docs/utilities/FFMetrics","sidebar":"tutorialSidebar"},{"id":"utilities/ffmpeg","path":"/docs/utilities/ffmpeg","sidebar":"tutorialSidebar"},{"id":"utilities/hdr10plus_tool","path":"/docs/utilities/hdr10plus_tool","sidebar":"tutorialSidebar"},{"id":"utilities/MKVToolNix","path":"/docs/utilities/MKVToolNix","sidebar":"tutorialSidebar"},{"id":"utilities/mp4box","path":"/docs/utilities/mp4box","sidebar":"tutorialSidebar"},{"id":"utilities/nmkoder","path":"/docs/utilities/nmkoder","sidebar":"tutorialSidebar"},{"id":"utilities/rAV1ator","path":"/docs/utilities/rAV1ator","sidebar":"tutorialSidebar"},{"id":"utilities/rav1ator-cli","path":"/docs/utilities/rav1ator-cli","sidebar":"tutorialSidebar"},{"id":"utilities/YUView","path":"/docs/utilities/YUView","sidebar":"tutorialSidebar"},{"id":"video-players","path":"/docs/video-players","sidebar":"tutorialSidebar"},{"id":"video/AV1","path":"/docs/video/AV1","sidebar":"tutorialSidebar"},{"id":"video/AVC","path":"/docs/video/AVC","sidebar":"tutorialSidebar"},{"id":"video/AVS3","path":"/docs/video/AVS3","sidebar":"tutorialSidebar"},{"id":"video/FFV1","path":"/docs/video/FFV1","sidebar":"tutorialSidebar"},{"id":"video/HEVC","path":"/docs/video/HEVC","sidebar":"tutorialSidebar"},{"id":"video/prores","path":"/docs/video/prores","sidebar":"tutorialSidebar"},{"id":"video/Theora","path":"/docs/video/Theora","sidebar":"tutorialSidebar"},{"id":"video/utvideo","path":"/docs/video/utvideo","sidebar":"tutorialSidebar"},{"id":"video/VC-1","path":"/docs/video/VC-1","sidebar":"tutorialSidebar"},{"id":"video/VP8","path":"/docs/video/VP8","sidebar":"tutorialSidebar"},{"id":"video/VP9","path":"/docs/video/VP9","sidebar":"tutorialSidebar"},{"id":"video/VVC","path":"/docs/video/VVC","sidebar":"tutorialSidebar"}],"draftIds":[],"sidebars":{"tutorialSidebar":{"link":{"path":"/docs/introduction/prologue","label":"introduction/prologue"}}}}],"breadcrumbs":true}}}'),i=JSON.parse('{"defaultLocale":"en","locales":["en"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"}}}');var l=n(7529);const s=JSON.parse('{"docusaurusVersion":"2.4.3","siteVersion":"0.0.0","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"2.4.3"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"2.4.3"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"2.4.3"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"2.4.3"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"2.4.3"}}}'),c={siteConfig:a.default,siteMetadata:s,globalData:o,i18n:i,codeTranslations:l},u=r.createContext(c);function d(e){let{children:t}=e;return r.createElement(u.Provider,{value:c},t)}},4763:(e,t,n)=>{"use strict";n.d(t,{Z:()=>p});var r=n(7294),a=n(412),o=n(5742),i=n(8780),l=n(7961);function s(e){let{error:t,tryAgain:n}=e;return r.createElement("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"}},r.createElement("h1",{style:{fontSize:"3rem"}},"This page crashed"),r.createElement("button",{type:"button",onClick:n,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"}},"Try again"),r.createElement(c,{error:t}))}function c(e){let{error:t}=e;const n=(0,i.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return r.createElement("p",{style:{whiteSpace:"pre-wrap"}},n)}function u(e){let{error:t,tryAgain:n}=e;return r.createElement(p,{fallback:()=>r.createElement(s,{error:t,tryAgain:n})},r.createElement(o.Z,null,r.createElement("title",null,"Page Error")),r.createElement(l.Z,null,r.createElement(s,{error:t,tryAgain:n})))}const d=e=>r.createElement(u,e);class p extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){a.Z.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:t}=this.state;if(t){const e={error:t,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??d)(e)}return e??null}}},412:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,a={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},5742:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(405);function o(e){return r.createElement(a.ql,e)}},9960:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(7462),a=n(7294),o=n(3727),i=n(8780),l=n(2263),s=n(3919),c=n(412);const u=a.createContext({collectLink:()=>{}});var d=n(4996);function p(e,t){let{isNavLink:n,to:p,href:f,activeClassName:m,isActive:h,"data-noBrokenLinkCheck":g,autoAddBaseUrl:b=!0,...v}=e;const{siteConfig:{trailingSlash:y,baseUrl:w}}=(0,l.Z)(),{withBaseUrl:k}=(0,d.C)(),S=(0,a.useContext)(u),E=(0,a.useRef)(null);(0,a.useImperativeHandle)(t,(()=>E.current));const x=p||f;const _=(0,s.Z)(x),C=x?.replace("pathname://","");let T=void 0!==C?(A=C,b&&(e=>e.startsWith("/"))(A)?k(A):A):void 0;var A;T&&_&&(T=(0,i.applyTrailingSlash)(T,{trailingSlash:y,baseUrl:w}));const L=(0,a.useRef)(!1),P=n?o.OL:o.rU,R=c.Z.canUseIntersectionObserver,N=(0,a.useRef)(),O=()=>{L.current||null==T||(window.docusaurus.preload(T),L.current=!0)};(0,a.useEffect)((()=>(!R&&_&&null!=T&&window.docusaurus.prefetch(T),()=>{R&&N.current&&N.current.disconnect()})),[N,T,R,_]);const I=T?.startsWith("#")??!1,D=!T||!_||I;return D||g||S.collectLink(T),D?a.createElement("a",(0,r.Z)({ref:E,href:T},x&&!_&&{target:"_blank",rel:"noopener noreferrer"},v)):a.createElement(P,(0,r.Z)({},v,{onMouseEnter:O,onTouchStart:O,innerRef:e=>{E.current=e,R&&e&&_&&(N.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(N.current.unobserve(e),N.current.disconnect(),null!=T&&window.docusaurus.prefetch(T))}))})),N.current.observe(e))},to:T},n&&{isActive:h,activeClassName:m}))}const f=a.forwardRef(p)},1875:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r=()=>null},5999:(e,t,n)=>{"use strict";n.d(t,{Z:()=>s,I:()=>l});var r=n(7294);function a(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e}));return n.some((e=>(0,r.isValidElement)(e)))?n.map(((e,t)=>(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e)).filter((e=>""!==e)):n.join("")}var o=n(7529);function i(e){let{id:t,message:n}=e;if(void 0===t&&void 0===n)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return o[t??n]??n??t}function l(e,t){let{message:n,id:r}=e;return a(i({message:n,id:r}),t)}function s(e){let{children:t,id:n,values:o}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal children",t),new Error("The Docusaurus component only accept simple string values");const l=i({message:t,id:n});return r.createElement(r.Fragment,null,a(l,o))}},9935:(e,t,n)=>{"use strict";n.d(t,{m:()=>r});const r="default"},3919:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function a(e){return void 0!==e&&!r(e)}n.d(t,{Z:()=>a,b:()=>r})},4996:(e,t,n)=>{"use strict";n.d(t,{C:()=>i,Z:()=>l});var r=n(7294),a=n(2263),o=n(3919);function i(){const{siteConfig:{baseUrl:e,url:t}}=(0,a.Z)(),n=(0,r.useCallback)(((n,r)=>function(e,t,n,r){let{forcePrependBaseUrl:a=!1,absolute:i=!1}=void 0===r?{}:r;if(!n||n.startsWith("#")||(0,o.b)(n))return n;if(a)return t+n.replace(/^\//,"");if(n===t.replace(/\/$/,""))return t;const l=n.startsWith(t)?n:t+n.replace(/^\//,"");return i?e+l:l}(t,e,n,r)),[t,e]);return{withBaseUrl:n}}function l(e,t){void 0===t&&(t={});const{withBaseUrl:n}=i();return n(e,t)}},2263:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(8940);function o(){return(0,r.useContext)(a._)}},2389:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(8934);function o(){return(0,r.useContext)(a._)}},9670:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});const r=e=>"object"==typeof e&&!!e&&Object.keys(e).length>0;function a(e){const t={};return function e(n,a){Object.entries(n).forEach((n=>{let[o,i]=n;const l=a?`${a}.${o}`:o;r(i)?e(i,l):t[l]=i}))}(e),t}},226:(e,t,n)=>{"use strict";n.d(t,{_:()=>a,z:()=>o});var r=n(7294);const a=r.createContext(null);function o(e){let{children:t,value:n}=e;const o=r.useContext(a),i=(0,r.useMemo)((()=>function(e){let{parent:t,value:n}=e;if(!t){if(!n)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in n))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return n}const r={...t.data,...n?.data};return{plugin:t.plugin,data:r}}({parent:o,value:n})),[o,n]);return r.createElement(a.Provider,{value:i},t)}},143:(e,t,n)=>{"use strict";n.d(t,{Iw:()=>h,gA:()=>p,_r:()=>u,Jo:()=>g,zh:()=>d,yW:()=>m,gB:()=>f});var r=n(6550),a=n(2263),o=n(9935);function i(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,a.Z)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}const l=e=>e.versions.find((e=>e.isLast));function s(e,t){const n=function(e,t){const n=l(e);return[...e.versions.filter((e=>e!==n)),n].find((e=>!!(0,r.LX)(t,{path:e.path,exact:!1,strict:!1})))}(e,t),a=n?.docs.find((e=>!!(0,r.LX)(t,{path:e.path,exact:!0,strict:!1})));return{activeVersion:n,activeDoc:a,alternateDocVersions:a?function(t){const n={};return e.versions.forEach((e=>{e.docs.forEach((r=>{r.id===t&&(n[e.name]=r)}))})),n}(a.id):{}}}const c={},u=()=>i("docusaurus-plugin-content-docs")??c,d=e=>function(e,t,n){void 0===t&&(t=o.m),void 0===n&&(n={});const r=i(e),a=r?.[t];if(!a&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return a}("docusaurus-plugin-content-docs",e,{failfast:!0});function p(e){void 0===e&&(e={});const t=u(),{pathname:n}=(0,r.TH)();return function(e,t,n){void 0===n&&(n={});const a=Object.entries(e).sort(((e,t)=>t[1].path.localeCompare(e[1].path))).find((e=>{let[,n]=e;return!!(0,r.LX)(t,{path:n.path,exact:!1,strict:!1})})),o=a?{pluginId:a[0],pluginData:a[1]}:void 0;if(!o&&n.failfast)throw new Error(`Can't find active docs plugin for "${t}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(e).map((e=>e.path)).join(", ")}`);return o}(t,n,e)}function f(e){return d(e).versions}function m(e){const t=d(e);return l(t)}function h(e){const t=d(e),{pathname:n}=(0,r.TH)();return s(t,n)}function g(e){const t=d(e),{pathname:n}=(0,r.TH)();return function(e,t){const n=l(e);return{latestDocSuggestion:s(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},8320:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(4865),a=n.n(r);a().configure({showSpinner:!1});const o={onRouteUpdate(e){let{location:t,previousLocation:n}=e;if(n&&t.pathname!==n.pathname){const e=window.setTimeout((()=>{a().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){a().done()}}},3310:(e,t,n)=>{"use strict";n.r(t);var r=n(7410),a=n(6809);!function(e){const{themeConfig:{prism:t}}=a.default,{additionalLanguages:r}=t;globalThis.Prism=e,r.forEach((e=>{n(6726)(`./prism-${e}`)})),delete globalThis.Prism}(r.Z)},9471:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294);const a={iconExternalLink:"iconExternalLink_nPIU"};function o(e){let{width:t=13.5,height:n=13.5}=e;return r.createElement("svg",{width:t,height:n,"aria-hidden":"true",viewBox:"0 0 24 24",className:a.iconExternalLink},r.createElement("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"}))}},7961:(e,t,n)=>{"use strict";n.d(t,{Z:()=>dt});var r=n(7294),a=n(6010),o=n(4763),i=n(1944),l=n(7462),s=n(6550),c=n(5999),u=n(5936);const d="__docusaurus_skipToContent_fallback";function p(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function f(){const e=(0,r.useRef)(null),{action:t}=(0,s.k6)(),n=(0,r.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(d);t&&p(t)}),[]);return(0,u.S)((n=>{let{location:r}=n;e.current&&!r.hash&&"PUSH"===t&&p(e.current)})),{containerRef:e,onClick:n}}const m=(0,c.I)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function h(e){const t=e.children??m,{containerRef:n,onClick:a}=f();return r.createElement("div",{ref:n,role:"region","aria-label":m},r.createElement("a",(0,l.Z)({},e,{href:`#${d}`,onClick:a}),t))}var g=n(5281),b=n(9727);const v={skipToContent:"skipToContent_fXgn"};function y(){return r.createElement(h,{className:v.skipToContent})}var w=n(6668),k=n(9689);function S(e){let{width:t=21,height:n=21,color:a="currentColor",strokeWidth:o=1.2,className:i,...s}=e;return r.createElement("svg",(0,l.Z)({viewBox:"0 0 15 15",width:t,height:n},s),r.createElement("g",{stroke:a,strokeWidth:o},r.createElement("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})))}const E={closeButton:"closeButton_CVFx"};function x(e){return r.createElement("button",(0,l.Z)({type:"button","aria-label":(0,c.I)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"})},e,{className:(0,a.Z)("clean-btn close",E.closeButton,e.className)}),r.createElement(S,{width:14,height:14,strokeWidth:3.1}))}const _={content:"content_knG7"};function C(e){const{announcementBar:t}=(0,w.L)(),{content:n}=t;return r.createElement("div",(0,l.Z)({},e,{className:(0,a.Z)(_.content,e.className),dangerouslySetInnerHTML:{__html:n}}))}const T={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function A(){const{announcementBar:e}=(0,w.L)(),{isActive:t,close:n}=(0,k.nT)();if(!t)return null;const{backgroundColor:a,textColor:o,isCloseable:i}=e;return r.createElement("div",{className:T.announcementBar,style:{backgroundColor:a,color:o},role:"banner"},i&&r.createElement("div",{className:T.announcementBarPlaceholder}),r.createElement(C,{className:T.announcementBarContent}),i&&r.createElement(x,{onClick:n,className:T.announcementBarClose}))}var L=n(3163),P=n(2466);var R=n(902),N=n(3102);const O=r.createContext(null);function I(e){let{children:t}=e;const n=function(){const e=(0,L.e)(),t=(0,N.HY)(),[n,a]=(0,r.useState)(!1),o=null!==t.component,i=(0,R.D9)(o);return(0,r.useEffect)((()=>{o&&!i&&a(!0)}),[o,i]),(0,r.useEffect)((()=>{o?e.shown||a(!0):a(!1)}),[e.shown,o]),(0,r.useMemo)((()=>[n,a]),[n])}();return r.createElement(O.Provider,{value:n},t)}function D(e){if(e.component){const t=e.component;return r.createElement(t,e.props)}}function M(){const e=(0,r.useContext)(O);if(!e)throw new R.i6("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,a=(0,r.useCallback)((()=>n(!1)),[n]),o=(0,N.HY)();return(0,r.useMemo)((()=>({shown:t,hide:a,content:D(o)})),[a,o,t])}function F(e){let{header:t,primaryMenu:n,secondaryMenu:o}=e;const{shown:i}=M();return r.createElement("div",{className:"navbar-sidebar"},t,r.createElement("div",{className:(0,a.Z)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":i})},r.createElement("div",{className:"navbar-sidebar__item menu"},n),r.createElement("div",{className:"navbar-sidebar__item menu"},o)))}var B=n(2949),j=n(2389);function z(e){return r.createElement("svg",(0,l.Z)({viewBox:"0 0 24 24",width:24,height:24},e),r.createElement("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"}))}function U(e){return r.createElement("svg",(0,l.Z)({viewBox:"0 0 24 24",width:24,height:24},e),r.createElement("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"}))}const V={toggle:"toggle_vylO",toggleButton:"toggleButton_gllP",darkToggleIcon:"darkToggleIcon_wfgR",lightToggleIcon:"lightToggleIcon_pyhR",toggleButtonDisabled:"toggleButtonDisabled_aARS"};function $(e){let{className:t,buttonClassName:n,value:o,onChange:i}=e;const l=(0,j.Z)(),s=(0,c.I)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===o?(0,c.I)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,c.I)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return r.createElement("div",{className:(0,a.Z)(V.toggle,t)},r.createElement("button",{className:(0,a.Z)("clean-btn",V.toggleButton,!l&&V.toggleButtonDisabled,n),type:"button",onClick:()=>i("dark"===o?"light":"dark"),disabled:!l,title:s,"aria-label":s,"aria-live":"polite"},r.createElement(z,{className:(0,a.Z)(V.toggleIcon,V.lightToggleIcon)}),r.createElement(U,{className:(0,a.Z)(V.toggleIcon,V.darkToggleIcon)})))}const H=r.memo($),G={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_X3D1"};function q(e){let{className:t}=e;const n=(0,w.L)().navbar.style,a=(0,w.L)().colorMode.disableSwitch,{colorMode:o,setColorMode:i}=(0,B.I)();return a?null:r.createElement(H,{className:t,buttonClassName:"dark"===n?G.darkNavbarColorModeToggle:void 0,value:o,onChange:i})}var Z=n(1327);function W(){return r.createElement(Z.Z,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function Y(){const e=(0,L.e)();return r.createElement("button",{type:"button","aria-label":(0,c.I)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle()},r.createElement(S,{color:"var(--ifm-color-emphasis-600)"}))}function K(){return r.createElement("div",{className:"navbar-sidebar__brand"},r.createElement(W,null),r.createElement(q,{className:"margin-right--md"}),r.createElement(Y,null))}var X=n(9960),Q=n(4996),J=n(3919);function ee(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}var te=n(9471);function ne(e){let{activeBasePath:t,activeBaseRegex:n,to:a,href:o,label:i,html:s,isDropdownLink:c,prependBaseUrlToHref:u,...d}=e;const p=(0,Q.Z)(a),f=(0,Q.Z)(t),m=(0,Q.Z)(o,{forcePrependBaseUrl:!0}),h=i&&o&&!(0,J.Z)(o),g=s?{dangerouslySetInnerHTML:{__html:s}}:{children:r.createElement(r.Fragment,null,i,h&&r.createElement(te.Z,c&&{width:12,height:12}))};return o?r.createElement(X.Z,(0,l.Z)({href:u?m:o},d,g)):r.createElement(X.Z,(0,l.Z)({to:p,isNavLink:!0},(t||n)&&{isActive:(e,t)=>n?ee(n,t.pathname):t.pathname.startsWith(f)},d,g))}function re(e){let{className:t,isDropdownItem:n=!1,...o}=e;const i=r.createElement(ne,(0,l.Z)({className:(0,a.Z)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n},o));return n?r.createElement("li",null,i):i}function ae(e){let{className:t,isDropdownItem:n,...o}=e;return r.createElement("li",{className:"menu__list-item"},r.createElement(ne,(0,l.Z)({className:(0,a.Z)("menu__link",t)},o)))}function oe(e){let{mobile:t=!1,position:n,...a}=e;const o=t?ae:re;return r.createElement(o,(0,l.Z)({},a,{activeClassName:a.activeClassName??(t?"menu__link--active":"navbar__link--active")}))}var ie=n(6043),le=n(8596),se=n(2263);function ce(e,t){return e.some((e=>function(e,t){return!!(0,le.Mg)(e.to,t)||!!ee(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function ue(e){let{items:t,position:n,className:o,onClick:i,...s}=e;const c=(0,r.useRef)(null),[u,d]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{const e=e=>{c.current&&!c.current.contains(e.target)&&d(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}}),[c]),r.createElement("div",{ref:c,className:(0,a.Z)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":u})},r.createElement(ne,(0,l.Z)({"aria-haspopup":"true","aria-expanded":u,role:"button",href:s.to?void 0:"#",className:(0,a.Z)("navbar__link",o)},s,{onClick:s.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),d(!u))}}),s.children??s.label),r.createElement("ul",{className:"dropdown__menu"},t.map(((e,t)=>r.createElement(xe,(0,l.Z)({isDropdownItem:!0,activeClassName:"dropdown__link--active"},e,{key:t}))))))}function de(e){let{items:t,className:n,position:o,onClick:i,...c}=e;const u=function(){const{siteConfig:{baseUrl:e}}=(0,se.Z)(),{pathname:t}=(0,s.TH)();return t.replace(e,"/")}(),d=ce(t,u),{collapsed:p,toggleCollapsed:f,setCollapsed:m}=(0,ie.u)({initialState:()=>!d});return(0,r.useEffect)((()=>{d&&m(!d)}),[u,d,m]),r.createElement("li",{className:(0,a.Z)("menu__list-item",{"menu__list-item--collapsed":p})},r.createElement(ne,(0,l.Z)({role:"button",className:(0,a.Z)("menu__link menu__link--sublist menu__link--sublist-caret",n)},c,{onClick:e=>{e.preventDefault(),f()}}),c.children??c.label),r.createElement(ie.z,{lazy:!0,as:"ul",className:"menu__list",collapsed:p},t.map(((e,t)=>r.createElement(xe,(0,l.Z)({mobile:!0,isDropdownItem:!0,onClick:i,activeClassName:"menu__link--active"},e,{key:t}))))))}function pe(e){let{mobile:t=!1,...n}=e;const a=t?de:ue;return r.createElement(a,n)}var fe=n(4711);function me(e){let{width:t=20,height:n=20,...a}=e;return r.createElement("svg",(0,l.Z)({viewBox:"0 0 24 24",width:t,height:n,"aria-hidden":!0},a),r.createElement("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"}))}const he="iconLanguage_nlXk";var ge=n(1875);const be={searchBox:"searchBox_ZlJk"};function ve(e){let{children:t,className:n}=e;return r.createElement("div",{className:(0,a.Z)(n,be.searchBox)},t)}var ye=n(143),we=n(3438);var ke=n(373);const Se=e=>e.docs.find((t=>t.id===e.mainDocId));const Ee={default:oe,localeDropdown:function(e){let{mobile:t,dropdownItemsBefore:n,dropdownItemsAfter:a,...o}=e;const{i18n:{currentLocale:i,locales:u,localeConfigs:d}}=(0,se.Z)(),p=(0,fe.l)(),{search:f,hash:m}=(0,s.TH)(),h=[...n,...u.map((e=>{const n=`${`pathname://${p.createUrl({locale:e,fullyQualified:!1})}`}${f}${m}`;return{label:d[e].label,lang:d[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===i?t?"menu__link--active":"dropdown__link--active":""}})),...a],g=t?(0,c.I)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):d[i].label;return r.createElement(pe,(0,l.Z)({},o,{mobile:t,label:r.createElement(r.Fragment,null,r.createElement(me,{className:he}),g),items:h}))},search:function(e){let{mobile:t,className:n}=e;return t?null:r.createElement(ve,{className:n},r.createElement(ge.Z,null))},dropdown:pe,html:function(e){let{value:t,className:n,mobile:o=!1,isDropdownItem:i=!1}=e;const l=i?"li":"div";return r.createElement(l,{className:(0,a.Z)({navbar__item:!o&&!i,"menu__list-item":o},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){let{docId:t,label:n,docsPluginId:a,...o}=e;const{activeDoc:i}=(0,ye.Iw)(a),s=(0,we.vY)(t,a);return null===s?null:r.createElement(oe,(0,l.Z)({exact:!0},o,{isActive:()=>i?.path===s.path||!!i?.sidebar&&i.sidebar===s.sidebar,label:n??s.id,to:s.path}))},docSidebar:function(e){let{sidebarId:t,label:n,docsPluginId:a,...o}=e;const{activeDoc:i}=(0,ye.Iw)(a),s=(0,we.oz)(t,a).link;if(!s)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return r.createElement(oe,(0,l.Z)({exact:!0},o,{isActive:()=>i?.sidebar===t,label:n??s.label,to:s.path}))},docsVersion:function(e){let{label:t,to:n,docsPluginId:a,...o}=e;const i=(0,we.lO)(a)[0],s=t??i.label,c=n??(e=>e.docs.find((t=>t.id===e.mainDocId)))(i).path;return r.createElement(oe,(0,l.Z)({},o,{label:s,to:c}))},docsVersionDropdown:function(e){let{mobile:t,docsPluginId:n,dropdownActiveClassDisabled:a,dropdownItemsBefore:o,dropdownItemsAfter:i,...u}=e;const{search:d,hash:p}=(0,s.TH)(),f=(0,ye.Iw)(n),m=(0,ye.gB)(n),{savePreferredVersionName:h}=(0,ke.J)(n),g=[...o,...m.map((e=>{const t=f.alternateDocVersions[e.name]??Se(e);return{label:e.label,to:`${t.path}${d}${p}`,isActive:()=>e===f.activeVersion,onClick:()=>h(e.name)}})),...i],b=(0,we.lO)(n)[0],v=t&&g.length>1?(0,c.I)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):b.label,y=t&&g.length>1?void 0:Se(b).path;return g.length<=1?r.createElement(oe,(0,l.Z)({},u,{mobile:t,label:v,to:y,isActive:a?()=>!1:void 0})):r.createElement(pe,(0,l.Z)({},u,{mobile:t,label:v,to:y,items:g,isActive:a?()=>!1:void 0}))}};function xe(e){let{type:t,...n}=e;const a=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),o=Ee[a];if(!o)throw new Error(`No NavbarItem component found for type "${t}".`);return r.createElement(o,n)}function _e(){const e=(0,L.e)(),t=(0,w.L)().navbar.items;return r.createElement("ul",{className:"menu__list"},t.map(((t,n)=>r.createElement(xe,(0,l.Z)({mobile:!0},t,{onClick:()=>e.toggle(),key:n})))))}function Ce(e){return r.createElement("button",(0,l.Z)({},e,{type:"button",className:"clean-btn navbar-sidebar__back"}),r.createElement(c.Z,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)"},"\u2190 Back to main menu"))}function Te(){const e=0===(0,w.L)().navbar.items.length,t=M();return r.createElement(r.Fragment,null,!e&&r.createElement(Ce,{onClick:()=>t.hide()}),t.content)}function Ae(){const e=(0,L.e)();var t;return void 0===(t=e.shown)&&(t=!0),(0,r.useEffect)((()=>(document.body.style.overflow=t?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[t]),e.shouldRender?r.createElement(F,{header:r.createElement(K,null),primaryMenu:r.createElement(_e,null),secondaryMenu:r.createElement(Te,null)}):null}const Le={navbarHideable:"navbarHideable_m1mJ",navbarHidden:"navbarHidden_jGov"};function Pe(e){return r.createElement("div",(0,l.Z)({role:"presentation"},e,{className:(0,a.Z)("navbar-sidebar__backdrop",e.className)}))}function Re(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:o}}=(0,w.L)(),i=(0,L.e)(),{navbarRef:l,isNavbarVisible:s}=function(e){const[t,n]=(0,r.useState)(e),a=(0,r.useRef)(!1),o=(0,r.useRef)(0),i=(0,r.useCallback)((e=>{null!==e&&(o.current=e.getBoundingClientRect().height)}),[]);return(0,P.RF)(((t,r)=>{let{scrollY:i}=t;if(!e)return;if(i=l?n(!1):i+c{if(!e)return;const r=t.location.hash;if(r?document.getElementById(r.substring(1)):void 0)return a.current=!0,void n(!1);n(!0)})),{navbarRef:i,isNavbarVisible:t}}(n);return r.createElement("nav",{ref:l,"aria-label":(0,c.I)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,a.Z)("navbar","navbar--fixed-top",n&&[Le.navbarHideable,!s&&Le.navbarHidden],{"navbar--dark":"dark"===o,"navbar--primary":"primary"===o,"navbar-sidebar--show":i.shown})},t,r.createElement(Pe,{onClick:i.toggle}),r.createElement(Ae,null))}var Ne=n(8780);const Oe={errorBoundaryError:"errorBoundaryError_a6uf"};function Ie(e){return r.createElement("button",(0,l.Z)({type:"button"},e),r.createElement(c.Z,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error"},"Try again"))}function De(e){let{error:t}=e;const n=(0,Ne.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return r.createElement("p",{className:Oe.errorBoundaryError},n)}class Me extends r.Component{componentDidCatch(e,t){throw this.props.onError(e,t)}render(){return this.props.children}}const Fe="right";function Be(e){let{width:t=30,height:n=30,className:a,...o}=e;return r.createElement("svg",(0,l.Z)({className:a,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true"},o),r.createElement("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"}))}function je(){const{toggle:e,shown:t}=(0,L.e)();return r.createElement("button",{onClick:e,"aria-label":(0,c.I)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":t,className:"navbar__toggle clean-btn",type:"button"},r.createElement(Be,null))}const ze={colorModeToggle:"colorModeToggle_DEke"};function Ue(e){let{items:t}=e;return r.createElement(r.Fragment,null,t.map(((e,t)=>r.createElement(Me,{key:t,onError:t=>new Error(`A theme navbar item failed to render.\nPlease double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:\n${JSON.stringify(e,null,2)}`,{cause:t})},r.createElement(xe,e)))))}function Ve(e){let{left:t,right:n}=e;return r.createElement("div",{className:"navbar__inner"},r.createElement("div",{className:"navbar__items"},t),r.createElement("div",{className:"navbar__items navbar__items--right"},n))}function $e(){const e=(0,L.e)(),t=(0,w.L)().navbar.items,[n,a]=function(e){function t(e){return"left"===(e.position??Fe)}return[e.filter(t),e.filter((e=>!t(e)))]}(t),o=t.find((e=>"search"===e.type));return r.createElement(Ve,{left:r.createElement(r.Fragment,null,!e.disabled&&r.createElement(je,null),r.createElement(W,null),r.createElement(Ue,{items:n})),right:r.createElement(r.Fragment,null,r.createElement(Ue,{items:a}),r.createElement(q,{className:ze.colorModeToggle}),!o&&r.createElement(ve,null,r.createElement(ge.Z,null)))})}function He(){return r.createElement(Re,null,r.createElement($e,null))}function Ge(e){let{item:t}=e;const{to:n,href:a,label:o,prependBaseUrlToHref:i,...s}=t,c=(0,Q.Z)(n),u=(0,Q.Z)(a,{forcePrependBaseUrl:!0});return r.createElement(X.Z,(0,l.Z)({className:"footer__link-item"},a?{href:i?u:a}:{to:c},s),o,a&&!(0,J.Z)(a)&&r.createElement(te.Z,null))}function qe(e){let{item:t}=e;return t.html?r.createElement("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):r.createElement("li",{key:t.href??t.to,className:"footer__item"},r.createElement(Ge,{item:t}))}function Ze(e){let{column:t}=e;return r.createElement("div",{className:"col footer__col"},r.createElement("div",{className:"footer__title"},t.title),r.createElement("ul",{className:"footer__items clean-list"},t.items.map(((e,t)=>r.createElement(qe,{key:t,item:e})))))}function We(e){let{columns:t}=e;return r.createElement("div",{className:"row footer__links"},t.map(((e,t)=>r.createElement(Ze,{key:t,column:e}))))}function Ye(){return r.createElement("span",{className:"footer__link-separator"},"\xb7")}function Ke(e){let{item:t}=e;return t.html?r.createElement("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):r.createElement(Ge,{item:t})}function Xe(e){let{links:t}=e;return r.createElement("div",{className:"footer__links text--center"},r.createElement("div",{className:"footer__links"},t.map(((e,n)=>r.createElement(r.Fragment,{key:n},r.createElement(Ke,{item:e}),t.length!==n+1&&r.createElement(Ye,null))))))}function Qe(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?r.createElement(We,{columns:t}):r.createElement(Xe,{links:t})}var Je=n(941);const et={footerLogoLink:"footerLogoLink_BH7S"};function tt(e){let{logo:t}=e;const{withBaseUrl:n}=(0,Q.C)(),o={light:n(t.src),dark:n(t.srcDark??t.src)};return r.createElement(Je.Z,{className:(0,a.Z)("footer__logo",t.className),alt:t.alt,sources:o,width:t.width,height:t.height,style:t.style})}function nt(e){let{logo:t}=e;return t.href?r.createElement(X.Z,{href:t.href,className:et.footerLogoLink,target:t.target},r.createElement(tt,{logo:t})):r.createElement(tt,{logo:t})}function rt(e){let{copyright:t}=e;return r.createElement("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}function at(e){let{style:t,links:n,logo:o,copyright:i}=e;return r.createElement("footer",{className:(0,a.Z)("footer",{"footer--dark":"dark"===t})},r.createElement("div",{className:"container container-fluid"},n,(o||i)&&r.createElement("div",{className:"footer__bottom text--center"},o&&r.createElement("div",{className:"margin-bottom--sm"},o),i)))}function ot(){const{footer:e}=(0,w.L)();if(!e)return null;const{copyright:t,links:n,logo:a,style:o}=e;return r.createElement(at,{style:o,links:n&&n.length>0&&r.createElement(Qe,{links:n}),logo:a&&r.createElement(nt,{logo:a}),copyright:t&&r.createElement(rt,{copyright:t})})}const it=r.memo(ot),lt=(0,R.Qc)([B.S,k.pl,P.OC,ke.L5,i.VC,function(e){let{children:t}=e;return r.createElement(N.n2,null,r.createElement(L.M,null,r.createElement(I,null,t)))}]);function st(e){let{children:t}=e;return r.createElement(lt,null,t)}function ct(e){let{error:t,tryAgain:n}=e;return r.createElement("main",{className:"container margin-vert--xl"},r.createElement("div",{className:"row"},r.createElement("div",{className:"col col--6 col--offset-3"},r.createElement("h1",{className:"hero__title"},r.createElement(c.Z,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed"},"This page crashed.")),r.createElement("div",{className:"margin-vert--lg"},r.createElement(Ie,{onClick:n,className:"button button--primary shadow--lw"})),r.createElement("hr",null),r.createElement("div",{className:"margin-vert--md"},r.createElement(De,{error:t})))))}const ut={mainWrapper:"mainWrapper_z2l0"};function dt(e){const{children:t,noFooter:n,wrapperClassName:l,title:s,description:c}=e;return(0,b.t)(),r.createElement(st,null,r.createElement(i.d,{title:s,description:c}),r.createElement(y,null),r.createElement(A,null),r.createElement(He,null),r.createElement("div",{id:d,className:(0,a.Z)(g.k.wrapper.main,ut.mainWrapper,l)},r.createElement(o.Z,{fallback:e=>r.createElement(ct,e)},t)),!n&&r.createElement(it,null))}},1327:(e,t,n)=>{"use strict";n.d(t,{Z:()=>d});var r=n(7462),a=n(7294),o=n(9960),i=n(4996),l=n(2263),s=n(6668),c=n(941);function u(e){let{logo:t,alt:n,imageClassName:r}=e;const o={light:(0,i.Z)(t.src),dark:(0,i.Z)(t.srcDark||t.src)},l=a.createElement(c.Z,{className:t.className,sources:o,height:t.height,width:t.width,alt:n,style:t.style});return r?a.createElement("div",{className:r},l):l}function d(e){const{siteConfig:{title:t}}=(0,l.Z)(),{navbar:{title:n,logo:c}}=(0,s.L)(),{imageClassName:d,titleClassName:p,...f}=e,m=(0,i.Z)(c?.href||"/"),h=n?"":t,g=c?.alt??h;return a.createElement(o.Z,(0,r.Z)({to:m},f,c?.target&&{target:c.target}),c&&a.createElement(u,{logo:c,alt:g,imageClassName:d}),null!=n&&a.createElement("b",{className:p},n))}},197:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(5742);function o(e){let{locale:t,version:n,tag:o}=e;const i=t;return r.createElement(a.Z,null,t&&r.createElement("meta",{name:"docusaurus_locale",content:t}),n&&r.createElement("meta",{name:"docusaurus_version",content:n}),o&&r.createElement("meta",{name:"docusaurus_tag",content:o}),i&&r.createElement("meta",{name:"docsearch:language",content:i}),n&&r.createElement("meta",{name:"docsearch:version",content:n}),o&&r.createElement("meta",{name:"docsearch:docusaurus_tag",content:o}))}},941:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c});var r=n(7462),a=n(7294),o=n(6010),i=n(2389),l=n(2949);const s={themedImage:"themedImage_ToTc","themedImage--light":"themedImage--light_HNdA","themedImage--dark":"themedImage--dark_i4oU"};function c(e){const t=(0,i.Z)(),{colorMode:n}=(0,l.I)(),{sources:c,className:u,alt:d,...p}=e,f=t?"dark"===n?["dark"]:["light"]:["light","dark"];return a.createElement(a.Fragment,null,f.map((e=>a.createElement("img",(0,r.Z)({key:e,src:c[e],alt:d,className:(0,o.Z)(s.themedImage,s[`themedImage--${e}`],u)},p)))))}},6043:(e,t,n)=>{"use strict";n.d(t,{u:()=>s,z:()=>g});var r=n(7462),a=n(7294),o=n(412),i=n(1442);const l="ease-in-out";function s(e){let{initialState:t}=e;const[n,r]=(0,a.useState)(t??!1),o=(0,a.useCallback)((()=>{r((e=>!e))}),[]);return{collapsed:n,setCollapsed:r,toggleCollapsed:o}}const c={display:"none",overflow:"hidden",height:"0px"},u={display:"block",overflow:"visible",height:"auto"};function d(e,t){const n=t?c:u;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function p(e){let{collapsibleRef:t,collapsed:n,animation:r}=e;const o=(0,a.useRef)(!1);(0,a.useEffect)((()=>{const e=t.current;function a(){const t=e.scrollHeight,n=r?.duration??function(e){if((0,i.n)())return 1;const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(t);return{transition:`height ${n}ms ${r?.easing??l}`,height:`${t}px`}}function s(){const t=a();e.style.transition=t.transition,e.style.height=t.height}if(!o.current)return d(e,n),void(o.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(s(),requestAnimationFrame((()=>{e.style.height=c.height,e.style.overflow=c.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{s()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,r])}function f(e){if(!o.Z.canUseDOM)return e?c:u}function m(e){let{as:t="div",collapsed:n,children:r,animation:o,onCollapseTransitionEnd:i,className:l,disableSSRStyle:s}=e;const c=(0,a.useRef)(null);return p({collapsibleRef:c,collapsed:n,animation:o}),a.createElement(t,{ref:c,style:s?void 0:f(n),onTransitionEnd:e=>{"height"===e.propertyName&&(d(c.current,n),i?.(n))},className:l},r)}function h(e){let{collapsed:t,...n}=e;const[o,i]=(0,a.useState)(!t),[l,s]=(0,a.useState)(t);return(0,a.useLayoutEffect)((()=>{t||i(!0)}),[t]),(0,a.useLayoutEffect)((()=>{o&&s(t)}),[o,t]),o?a.createElement(m,(0,r.Z)({},n,{collapsed:l})):null}function g(e){let{lazy:t,...n}=e;const r=t?h:m;return a.createElement(r,n)}},9689:(e,t,n)=>{"use strict";n.d(t,{nT:()=>m,pl:()=>f});var r=n(7294),a=n(2389),o=n(12),i=n(902),l=n(6668);const s=(0,o.WA)("docusaurus.announcement.dismiss"),c=(0,o.WA)("docusaurus.announcement.id"),u=()=>"true"===s.get(),d=e=>s.set(String(e)),p=r.createContext(null);function f(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,l.L)(),t=(0,a.Z)(),[n,o]=(0,r.useState)((()=>!!t&&u()));(0,r.useEffect)((()=>{o(u())}),[]);const i=(0,r.useCallback)((()=>{d(!0),o(!0)}),[]);return(0,r.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=c.get();"annoucement-bar"===n&&(n="announcement-bar");const r=t!==n;c.set(t),r&&d(!1),!r&&u()||o(!1)}),[e]),(0,r.useMemo)((()=>({isActive:!!e&&!n,close:i})),[e,n,i])}();return r.createElement(p.Provider,{value:n},t)}function m(){const e=(0,r.useContext)(p);if(!e)throw new i.i6("AnnouncementBarProvider");return e}},2949:(e,t,n)=>{"use strict";n.d(t,{I:()=>g,S:()=>h});var r=n(7294),a=n(412),o=n(902),i=n(12),l=n(6668);const s=r.createContext(void 0),c="theme",u=(0,i.WA)(c),d={light:"light",dark:"dark"},p=e=>e===d.dark?d.dark:d.light,f=e=>a.Z.canUseDOM?p(document.documentElement.getAttribute("data-theme")):p(e),m=e=>{u.set(p(e))};function h(e){let{children:t}=e;const n=function(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,l.L)(),[a,o]=(0,r.useState)(f(e));(0,r.useEffect)((()=>{t&&u.del()}),[t]);const i=(0,r.useCallback)((function(t,r){void 0===r&&(r={});const{persist:a=!0}=r;t?(o(t),a&&m(t)):(o(n?window.matchMedia("(prefers-color-scheme: dark)").matches?d.dark:d.light:e),u.del())}),[n,e]);(0,r.useEffect)((()=>{document.documentElement.setAttribute("data-theme",p(a))}),[a]),(0,r.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==c)return;const t=u.get();null!==t&&i(p(t))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,i]);const s=(0,r.useRef)(!1);return(0,r.useEffect)((()=>{if(t&&!n)return;const e=window.matchMedia("(prefers-color-scheme: dark)"),r=()=>{window.matchMedia("print").matches||s.current?s.current=window.matchMedia("print").matches:i(null)};return e.addListener(r),()=>e.removeListener(r)}),[i,t,n]),(0,r.useMemo)((()=>({colorMode:a,setColorMode:i,get isDarkTheme(){return a===d.dark},setLightTheme(){i(d.light)},setDarkTheme(){i(d.dark)}})),[a,i])}();return r.createElement(s.Provider,{value:n},t)}function g(){const e=(0,r.useContext)(s);if(null==e)throw new o.i6("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},373:(e,t,n)=>{"use strict";n.d(t,{J:()=>v,L5:()=>g});var r=n(7294),a=n(143),o=n(9935),i=n(6668),l=n(3438),s=n(902),c=n(12);const u=e=>`docs-preferred-version-${e}`,d={save:(e,t,n)=>{(0,c.WA)(u(e),{persistence:t}).set(n)},read:(e,t)=>(0,c.WA)(u(e),{persistence:t}).get(),clear:(e,t)=>{(0,c.WA)(u(e),{persistence:t}).del()}},p=e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}])));const f=r.createContext(null);function m(){const e=(0,a._r)(),t=(0,i.L)().docs.versionPersistence,n=(0,r.useMemo)((()=>Object.keys(e)),[e]),[o,l]=(0,r.useState)((()=>p(n)));(0,r.useEffect)((()=>{l(function(e){let{pluginIds:t,versionPersistence:n,allDocsData:r}=e;function a(e){const t=d.read(e,n);return r[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:(d.clear(e,n),{preferredVersionName:null})}return Object.fromEntries(t.map((e=>[e,a(e)])))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]);return[o,(0,r.useMemo)((()=>({savePreferredVersion:function(e,n){d.save(e,t,n),l((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function h(e){let{children:t}=e;const n=m();return r.createElement(f.Provider,{value:n},t)}function g(e){let{children:t}=e;return l.cE?r.createElement(h,null,t):r.createElement(r.Fragment,null,t)}function b(){const e=(0,r.useContext)(f);if(!e)throw new s.i6("DocsPreferredVersionContextProvider");return e}function v(e){void 0===e&&(e=o.m);const t=(0,a.zh)(e),[n,i]=b(),{preferredVersionName:l}=n[e];return{preferredVersion:t.versions.find((e=>e.name===l))??null,savePreferredVersionName:(0,r.useCallback)((t=>{i.savePreferredVersion(e,t)}),[i,e])}}},1116:(e,t,n)=>{"use strict";n.d(t,{V:()=>s,b:()=>l});var r=n(7294),a=n(902);const o=Symbol("EmptyContext"),i=r.createContext(o);function l(e){let{children:t,name:n,items:a}=e;const o=(0,r.useMemo)((()=>n&&a?{name:n,items:a}:null),[n,a]);return r.createElement(i.Provider,{value:o},t)}function s(){const e=(0,r.useContext)(i);if(e===o)throw new a.i6("DocsSidebarProvider");return e}},3163:(e,t,n)=>{"use strict";n.d(t,{M:()=>d,e:()=>p});var r=n(7294),a=n(3102),o=n(7524),i=n(1980),l=n(6668),s=n(902);const c=r.createContext(void 0);function u(){const e=function(){const e=(0,a.HY)(),{items:t}=(0,l.L)().navbar;return 0===t.length&&!e.component}(),t=(0,o.i)(),n=!e&&"mobile"===t,[s,c]=(0,r.useState)(!1);(0,i.Rb)((()=>{if(s)return c(!1),!1}));const u=(0,r.useCallback)((()=>{c((e=>!e))}),[]);return(0,r.useEffect)((()=>{"desktop"===t&&c(!1)}),[t]),(0,r.useMemo)((()=>({disabled:e,shouldRender:n,toggle:u,shown:s})),[e,n,u,s])}function d(e){let{children:t}=e;const n=u();return r.createElement(c.Provider,{value:n},t)}function p(){const e=r.useContext(c);if(void 0===e)throw new s.i6("NavbarMobileSidebarProvider");return e}},3102:(e,t,n)=>{"use strict";n.d(t,{HY:()=>l,Zo:()=>s,n2:()=>i});var r=n(7294),a=n(902);const o=r.createContext(null);function i(e){let{children:t}=e;const n=(0,r.useState)({component:null,props:null});return r.createElement(o.Provider,{value:n},t)}function l(){const e=(0,r.useContext)(o);if(!e)throw new a.i6("NavbarSecondaryMenuContentProvider");return e[0]}function s(e){let{component:t,props:n}=e;const i=(0,r.useContext)(o);if(!i)throw new a.i6("NavbarSecondaryMenuContentProvider");const[,l]=i,s=(0,a.Ql)(n);return(0,r.useEffect)((()=>{l({component:t,props:s})}),[l,t,s]),(0,r.useEffect)((()=>()=>l({component:null,props:null})),[l]),null}},9727:(e,t,n)=>{"use strict";n.d(t,{h:()=>a,t:()=>o});var r=n(7294);const a="navigation-with-keyboard";function o(){(0,r.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(a),"mousedown"===e.type&&document.body.classList.remove(a)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(a),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},7524:(e,t,n)=>{"use strict";n.d(t,{i:()=>c});var r=n(7294),a=n(412);const o={desktop:"desktop",mobile:"mobile",ssr:"ssr"},i=996;function l(){return a.Z.canUseDOM?window.innerWidth>i?o.desktop:o.mobile:o.ssr}const s=!1;function c(){const[e,t]=(0,r.useState)((()=>s?"ssr":l()));return(0,r.useEffect)((()=>{function e(){t(l())}const n=s?window.setTimeout(e,1e3):void 0;return window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e),clearTimeout(n)}}),[]),e}},5281:(e,t,n)=>{"use strict";n.d(t,{k:()=>r});const r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",admonitionType:e=>`theme-admonition-${e}`},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{}}},1442:(e,t,n)=>{"use strict";function r(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{n:()=>r})},3438:(e,t,n)=>{"use strict";n.d(t,{Wl:()=>p,_F:()=>h,cE:()=>d,hI:()=>k,lO:()=>v,oz:()=>y,s1:()=>b,vY:()=>w});var r=n(7294),a=n(6550),o=n(8790),i=n(143),l=n(373),s=n(1116),c=n(7392),u=n(8596);const d=!!i._r;function p(e){if(e.href)return e.href;for(const t of e.items){if("link"===t.type)return t.href;if("category"===t.type){const e=p(t);if(e)return e}}}const f=(e,t)=>void 0!==e&&(0,u.Mg)(e,t),m=(e,t)=>e.some((e=>h(e,t)));function h(e,t){return"link"===e.type?f(e.href,t):"category"===e.type&&(f(e.href,t)||m(e.items,t))}function g(e){let{sidebarItems:t,pathname:n,onlyCategories:r=!1}=e;const a=[];return function e(t){for(const o of t)if("category"===o.type&&((0,u.Mg)(o.href,n)||e(o.items))||"link"===o.type&&(0,u.Mg)(o.href,n)){return r&&"category"!==o.type||a.unshift(o),!0}return!1}(t),a}function b(){const e=(0,s.V)(),{pathname:t}=(0,a.TH)(),n=(0,i.gA)()?.pluginData.breadcrumbs;return!1!==n&&e?g({sidebarItems:e.items,pathname:t}):null}function v(e){const{activeVersion:t}=(0,i.Iw)(e),{preferredVersion:n}=(0,l.J)(e),a=(0,i.yW)(e);return(0,r.useMemo)((()=>(0,c.j)([t,n,a].filter(Boolean))),[t,n,a])}function y(e,t){const n=v(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),r=t.find((t=>t[0]===e));if(!r)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\nAvailable sidebar ids are:\n- ${t.map((e=>e[0])).join("\n- ")}`);return r[1]}),[e,n])}function w(e,t){const n=v(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),r=t.find((t=>t.id===e));if(!r){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`Couldn't find any doc with id "${e}" in version${n.length>1?"s":""} "${n.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${(0,c.j)(t.map((e=>e.id))).join("\n- ")}`)}return r}),[e,n])}function k(e){let{route:t,versionMetadata:n}=e;const r=(0,a.TH)(),i=t.routes,l=i.find((e=>(0,a.LX)(r.pathname,e)));if(!l)return null;const s=l.sidebar,c=s?n.docsSidebars[s]:void 0;return{docElement:(0,o.H)(i),sidebarName:s,sidebarItems:c}}},1980:(e,t,n)=>{"use strict";n.d(t,{Rb:()=>l,_X:()=>s});var r=n(7294),a=n(6550),o=n(1688),i=n(902);function l(e){!function(e){const t=(0,a.k6)(),n=(0,i.zX)(e);(0,r.useEffect)((()=>t.block(((e,t)=>n(e,t)))),[t,n])}(((t,n)=>{if("POP"===n)return e(t,n)}))}function s(e){return function(e){const t=(0,a.k6)();return(0,o.useSyncExternalStore)(t.listen,(()=>e(t)),(()=>e(t)))}((t=>null===e?null:new URLSearchParams(t.location.search).get(e)))}},7392:(e,t,n)=>{"use strict";function r(e,t){return void 0===t&&(t=(e,t)=>e===t),e.filter(((n,r)=>e.findIndex((e=>t(e,n)))!==r))}function a(e){return Array.from(new Set(e))}n.d(t,{j:()=>a,l:()=>r})},1944:(e,t,n)=>{"use strict";n.d(t,{FG:()=>p,d:()=>u,VC:()=>f});var r=n(7294),a=n(6010),o=n(5742),i=n(226);function l(){const e=r.useContext(i._);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}var s=n(4996),c=n(2263);function u(e){let{title:t,description:n,keywords:a,image:i,children:l}=e;const u=function(e){const{siteConfig:t}=(0,c.Z)(),{title:n,titleDelimiter:r}=t;return e?.trim().length?`${e.trim()} ${r} ${n}`:n}(t),{withBaseUrl:d}=(0,s.C)(),p=i?d(i,{absolute:!0}):void 0;return r.createElement(o.Z,null,t&&r.createElement("title",null,u),t&&r.createElement("meta",{property:"og:title",content:u}),n&&r.createElement("meta",{name:"description",content:n}),n&&r.createElement("meta",{property:"og:description",content:n}),a&&r.createElement("meta",{name:"keywords",content:Array.isArray(a)?a.join(","):a}),p&&r.createElement("meta",{property:"og:image",content:p}),p&&r.createElement("meta",{name:"twitter:image",content:p}),l)}const d=r.createContext(void 0);function p(e){let{className:t,children:n}=e;const i=r.useContext(d),l=(0,a.Z)(i,t);return r.createElement(d.Provider,{value:l},r.createElement(o.Z,null,r.createElement("html",{className:l})),n)}function f(e){let{children:t}=e;const n=l(),o=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const i=`plugin-id-${n.plugin.id}`;return r.createElement(p,{className:(0,a.Z)(o,i)},t)}},902:(e,t,n)=>{"use strict";n.d(t,{D9:()=>i,Qc:()=>c,Ql:()=>s,i6:()=>l,zX:()=>o});var r=n(7294);const a=n(412).Z.canUseDOM?r.useLayoutEffect:r.useEffect;function o(e){const t=(0,r.useRef)(e);return a((()=>{t.current=e}),[e]),(0,r.useCallback)((function(){return t.current(...arguments)}),[])}function i(e){const t=(0,r.useRef)();return a((()=>{t.current=e})),t.current}class l extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?\w+)/)?.groups.name??""} is called outside the <${e}>. ${t??""}`}}function s(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,r.useMemo)((()=>e),t.flat())}function c(e){return t=>{let{children:n}=t;return r.createElement(r.Fragment,null,e.reduceRight(((e,t)=>r.createElement(t,null,e)),n))}}},8596:(e,t,n)=>{"use strict";n.d(t,{Mg:()=>i,Ns:()=>l});var r=n(7294),a=n(723),o=n(2263);function i(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function l(){const{baseUrl:e}=(0,o.Z)().siteConfig;return(0,r.useMemo)((()=>function(e){let{baseUrl:t,routes:n}=e;function r(e){return e.path===t&&!0===e.exact}function a(e){return e.path===t&&!e.exact}return function e(t){if(0===t.length)return;return t.find(r)||e(t.filter(a).flatMap((e=>e.routes??[])))}(n)}({routes:a.Z,baseUrl:e})),[e])}},2466:(e,t,n)=>{"use strict";n.d(t,{Ct:()=>f,OC:()=>s,RF:()=>d,o5:()=>p});var r=n(7294),a=n(412),o=n(2389),i=n(902);const l=r.createContext(void 0);function s(e){let{children:t}=e;const n=function(){const e=(0,r.useRef)(!0);return(0,r.useMemo)((()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}})),[])}();return r.createElement(l.Provider,{value:n},t)}function c(){const e=(0,r.useContext)(l);if(null==e)throw new i.i6("ScrollControllerProvider");return e}const u=()=>a.Z.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function d(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=c(),a=(0,r.useRef)(u()),o=(0,i.zX)(e);(0,r.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=u();o(e,a.current),a.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)}),[o,n,...t])}function p(){const e=c(),t=function(){const e=(0,r.useRef)({elem:null,top:0}),t=(0,r.useCallback)((t=>{e.current={elem:t,top:t.getBoundingClientRect().top}}),[]),n=(0,r.useCallback)((()=>{const{current:{elem:t,top:n}}=e;if(!t)return{restored:!1};const r=t.getBoundingClientRect().top-n;return r&&window.scrollBy({left:0,top:r}),e.current={elem:null,top:0},{restored:0!==r}}),[]);return(0,r.useMemo)((()=>({save:t,restore:n})),[n,t])}(),n=(0,r.useRef)(void 0),a=(0,r.useCallback)((r=>{t.save(r),e.disableScrollEvents(),n.current=()=>{const{restored:r}=t.restore();if(n.current=void 0,r){const t=()=>{e.enableScrollEvents(),window.removeEventListener("scroll",t)};window.addEventListener("scroll",t)}else e.enableScrollEvents()}}),[e,t]);return(0,r.useLayoutEffect)((()=>{queueMicrotask((()=>n.current?.()))})),{blockElementScrollPositionUntilNextRender:a}}function f(){const e=(0,r.useRef)(null),t=(0,o.Z)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:n=>{e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(n):function(e){let t=null;const n=document.documentElement.scrollTop>e;return function r(){const a=document.documentElement.scrollTop;(n&&a>e||!n&&at&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>e.current?.()}}},3320:(e,t,n)=>{"use strict";n.d(t,{HX:()=>r,os:()=>a});n(2263);const r="default";function a(e,t){return`docs-${e}-${t}`}},12:(e,t,n)=>{"use strict";n.d(t,{Nk:()=>d,WA:()=>u});var r=n(7294),a=n(1688);const o="localStorage";function i(e){let{key:t,oldValue:n,newValue:r,storage:a}=e;if(n===r)return;const o=document.createEvent("StorageEvent");o.initStorageEvent("storage",!1,!1,t,n,r,window.location.href,a),window.dispatchEvent(o)}function l(e){if(void 0===e&&(e=o),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,s||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),s=!0),null}var t}let s=!1;const c={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function u(e,t){if("undefined"==typeof window)return function(e){function t(){throw new Error(`Illegal storage API usage for storage key "${e}".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.`)}return{get:t,set:t,del:t,listen:t}}(e);const n=l(t?.persistence);return null===n?c:{get:()=>{try{return n.getItem(e)}catch(t){return console.error(`Docusaurus storage error, can't get key=${e}`,t),null}},set:t=>{try{const r=n.getItem(e);n.setItem(e,t),i({key:e,oldValue:r,newValue:t,storage:n})}catch(r){console.error(`Docusaurus storage error, can't set ${e}=${t}`,r)}},del:()=>{try{const t=n.getItem(e);n.removeItem(e),i({key:e,oldValue:t,newValue:null,storage:n})}catch(t){console.error(`Docusaurus storage error, can't delete key=${e}`,t)}},listen:t=>{try{const r=r=>{r.storageArea===n&&r.key===e&&t(r)};return window.addEventListener("storage",r),()=>window.removeEventListener("storage",r)}catch(r){return console.error(`Docusaurus storage error, can't listen for changes of key=${e}`,r),()=>{}}}}}function d(e,t){const n=(0,r.useRef)((()=>null===e?c:u(e,t))).current(),o=(0,r.useCallback)((e=>"undefined"==typeof window?()=>{}:n.listen(e)),[n]);return[(0,a.useSyncExternalStore)(o,(()=>"undefined"==typeof window?null:n.get()),(()=>null)),n]}},4711:(e,t,n)=>{"use strict";n.d(t,{l:()=>i});var r=n(2263),a=n(6550),o=n(8780);function i(){const{siteConfig:{baseUrl:e,url:t,trailingSlash:n},i18n:{defaultLocale:i,currentLocale:l}}=(0,r.Z)(),{pathname:s}=(0,a.TH)(),c=(0,o.applyTrailingSlash)(s,{trailingSlash:n,baseUrl:e}),u=l===i?e:e.replace(`/${l}/`,"/"),d=c.replace(e,"");return{createUrl:function(e){let{locale:n,fullyQualified:r}=e;return`${r?t:""}${function(e){return e===i?`${u}`:`${u}${e}/`}(n)}${d}`}}}},5936:(e,t,n)=>{"use strict";n.d(t,{S:()=>i});var r=n(7294),a=n(6550),o=n(902);function i(e){const t=(0,a.TH)(),n=(0,o.D9)(t),i=(0,o.zX)(e);(0,r.useEffect)((()=>{n&&t!==n&&i({location:t,previousLocation:n})}),[i,t,n])}},6668:(e,t,n)=>{"use strict";n.d(t,{L:()=>a});var r=n(2263);function a(){return(0,r.Z)().siteConfig.themeConfig}},8802:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){const{trailingSlash:n,baseUrl:r}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[a]=e.split(/[#?]/),o="/"===a||a===r?a:(i=a,n?function(e){return e.endsWith("/")?e:`${e}/`}(i):function(e){return e.endsWith("/")?e.slice(0,-1):e}(i));var i;return e.replace(a,o)}},4143:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=void 0,t.getErrorCausalChain=function e(t){return t.cause?[t,...e(t.cause)]:[t]}},8780:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=t.applyTrailingSlash=t.blogPostContainerID=void 0,t.blogPostContainerID="__blog-post-container";var a=n(8802);Object.defineProperty(t,"applyTrailingSlash",{enumerable:!0,get:function(){return r(a).default}});var o=n(4143);Object.defineProperty(t,"getErrorCausalChain",{enumerable:!0,get:function(){return o.getErrorCausalChain}})},6010:(e,t,n)=>{"use strict";function r(e){var t,n,a="";if("string"==typeof e||"number"==typeof e)a+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;ta});const a=function(){for(var e,t,n=0,a="";n{"use strict";n.d(t,{lX:()=>w,q_:()=>C,ob:()=>f,PP:()=>A,Ep:()=>p});var r=n(7462);function a(e){return"/"===e.charAt(0)}function o(e,t){for(var n=t,r=n+1,a=e.length;r=0;p--){var f=i[p];"."===f?o(i,p):".."===f?(o(i,p),d++):d&&(o(i,p),d--)}if(!c)for(;d--;d)i.unshift("..");!c||""===i[0]||i[0]&&a(i[0])||i.unshift("");var m=i.join("/");return n&&"/"!==m.substr(-1)&&(m+="/"),m};var l=n(8776);function s(e){return"/"===e.charAt(0)?e:"/"+e}function c(e){return"/"===e.charAt(0)?e.substr(1):e}function u(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function d(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function p(e){var t=e.pathname,n=e.search,r=e.hash,a=t||"/";return n&&"?"!==n&&(a+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(a+="#"===r.charAt(0)?r:"#"+r),a}function f(e,t,n,a){var o;"string"==typeof e?(o=function(e){var t=e||"/",n="",r="",a=t.indexOf("#");-1!==a&&(r=t.substr(a),t=t.substr(0,a));var o=t.indexOf("?");return-1!==o&&(n=t.substr(o),t=t.substr(0,o)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),o.state=t):(void 0===(o=(0,r.Z)({},e)).pathname&&(o.pathname=""),o.search?"?"!==o.search.charAt(0)&&(o.search="?"+o.search):o.search="",o.hash?"#"!==o.hash.charAt(0)&&(o.hash="#"+o.hash):o.hash="",void 0!==t&&void 0===o.state&&(o.state=t));try{o.pathname=decodeURI(o.pathname)}catch(l){throw l instanceof URIError?new URIError('Pathname "'+o.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):l}return n&&(o.key=n),a?o.pathname?"/"!==o.pathname.charAt(0)&&(o.pathname=i(o.pathname,a.pathname)):o.pathname=a.pathname:o.pathname||(o.pathname="/"),o}function m(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,a){if(null!=e){var o="function"==typeof e?e(t,n):e;"string"==typeof o?"function"==typeof r?r(o,a):a(!0):a(!1!==o)}else a(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;rt?n.splice(t,n.length-t,a):n.push(a),d({action:r,location:a,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",a=f(e,t,h(),w.location);u.confirmTransitionTo(a,r,n,(function(e){e&&(w.entries[w.index]=a,d({action:r,location:a}))}))},go:y,goBack:function(){y(-1)},goForward:function(){y(1)},canGo:function(e){var t=w.index+e;return t>=0&&t{"use strict";var r=n(9864),a={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},o={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},l={};function s(e){return r.isMemo(e)?i:l[e.$$typeof]||a}l[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},l[r.Memo]=i;var c=Object.defineProperty,u=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,p=Object.getOwnPropertyDescriptor,f=Object.getPrototypeOf,m=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(m){var a=f(n);a&&a!==m&&e(t,a,r)}var i=u(n);d&&(i=i.concat(d(n)));for(var l=s(t),h=s(n),g=0;g{"use strict";e.exports=function(e,t,n,r,a,o,i,l){if(!e){var s;if(void 0===t)s=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var c=[n,r,a,o,i,l],u=0;(s=new Error(t.replace(/%s/g,(function(){return c[u++]})))).name="Invariant Violation"}throw s.framesToPop=1,s}}},5826:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},2497:(e,t,n)=>{"use strict";n.r(t)},2295:(e,t,n)=>{"use strict";n.r(t)},4865:function(e,t,n){var r,a;r=function(){var e,t,n={version:"0.2.0"},r=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'
'};function a(e,t,n){return en?n:e}function o(e){return 100*(-1+e)}function i(e,t,n){var a;return(a="translate3d"===r.positionUsing?{transform:"translate3d("+o(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+o(e)+"%,0)"}:{"margin-left":o(e)+"%"}).transition="all "+t+"ms "+n,a}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=a(e,r.minimum,1),n.status=1===e?null:e;var o=n.render(!t),c=o.querySelector(r.barSelector),u=r.speed,d=r.easing;return o.offsetWidth,l((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),s(c,i(e,u,d)),1===e?(s(o,{transition:"none",opacity:1}),o.offsetWidth,setTimeout((function(){s(o,{transition:"all "+u+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),u)}),u)):setTimeout(t,u)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*a(Math.random()*t,.1,.95)),t=a(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");u(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var a,i=t.querySelector(r.barSelector),l=e?"-100":o(n.status||0),c=document.querySelector(r.parent);return s(i,{transition:"all 0 linear",transform:"translate3d("+l+"%,0,0)"}),r.showSpinner||(a=t.querySelector(r.spinnerSelector))&&f(a),c!=document.body&&u(c,"nprogress-custom-parent"),c.appendChild(t),t},n.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&f(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var l=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),s=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function r(t){var n=document.body.style;if(t in n)return t;for(var r,a=e.length,o=t.charAt(0).toUpperCase()+t.slice(1);a--;)if((r=e[a]+o)in n)return r;return t}function a(e){return e=n(e),t[e]||(t[e]=r(e))}function o(e,t,n){t=a(t),e.style[t]=n}return function(e,t){var n,r,a=arguments;if(2==a.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&o(e,n,r);else o(e,a[1],a[2])}}();function c(e,t){return("string"==typeof e?e:p(e)).indexOf(" "+t+" ")>=0}function u(e,t){var n=p(e),r=n+t;c(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=p(e);c(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function p(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function f(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(a="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=a)},7418:e=>{"use strict";var t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(a){return!1}}()?Object.assign:function(e,a){for(var o,i,l=function(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}(e),s=1;s{"use strict";n.d(t,{Z:()=>o});var r=function(){var e=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,n={},r={util:{encode:function e(t){return t instanceof a?new a(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/=d.reach);E+=S.value.length,S=S.next){var x=S.value;if(t.length>e.length)return;if(!(x instanceof a)){var _,C=1;if(v){if(!(_=o(k,E,e,b))||_.index>=e.length)break;var T=_.index,A=_.index+_[0].length,L=E;for(L+=S.value.length;T>=L;)L+=(S=S.next).value.length;if(E=L-=S.value.length,S.value instanceof a)continue;for(var P=S;P!==t.tail&&(Ld.reach&&(d.reach=I);var D=S.prev;if(N&&(D=s(t,D,N),E+=N.length),c(t,D,C),S=s(t,D,new a(p,g?r.tokenize(R,g):R,y,R)),O&&s(t,S,O),C>1){var M={cause:p+","+m,reach:I};i(e,t,n,S.prev,E,M),d&&M.reach>d.reach&&(d.reach=M.reach)}}}}}}function l(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function s(e,t,n){var r=t.next,a={value:n,prev:t,next:r};return t.next=a,r.prev=a,e.length++,a}function c(e,t,n){for(var r=t.next,a=0;a"+o.content+""},r}(),a=r;r.default=r,a.languages.markup={comment:{pattern://,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},a.languages.markup.tag.inside["attr-value"].inside.entity=a.languages.markup.entity,a.languages.markup.doctype.inside["internal-subset"].inside=a.languages.markup,a.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(a.languages.markup.tag,"addInlined",{value:function(e,t){var n={};n["language-"+t]={pattern:/(^$)/i,lookbehind:!0,inside:a.languages[t]},n.cdata=/^$/i;var r={"included-cdata":{pattern://i,inside:n}};r["language-"+t]={pattern:/[\s\S]+/,inside:a.languages[t]};var o={};o[e]={pattern:RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:r},a.languages.insertBefore("markup","cdata",o)}}),Object.defineProperty(a.languages.markup.tag,"addAttribute",{value:function(e,t){a.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:a.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),a.languages.html=a.languages.markup,a.languages.mathml=a.languages.markup,a.languages.svg=a.languages.markup,a.languages.xml=a.languages.extend("markup",{}),a.languages.ssml=a.languages.xml,a.languages.atom=a.languages.xml,a.languages.rss=a.languages.xml,function(e){var t="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",n={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},r={bash:n,environment:{pattern:RegExp("\\$"+t),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+t),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b[\w-]+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+t),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:r},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:n}},{pattern:/(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/,lookbehind:!0,greedy:!0,inside:r},{pattern:/(^|[^$\\])'[^']*'/,lookbehind:!0,greedy:!0},{pattern:/\$'(?:[^'\\]|\\[\s\S])*'/,greedy:!0,inside:{entity:r.entity}}],environment:{pattern:RegExp("\\$?"+t),alias:"constant"},variable:r.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},n.inside=e.languages.bash;for(var a=["comment","function-name","for-or-select","assign-left","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],o=r.variable[1].inside,i=0;i]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},a.languages.c=a.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),a.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),a.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},a.languages.c.string],char:a.languages.c.char,comment:a.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:a.languages.c}}}}),a.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete a.languages.c.boolean,function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n=/\b(?!)\w+(?:\s*\.\s*\w+)*\b/.source.replace(//g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!)\w+/.source.replace(//g,(function(){return t.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/(?:\s*:\s*)?|:\s*/.source.replace(//g,(function(){return n}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(a),function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),n.tag.addAttribute("style","css"))}(a),function(e){var t,n=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;e.languages.css.selector={pattern:e.languages.css.selector.pattern,lookbehind:!0,inside:t={"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+/,class:/\.[-\w]+/,id:/#[-\w]+/,attribute:{pattern:RegExp("\\[(?:[^[\\]\"']|"+n.source+")*\\]"),greedy:!0,inside:{punctuation:/^\[|\]$/,"case-sensitivity":{pattern:/(\s)[si]$/i,lookbehind:!0,alias:"keyword"},namespace:{pattern:/^(\s*)(?:(?!\s)[-*\w\xA0-\uFFFF])*\|(?!=)/,lookbehind:!0,inside:{punctuation:/\|$/}},"attr-name":{pattern:/^(\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+/,lookbehind:!0},"attr-value":[n,{pattern:/(=\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+(?=\s*$)/,lookbehind:!0}],operator:/[|~*^$]?=/}},"n-th":[{pattern:/(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/,lookbehind:!0,inside:{number:/[\dn]+/,operator:/[+-]/}},{pattern:/(\(\s*)(?:even|odd)(?=\s*\))/i,lookbehind:!0}],combinator:/>|\+|~|\|\|/,punctuation:/[(),]/}},e.languages.css.atrule.inside["selector-function-argument"].inside=t,e.languages.insertBefore("css","property",{variable:{pattern:/(^|[^-\w\xA0-\uFFFF])--(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*/i,lookbehind:!0}});var r={pattern:/(\b\d+)(?:%|[a-z]+(?![\w-]))/,lookbehind:!0},a={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0};e.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:{pattern:/\B#[\da-f]{3,8}\b/i,alias:"color"},color:[{pattern:/(^|[^\w-])(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)(?![\w-])/i,lookbehind:!0},{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:r,number:a,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:r,number:a})}(a),a.languages.javascript=a.languages.extend("clike",{"class-name":[a.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),a.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,a.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:a.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:a.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:a.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:a.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:a.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),a.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:a.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),a.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),a.languages.markup&&(a.languages.markup.tag.addInlined("script","javascript"),a.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),a.languages.js=a.languages.javascript,function(e){var t=/#(?!\{).+/,n={pattern:/#\{[^}]+\}/,alias:"variable"};e.languages.coffeescript=e.languages.extend("javascript",{comment:t,string:[{pattern:/'(?:\\[\s\S]|[^\\'])*'/,greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0,inside:{interpolation:n}}],keyword:/\b(?:and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,"class-member":{pattern:/@(?!\d)\w+/,alias:"variable"}}),e.languages.insertBefore("coffeescript","comment",{"multiline-comment":{pattern:/###[\s\S]+?###/,alias:"comment"},"block-regex":{pattern:/\/{3}[\s\S]*?\/{3}/,alias:"regex",inside:{comment:t,interpolation:n}}}),e.languages.insertBefore("coffeescript","string",{"inline-javascript":{pattern:/`(?:\\[\s\S]|[^\\`])*`/,inside:{delimiter:{pattern:/^`|`$/,alias:"punctuation"},script:{pattern:/[\s\S]+/,alias:"language-javascript",inside:e.languages.javascript}}},"multiline-string":[{pattern:/'''[\s\S]*?'''/,greedy:!0,alias:"string"},{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string",inside:{interpolation:n}}]}),e.languages.insertBefore("coffeescript","keyword",{property:/(?!\d)\w+(?=\s*:(?!:))/}),delete e.languages.coffeescript["template-string"],e.languages.coffee=e.languages.coffeescript}(a),function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",a=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-])(?:[ \t]*(?:(?![#:])|:))*/.source.replace(//g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),o=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function i(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<>[ \t]+)?)(?:<>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return e}));return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<>/g,(function(){return r}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<>[ \t]+)?)<>(?=\s*:\s)/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return"(?:"+a+"|"+o+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:i(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:i(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:i(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:i(o),lookbehind:!0,greedy:!0},number:{pattern:i(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:n,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(a),function(e){var t=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function n(e){return e=e.replace(//g,(function(){return t})),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var r=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,a=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,(function(){return r})),o=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source;e.languages.markdown=e.languages.extend("markup",{}),e.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:e.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+a+o+"(?:"+a+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+a+o+")(?:"+a+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(r),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+a+")"+o+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+a+"$"),inside:{"table-header":{pattern:RegExp(r),alias:"important",inside:e.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:n(/\b__(?:(?!_)|_(?:(?!_))+_)+__\b|\*\*(?:(?!\*)|\*(?:(?!\*))+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n(/\b_(?:(?!_)|__(?:(?!_))+__)+_\b|\*(?:(?!\*)|\*\*(?:(?!\*))+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n(/(~~?)(?:(?!~))+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:n(/!?\[(?:(?!\]))+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\]))+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach((function(t){["url","bold","italic","strike","code-snippet"].forEach((function(n){t!==n&&(e.languages.markdown[t].inside.content.inside[n]=e.languages.markdown[n])}))})),e.hooks.add("after-tokenize",(function(e){"markdown"!==e.language&&"md"!==e.language||function e(t){if(t&&"string"!=typeof t)for(var n=0,r=t.length;n",quot:'"'},s=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(a),a.languages.graphql={comment:/#.*/,description:{pattern:/(?:"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*")(?=\s*[a-z_])/i,greedy:!0,alias:"string",inside:{"language-markdown":{pattern:/(^"(?:"")?)(?!\1)[\s\S]+(?=\1$)/,lookbehind:!0,inside:a.languages.markdown}}},string:{pattern:/"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},number:/(?:\B-|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,boolean:/\b(?:false|true)\b/,variable:/\$[a-z_]\w*/i,directive:{pattern:/@[a-z_]\w*/i,alias:"function"},"attr-name":{pattern:/\b[a-z_]\w*(?=\s*(?:\((?:[^()"]|"(?:\\.|[^\\"\r\n])*")*\))?:)/i,greedy:!0},"atom-input":{pattern:/\b[A-Z]\w*Input\b/,alias:"class-name"},scalar:/\b(?:Boolean|Float|ID|Int|String)\b/,constant:/\b[A-Z][A-Z_\d]*\b/,"class-name":{pattern:/(\b(?:enum|implements|interface|on|scalar|type|union)\s+|&\s*|:\s*|\[)[A-Z_]\w*/,lookbehind:!0},fragment:{pattern:/(\bfragment\s+|\.{3}\s*(?!on\b))[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-mutation":{pattern:/(\bmutation\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-query":{pattern:/(\bquery\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},keyword:/\b(?:directive|enum|extend|fragment|implements|input|interface|mutation|on|query|repeatable|scalar|schema|subscription|type|union)\b/,operator:/[!=|&]|\.{3}/,"property-query":/\w+(?=\s*\()/,object:/\w+(?=\s*\{)/,punctuation:/[!(){}\[\]:=,]/,property:/\w+/},a.hooks.add("after-tokenize",(function(e){if("graphql"===e.language)for(var t=e.tokens.filter((function(e){return"string"!=typeof e&&"comment"!==e.type&&"scalar"!==e.type})),n=0;n0)){var l=p(/^\{$/,/^\}$/);if(-1===l)continue;for(var s=n;s=0&&f(c,"variable-input")}}}}function u(e){return t[n+e]}function d(e,t){t=t||0;for(var n=0;n?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/},function(e){var t=e.languages.javascript["template-string"],n=t.pattern.source,r=t.inside.interpolation,a=r.inside["interpolation-punctuation"],o=r.pattern.source;function i(t,r){if(e.languages[t])return{pattern:RegExp("((?:"+r+")\\s*)"+n),lookbehind:!0,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},"embedded-code":{pattern:/[\s\S]+/,alias:t}}}}function l(e,t){return"___"+t.toUpperCase()+"_"+e+"___"}function s(t,n,r){var a={code:t,grammar:n,language:r};return e.hooks.run("before-tokenize",a),a.tokens=e.tokenize(a.code,a.grammar),e.hooks.run("after-tokenize",a),a.tokens}function c(t){var n={};n["interpolation-punctuation"]=a;var o=e.tokenize(t,n);if(3===o.length){var i=[1,1];i.push.apply(i,s(o[1],e.languages.javascript,"javascript")),o.splice.apply(o,i)}return new e.Token("interpolation",o,r.alias,t)}function u(t,n,r){var a=e.tokenize(t,{interpolation:{pattern:RegExp(o),lookbehind:!0}}),i=0,u={},d=s(a.map((function(e){if("string"==typeof e)return e;for(var n,a=e.content;-1!==t.indexOf(n=l(i++,r)););return u[n]=a,n})).join(""),n,r),p=Object.keys(u);return i=0,function e(t){for(var n=0;n=p.length)return;var r=t[n];if("string"==typeof r||"string"==typeof r.content){var a=p[i],o="string"==typeof r?r:r.content,l=o.indexOf(a);if(-1!==l){++i;var s=o.substring(0,l),d=c(u[a]),f=o.substring(l+a.length),m=[];if(s&&m.push(s),m.push(d),f){var h=[f];e(h),m.push.apply(m,h)}"string"==typeof r?(t.splice.apply(t,[n,1].concat(m)),n+=m.length-1):r.content=m}}else{var g=r.content;Array.isArray(g)?e(g):e([g])}}}(d),new e.Token(r,d,"language-"+r,t)}e.languages.javascript["template-string"]=[i("css",/\b(?:styled(?:\([^)]*\))?(?:\s*\.\s*\w+(?:\([^)]*\))*)*|css(?:\s*\.\s*(?:global|resolve))?|createGlobalStyle|keyframes)/.source),i("html",/\bhtml|\.\s*(?:inner|outer)HTML\s*\+?=/.source),i("svg",/\bsvg/.source),i("markdown",/\b(?:markdown|md)/.source),i("graphql",/\b(?:gql|graphql(?:\s*\.\s*experimental)?)/.source),i("sql",/\bsql/.source),t].filter(Boolean);var d={javascript:!0,js:!0,typescript:!0,ts:!0,jsx:!0,tsx:!0};function p(e){return"string"==typeof e?e:Array.isArray(e)?e.map(p).join(""):p(e.content)}e.hooks.add("after-tokenize",(function(t){t.language in d&&function t(n){for(var r=0,a=n.length;r]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter,delete e.languages.typescript["literal-property"];var t=e.languages.extend("typescript",{});delete t["class-name"],e.languages.typescript["class-name"].inside=t,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:t}}}}),e.languages.ts=e.languages.typescript}(a),function(e){function t(e,t){return RegExp(e.replace(//g,(function(){return/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/.source})),t)}e.languages.insertBefore("javascript","function-variable",{"method-variable":{pattern:RegExp("(\\.\\s*)"+e.languages.javascript["function-variable"].pattern.source),lookbehind:!0,alias:["function-variable","method","function","property-access"]}}),e.languages.insertBefore("javascript","function",{method:{pattern:RegExp("(\\.\\s*)"+e.languages.javascript.function.source),lookbehind:!0,alias:["function","property-access"]}}),e.languages.insertBefore("javascript","constant",{"known-class-name":[{pattern:/\b(?:(?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)?Array|ArrayBuffer|BigInt|Boolean|DataView|Date|Error|Function|Intl|JSON|(?:Weak)?(?:Map|Set)|Math|Number|Object|Promise|Proxy|Reflect|RegExp|String|Symbol|WebAssembly)\b/,alias:"class-name"},{pattern:/\b(?:[A-Z]\w*)Error\b/,alias:"class-name"}]}),e.languages.insertBefore("javascript","keyword",{imports:{pattern:t(/(\bimport\b\s*)(?:(?:\s*,\s*(?:\*\s*as\s+|\{[^{}]*\}))?|\*\s*as\s+|\{[^{}]*\})(?=\s*\bfrom\b)/.source),lookbehind:!0,inside:e.languages.javascript},exports:{pattern:t(/(\bexport\b\s*)(?:\*(?:\s*as\s+)?(?=\s*\bfrom\b)|\{[^{}]*\})/.source),lookbehind:!0,inside:e.languages.javascript}}),e.languages.javascript.keyword.unshift({pattern:/\b(?:as|default|export|from|import)\b/,alias:"module"},{pattern:/\b(?:await|break|catch|continue|do|else|finally|for|if|return|switch|throw|try|while|yield)\b/,alias:"control-flow"},{pattern:/\bnull\b/,alias:["null","nil"]},{pattern:/\bundefined\b/,alias:"nil"}),e.languages.insertBefore("javascript","operator",{spread:{pattern:/\.{3}/,alias:"operator"},arrow:{pattern:/=>/,alias:"operator"}}),e.languages.insertBefore("javascript","punctuation",{"property-access":{pattern:t(/(\.\s*)#?/.source),lookbehind:!0},"maybe-class-name":{pattern:/(^|[^$\w\xA0-\uFFFF])[A-Z][$\w\xA0-\uFFFF]+/,lookbehind:!0},dom:{pattern:/\b(?:document|(?:local|session)Storage|location|navigator|performance|window)\b/,alias:"variable"},console:{pattern:/\bconsole(?=\s*\.)/,alias:"class-name"}});for(var n=["function","function-variable","method","method-variable","property-access"],r=0;r*\.{3}(?:[^{}]|)*\})/.source;function o(e,t){return e=e.replace(//g,(function(){return n})).replace(//g,(function(){return r})).replace(//g,(function(){return a})),RegExp(e,t)}a=o(a).source,e.languages.jsx=e.languages.extend("markup",t),e.languages.jsx.tag.pattern=o(/<\/?(?:[\w.:-]+(?:+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|))?|))**\/?)?>/.source),e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.jsx.tag.inside.comment=t.comment,e.languages.insertBefore("inside","attr-name",{spread:{pattern:o(//.source),inside:e.languages.jsx}},e.languages.jsx.tag),e.languages.insertBefore("inside","special-attr",{script:{pattern:o(/=/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:e.languages.jsx}}},e.languages.jsx.tag);var i=function(e){return e?"string"==typeof e?e:"string"==typeof e.content?e.content:e.content.map(i).join(""):""},l=function(t){for(var n=[],r=0;r0&&n[n.length-1].tagName===i(a.content[0].content[1])&&n.pop():"/>"===a.content[a.content.length-1].content||n.push({tagName:i(a.content[0].content[1]),openedBraces:0}):n.length>0&&"punctuation"===a.type&&"{"===a.content?n[n.length-1].openedBraces++:n.length>0&&n[n.length-1].openedBraces>0&&"punctuation"===a.type&&"}"===a.content?n[n.length-1].openedBraces--:o=!0),(o||"string"==typeof a)&&n.length>0&&0===n[n.length-1].openedBraces){var s=i(a);r0&&("string"==typeof t[r-1]||"plain-text"===t[r-1].type)&&(s=i(t[r-1])+s,t.splice(r-1,1),r--),t[r]=new e.Token("plain-text",s,null,s)}a.content&&"string"!=typeof a.content&&l(a.content)}};e.hooks.add("after-tokenize",(function(e){"jsx"!==e.language&&"tsx"!==e.language||l(e.tokens)}))}(a),function(e){e.languages.diff={coord:[/^(?:\*{3}|-{3}|\+{3}).*$/m,/^@@.*@@$/m,/^\d.*$/m]};var t={"deleted-sign":"-","deleted-arrow":"<","inserted-sign":"+","inserted-arrow":">",unchanged:" ",diff:"!"};Object.keys(t).forEach((function(n){var r=t[n],a=[];/^\w+$/.test(n)||a.push(/\w+/.exec(n)[0]),"diff"===n&&a.push("bold"),e.languages.diff[n]={pattern:RegExp("^(?:["+r+"].*(?:\r\n?|\n|(?![\\s\\S])))+","m"),alias:a,inside:{line:{pattern:/(.)(?=[\s\S]).*(?:\r\n?|\n)?/,lookbehind:!0},prefix:{pattern:/[\s\S]/,alias:/\w+/.exec(n)[0]}}}})),Object.defineProperty(e.languages.diff,"PREFIXES",{value:t})}(a),a.languages.git={comment:/^#.*/m,deleted:/^[-\u2013].*/m,inserted:/^\+.*/m,string:/("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,command:{pattern:/^.*\$ git .*$/m,inside:{parameter:/\s--?\w+/}},coord:/^@@.*@@$/m,"commit-sha1":/^commit \w{40}$/m},a.languages.go=a.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),a.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete a.languages.go["class-name"],function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,a,o){if(n.language===r){var i=n.tokenStack=[];n.code=n.code.replace(a,(function(e){if("function"==typeof o&&!o(e))return e;for(var a,l=i.length;-1!==n.code.indexOf(a=t(r,l));)++l;return i[l]=e,a})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var a=0,o=Object.keys(n.tokenStack);!function i(l){for(var s=0;s=o.length);s++){var c=l[s];if("string"==typeof c||c.content&&"string"==typeof c.content){var u=o[a],d=n.tokenStack[u],p="string"==typeof c?c:c.content,f=t(r,u),m=p.indexOf(f);if(m>-1){++a;var h=p.substring(0,m),g=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),b=p.substring(m+f.length),v=[];h&&v.push.apply(v,i([h])),v.push(g),b&&v.push.apply(v,i([b])),"string"==typeof c?l.splice.apply(l,[s,1].concat(v)):c.content=v}}else c.content&&i(c.content)}return l}(n.tokens)}}}})}(a),function(e){e.languages.handlebars={comment:/\{\{![\s\S]*?\}\}/,delimiter:{pattern:/^\{\{\{?|\}\}\}?$/,alias:"punctuation"},string:/(["'])(?:\\.|(?!\1)[^\\\r\n])*\1/,number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee][+-]?\d+)?/,boolean:/\b(?:false|true)\b/,block:{pattern:/^(\s*(?:~\s*)?)[#\/]\S+?(?=\s*(?:~\s*)?$|\s)/,lookbehind:!0,alias:"keyword"},brackets:{pattern:/\[[^\]]+\]/,inside:{punctuation:/\[|\]/,variable:/[\s\S]+/}},punctuation:/[!"#%&':()*+,.\/;<=>@\[\\\]^`{|}~]/,variable:/[^!"#%&'()*+,\/;<=>@\[\\\]^`{|}~\s]+/},e.hooks.add("before-tokenize",(function(t){e.languages["markup-templating"].buildPlaceholders(t,"handlebars",/\{\{\{[\s\S]+?\}\}\}|\{\{[\s\S]+?\}\}/g)})),e.hooks.add("after-tokenize",(function(t){e.languages["markup-templating"].tokenizePlaceholders(t,"handlebars")})),e.languages.hbs=e.languages.handlebars}(a),a.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},a.languages.webmanifest=a.languages.json,a.languages.less=a.languages.extend("css",{comment:[/\/\*[\s\S]*?\*\//,{pattern:/(^|[^\\])\/\/.*/,lookbehind:!0}],atrule:{pattern:/@[\w-](?:\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{punctuation:/[:()]/}},selector:{pattern:/(?:@\{[\w-]+\}|[^{};\s@])(?:@\{[\w-]+\}|\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};@\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{variable:/@+[\w-]+/}},property:/(?:@\{[\w-]+\}|[\w-])+(?:\+_?)?(?=\s*:)/,operator:/[+\-*\/]/}),a.languages.insertBefore("less","property",{variable:[{pattern:/@[\w-]+\s*:/,inside:{punctuation:/:/}},/@@?[\w-]+/],"mixin-usage":{pattern:/([{;]\s*)[.#](?!\d)[\w-].*?(?=[(;])/,lookbehind:!0,alias:"function"}}),a.languages.makefile={comment:{pattern:/(^|[^\\])#(?:\\(?:\r\n|[\s\S])|[^\\\r\n])*/,lookbehind:!0},string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"builtin-target":{pattern:/\.[A-Z][^:#=\s]+(?=\s*:(?!=))/,alias:"builtin"},target:{pattern:/^(?:[^:=\s]|[ \t]+(?![\s:]))+(?=\s*:(?!=))/m,alias:"symbol",inside:{variable:/\$+(?:(?!\$)[^(){}:#=\s]+|(?=[({]))/}},variable:/\$+(?:(?!\$)[^(){}:#=\s]+|\([@*%<^+?][DF]\)|(?=[({]))/,keyword:/-include\b|\b(?:define|else|endef|endif|export|ifn?def|ifn?eq|include|override|private|sinclude|undefine|unexport|vpath)\b/,function:{pattern:/(\()(?:abspath|addsuffix|and|basename|call|dir|error|eval|file|filter(?:-out)?|findstring|firstword|flavor|foreach|guile|if|info|join|lastword|load|notdir|or|origin|patsubst|realpath|shell|sort|strip|subst|suffix|value|warning|wildcard|word(?:list|s)?)(?=[ \t])/,lookbehind:!0},operator:/(?:::|[?:+!])?=|[|@]/,punctuation:/[:;(){}]/},a.languages.objectivec=a.languages.extend("c",{string:{pattern:/@?"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},keyword:/\b(?:asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|in|inline|int|long|register|return|self|short|signed|sizeof|static|struct|super|switch|typedef|typeof|union|unsigned|void|volatile|while)\b|(?:@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b/,operator:/-[->]?|\+\+?|!=?|<>?=?|==?|&&?|\|\|?|[~^%?*\/@]/}),delete a.languages.objectivec["class-name"],a.languages.objc=a.languages.objectivec,a.languages.ocaml={comment:{pattern:/\(\*[\s\S]*?\*\)/,greedy:!0},char:{pattern:/'(?:[^\\\r\n']|\\(?:.|[ox]?[0-9a-f]{1,3}))'/i,greedy:!0},string:[{pattern:/"(?:\\(?:[\s\S]|\r\n)|[^\\\r\n"])*"/,greedy:!0},{pattern:/\{([a-z_]*)\|[\s\S]*?\|\1\}/,greedy:!0}],number:[/\b(?:0b[01][01_]*|0o[0-7][0-7_]*)\b/i,/\b0x[a-f0-9][a-f0-9_]*(?:\.[a-f0-9_]*)?(?:p[+-]?\d[\d_]*)?(?!\w)/i,/\b\d[\d_]*(?:\.[\d_]*)?(?:e[+-]?\d[\d_]*)?(?!\w)/i],directive:{pattern:/\B#\w+/,alias:"property"},label:{pattern:/\B~\w+/,alias:"property"},"type-variable":{pattern:/\B'\w+/,alias:"function"},variant:{pattern:/`\w+/,alias:"symbol"},keyword:/\b(?:as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|match|method|module|mutable|new|nonrec|object|of|open|private|rec|sig|struct|then|to|try|type|val|value|virtual|when|where|while|with)\b/,boolean:/\b(?:false|true)\b/,"operator-like-punctuation":{pattern:/\[[<>|]|[>|]\]|\{<|>\}/,alias:"punctuation"},operator:/\.[.~]|:[=>]|[=<>@^|&+\-*\/$%!?~][!$%&*+\-.\/:<=>?@^|~]*|\b(?:and|asr|land|lor|lsl|lsr|lxor|mod|or)\b/,punctuation:/;;|::|[(){}\[\].,:;#]|\b_\b/},a.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},a.languages.python["string-interpolation"].inside.interpolation.inside.rest=a.languages.python,a.languages.py=a.languages.python,a.languages.reason=a.languages.extend("clike",{string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^\\\r\n"])*"/,greedy:!0},"class-name":/\b[A-Z]\w*/,keyword:/\b(?:and|as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|method|module|mutable|new|nonrec|object|of|open|or|private|rec|sig|struct|switch|then|to|try|type|val|virtual|when|while|with)\b/,operator:/\.{3}|:[:=]|\|>|->|=(?:==?|>)?|<=?|>=?|[|^?'#!~`]|[+\-*\/]\.?|\b(?:asr|land|lor|lsl|lsr|lxor|mod)\b/}),a.languages.insertBefore("reason","class-name",{char:{pattern:/'(?:\\x[\da-f]{2}|\\o[0-3][0-7][0-7]|\\\d{3}|\\.|[^'\\\r\n])'/,greedy:!0},constructor:/\b[A-Z]\w*\b(?!\s*\.)/,label:{pattern:/\b[a-z]\w*(?=::)/,alias:"symbol"}}),delete a.languages.reason.function,function(e){e.languages.sass=e.languages.extend("css",{comment:{pattern:/^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t].+)*/m,lookbehind:!0,greedy:!0}}),e.languages.insertBefore("sass","atrule",{"atrule-line":{pattern:/^(?:[ \t]*)[@+=].+/m,greedy:!0,inside:{atrule:/(?:@[\w-]+|[+=])/}}}),delete e.languages.sass.atrule;var t=/\$[-\w]+|#\{\$[-\w]+\}/,n=[/[+*\/%]|[=!]=|<=?|>=?|\b(?:and|not|or)\b/,{pattern:/(\s)-(?=\s)/,lookbehind:!0}];e.languages.insertBefore("sass","property",{"variable-line":{pattern:/^[ \t]*\$.+/m,greedy:!0,inside:{punctuation:/:/,variable:t,operator:n}},"property-line":{pattern:/^[ \t]*(?:[^:\s]+ *:.*|:[^:\s].*)/m,greedy:!0,inside:{property:[/[^:\s]+(?=\s*:)/,{pattern:/(:)[^:\s]+/,lookbehind:!0}],punctuation:/:/,variable:t,operator:n,important:e.languages.sass.important}}}),delete e.languages.sass.property,delete e.languages.sass.important,e.languages.insertBefore("sass","punctuation",{selector:{pattern:/^([ \t]*)\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*(?:,(?:\r?\n|\r)\1[ \t]+\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*)*/m,lookbehind:!0,greedy:!0}})}(a),a.languages.scss=a.languages.extend("css",{comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},atrule:{pattern:/@[\w-](?:\([^()]+\)|[^()\s]|\s+(?!\s))*?(?=\s+[{;])/,inside:{rule:/@[\w-]+/}},url:/(?:[-a-z]+-)?url(?=\()/i,selector:{pattern:/(?=\S)[^@;{}()]?(?:[^@;{}()\s]|\s+(?!\s)|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}][^:{}]*[:{][^}]))/,inside:{parent:{pattern:/&/,alias:"important"},placeholder:/%[-\w]+/,variable:/\$[-\w]+|#\{\$[-\w]+\}/}},property:{pattern:/(?:[-\w]|\$[-\w]|#\{\$[-\w]+\})+(?=\s*:)/,inside:{variable:/\$[-\w]+|#\{\$[-\w]+\}/}}}),a.languages.insertBefore("scss","atrule",{keyword:[/@(?:content|debug|each|else(?: if)?|extend|for|forward|function|if|import|include|mixin|return|use|warn|while)\b/i,{pattern:/( )(?:from|through)(?= )/,lookbehind:!0}]}),a.languages.insertBefore("scss","important",{variable:/\$[-\w]+|#\{\$[-\w]+\}/}),a.languages.insertBefore("scss","function",{"module-modifier":{pattern:/\b(?:as|hide|show|with)\b/i,alias:"keyword"},placeholder:{pattern:/%[-\w]+/,alias:"selector"},statement:{pattern:/\B!(?:default|optional)\b/i,alias:"keyword"},boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"},operator:{pattern:/(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|not|or)(?=\s)/,lookbehind:!0}}),a.languages.scss.atrule.inside.rest=a.languages.scss,function(e){var t={pattern:/(\b\d+)(?:%|[a-z]+)/,lookbehind:!0},n={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0},r={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},url:{pattern:/\burl\((["']?).*?\1\)/i,greedy:!0},string:{pattern:/("|')(?:(?!\1)[^\\\r\n]|\\(?:\r\n|[\s\S]))*\1/,greedy:!0},interpolation:null,func:null,important:/\B!(?:important|optional)\b/i,keyword:{pattern:/(^|\s+)(?:(?:else|for|if|return|unless)(?=\s|$)|@[\w-]+)/,lookbehind:!0},hexcode:/#[\da-f]{3,6}/i,color:[/\b(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)\b/i,{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:t,number:n,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:t,boolean:/\b(?:false|true)\b/,operator:[/~|[+!\/%<>?=]=?|[-:]=|\*[*=]?|\.{2,3}|&&|\|\||\B-\B|\b(?:and|in|is(?: a| defined| not|nt)?|not|or)\b/],number:n,punctuation:/[{}()\[\];:,]/};r.interpolation={pattern:/\{[^\r\n}:]+\}/,alias:"variable",inside:{delimiter:{pattern:/^\{|\}$/,alias:"punctuation"},rest:r}},r.func={pattern:/[\w-]+\([^)]*\).*/,inside:{function:/^[^(]+/,rest:r}},e.languages.stylus={"atrule-declaration":{pattern:/(^[ \t]*)@.+/m,lookbehind:!0,inside:{atrule:/^@[\w-]+/,rest:r}},"variable-declaration":{pattern:/(^[ \t]*)[\w$-]+\s*.?=[ \t]*(?:\{[^{}]*\}|\S.*|$)/m,lookbehind:!0,inside:{variable:/^\S+/,rest:r}},statement:{pattern:/(^[ \t]*)(?:else|for|if|return|unless)[ \t].+/m,lookbehind:!0,inside:{keyword:/^\S+/,rest:r}},"property-declaration":{pattern:/((?:^|\{)([ \t]*))(?:[\w-]|\{[^}\r\n]+\})+(?:\s*:\s*|[ \t]+)(?!\s)[^{\r\n]*(?:;|[^{\r\n,]$(?!(?:\r?\n|\r)(?:\{|\2[ \t])))/m,lookbehind:!0,inside:{property:{pattern:/^[^\s:]+/,inside:{interpolation:r.interpolation}},rest:r}},selector:{pattern:/(^[ \t]*)(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)(?:(?:\r?\n|\r)(?:\1(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)))*(?:,$|\{|(?=(?:\r?\n|\r)(?:\{|\1[ \t])))/m,lookbehind:!0,inside:{interpolation:r.interpolation,comment:r.comment,punctuation:/[{},]/}},func:r.func,string:r.string,comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0,greedy:!0},interpolation:r.interpolation,punctuation:/[{}()\[\];:.]/}}(a),function(e){var t=e.util.clone(e.languages.typescript);e.languages.tsx=e.languages.extend("jsx",t),delete e.languages.tsx.parameter,delete e.languages.tsx["literal-property"];var n=e.languages.tsx.tag;n.pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+n.pattern.source+")",n.pattern.flags),n.lookbehind=!0}(a),a.languages.wasm={comment:[/\(;[\s\S]*?;\)/,{pattern:/;;.*/,greedy:!0}],string:{pattern:/"(?:\\[\s\S]|[^"\\])*"/,greedy:!0},keyword:[{pattern:/\b(?:align|offset)=/,inside:{operator:/=/}},{pattern:/\b(?:(?:f32|f64|i32|i64)(?:\.(?:abs|add|and|ceil|clz|const|convert_[su]\/i(?:32|64)|copysign|ctz|demote\/f64|div(?:_[su])?|eqz?|extend_[su]\/i32|floor|ge(?:_[su])?|gt(?:_[su])?|le(?:_[su])?|load(?:(?:8|16|32)_[su])?|lt(?:_[su])?|max|min|mul|neg?|nearest|or|popcnt|promote\/f32|reinterpret\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|sqrt|store(?:8|16|32)?|sub|trunc(?:_[su]\/f(?:32|64))?|wrap\/i64|xor))?|memory\.(?:grow|size))\b/,inside:{punctuation:/\./}},/\b(?:anyfunc|block|br(?:_if|_table)?|call(?:_indirect)?|data|drop|elem|else|end|export|func|get_(?:global|local)|global|if|import|local|loop|memory|module|mut|nop|offset|param|result|return|select|set_(?:global|local)|start|table|tee_local|then|type|unreachable)\b/],variable:/\$[\w!#$%&'*+\-./:<=>?@\\^`|~]+/,number:/[+-]?\b(?:\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?|0x[\da-fA-F](?:_?[\da-fA-F])*(?:\.[\da-fA-F](?:_?[\da-fA-D])*)?(?:[pP][+-]?\d(?:_?\d)*)?)\b|\binf\b|\bnan(?::0x[\da-fA-F](?:_?[\da-fA-D])*)?\b/,punctuation:/[()]/};const o=a},9901:e=>{e.exports&&(e.exports={core:{meta:{path:"components/prism-core.js",option:"mandatory"},core:"Core"},themes:{meta:{path:"themes/{id}.css",link:"index.html?theme={id}",exclusive:!0},prism:{title:"Default",option:"default"},"prism-dark":"Dark","prism-funky":"Funky","prism-okaidia":{title:"Okaidia",owner:"ocodia"},"prism-twilight":{title:"Twilight",owner:"remybach"},"prism-coy":{title:"Coy",owner:"tshedor"},"prism-solarizedlight":{title:"Solarized Light",owner:"hectormatos2011 "},"prism-tomorrow":{title:"Tomorrow Night",owner:"Rosey"}},languages:{meta:{path:"components/prism-{id}",noCSS:!0,examplesPath:"examples/prism-{id}",addCheckAll:!0},markup:{title:"Markup",alias:["html","xml","svg","mathml","ssml","atom","rss"],aliasTitles:{html:"HTML",xml:"XML",svg:"SVG",mathml:"MathML",ssml:"SSML",atom:"Atom",rss:"RSS"},option:"default"},css:{title:"CSS",option:"default",modify:"markup"},clike:{title:"C-like",option:"default"},javascript:{title:"JavaScript",require:"clike",modify:"markup",optional:"regex",alias:"js",option:"default"},abap:{title:"ABAP",owner:"dellagustin"},abnf:{title:"ABNF",owner:"RunDevelopment"},actionscript:{title:"ActionScript",require:"javascript",modify:"markup",owner:"Golmote"},ada:{title:"Ada",owner:"Lucretia"},agda:{title:"Agda",owner:"xy-ren"},al:{title:"AL",owner:"RunDevelopment"},antlr4:{title:"ANTLR4",alias:"g4",owner:"RunDevelopment"},apacheconf:{title:"Apache Configuration",owner:"GuiTeK"},apex:{title:"Apex",require:["clike","sql"],owner:"RunDevelopment"},apl:{title:"APL",owner:"ngn"},applescript:{title:"AppleScript",owner:"Golmote"},aql:{title:"AQL",owner:"RunDevelopment"},arduino:{title:"Arduino",require:"cpp",alias:"ino",owner:"dkern"},arff:{title:"ARFF",owner:"Golmote"},armasm:{title:"ARM Assembly",alias:"arm-asm",owner:"RunDevelopment"},arturo:{title:"Arturo",alias:"art",optional:["bash","css","javascript","markup","markdown","sql"],owner:"drkameleon"},asciidoc:{alias:"adoc",title:"AsciiDoc",owner:"Golmote"},aspnet:{title:"ASP.NET (C#)",require:["markup","csharp"],owner:"nauzilus"},asm6502:{title:"6502 Assembly",owner:"kzurawel"},asmatmel:{title:"Atmel AVR Assembly",owner:"cerkit"},autohotkey:{title:"AutoHotkey",owner:"aviaryan"},autoit:{title:"AutoIt",owner:"Golmote"},avisynth:{title:"AviSynth",alias:"avs",owner:"Zinfidel"},"avro-idl":{title:"Avro IDL",alias:"avdl",owner:"RunDevelopment"},awk:{title:"AWK",alias:"gawk",aliasTitles:{gawk:"GAWK"},owner:"RunDevelopment"},bash:{title:"Bash",alias:["sh","shell"],aliasTitles:{sh:"Shell",shell:"Shell"},owner:"zeitgeist87"},basic:{title:"BASIC",owner:"Golmote"},batch:{title:"Batch",owner:"Golmote"},bbcode:{title:"BBcode",alias:"shortcode",aliasTitles:{shortcode:"Shortcode"},owner:"RunDevelopment"},bbj:{title:"BBj",owner:"hyyan"},bicep:{title:"Bicep",owner:"johnnyreilly"},birb:{title:"Birb",require:"clike",owner:"Calamity210"},bison:{title:"Bison",require:"c",owner:"Golmote"},bnf:{title:"BNF",alias:"rbnf",aliasTitles:{rbnf:"RBNF"},owner:"RunDevelopment"},bqn:{title:"BQN",owner:"yewscion"},brainfuck:{title:"Brainfuck",owner:"Golmote"},brightscript:{title:"BrightScript",owner:"RunDevelopment"},bro:{title:"Bro",owner:"wayward710"},bsl:{title:"BSL (1C:Enterprise)",alias:"oscript",aliasTitles:{oscript:"OneScript"},owner:"Diversus23"},c:{title:"C",require:"clike",owner:"zeitgeist87"},csharp:{title:"C#",require:"clike",alias:["cs","dotnet"],owner:"mvalipour"},cpp:{title:"C++",require:"c",owner:"zeitgeist87"},cfscript:{title:"CFScript",require:"clike",alias:"cfc",owner:"mjclemente"},chaiscript:{title:"ChaiScript",require:["clike","cpp"],owner:"RunDevelopment"},cil:{title:"CIL",owner:"sbrl"},cilkc:{title:"Cilk/C",require:"c",alias:"cilk-c",owner:"OpenCilk"},cilkcpp:{title:"Cilk/C++",require:"cpp",alias:["cilk-cpp","cilk"],owner:"OpenCilk"},clojure:{title:"Clojure",owner:"troglotit"},cmake:{title:"CMake",owner:"mjrogozinski"},cobol:{title:"COBOL",owner:"RunDevelopment"},coffeescript:{title:"CoffeeScript",require:"javascript",alias:"coffee",owner:"R-osey"},concurnas:{title:"Concurnas",alias:"conc",owner:"jasontatton"},csp:{title:"Content-Security-Policy",owner:"ScottHelme"},cooklang:{title:"Cooklang",owner:"ahue"},coq:{title:"Coq",owner:"RunDevelopment"},crystal:{title:"Crystal",require:"ruby",owner:"MakeNowJust"},"css-extras":{title:"CSS Extras",require:"css",modify:"css",owner:"milesj"},csv:{title:"CSV",owner:"RunDevelopment"},cue:{title:"CUE",owner:"RunDevelopment"},cypher:{title:"Cypher",owner:"RunDevelopment"},d:{title:"D",require:"clike",owner:"Golmote"},dart:{title:"Dart",require:"clike",owner:"Golmote"},dataweave:{title:"DataWeave",owner:"machaval"},dax:{title:"DAX",owner:"peterbud"},dhall:{title:"Dhall",owner:"RunDevelopment"},diff:{title:"Diff",owner:"uranusjr"},django:{title:"Django/Jinja2",require:"markup-templating",alias:"jinja2",owner:"romanvm"},"dns-zone-file":{title:"DNS zone file",owner:"RunDevelopment",alias:"dns-zone"},docker:{title:"Docker",alias:"dockerfile",owner:"JustinBeckwith"},dot:{title:"DOT (Graphviz)",alias:"gv",optional:"markup",owner:"RunDevelopment"},ebnf:{title:"EBNF",owner:"RunDevelopment"},editorconfig:{title:"EditorConfig",owner:"osipxd"},eiffel:{title:"Eiffel",owner:"Conaclos"},ejs:{title:"EJS",require:["javascript","markup-templating"],owner:"RunDevelopment",alias:"eta",aliasTitles:{eta:"Eta"}},elixir:{title:"Elixir",owner:"Golmote"},elm:{title:"Elm",owner:"zwilias"},etlua:{title:"Embedded Lua templating",require:["lua","markup-templating"],owner:"RunDevelopment"},erb:{title:"ERB",require:["ruby","markup-templating"],owner:"Golmote"},erlang:{title:"Erlang",owner:"Golmote"},"excel-formula":{title:"Excel Formula",alias:["xlsx","xls"],owner:"RunDevelopment"},fsharp:{title:"F#",require:"clike",owner:"simonreynolds7"},factor:{title:"Factor",owner:"catb0t"},false:{title:"False",owner:"edukisto"},"firestore-security-rules":{title:"Firestore security rules",require:"clike",owner:"RunDevelopment"},flow:{title:"Flow",require:"javascript",owner:"Golmote"},fortran:{title:"Fortran",owner:"Golmote"},ftl:{title:"FreeMarker Template Language",require:"markup-templating",owner:"RunDevelopment"},gml:{title:"GameMaker Language",alias:"gamemakerlanguage",require:"clike",owner:"LiarOnce"},gap:{title:"GAP (CAS)",owner:"RunDevelopment"},gcode:{title:"G-code",owner:"RunDevelopment"},gdscript:{title:"GDScript",owner:"RunDevelopment"},gedcom:{title:"GEDCOM",owner:"Golmote"},gettext:{title:"gettext",alias:"po",owner:"RunDevelopment"},gherkin:{title:"Gherkin",owner:"hason"},git:{title:"Git",owner:"lgiraudel"},glsl:{title:"GLSL",require:"c",owner:"Golmote"},gn:{title:"GN",alias:"gni",owner:"RunDevelopment"},"linker-script":{title:"GNU Linker Script",alias:"ld",owner:"RunDevelopment"},go:{title:"Go",require:"clike",owner:"arnehormann"},"go-module":{title:"Go module",alias:"go-mod",owner:"RunDevelopment"},gradle:{title:"Gradle",require:"clike",owner:"zeabdelkhalek-badido18"},graphql:{title:"GraphQL",optional:"markdown",owner:"Golmote"},groovy:{title:"Groovy",require:"clike",owner:"robfletcher"},haml:{title:"Haml",require:"ruby",optional:["css","css-extras","coffeescript","erb","javascript","less","markdown","scss","textile"],owner:"Golmote"},handlebars:{title:"Handlebars",require:"markup-templating",alias:["hbs","mustache"],aliasTitles:{mustache:"Mustache"},owner:"Golmote"},haskell:{title:"Haskell",alias:"hs",owner:"bholst"},haxe:{title:"Haxe",require:"clike",optional:"regex",owner:"Golmote"},hcl:{title:"HCL",owner:"outsideris"},hlsl:{title:"HLSL",require:"c",owner:"RunDevelopment"},hoon:{title:"Hoon",owner:"matildepark"},http:{title:"HTTP",optional:["csp","css","hpkp","hsts","javascript","json","markup","uri"],owner:"danielgtaylor"},hpkp:{title:"HTTP Public-Key-Pins",owner:"ScottHelme"},hsts:{title:"HTTP Strict-Transport-Security",owner:"ScottHelme"},ichigojam:{title:"IchigoJam",owner:"BlueCocoa"},icon:{title:"Icon",owner:"Golmote"},"icu-message-format":{title:"ICU Message Format",owner:"RunDevelopment"},idris:{title:"Idris",alias:"idr",owner:"KeenS",require:"haskell"},ignore:{title:".ignore",owner:"osipxd",alias:["gitignore","hgignore","npmignore"],aliasTitles:{gitignore:".gitignore",hgignore:".hgignore",npmignore:".npmignore"}},inform7:{title:"Inform 7",owner:"Golmote"},ini:{title:"Ini",owner:"aviaryan"},io:{title:"Io",owner:"AlesTsurko"},j:{title:"J",owner:"Golmote"},java:{title:"Java",require:"clike",owner:"sherblot"},javadoc:{title:"JavaDoc",require:["markup","java","javadoclike"],modify:"java",optional:"scala",owner:"RunDevelopment"},javadoclike:{title:"JavaDoc-like",modify:["java","javascript","php"],owner:"RunDevelopment"},javastacktrace:{title:"Java stack trace",owner:"RunDevelopment"},jexl:{title:"Jexl",owner:"czosel"},jolie:{title:"Jolie",require:"clike",owner:"thesave"},jq:{title:"JQ",owner:"RunDevelopment"},jsdoc:{title:"JSDoc",require:["javascript","javadoclike","typescript"],modify:"javascript",optional:["actionscript","coffeescript"],owner:"RunDevelopment"},"js-extras":{title:"JS Extras",require:"javascript",modify:"javascript",optional:["actionscript","coffeescript","flow","n4js","typescript"],owner:"RunDevelopment"},json:{title:"JSON",alias:"webmanifest",aliasTitles:{webmanifest:"Web App Manifest"},owner:"CupOfTea696"},json5:{title:"JSON5",require:"json",owner:"RunDevelopment"},jsonp:{title:"JSONP",require:"json",owner:"RunDevelopment"},jsstacktrace:{title:"JS stack trace",owner:"sbrl"},"js-templates":{title:"JS Templates",require:"javascript",modify:"javascript",optional:["css","css-extras","graphql","markdown","markup","sql"],owner:"RunDevelopment"},julia:{title:"Julia",owner:"cdagnino"},keepalived:{title:"Keepalived Configure",owner:"dev-itsheng"},keyman:{title:"Keyman",owner:"mcdurdin"},kotlin:{title:"Kotlin",alias:["kt","kts"],aliasTitles:{kts:"Kotlin Script"},require:"clike",owner:"Golmote"},kumir:{title:"KuMir (\u041a\u0443\u041c\u0438\u0440)",alias:"kum",owner:"edukisto"},kusto:{title:"Kusto",owner:"RunDevelopment"},latex:{title:"LaTeX",alias:["tex","context"],aliasTitles:{tex:"TeX",context:"ConTeXt"},owner:"japborst"},latte:{title:"Latte",require:["clike","markup-templating","php"],owner:"nette"},less:{title:"Less",require:"css",optional:"css-extras",owner:"Golmote"},lilypond:{title:"LilyPond",require:"scheme",alias:"ly",owner:"RunDevelopment"},liquid:{title:"Liquid",require:"markup-templating",owner:"cinhtau"},lisp:{title:"Lisp",alias:["emacs","elisp","emacs-lisp"],owner:"JuanCaicedo"},livescript:{title:"LiveScript",owner:"Golmote"},llvm:{title:"LLVM IR",owner:"porglezomp"},log:{title:"Log file",optional:"javastacktrace",owner:"RunDevelopment"},lolcode:{title:"LOLCODE",owner:"Golmote"},lua:{title:"Lua",owner:"Golmote"},magma:{title:"Magma (CAS)",owner:"RunDevelopment"},makefile:{title:"Makefile",owner:"Golmote"},markdown:{title:"Markdown",require:"markup",optional:"yaml",alias:"md",owner:"Golmote"},"markup-templating":{title:"Markup templating",require:"markup",owner:"Golmote"},mata:{title:"Mata",owner:"RunDevelopment"},matlab:{title:"MATLAB",owner:"Golmote"},maxscript:{title:"MAXScript",owner:"RunDevelopment"},mel:{title:"MEL",owner:"Golmote"},mermaid:{title:"Mermaid",owner:"RunDevelopment"},metafont:{title:"METAFONT",owner:"LaeriExNihilo"},mizar:{title:"Mizar",owner:"Golmote"},mongodb:{title:"MongoDB",owner:"airs0urce",require:"javascript"},monkey:{title:"Monkey",owner:"Golmote"},moonscript:{title:"MoonScript",alias:"moon",owner:"RunDevelopment"},n1ql:{title:"N1QL",owner:"TMWilds"},n4js:{title:"N4JS",require:"javascript",optional:"jsdoc",alias:"n4jsd",owner:"bsmith-n4"},"nand2tetris-hdl":{title:"Nand To Tetris HDL",owner:"stephanmax"},naniscript:{title:"Naninovel Script",owner:"Elringus",alias:"nani"},nasm:{title:"NASM",owner:"rbmj"},neon:{title:"NEON",owner:"nette"},nevod:{title:"Nevod",owner:"nezaboodka"},nginx:{title:"nginx",owner:"volado"},nim:{title:"Nim",owner:"Golmote"},nix:{title:"Nix",owner:"Golmote"},nsis:{title:"NSIS",owner:"idleberg"},objectivec:{title:"Objective-C",require:"c",alias:"objc",owner:"uranusjr"},ocaml:{title:"OCaml",owner:"Golmote"},odin:{title:"Odin",owner:"edukisto"},opencl:{title:"OpenCL",require:"c",modify:["c","cpp"],owner:"Milania1"},openqasm:{title:"OpenQasm",alias:"qasm",owner:"RunDevelopment"},oz:{title:"Oz",owner:"Golmote"},parigp:{title:"PARI/GP",owner:"Golmote"},parser:{title:"Parser",require:"markup",owner:"Golmote"},pascal:{title:"Pascal",alias:"objectpascal",aliasTitles:{objectpascal:"Object Pascal"},owner:"Golmote"},pascaligo:{title:"Pascaligo",owner:"DefinitelyNotAGoat"},psl:{title:"PATROL Scripting Language",owner:"bertysentry"},pcaxis:{title:"PC-Axis",alias:"px",owner:"RunDevelopment"},peoplecode:{title:"PeopleCode",alias:"pcode",owner:"RunDevelopment"},perl:{title:"Perl",owner:"Golmote"},php:{title:"PHP",require:"markup-templating",owner:"milesj"},phpdoc:{title:"PHPDoc",require:["php","javadoclike"],modify:"php",owner:"RunDevelopment"},"php-extras":{title:"PHP Extras",require:"php",modify:"php",owner:"milesj"},"plant-uml":{title:"PlantUML",alias:"plantuml",owner:"RunDevelopment"},plsql:{title:"PL/SQL",require:"sql",owner:"Golmote"},powerquery:{title:"PowerQuery",alias:["pq","mscript"],owner:"peterbud"},powershell:{title:"PowerShell",owner:"nauzilus"},processing:{title:"Processing",require:"clike",owner:"Golmote"},prolog:{title:"Prolog",owner:"Golmote"},promql:{title:"PromQL",owner:"arendjr"},properties:{title:".properties",owner:"Golmote"},protobuf:{title:"Protocol Buffers",require:"clike",owner:"just-boris"},pug:{title:"Pug",require:["markup","javascript"],optional:["coffeescript","ejs","handlebars","less","livescript","markdown","scss","stylus","twig"],owner:"Golmote"},puppet:{title:"Puppet",owner:"Golmote"},pure:{title:"Pure",optional:["c","cpp","fortran"],owner:"Golmote"},purebasic:{title:"PureBasic",require:"clike",alias:"pbfasm",owner:"HeX0R101"},purescript:{title:"PureScript",require:"haskell",alias:"purs",owner:"sriharshachilakapati"},python:{title:"Python",alias:"py",owner:"multipetros"},qsharp:{title:"Q#",require:"clike",alias:"qs",owner:"fedonman"},q:{title:"Q (kdb+ database)",owner:"Golmote"},qml:{title:"QML",require:"javascript",owner:"RunDevelopment"},qore:{title:"Qore",require:"clike",owner:"temnroegg"},r:{title:"R",owner:"Golmote"},racket:{title:"Racket",require:"scheme",alias:"rkt",owner:"RunDevelopment"},cshtml:{title:"Razor C#",alias:"razor",require:["markup","csharp"],optional:["css","css-extras","javascript","js-extras"],owner:"RunDevelopment"},jsx:{title:"React JSX",require:["markup","javascript"],optional:["jsdoc","js-extras","js-templates"],owner:"vkbansal"},tsx:{title:"React TSX",require:["jsx","typescript"]},reason:{title:"Reason",require:"clike",owner:"Golmote"},regex:{title:"Regex",owner:"RunDevelopment"},rego:{title:"Rego",owner:"JordanSh"},renpy:{title:"Ren'py",alias:"rpy",owner:"HyuchiaDiego"},rescript:{title:"ReScript",alias:"res",owner:"vmarcosp"},rest:{title:"reST (reStructuredText)",owner:"Golmote"},rip:{title:"Rip",owner:"ravinggenius"},roboconf:{title:"Roboconf",owner:"Golmote"},robotframework:{title:"Robot Framework",alias:"robot",owner:"RunDevelopment"},ruby:{title:"Ruby",require:"clike",alias:"rb",owner:"samflores"},rust:{title:"Rust",owner:"Golmote"},sas:{title:"SAS",optional:["groovy","lua","sql"],owner:"Golmote"},sass:{title:"Sass (Sass)",require:"css",optional:"css-extras",owner:"Golmote"},scss:{title:"Sass (SCSS)",require:"css",optional:"css-extras",owner:"MoOx"},scala:{title:"Scala",require:"java",owner:"jozic"},scheme:{title:"Scheme",owner:"bacchus123"},"shell-session":{title:"Shell session",require:"bash",alias:["sh-session","shellsession"],owner:"RunDevelopment"},smali:{title:"Smali",owner:"RunDevelopment"},smalltalk:{title:"Smalltalk",owner:"Golmote"},smarty:{title:"Smarty",require:"markup-templating",optional:"php",owner:"Golmote"},sml:{title:"SML",alias:"smlnj",aliasTitles:{smlnj:"SML/NJ"},owner:"RunDevelopment"},solidity:{title:"Solidity (Ethereum)",alias:"sol",require:"clike",owner:"glachaud"},"solution-file":{title:"Solution file",alias:"sln",owner:"RunDevelopment"},soy:{title:"Soy (Closure Template)",require:"markup-templating",owner:"Golmote"},sparql:{title:"SPARQL",require:"turtle",owner:"Triply-Dev",alias:"rq"},"splunk-spl":{title:"Splunk SPL",owner:"RunDevelopment"},sqf:{title:"SQF: Status Quo Function (Arma 3)",require:"clike",owner:"RunDevelopment"},sql:{title:"SQL",owner:"multipetros"},squirrel:{title:"Squirrel",require:"clike",owner:"RunDevelopment"},stan:{title:"Stan",owner:"RunDevelopment"},stata:{title:"Stata Ado",require:["mata","java","python"],owner:"RunDevelopment"},iecst:{title:"Structured Text (IEC 61131-3)",owner:"serhioromano"},stylus:{title:"Stylus",owner:"vkbansal"},supercollider:{title:"SuperCollider",alias:"sclang",owner:"RunDevelopment"},swift:{title:"Swift",owner:"chrischares"},systemd:{title:"Systemd configuration file",owner:"RunDevelopment"},"t4-templating":{title:"T4 templating",owner:"RunDevelopment"},"t4-cs":{title:"T4 Text Templates (C#)",require:["t4-templating","csharp"],alias:"t4",owner:"RunDevelopment"},"t4-vb":{title:"T4 Text Templates (VB)",require:["t4-templating","vbnet"],owner:"RunDevelopment"},tap:{title:"TAP",owner:"isaacs",require:"yaml"},tcl:{title:"Tcl",owner:"PeterChaplin"},tt2:{title:"Template Toolkit 2",require:["clike","markup-templating"],owner:"gflohr"},textile:{title:"Textile",require:"markup",optional:"css",owner:"Golmote"},toml:{title:"TOML",owner:"RunDevelopment"},tremor:{title:"Tremor",alias:["trickle","troy"],owner:"darach",aliasTitles:{trickle:"trickle",troy:"troy"}},turtle:{title:"Turtle",alias:"trig",aliasTitles:{trig:"TriG"},owner:"jakubklimek"},twig:{title:"Twig",require:"markup-templating",owner:"brandonkelly"},typescript:{title:"TypeScript",require:"javascript",optional:"js-templates",alias:"ts",owner:"vkbansal"},typoscript:{title:"TypoScript",alias:"tsconfig",aliasTitles:{tsconfig:"TSConfig"},owner:"dkern"},unrealscript:{title:"UnrealScript",alias:["uscript","uc"],owner:"RunDevelopment"},uorazor:{title:"UO Razor Script",owner:"jaseowns"},uri:{title:"URI",alias:"url",aliasTitles:{url:"URL"},owner:"RunDevelopment"},v:{title:"V",require:"clike",owner:"taggon"},vala:{title:"Vala",require:"clike",optional:"regex",owner:"TemplarVolk"},vbnet:{title:"VB.Net",require:"basic",owner:"Bigsby"},velocity:{title:"Velocity",require:"markup",owner:"Golmote"},verilog:{title:"Verilog",owner:"a-rey"},vhdl:{title:"VHDL",owner:"a-rey"},vim:{title:"vim",owner:"westonganger"},"visual-basic":{title:"Visual Basic",alias:["vb","vba"],aliasTitles:{vba:"VBA"},owner:"Golmote"},warpscript:{title:"WarpScript",owner:"RunDevelopment"},wasm:{title:"WebAssembly",owner:"Golmote"},"web-idl":{title:"Web IDL",alias:"webidl",owner:"RunDevelopment"},wgsl:{title:"WGSL",owner:"Dr4gonthree"},wiki:{title:"Wiki markup",require:"markup",owner:"Golmote"},wolfram:{title:"Wolfram language",alias:["mathematica","nb","wl"],aliasTitles:{mathematica:"Mathematica",nb:"Mathematica Notebook"},owner:"msollami"},wren:{title:"Wren",owner:"clsource"},xeora:{title:"Xeora",require:"markup",alias:"xeoracube",aliasTitles:{xeoracube:"XeoraCube"},owner:"freakmaxi"},"xml-doc":{title:"XML doc (.net)",require:"markup",modify:["csharp","fsharp","vbnet"],owner:"RunDevelopment"},xojo:{title:"Xojo (REALbasic)",owner:"Golmote"},xquery:{title:"XQuery",require:"markup",owner:"Golmote"},yaml:{title:"YAML",alias:"yml",owner:"hason"},yang:{title:"YANG",owner:"RunDevelopment"},zig:{title:"Zig",owner:"RunDevelopment"}},plugins:{meta:{path:"plugins/{id}/prism-{id}",link:"plugins/{id}/"},"line-highlight":{title:"Line Highlight",description:"Highlights specific lines and/or line ranges."},"line-numbers":{title:"Line Numbers",description:"Line number at the beginning of code lines.",owner:"kuba-kubula"},"show-invisibles":{title:"Show Invisibles",description:"Show hidden characters such as tabs and line breaks.",optional:["autolinker","data-uri-highlight"]},autolinker:{title:"Autolinker",description:"Converts URLs and emails in code to clickable links. Parses Markdown links in comments."},wpd:{title:"WebPlatform Docs",description:'Makes tokens link to WebPlatform.org documentation. The links open in a new tab.'},"custom-class":{title:"Custom Class",description:"This plugin allows you to prefix Prism's default classes (.comment can become .namespace--comment) or replace them with your defined ones (like .editor__comment). You can even add new classes.",owner:"dvkndn",noCSS:!0},"file-highlight":{title:"File Highlight",description:"Fetch external files and highlight them with Prism. Used on the Prism website itself.",noCSS:!0},"show-language":{title:"Show Language",description:"Display the highlighted language in code blocks (inline code does not show the label).",owner:"nauzilus",noCSS:!0,require:"toolbar"},"jsonp-highlight":{title:"JSONP Highlight",description:"Fetch content with JSONP and highlight some interesting content (e.g. GitHub/Gists or Bitbucket API).",noCSS:!0,owner:"nauzilus"},"highlight-keywords":{title:"Highlight Keywords",description:"Adds special CSS classes for each keyword for fine-grained highlighting.",owner:"vkbansal",noCSS:!0},"remove-initial-line-feed":{title:"Remove initial line feed",description:"Removes the initial line feed in code blocks.",owner:"Golmote",noCSS:!0},"inline-color":{title:"Inline color",description:"Adds a small inline preview for colors in style sheets.",require:"css-extras",owner:"RunDevelopment"},previewers:{title:"Previewers",description:"Previewers for angles, colors, gradients, easing and time.",require:"css-extras",owner:"Golmote"},autoloader:{title:"Autoloader",description:"Automatically loads the needed languages to highlight the code blocks.",owner:"Golmote",noCSS:!0},"keep-markup":{title:"Keep Markup",description:"Prevents custom markup from being dropped out during highlighting.",owner:"Golmote",optional:"normalize-whitespace",noCSS:!0},"command-line":{title:"Command Line",description:"Display a command line with a prompt and, optionally, the output/response from the commands.",owner:"chriswells0"},"unescaped-markup":{title:"Unescaped Markup",description:"Write markup without having to escape anything."},"normalize-whitespace":{title:"Normalize Whitespace",description:"Supports multiple operations to normalize whitespace in code blocks.",owner:"zeitgeist87",optional:"unescaped-markup",noCSS:!0},"data-uri-highlight":{title:"Data-URI Highlight",description:"Highlights data-URI contents.",owner:"Golmote",noCSS:!0},toolbar:{title:"Toolbar",description:"Attach a toolbar for plugins to easily register buttons on the top of a code block.",owner:"mAAdhaTTah"},"copy-to-clipboard":{title:"Copy to Clipboard Button",description:"Add a button that copies the code block to the clipboard when clicked.",owner:"mAAdhaTTah",require:"toolbar",noCSS:!0},"download-button":{title:"Download Button",description:"A button in the toolbar of a code block adding a convenient way to download a code file.",owner:"Golmote",require:"toolbar",noCSS:!0},"match-braces":{title:"Match braces",description:"Highlights matching braces.",owner:"RunDevelopment"},"diff-highlight":{title:"Diff Highlight",description:"Highlights the code inside diff blocks.",owner:"RunDevelopment",require:"diff"},"filter-highlight-all":{title:"Filter highlightAll",description:"Filters the elements the highlightAll and highlightAllUnder methods actually highlight.",owner:"RunDevelopment",noCSS:!0},treeview:{title:"Treeview",description:"A language with special styles to highlight file system tree structures.",owner:"Golmote"}}})},2885:(e,t,n)=>{const r=n(9901),a=n(9642),o=new Set;function i(e){void 0===e?e=Object.keys(r.languages).filter((e=>"meta"!=e)):Array.isArray(e)||(e=[e]);const t=[...o,...Object.keys(Prism.languages)];a(r,e,t).load((e=>{if(!(e in r.languages))return void(i.silent||console.warn("Language does not exist: "+e));const t="./prism-"+e;delete n.c[n(6500).resolve(t)],delete Prism.languages[e],n(6500)(t),o.add(e)}))}i.silent=!1,e.exports=i},6726:(e,t,n)=>{var r={"./":2885};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=6726},6500:(e,t,n)=>{var r={"./":2885};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=6500},9642:e=>{"use strict";var t=function(){var e=function(){};function t(e,t){Array.isArray(e)?e.forEach(t):null!=e&&t(e,0)}function n(e){for(var t={},n=0,r=e.length;n "));var l={},s=e[r];if(s){function c(t){if(!(t in e))throw new Error(r+" depends on an unknown component "+t);if(!(t in l))for(var i in a(t,o),l[t]=!0,n[t])l[i]=!0}t(s.require,c),t(s.optional,c),t(s.modify,c)}n[r]=l,o.pop()}}return function(e){var t=n[e];return t||(a(e,r),t=n[e]),t}}function a(e){for(var t in e)return!0;return!1}return function(o,i,l){var s=function(e){var t={};for(var n in e){var r=e[n];for(var a in r)if("meta"!=a){var o=r[a];t[a]="string"==typeof o?{title:o}:o}}return t}(o),c=function(e){var n;return function(r){if(r in e)return r;if(!n)for(var a in n={},e){var o=e[a];t(o&&o.alias,(function(t){if(t in n)throw new Error(t+" cannot be alias for both "+a+" and "+n[t]);if(t in e)throw new Error(t+" cannot be alias of "+a+" because it is a component.");n[t]=a}))}return n[r]||r}}(s);i=i.map(c),l=(l||[]).map(c);var u=n(i),d=n(l);i.forEach((function e(n){var r=s[n];t(r&&r.require,(function(t){t in d||(u[t]=!0,e(t))}))}));for(var p,f=r(s),m=u;a(m);){for(var h in p={},m){var g=s[h];t(g&&g.modify,(function(e){e in d&&(p[e]=!0)}))}for(var b in d)if(!(b in u))for(var v in f(b))if(v in u){p[b]=!0;break}for(var y in m=p)u[y]=!0}var w={getIds:function(){var e=[];return w.load((function(t){e.push(t)})),e},load:function(t,n){return function(t,n,r,a){var o=a?a.series:void 0,i=a?a.parallel:e,l={},s={};function c(e){if(e in l)return l[e];s[e]=!0;var a,u=[];for(var d in t(e))d in n&&u.push(d);if(0===u.length)a=r(e);else{var p=i(u.map((function(e){var t=c(e);return delete s[e],t})));o?a=o(p,(function(){return r(e)})):r(e)}return l[e]=a}for(var u in n)c(u);var d=[];for(var p in s)d.push(l[p]);return i(d)}(f,u,t,n)}};return w}}();e.exports=t},2703:(e,t,n)=>{"use strict";var r=n(414);function a(){}function o(){}o.resetWarningCache=a,e.exports=function(){function e(e,t,n,a,o,i){if(i!==r){var l=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw l.name="Invariant Violation",l}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:o,resetWarningCache:a};return n.PropTypes=n,n}},5697:(e,t,n)=>{e.exports=n(2703)()},414:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},4448:(e,t,n)=>{"use strict";var r=n(7294),a=n(7418),o=n(3840);function i(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n