1"use strict";(self.webpackChunktoolkit_site_docusaurus=self.webpackChunktoolkit_site_docusaurus||[]).push([[1115],{1852:(e,t,a)=>{a.d(t,{A:()=>o});a(96540),a(51410),a(40797),a(27143),a(86871),a(61934),a(64973);var n=a(83750),s=(a(84060),a(74848));function o(e){let{vector:t,title:a,clazz:o,preamble:r}=e;const{metadata:i,isBlogPostPage:d}=(0,n.e7)();return a=a||"",t=t||"blog",o=`${o||""} p-3 tan br-3 blog-trial-embed`,(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)("h2",{className:"blog-trial-embed",children:"Start a free trial"}),(0,s.jsx)("p",{children:"Interested in the concepts discussed in this article? JsPlumb is now in maintenance mode, but the good news is that we've released a bigger and better library - VisuallyJs. If you can do it in JsPlumb you can do it more easily in VisuallyJs."}),(0,s.jsx)("img",{src:"https://static.visuallyjs.com/img/og.png",style:{marginBottom:"1rem"}}),(0,s.jsxs)("p",{children:["To read more about VisuallyJs, check out ",(0,s.jsx)("a",{href:"https://visuallyjs.com",children:"the home page"}),", or if you want to get started on a trial right now, head over to the trial page at ",(0,s.jsx)("a",{href:"https://visuallyjs.com/trial",children:"https://visuallyjs.com/trial"})]})]})}},41633:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>l,default:()=>m,frontMatter:()=>d,metadata:()=>n,toc:()=>h});var n=a(67340),s=a(74848),o=a(28453),r=a(69552),i=a(1852);const d={title:"World Cup 2018, part 1",authors:["sporritt"],tags:["toolkit","typescript"]},l=void 0,c={authorsImageUrls:[void 0]},h=[{value:"The result",id:"the-result",level:3},{value:"The dataset",id:"the-dataset",level:3},{value:"The rendering",id:"the-rendering",level:3},{value:"Processing the data",id:"processing-the-data",level:4},{value:"Instantiating a Toolkit instance",id:"instantiating-a-toolkit-instance",level:4},{value:"Rendering the dataset",id:"rendering-the-dataset",level:4},{value:"The next step",id:"the-next-step",level:3},{value:"Get in touch!",id:"get-in-touch",level:2}];function u(e){const t={a:"a",admonition:"admonition",code:"code",h2:"h2",h3:"h3",h4:"h4",hr:"hr",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.p,{children:"It's world cup time again and I've been looking for a good overview of how it's all progressing in the group stages. Being a computer programmer I of course spent a small amount of time looking for one done by someone else, and then decided to just do it myself. With the trusty jsPlumb Toolkit at my disposal I figure it'll be a doddle."}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsxs)(t.p,{children:["This post was originally written in 2018, and at the time I was hoping to re-use this code when the next World Cup\ncame around. For 2022 we've pulled this post into a standalone site - check it out at ",(0,s.jsx)("a",{href:"https://fifaworldcup.jsplumbtoolkit.com",children:(0,s.jsx)(t.a,{href:"https://fifaworldcup.jsplumbtoolkit.com",children:"https://fifaworldcup.jsplumbtoolkit.com"})})]})}),"\n","\n",(0,s.jsx)(t.h3,{id:"the-result",children:"The result"}),"\n",(0,s.jsx)(t.p,{children:"Let's jump to the result of my endeavours and then we'll go through how I got to this point. Here's what all the groups look like on the 25th of June 2018:"}),"\n",(0,s.jsx)("table",{className:"group-table",children:(0,s.jsxs)("tbody",{children:[(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,s.jsx)(r.X,{groupId:"A"})}),(0,s.jsx)("td",{children:(0,s.jsx)(r.X,{groupId:"B"})})]}),(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,s.jsx)(r.X,{groupId:"C"})}),(0,s.jsx)("td",{children:(0,s.jsx)(r.X,{groupId:"D"})})]}),(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,s.jsx)(r.X,{groupId:"E"})}),(0,s.jsx)("td",{children:(0,s.jsx)(r.X,{groupId:"F"})})]}),(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,s.jsx)(r.X,{groupId:"G"})}),(0,s.jsx)("td",{children:(0,s.jsx)(r.X,{groupId:"H"})})]})]})}),"\n",(0,s.jsx)(t.h3,{id:"the-dataset",children:"The dataset"}),"\n",(0,s.jsx)(t.p,{children:"The model for this visualisation is broken up into several files. For starters we have the list of teams, in this format (this is obviously not the full list):"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-json",children:'[\n {"code": "ru", "name": "Russia"},\n {"code": "uy", "name": "Uruguay"},\n {"code": "eg", "name": "Egypt"}\n] \n'})}
1),"\n",(0,s.jsx)(t.p,{children:"Then we have the groups:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-json",children:'[\n {"id": "A", "teams": ["ru", "uy", "eg", "sa"]},\n {"id": "B", "teams": ["es", "pt", "ir", "ma"]},\n {"id": "C", "teams": ["dk", "fr", "au", "pe"]},\n {"id": "D", "teams": ["hr", "ng", "is", "ar"]},\n {"id": "E", "teams": ["br", "ch", "rs", "cr"]},\n {"id": "F", "teams": ["mx", "de", "se", "kr"]},\n {"id": "G", "teams": ["en", "be", "tn", "pa"]},\n {"id": "H", "teams": ["jp", "sn", "co", "pl"]}\n]\n'})}),"\n",(0,s.jsx)(t.p,{children:"And we maintain a list of matches, broken up into the various phases of the tournament - first, the groups, then the round of 16, then the semis, then the final + third place playoff:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-json",children:'{\n groups:[\n {"id":"1","teams":["ru","sa"],"date":0, "score":[5,0]},\n {"id":"2","teams":["eg","uy"],"date":0, "score":[0,1]},\n {"id":"3","teams":["ir","ma"],"date":0, "score":[1,0]},\n { .. }\n ],\n roundof16: [],\n semis:[],\n final:{},\n thirdPlace:{}\n}\n'})}),"\n",(0,s.jsx)(t.p,{children:"This is an attenuated version of the dataset, and contains no entries for anything past the group stage, as it hasn't happened yet."}),"\n",(0,s.jsx)(t.h3,{id:"the-rendering",children:"The rendering"}),"\n",(0,s.jsxs)(t.p,{children:["To render each group we're going to load each group's data with an instance of JsPlumb, and then render it using a ",(0,s.jsx)(t.code,{children:"Circular"})," layout, with a flag representing each country, and an edge between each pair of countries that shows the result of the match that those countries played. As a reminder of what we showed above, here's Group ",(0,s.jsx)(t.strong,{children:"A"})," (as of the 25th of June 2018):"]}),"\n",(0,s.jsx)(r.X,{groupId:"A"}),"\n",(0,s.jsx)(t.h4,{id:"processing-the-data",children:"Processing the data"}),"\n",(0,s.jsx)(t.p,{children:"To load a group we first have to massage the data. Our steps are:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"load the group, and add each team as a node on the dataset"}),"\n",(0,s.jsx)(t.li,{children:"for each pair of teams, load the match they have played"}),"\n",(0,s.jsx)(t.li,{children:"if such a match exists, track who won/lost, or whether it was a draw. This information is stored in an array on each team, ie. for a given team we know how many matches they have won, lost and drawn."}),"\n",(0,s.jsx)(t.li,{children:"Add an edge for the match, if it has been played, to the dataset, supplying the match score as data for the edge."}),"\n",(0,s.jsx)(t.li,{children:"sort the teams by their win/loss/draw records, and assign a rank to each team, with 0 being the first-placed team in the group."}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"So as an example, in the visualisation shown above, the dataset we load into our Toolkit instance is:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-json",children:'{\n "nodes": [\n {\n "code": "ru",\n "name": "Russia",\n "wins": 4,\n "losses": 0,\n "goals": 16,\n "draws": 0,\n "rank": 0\n },\n {\n "code": "uy",\n "name": "Uruguay",\n "wins": 4,\n "losses": 0,\n "goals": 4,\n "draws": 0,\n "rank": 1\n },\n {\n "code": "eg",\n "name": "Egypt",\n "wins": 0,\n "losses": 4,\n "goals": 2,\n "draws": 0,\n "rank": 2\n },\n {\n "code": "sa",\n "name": "Saudi Arabia",\n "wins": 0,\n "losses": 4,\n "goals": 0,\n "draws": 0,\n "rank": 3\n }\n ],\n "edges": [\n {\n "source": "ru",\n "target": "sa",\n "data": {\n "scoreA": "5",\n "scoreB": "0"\n }\n },\n {\n "source": "eg",\n "target": "ru",\n "data": {\n "scoreA": "1",\n "scoreB": "3"\n }\n },\n {\n "source": "eg",\n "target": "uy",\n "data": {\n "scoreA": "0",\n "scoreB": "1"\n }\n },\n {\n "source": "sa",\n "target": "uy",\n "data": {\n "scoreA": "0",\n "scoreB": "1"\n }\n }\n ]\n}\n'})}),"\n",(0,s.jsx)(t.h4,{id:"instantiating-a-toolkit-instance",children:"Instantiating a Toolkit instance"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-javascript",children:'import { newInstance } from "@jsplumbtoolkit/browser-ui"\n\nconst toolkit = newInstance();\n'})}),"\n",(0,s.jsx)(t.h4,{id:"rendering-the-dataset",children:"Rendering the dataset"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-javascript",children:'toolkit.render(container, {\n layout:{\n type:"Circular"\n },\n view:{\n nodes:{\n default:{\n template:\'<div class="group-node" title="{{name}}" rank="{{rank}}"><img class="flag" src="/img/flags/1x1/{{code}}.svg" alt="{{name}} Flag"/></div>\'\n }\n },\n edges:{\n default:{\n overlays:[\n { type:"Label", options:{ label:"{{scoreA}}", location:0.3 }},\n { type: "Label", options: { label:"{{scoreB}}", location:0.7 }}\n ]\n }\n }\n },\n defaults:{\n connector:"Straight",\n endpoint: "Blank",\n anchor: "Center"\n }
1,\n enableWheelZoom: false,\n enablePan: false,\n zoomToFit: true\n})\n'})}),"\n",(0,s.jsxs)(t.p,{children:["This is a summary of what's happening in the ",(0,s.jsx)(t.code,{children:"render"})," call:"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["We use a layout of type ",(0,s.jsx)(t.code,{children:"Circular"})]}),"\n",(0,s.jsxs)(t.li,{children:["We map a single node type ",(0,s.jsx)(t.code,{children:'"default"'})," to a template, which writes out a simple element that contains an image with the given country's flag."]}),"\n",(0,s.jsxs)(t.li,{children:['We map a single edge type "',(0,s.jsx)(t.code,{children:"default"}),"\", which will apply to all edges, and which declares two overlays, one for each team's score."]}),"\n",(0,s.jsxs)(t.li,{children:["We provide default values for all edges - a ",(0,s.jsx)(t.code,{children:"Straight"})," connector, a ",(0,s.jsx)(t.code,{children:"Blank"})," endpoint, and a ",(0,s.jsx)(t.code,{children:"Center"})," anchor."]}),"\n",(0,s.jsx)(t.li,{children:"We disable wheel zoom and pan"}),"\n",(0,s.jsx)(t.li,{children:"We instruct the Surface to zoom the contents to fit after a data load operation."}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"the-next-step",children:"The next step"}),"\n",(0,s.jsxs)(t.p,{children:["In ",(0,s.jsx)(t.a,{href:"/blog/2018/06/26/world-cup-visualisation-part-2",children:"part 2 of this series"})," we'll take a look at another way to visualise the progress of the World Cup - a tree view of the progress of teams from the group finals through the round of 16, quarter finals, semi finals and the final/third place playoff."]}),"\n",(0,s.jsx)(t.hr,{}),"\n",(0,s.jsx)(i.A,{vector:"world-cup-1"}),"\n",(0,s.jsx)(t.hr,{}),"\n",(0,s.jsx)(t.h2,{id:"get-in-touch",children:"Get in touch!"}),"\n",(0,s.jsxs)(t.p,{children:["If you'd like to discuss any of the ideas/concepts in this article we'd love to hear from you - drop us a line at ",(0,s.jsx)(t.a,{href:"mailto:[email protected]",children:"[email protected]"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["Not a user of the jsPlumb Toolkit but thinking of checking it out? Head over to ",(0,s.jsx)(t.a,{href:"https://jsplumbtoolkit.com/trial",children:"https://jsplumbtoolkit.com/trial"}),". It's a good time to get started with jsPlumb."]})]})}function m(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(u,{...e})}):u(e)}},64973:(e,t,a)=>{a(96540),a(51410),a(40797),a(27143),a(86871),a(61934),a(74848)},67340:e=>{e.exports=JSON.parse('{"permalink":"/blog/2018/06/25/world-cup-visualisation-part-1","source":"@site/blog/2018-06-25-world-cup-visualisation-part-1/index.mdx","title":"World Cup 2018, part 1","description":"It\'s world cup time again and I\'ve been looking for a good overview of how it\'s all progressing in the group stages. Being a computer programmer I of course spent a small amount of time looking for one done by someone else, and then decided to just do it myself. With the trusty jsPlumb Toolkit at my disposal I figure it\'ll be a doddle.","date":"2018-06-25T00:00:00.000Z","tags":[{"inline":true,"label":"toolkit","permalink":"/blog/tags/toolkit"},{"inline":true,"label":"typescript","permalink":"/blog/tags/typescript"}],"readingTime":5.095,"hasTruncateMarker":true,"authors":[{"name":"Simon Porritt","title":"JsPlumb core team","url":"https://github.com/sporritt","imageURL":"https://avatars.githubusercontent.com/u/262720?s=60&v=4","key":"sporritt","page":null}],"frontMatter":{"title":"World Cup 2018, part 1","authors":["sporritt"],"tags":["toolkit","typescript"]},"unlisted":false,"prevItem":{"title":"World Cup 2018, part 2","permalink":"/blog/2018/06/26/world-cup-visualisation-part-2"}}')},68859:(e,t,a)=>{a.d(t,{T:()=>n});const n=()=>[{id:"A",teams:["ru","uy","eg","sa"],rank:[]},{id:"B",teams:["es","pt","ir","ma"],rank:[]},{id:"C",teams:["dk","fr","au","pe"],rank:[]},{id:"D",teams:["hr","ng","is","ar"],rank:[]},{id:"E",teams:["br","ch","rs","cr"],rank:[]},{id:"F",teams:["mx","de","se","kr"],rank:[]},{id:"G",teams:["en","be","tn","pa"],rank:[]},{id:"H",teams:["jp","sn","co","pl"],rank:[]}]}
1,69552:(e,t,a)=>{a.d(t,{X:()=>p});var n=a(96540),s=a(61934),o=a(82917);const r=[{id:"1",teams:["ru","sa"],date:0,score:[5,0]},{id:"2",teams:["eg","uy"],date:0,score:[0,1]},{id:"3",teams:["ir","ma"],date:0,score:[1,0]},{id:"4",teams:["es","pt"],date:0,score:[3,3]},{id:"5",teams:["au","fr"],date:0,score:[1,2]},{id:"6",teams:["ar","is"],date:0,score:[1,1]},{id:"7",teams:["dk","pe"],date:0,score:[1,0]},{id:"8",teams:["hr","ng"],date:0,score:[2,0]},{id:"9",teams:["cr","rs"],date:0,score:[0,1]},{id:"10",teams:["de","mx"],date:0,score:[0,1]},{id:"11",teams:["br","ch"],date:0,score:[1,1]},{id:"12",teams:["kr","se"],date:0,score:[0,1]},{id:"13",teams:["be","pa"],date:0,score:[3,0]},{id:"14",teams:["en","tn"],date:0,score:[2,1]},{id:"15",teams:["co","jp"],date:0,score:[1,2]},{id:"16",teams:["pl","sn"],date:0,score:[1,2]},{id:"17",teams:["eg","ru"],date:0,score:[1,3]},{id:"18",teams:["ma","pt"],date:0,score:[0,1]},{id:"19",teams:["sa","uy"],date:0,score:[0,1]},{id:"20",teams:["es","ir"],date:0,score:[1,0]},{id:"21",teams:["au","dk"],date:0,score:[1,1]},{id:"22",teams:["fr","pe"],date:0,score:[1,0]},{id:"23",teams:["ar","hr"],date:0,score:[0,3]},{id:"24",teams:["br","cr"],date:0,score:[2,0]},{id:"25",teams:["is","ng"],date:0,score:[0,2]},{id:"26",teams:["ch","rs"],date:0,score:[2,1]},{id:"27",teams:["be","tn"],date:0,score:[5,2]},{id:"28",teams:["kr","mx"],date:0,score:[1,2]},{id:"29",teams:["de","se"],date:0,score:[2,1]},{id:"30",teams:["en","pa"],date:0,score:[6,1]},{id:"31",teams:["jp","sn"],date:0,score:[2,2]},{id:"32",teams:["co","pl"],date:0,score:[3,0]}];var i=a(68859);const d=(0,o.r)(),l=(0,i.T)();function c(e){const t=d.filter((t=>t.code===e))[0];return t&&(t.wins=t.wins||0,t.losses=t.losses||0,t.goals=t.goals||0,t.draws=t.draws||0),t}function h(e,t){const a=function(e,t,a){return e.find((e=>e.teams[0]===t.code&&e.teams[1]===a.code||e.teams[0]===a.code&&e.teams[1]===t.code))}(r,e,t);return null==a?null:e.code<t.code?a.score:a.score.reverse()}function u(e){const t=(a=e,l.filter((e=>e.id===a))[0]);var a;const n=[],s=[];for(let o=0;o<t.teams.length;o++){let e=c(t.teams[o]);n.push(e);for(let a=0;a<t.teams.length;a++){let n=c(t.teams[a]);if(e.code<n.code){const t=h(e,n);null!=t&&(s.push({source:e.code,target:n.code,data:{scoreA:""+t[0],scoreB:""+t[1]}}),e.goals+=t[0],n.goals+=t[1],t[0]===t[1]?(e.draws++,n.draws++):(e[t[0]>t[1]?"wins":"losses"]++,n[t[0]>t[1]?"losses":"wins"]++))}}}return n.sort((function(e,t){return e.wins>t.wins?-1:t.wins>e.wins?1:e.goals>t.goals?-1:1})),n.forEach((function(e,a){e.rank=a,t.rank[a]=e.code})),{nodes:n,edges:s}}var m=a(74848);const p=e=>{let{groupId:t}=e;const o=(0,n.useRef)(null);return(0,n.useEffect)((()=>{const e=o.current;if(s.A.canUseDOM){const n=a(32689).newInstance(),s=(n.render(e,{layout:{type:"Circular"},view:{nodes:{default:{template:'<div class="group-node" title="${name}" rank="${rank}"><img class="flag" src="/img/flags/1x1/{{code}}.svg" alt="{{name}} Flag"/></div>'}},edges:{default:{overlays:[{type:"Label",options:{label:"{{scoreA}}",location:.3}},{type:"Label",options:{label:"{{scoreB}}",location:.7}}]}}},defaults:{connector:"Straight",endpoint:"Blank",anchor:"Center"},enableWheelZoom:!1,enablePan:!1,zoomToFit:!0}),u(t));n.load({data:s})}}),[]),(0,m.jsx)("div",{ref:o,className:"group-vis",children:(0,m.jsx)("span",{children:t})})}},82917:(e,t,a)=>{a.d(t,{r:()=>n});const n=()=>[{code:"ru",name:"Russia",id:"ru"},{code:"uy",name:"Uruguay",id:"uy"},{code:"eg",name:"Egypt",id:"eg"},{code:"sa",name:"Saudi Arabia",id:"sa"},{code:"es",name:"Spain",id:"es"},{code:"pt",name:"Portugal",id:"pt"},{code:"ir",name:"Iran",id:"ir"},{code:"ma",name:"Morocco",id:"ma"},{code:"fr",name:"France",id:"fr"},{code:"dk",name:"Denmark",id:"dk"},{code:"au",name:"Australia",id:"au"},{code:"pe",name:"Peru",id:"pe"},{code:"hr",name:"Croatia",id:"hr"},{code:"ng",name:"Nigeria",id:"ng"},{code:"is",name:"Iceland",id:"is"},{code:"ar",name:"Argentina",id:"ar"},{code:"br",name:"Brazil",id:"br"},{code:"ch",name:"Switzerland",id:"ch"},{code:"rs",name:"Serbia",id:"rs"},{code:"cr",name:"Costa Rica",id:"cr"},{code:"mx",name:"Mexico",id:"mx"},{code:"de",name:"Germany",id:"de"},{code:"se",name:"Sweden",id:"se"},{code:"kr",name:"South Korea",id:"kr"},{code:"en",name:"England",id:"en"},{code:"be",name:"Belgium",id:"be"},{code:"tn",name:"Tunisia",id:"tn"},{code:"pa",name:"Panama",id:"pa"},{code:"jp",name:"Japan",id:"jp"},{code:"sn",name:"Senegal",id:"sn"}
1,{code:"co",name:"Colombia",id:"co"},{code:"pl",name:"Poland",id:"pl"}]},83750:(e,t,a)=>{a.d(t,{in:()=>l,OU:()=>T,Ki:()=>I,kJ:()=>f,x:()=>i,e7:()=>c,J_:()=>j,Gx:()=>P});var n=a(96540),s=a(26849),o=a(69062),r=a(74848);function i(){const e=(0,o.A)(),t=e?.data?.blogMetadata;if(!t)throw new Error("useBlogMetadata() can't be called on the current route because the blog metadata could not be found in route context");return t}const d=n.createContext(null);function l(e){let{children:t,content:a,isBlogPostPage:s=!1}=e;const o=function(e){let{content:t,isBlogPostPage:a}=e;return(0,n.useMemo)((()=>({metadata:t.metadata,frontMatter:t.frontMatter,assets:t.assets,toc:t.toc,isBlogPostPage:a})),[t,a])}({content:a,isBlogPostPage:s});return(0,r.jsx)(d.Provider,{value:o,children:t})}function c(){const e=(0,n.useContext)(d);if(null===e)throw new s.dV("BlogPostProvider");return e}var h=a(29030),u=a(40797);const m=e=>new Date(e).toISOString();function p(e){const t=e.map(x);return{author:1===t.length?t[0]:t}}function g(e,t,a){return e?{image:w({imageUrl:t(e,{absolute:!0}),caption:`title image for the blog post: ${a}`})}:{}}function f(e){const{siteConfig:t}=(0,u.A)(),{withBaseUrl:a}=(0,h.hH)(),{metadata:{blogDescription:n,blogTitle:s,permalink:o}}=e,r=`${t.url}${o}`;return{"@context":"https://schema.org","@type":"Blog","@id":r,mainEntityOfPage:r,headline:s,description:n,blogPost:e.items.map((e=>function(e,t,a){const{assets:n,frontMatter:s,metadata:o}=e,{date:r,title:i,description:d,lastUpdatedAt:l}=o,c=n.image??s.image,h=s.keywords??[],u=`${t.url}${o.permalink}`,f=l?m(l):void 0;return{"@type":"BlogPosting","@id":u,mainEntityOfPage:u,url:u,headline:i,name:i,description:d,datePublished:r,...f?{dateModified:f}:{},...p(o.authors),...g(c,a,i),...h?{keywords:h}:{}}}(e.content,t,a)))}}function j(){const e=i(),{assets:t,metadata:a}=c(),{siteConfig:n}=(0,u.A)(),{withBaseUrl:s}=(0,h.hH)(),{date:o,title:r,description:d,frontMatter:l,lastUpdatedAt:f}=a,j=t.image??l.image,x=l.keywords??[],w=f?m(f):void 0,b=`${n.url}${a.permalink}`;return{"@context":"https://schema.org","@type":"BlogPosting","@id":b,mainEntityOfPage:b,url:b,headline:r,name:r,description:d,datePublished:o,...w?{dateModified:w}:{},...p(a.authors),...g(j,s,r),...x?{keywords:x}:{},isPartOf:{"@type":"Blog","@id":`${n.url}${e.blogBasePath}`,name:e.blogTitle}}}function x(e){return{"@type":"Person",...e.name?{name:e.name}:{},...e.title?{description:e.title}:{},...e.url?{url:e.url}:{},...e.email?{email:e.email}:{},...e.imageURL?{image:e.imageURL}:{}}}function w(e){let{imageUrl:t,caption:a}=e;return{"@type":"ImageObject","@id":t,url:t,contentUrl:t,caption:a}}var b=a(56347),y=a(56289),k=a(11861),v=a(30214);function P(e){const{pathname:t}=(0,b.zy)();return(0,n.useMemo)((()=>e.filter((e=>function(e,t){return!(e.unlisted&&!(0,v.ys)(e.permalink,t))}(e,t)))),[e,t])}function I(e){const t=(0,k.$z)(e,(e=>`${new Date(e.date).getFullYear()}`)),a=Object.entries(t);return a.reverse(),a}function T(e){let{items:t,ulClassName:a,liClassName:n,linkClassName:s,linkActiveClassName:o}=e;return(0,r.jsx)("ul",{className:a,children:t.map((e=>(0,r.jsx)("li",{className:n,children:(0,r.jsx)(y.A,{isNavLink:!0,to:e.permalink,className:s,activeClassName:o,children:e.title})},e.permalink)))})}},86871:(e,t,a)=>{a(96540),a(74848)}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.