[{"data":1,"prerenderedAt":13520},["ShallowReactive",2],{"footer-articles":3,"/blog/build-command-line-tools-in-typescript-a-step-by-step-guide":7386,"related-/blog/build-command-line-tools-in-typescript-a-step-by-step-guide":13386},[4,7283,7321,7355],{"id":5,"title":6,"body":7,"category":46,"date":7273,"description":7274,"draft":7275,"extension":7276,"image":7277,"meta":7278,"navigation":1524,"path":7279,"seo":7280,"stem":7281,"tighten":7275,"__hash__":7282},"blog/blog/build-command-line-tools-in-typescript-a-step-by-step-guide.md","Build Command Line Tools in TypeScript: A Step-by-Step Guide",{"type":8,"value":9,"toc":7258},"minimark",[10,14,40,56,65,68,71,76,79,107,116,151,158,164,184,201,205,208,222,225,233,236,242,245,257,383,386,400,604,614,622,626,635,691,706,715,719,725,748,771,851,863,873,880,1232,1242,1245,1285,1288,1461,1480,1495,1498,1704,1724,1730,1736,1745,1749,1752,1758,1776,1780,1790,2255,2258,2322,2329,2335,2347,2363,2367,2380,2577,2624,2629,3589,3611,3616,3619,3626,3629,3659,3749,3752,3766,3772,3778,3782,3795,3798,4263,4266,4321,4326,4332,4335,4773,4786,4798,5000,5012,5018,5086,5091,5120,5210,5216,5220,5227,5417,5434,5439,5446,5458,5625,5628,5631,5884,5887,5900,6074,6077,6081,6087,6090,6318,6324,6603,6610,7027,7030,7042,7048,7054,7058,7061,7076,7084,7109,7128,7150,7156,7159,7181,7185,7204,7207,7230,7234,7240,7243,7251,7254],[11,12,13],"p",{},"How far is Tokyo from Buenos Aires? You could open a map, drop two pins, and squint at the scale bar. Or you could type a single command:",[15,16,21],"pre",{"className":17,"code":18,"language":19,"meta":20,"style":20},"language-bash shiki shiki-themes monokai","npx @nicodevs/howfar Tokyo\n","bash","",[22,23,24],"code",{"__ignoreMap":20},[25,26,29,33,37],"span",{"class":27,"line":28},"line",1,[25,30,32],{"class":31},"sHkqI","npx",[25,34,36],{"class":35},"s_Ekj"," @nicodevs/howfar",[25,38,39],{"class":35}," Tokyo\n",[11,41,42,43,47,48,51,52,55],{},"That's what we're building today: a command-line tool in ",[44,45,46],"strong",{},"TypeScript"," that tells you how far any city is from yours. We'll publish it to ",[44,49,50],{},"npm",", so anyone with ",[44,53,54],{},"Node.js"," can run it from any folder without installing anything.",[11,57,58,59,64],{},"It follows the same structure I use in ",[60,61,63],"a",{"href":62},"/blog/climail-the-email-client-for-your-agent","climail",", my command-line email client, and it prints JSON, so both people and AI agents can use its output.",[11,66,67],{},"I know, I know, measuring distances is a simple example. But you can swap the distance math for your own code. What carries over is how to structure the project, how to publish it, and which libraries make a CLI beautiful and useful without reinventing the wheel.",[11,69,70],{},"Let's dive in!",[72,73,75],"h2",{"id":74},"how-npx-works","How npx Works",[11,77,78],{},"If you've never published a package before, that command has a few moving parts, so let's go through them one by one.",[11,80,81,82,84,85,87,88,91,92,98,99,102,103,106],{},"When you install ",[44,83,54],{},", you also get ",[44,86,50],{},", its package manager. npm comes with a public ",[44,89,90],{},"registry",", ",[60,93,97],{"href":94,"rel":95},"https://www.npmjs.com/",[96],"nofollow","npmjs.com",", which is where packages live. When you run ",[22,100,101],{},"npm install something",", npm downloads ",[22,104,105],{},"something"," from that registry and adds it to your project.",[11,108,109,111,112,115],{},[44,110,32],{}," comes with npm too, and it works a little differently. Instead of adding a package to your project, it downloads it to a cache, runs the command inside it, and leaves your project untouched. That's why ",[22,113,114],{},"npx @nicodevs/howfar Tokyo"," works from any folder, without installing anything first.",[11,117,118,119,122,123,126,127,130,131,134,135,138,139,142,143,146,147,150],{},"Now, what about the ",[22,120,121],{},"@nicodevs/"," part? That's called a ",[44,124,125],{},"scope",". Every package on the registry needs a unique name, and short names like ",[22,128,129],{},"howfar"," get claimed fast (this one already is). Scopes solve that problem. When you create an account on npmjs.com, you get a scope that matches your username, and only you can publish packages under it. My npm username is ",[22,132,133],{},"nicodevs",", so my package is called ",[22,136,137],{},"@nicodevs/howfar",". If your npm username is ",[22,140,141],{},"jane",", your package will be called ",[22,144,145],{},"@jane/howfar",", and people will run it with ",[22,148,149],{},"npx @jane/howfar",".",[11,152,153,154,157],{},"When we build our own version, I'll use ",[22,155,156],{},"@username"," as a placeholder. Whenever you see it, replace it with your own npm username.",[159,160,161],"blockquote",{},[11,162,163],{},"Can npx run a GitHub repository too?",[11,165,166,167,91,170,173,174,177,178,180,181,183],{},"It can, but with a different syntax. Without the ",[22,168,169],{},"@",[22,171,172],{},"npx jane/howfar"," (or the more explicit ",[22,175,176],{},"npx github:jane/howfar",") means \"the ",[22,179,129],{}," repository of the GitHub user ",[22,182,141],{},".\" In that case, npx clones the repository, installs it, and runs its command, with no npm account or registry involved.",[11,185,186,187,190,191,193,194,197,198,200],{},"There's one catch, though. A GitHub repository usually holds the source code, not the built file that npx needs to run. In our project, the built file will live in a ",[22,188,189],{},"dist"," folder that we keep out of Git. So if you want to go the GitHub route, you'll need to either commit ",[22,192,189],{}," or make the ",[22,195,196],{},"prepare"," script build the project, since npm runs ",[22,199,196],{}," when it installs a package from Git. Publishing to npm avoids all of that, so that's what we'll do in this article.",[72,202,204],{"id":203},"the-final-product","The Final Product",[11,206,207],{},"Okay, let's take a look at the final product. The first time, we run the setup wizard:",[15,209,211],{"className":17,"code":210,"language":19,"meta":20,"style":20},"npx @nicodevs/howfar init\n",[22,212,213],{"__ignoreMap":20},[25,214,215,217,219],{"class":27,"line":28},[25,216,32],{"class":31},[25,218,36],{"class":35},[25,220,221],{"class":35}," init\n",[11,223,224],{},"It asks for our city, and then for the unit we want our distances in:",[15,226,231],{"className":227,"code":229,"language":230,"meta":20},[228],"language-text","┌  howfar setup\n│\n◇  Your city\n│  Buenos Aires\n│\n◆  Distance unit\n│  ● Kilometers\n│  ○ Miles\n│  ↑/↓ to navigate • Enter: confirm\n└\n","text",[22,232,229],{"__ignoreMap":20},[11,234,235],{},"Once we pick a unit and press Enter, it saves our answers and tells us what to try next:",[15,237,240],{"className":238,"code":239,"language":230,"meta":20},[228],"◇  Distance unit\n│  Kilometers\n│\n◆  Saved config to ~/.config/howfar.conf\n│\n└  Done. Try: npx @nicodevs/howfar Tokyo\n",[22,241,239],{"__ignoreMap":20},[11,243,244],{},"That's it. From now on, we can ask how far any city is from home:",[15,246,247],{"className":17,"code":18,"language":19,"meta":20,"style":20},[22,248,249],{"__ignoreMap":20},[25,250,251,253,255],{"class":27,"line":28},[25,252,32],{"class":31},[25,254,36],{"class":35},[25,256,39],{"class":35},[15,258,262],{"className":259,"code":260,"language":261,"meta":20,"style":20},"language-json shiki shiki-themes monokai","{\n  \"ok\": true,\n  \"from\": \"Buenos Aires, Argentina\",\n  \"city\": \"Tokyo, Japan\",\n  \"latitude\": 35.6895,\n  \"longitude\": 139.69171,\n  \"distance\": 18370,\n  \"unit\": \"km\",\n  \"summary\": \"Tokyo is 18,370 km from Buenos Aires\"\n}\n","json",[22,263,264,270,287,301,314,327,340,353,366,377],{"__ignoreMap":20},[25,265,266],{"class":27,"line":28},[25,267,269],{"class":268},"sCdxs","{\n",[25,271,273,277,280,284],{"class":27,"line":272},2,[25,274,276],{"class":275},"sOx1s","  \"ok\"",[25,278,279],{"class":268},": ",[25,281,283],{"class":282},"s7s5_","true",[25,285,286],{"class":268},",\n",[25,288,290,293,295,299],{"class":27,"line":289},3,[25,291,292],{"class":275},"  \"from\"",[25,294,279],{"class":268},[25,296,298],{"class":297},"susgL","\"Buenos Aires, Argentina\"",[25,300,286],{"class":268},[25,302,304,307,309,312],{"class":27,"line":303},4,[25,305,306],{"class":275},"  \"city\"",[25,308,279],{"class":268},[25,310,311],{"class":297},"\"Tokyo, Japan\"",[25,313,286],{"class":268},[25,315,317,320,322,325],{"class":27,"line":316},5,[25,318,319],{"class":275},"  \"latitude\"",[25,321,279],{"class":268},[25,323,324],{"class":282},"35.6895",[25,326,286],{"class":268},[25,328,330,333,335,338],{"class":27,"line":329},6,[25,331,332],{"class":275},"  \"longitude\"",[25,334,279],{"class":268},[25,336,337],{"class":282},"139.69171",[25,339,286],{"class":268},[25,341,343,346,348,351],{"class":27,"line":342},7,[25,344,345],{"class":275},"  \"distance\"",[25,347,279],{"class":268},[25,349,350],{"class":282},"18370",[25,352,286],{"class":268},[25,354,356,359,361,364],{"class":27,"line":355},8,[25,357,358],{"class":275},"  \"unit\"",[25,360,279],{"class":268},[25,362,363],{"class":297},"\"km\"",[25,365,286],{"class":268},[25,367,369,372,374],{"class":27,"line":368},9,[25,370,371],{"class":275},"  \"summary\"",[25,373,279],{"class":268},[25,375,376],{"class":297},"\"Tokyo is 18,370 km from Buenos Aires\"\n",[25,378,380],{"class":27,"line":379},10,[25,381,382],{"class":268},"}\n",[11,384,385],{},"We can also measure several cities at once:",[15,387,389],{"className":17,"code":388,"language":19,"meta":20,"style":20},"npx @nicodevs/howfar \"Tokyo, San Francisco\"\n",[22,390,391],{"__ignoreMap":20},[25,392,393,395,397],{"class":27,"line":28},[25,394,32],{"class":31},[25,396,36],{"class":35},[25,398,399],{"class":35}," \"Tokyo, San Francisco\"\n",[15,401,403],{"className":259,"code":402,"language":261,"meta":20,"style":20},"{\n  \"ok\": true,\n  \"from\": \"Buenos Aires, Argentina\",\n  \"cities\": [\n    {\n      \"city\": \"Tokyo, Japan\",\n      \"latitude\": 35.6895,\n      \"longitude\": 139.69171,\n      \"distance\": 18370,\n      \"unit\": \"km\",\n      \"summary\": \"Tokyo is 18,370 km from Buenos Aires\"\n    },\n    {\n      \"city\": \"San Francisco, United States\",\n      \"latitude\": 37.77493,\n      \"longitude\": -122.41942,\n      \"distance\": 10411,\n      \"unit\": \"km\",\n      \"summary\": \"San Francisco is 10,411 km from Buenos Aires\"\n    }\n  ]\n}\n",[22,404,405,409,419,429,437,442,453,464,475,486,497,507,513,518,530,542,554,566,577,587,593,599],{"__ignoreMap":20},[25,406,407],{"class":27,"line":28},[25,408,269],{"class":268},[25,410,411,413,415,417],{"class":27,"line":272},[25,412,276],{"class":275},[25,414,279],{"class":268},[25,416,283],{"class":282},[25,418,286],{"class":268},[25,420,421,423,425,427],{"class":27,"line":289},[25,422,292],{"class":275},[25,424,279],{"class":268},[25,426,298],{"class":297},[25,428,286],{"class":268},[25,430,431,434],{"class":27,"line":303},[25,432,433],{"class":275},"  \"cities\"",[25,435,436],{"class":268},": [\n",[25,438,439],{"class":27,"line":316},[25,440,441],{"class":268},"    {\n",[25,443,444,447,449,451],{"class":27,"line":329},[25,445,446],{"class":275},"      \"city\"",[25,448,279],{"class":268},[25,450,311],{"class":297},[25,452,286],{"class":268},[25,454,455,458,460,462],{"class":27,"line":342},[25,456,457],{"class":275},"      \"latitude\"",[25,459,279],{"class":268},[25,461,324],{"class":282},[25,463,286],{"class":268},[25,465,466,469,471,473],{"class":27,"line":355},[25,467,468],{"class":275},"      \"longitude\"",[25,470,279],{"class":268},[25,472,337],{"class":282},[25,474,286],{"class":268},[25,476,477,480,482,484],{"class":27,"line":368},[25,478,479],{"class":275},"      \"distance\"",[25,481,279],{"class":268},[25,483,350],{"class":282},[25,485,286],{"class":268},[25,487,488,491,493,495],{"class":27,"line":379},[25,489,490],{"class":275},"      \"unit\"",[25,492,279],{"class":268},[25,494,363],{"class":297},[25,496,286],{"class":268},[25,498,500,503,505],{"class":27,"line":499},11,[25,501,502],{"class":275},"      \"summary\"",[25,504,279],{"class":268},[25,506,376],{"class":297},[25,508,510],{"class":27,"line":509},12,[25,511,512],{"class":268},"    },\n",[25,514,516],{"class":27,"line":515},13,[25,517,441],{"class":268},[25,519,521,523,525,528],{"class":27,"line":520},14,[25,522,446],{"class":275},[25,524,279],{"class":268},[25,526,527],{"class":297},"\"San Francisco, United States\"",[25,529,286],{"class":268},[25,531,533,535,537,540],{"class":27,"line":532},15,[25,534,457],{"class":275},[25,536,279],{"class":268},[25,538,539],{"class":282},"37.77493",[25,541,286],{"class":268},[25,543,545,547,549,552],{"class":27,"line":544},16,[25,546,468],{"class":275},[25,548,279],{"class":268},[25,550,551],{"class":282},"-122.41942",[25,553,286],{"class":268},[25,555,557,559,561,564],{"class":27,"line":556},17,[25,558,479],{"class":275},[25,560,279],{"class":268},[25,562,563],{"class":282},"10411",[25,565,286],{"class":268},[25,567,569,571,573,575],{"class":27,"line":568},18,[25,570,490],{"class":275},[25,572,279],{"class":268},[25,574,363],{"class":297},[25,576,286],{"class":268},[25,578,580,582,584],{"class":27,"line":579},19,[25,581,502],{"class":275},[25,583,279],{"class":268},[25,585,586],{"class":297},"\"San Francisco is 10,411 km from Buenos Aires\"\n",[25,588,590],{"class":27,"line":589},20,[25,591,592],{"class":268},"    }\n",[25,594,596],{"class":27,"line":595},21,[25,597,598],{"class":268},"  ]\n",[25,600,602],{"class":27,"line":601},22,[25,603,382],{"class":268},[11,605,606,607,610,611,150],{},"And when we want to measure from somewhere else, ",[22,608,609],{},"--from"," overrides our home city for a single run, as in ",[22,612,613],{},"npx @nicodevs/howfar Tokyo --from Lima",[11,615,616,617,150],{},"Pretty cool, right? It's already published, so you can try any of these commands right now. And the full source code is on ",[60,618,621],{"href":619,"rel":620},"https://github.com/nicodevs/howfar",[96],"GitHub",[72,623,625],{"id":624},"the-building-blocks","The Building Blocks",[11,627,628,629,634],{},"A CLI has to parse arguments, ask the user questions, remember settings between runs, and check those settings before trusting them. Rather than one big framework, we'll use a small package for each of those jobs. Three of them come from the ",[60,630,633],{"href":631,"rel":632},"https://unjs.io/",[96],"UnJS"," collection, which is a set of small, well-maintained packages that work anywhere JavaScript runs.",[636,637,638,657,671,681],"ul",{},[639,640,641,648,649,652,653,656],"li",{},[44,642,643],{},[60,644,647],{"href":645,"rel":646},"https://github.com/unjs/citty",[96],"citty"," defines commands and parses arguments. You describe a command as an object (name, description, args, run function) and citty handles ",[22,650,651],{},"--flags",", positional arguments, and the ",[22,654,655],{},"--help"," screen.",[639,658,659,666,667,670],{},[44,660,661],{},[60,662,665],{"href":663,"rel":664},"https://github.com/bombshell-dev/clack",[96],"@clack/prompts"," draws interactive prompts, such as text inputs, password fields, and select menus. It's what draws the ",[22,668,669],{},"init"," wizard you just saw.",[639,672,673,680],{},[44,674,675],{},[60,676,679],{"href":677,"rel":678},"https://github.com/unjs/rc9",[96],"rc9"," reads and writes config files in the user's home directory, so the tool remembers its settings between runs.",[639,682,683,690],{},[44,684,685],{},[60,686,689],{"href":687,"rel":688},"https://zod.dev/",[96],"zod"," validates that config before we trust it.",[11,692,693,694,701,702,705],{},"Then, for tooling, we'll use ",[44,695,696],{},[60,697,700],{"href":698,"rel":699},"https://viteplus.dev/",[96],"Vite+",", a single binary called ",[22,703,704],{},"vp"," that bundles a formatter, a linter, a test runner, a bundler, and Git hooks. Before Vite+, I had five dev dependencies and five config files for that. Now I have one of each.",[11,707,708,709,714],{},"And finally, to find each city, we'll call the ",[60,710,713],{"href":711,"rel":712},"https://open-meteo.com/",[96],"Open-Meteo"," geocoding API, which is free, needs no key, and returns the city's coordinates. The distance between two sets of coordinates is a formula we'll write ourselves, so that's the only API we need.",[72,716,718],{"id":717},"creating-the-project","Creating the Project",[11,720,721,722,724],{},"Alright, let's get started. First, let's install the global ",[22,723,704],{}," binary:",[15,726,728],{"className":17,"code":727,"language":19,"meta":20,"style":20},"curl -fsSL https://vite.plus | bash\n",[22,729,730],{"__ignoreMap":20},[25,731,732,735,738,741,745],{"class":27,"line":28},[25,733,734],{"class":31},"curl",[25,736,737],{"class":282}," -fsSL",[25,739,740],{"class":35}," https://vite.plus",[25,742,744],{"class":743},"s8I7P"," |",[25,746,747],{"class":31}," bash\n",[11,749,750,751,754,755,758,759,762,763,766,767,770],{},"Now, let's create the folder and initialize the package. We'll also add ",[22,752,753],{},"vite-plus"," as a dev dependency, so the project pins its own version and our config file can import from it. The odd-looking ",[22,756,757],{},"vite@npm:..."," entry installs the Vite+ core under the name ",[22,760,761],{},"vite",", which is the name the test runner looks for. Without it, ",[22,764,765],{},"npm test"," fails with ",[22,768,769],{},"Cannot find package 'vite'",":",[15,772,774],{"className":17,"code":773,"language":19,"meta":20,"style":20},"mkdir howfar && cd howfar\ngit init\nnpm init -y\nnpm install citty @clack/prompts rc9 zod\nnpm install -D typescript vite-plus @types/node vite@npm:@voidzero-dev/vite-plus-core\n",[22,775,776,794,801,811,830],{"__ignoreMap":20},[25,777,778,781,784,787,791],{"class":27,"line":28},[25,779,780],{"class":31},"mkdir",[25,782,783],{"class":35}," howfar",[25,785,786],{"class":268}," && ",[25,788,790],{"class":789},"sYf5A","cd",[25,792,793],{"class":35}," howfar\n",[25,795,796,799],{"class":27,"line":272},[25,797,798],{"class":31},"git",[25,800,221],{"class":35},[25,802,803,805,808],{"class":27,"line":289},[25,804,50],{"class":31},[25,806,807],{"class":35}," init",[25,809,810],{"class":282}," -y\n",[25,812,813,815,818,821,824,827],{"class":27,"line":303},[25,814,50],{"class":31},[25,816,817],{"class":35}," install",[25,819,820],{"class":35}," citty",[25,822,823],{"class":35}," @clack/prompts",[25,825,826],{"class":35}," rc9",[25,828,829],{"class":35}," zod\n",[25,831,832,834,836,839,842,845,848],{"class":27,"line":316},[25,833,50],{"class":31},[25,835,817],{"class":35},[25,837,838],{"class":282}," -D",[25,840,841],{"class":35}," typescript",[25,843,844],{"class":35}," vite-plus",[25,846,847],{"class":35}," @types/node",[25,849,850],{"class":35}," vite@npm:@voidzero-dev/vite-plus-core\n",[159,852,853],{},[11,854,855,858,859,862],{},[22,856,857],{},"npm install"," crashes with ",[22,860,861],{},"Cannot read properties of null (reading 'edgesOut')","?",[11,864,865,866,868,869,872],{},"That's a bug in npm 10, the version bundled with Node 22, when it resolves the peer dependencies of ",[22,867,753],{},". You can fix it by upgrading npm with ",[22,870,871],{},"npm install -g npm@11",", or by switching to Node 24, which ships with it. Then, run the install again.",[11,874,875,876,879],{},"Then, let's open ",[22,877,878],{},"package.json"," and make it look like this:",[15,881,883],{"className":259,"code":882,"filename":878,"language":261,"meta":20,"style":20},"{\n  \"name\": \"@username/howfar\",\n  \"version\": \"0.1.0\",\n  \"description\": \"How far any city is from yours, as JSON.\",\n  \"license\": \"MIT\",\n  \"type\": \"module\",\n  \"bin\": {\n    \"howfar\": \"dist/howfar.mjs\"\n  },\n  \"files\": [\"dist\"],\n  \"engines\": {\n    \"node\": \">=22\"\n  },\n  \"scripts\": {\n    \"lint\": \"vp lint\",\n    \"format\": \"vp fmt\",\n    \"test\": \"vp test run\",\n    \"type-check\": \"tsc --noEmit\",\n    \"build\": \"vp run type-check && vp pack\",\n    \"prepare\": \"vp config --no-agent\",\n    \"prepublishOnly\": \"npm run build\"\n  },\n  \"dependencies\": {\n    \"@clack/prompts\": \"^1.8.1\",\n    \"citty\": \"^0.2.2\",\n    \"rc9\": \"^3.1.0\",\n    \"zod\": \"^4.6.7\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^26.6.6\",\n    \"typescript\": \"^7.0.2\",\n    \"vite\": \"npm:@voidzero-dev/vite-plus-core@^1.4.0\",\n    \"vite-plus\": \"^1.4.0\"\n  }\n}\n",[22,884,885,889,901,913,925,937,949,957,967,972,986,993,1003,1007,1014,1026,1038,1050,1062,1074,1086,1096,1100,1108,1121,1134,1147,1158,1163,1171,1184,1197,1210,1221,1227],{"__ignoreMap":20},[25,886,887],{"class":27,"line":28},[25,888,269],{"class":268},[25,890,891,894,896,899],{"class":27,"line":272},[25,892,893],{"class":275},"  \"name\"",[25,895,279],{"class":268},[25,897,898],{"class":297},"\"@username/howfar\"",[25,900,286],{"class":268},[25,902,903,906,908,911],{"class":27,"line":289},[25,904,905],{"class":275},"  \"version\"",[25,907,279],{"class":268},[25,909,910],{"class":297},"\"0.1.0\"",[25,912,286],{"class":268},[25,914,915,918,920,923],{"class":27,"line":303},[25,916,917],{"class":275},"  \"description\"",[25,919,279],{"class":268},[25,921,922],{"class":297},"\"How far any city is from yours, as JSON.\"",[25,924,286],{"class":268},[25,926,927,930,932,935],{"class":27,"line":316},[25,928,929],{"class":275},"  \"license\"",[25,931,279],{"class":268},[25,933,934],{"class":297},"\"MIT\"",[25,936,286],{"class":268},[25,938,939,942,944,947],{"class":27,"line":329},[25,940,941],{"class":275},"  \"type\"",[25,943,279],{"class":268},[25,945,946],{"class":297},"\"module\"",[25,948,286],{"class":268},[25,950,951,954],{"class":27,"line":342},[25,952,953],{"class":275},"  \"bin\"",[25,955,956],{"class":268},": {\n",[25,958,959,962,964],{"class":27,"line":355},[25,960,961],{"class":275},"    \"howfar\"",[25,963,279],{"class":268},[25,965,966],{"class":297},"\"dist/howfar.mjs\"\n",[25,968,969],{"class":27,"line":368},[25,970,971],{"class":268},"  },\n",[25,973,974,977,980,983],{"class":27,"line":379},[25,975,976],{"class":275},"  \"files\"",[25,978,979],{"class":268},": [",[25,981,982],{"class":297},"\"dist\"",[25,984,985],{"class":268},"],\n",[25,987,988,991],{"class":27,"line":499},[25,989,990],{"class":275},"  \"engines\"",[25,992,956],{"class":268},[25,994,995,998,1000],{"class":27,"line":509},[25,996,997],{"class":275},"    \"node\"",[25,999,279],{"class":268},[25,1001,1002],{"class":297},"\">=22\"\n",[25,1004,1005],{"class":27,"line":515},[25,1006,971],{"class":268},[25,1008,1009,1012],{"class":27,"line":520},[25,1010,1011],{"class":275},"  \"scripts\"",[25,1013,956],{"class":268},[25,1015,1016,1019,1021,1024],{"class":27,"line":532},[25,1017,1018],{"class":275},"    \"lint\"",[25,1020,279],{"class":268},[25,1022,1023],{"class":297},"\"vp lint\"",[25,1025,286],{"class":268},[25,1027,1028,1031,1033,1036],{"class":27,"line":544},[25,1029,1030],{"class":275},"    \"format\"",[25,1032,279],{"class":268},[25,1034,1035],{"class":297},"\"vp fmt\"",[25,1037,286],{"class":268},[25,1039,1040,1043,1045,1048],{"class":27,"line":556},[25,1041,1042],{"class":275},"    \"test\"",[25,1044,279],{"class":268},[25,1046,1047],{"class":297},"\"vp test run\"",[25,1049,286],{"class":268},[25,1051,1052,1055,1057,1060],{"class":27,"line":568},[25,1053,1054],{"class":275},"    \"type-check\"",[25,1056,279],{"class":268},[25,1058,1059],{"class":297},"\"tsc --noEmit\"",[25,1061,286],{"class":268},[25,1063,1064,1067,1069,1072],{"class":27,"line":579},[25,1065,1066],{"class":275},"    \"build\"",[25,1068,279],{"class":268},[25,1070,1071],{"class":297},"\"vp run type-check && vp pack\"",[25,1073,286],{"class":268},[25,1075,1076,1079,1081,1084],{"class":27,"line":589},[25,1077,1078],{"class":275},"    \"prepare\"",[25,1080,279],{"class":268},[25,1082,1083],{"class":297},"\"vp config --no-agent\"",[25,1085,286],{"class":268},[25,1087,1088,1091,1093],{"class":27,"line":595},[25,1089,1090],{"class":275},"    \"prepublishOnly\"",[25,1092,279],{"class":268},[25,1094,1095],{"class":297},"\"npm run build\"\n",[25,1097,1098],{"class":27,"line":601},[25,1099,971],{"class":268},[25,1101,1103,1106],{"class":27,"line":1102},23,[25,1104,1105],{"class":275},"  \"dependencies\"",[25,1107,956],{"class":268},[25,1109,1111,1114,1116,1119],{"class":27,"line":1110},24,[25,1112,1113],{"class":275},"    \"@clack/prompts\"",[25,1115,279],{"class":268},[25,1117,1118],{"class":297},"\"^1.8.1\"",[25,1120,286],{"class":268},[25,1122,1124,1127,1129,1132],{"class":27,"line":1123},25,[25,1125,1126],{"class":275},"    \"citty\"",[25,1128,279],{"class":268},[25,1130,1131],{"class":297},"\"^0.2.2\"",[25,1133,286],{"class":268},[25,1135,1137,1140,1142,1145],{"class":27,"line":1136},26,[25,1138,1139],{"class":275},"    \"rc9\"",[25,1141,279],{"class":268},[25,1143,1144],{"class":297},"\"^3.1.0\"",[25,1146,286],{"class":268},[25,1148,1150,1153,1155],{"class":27,"line":1149},27,[25,1151,1152],{"class":275},"    \"zod\"",[25,1154,279],{"class":268},[25,1156,1157],{"class":297},"\"^4.6.7\"\n",[25,1159,1161],{"class":27,"line":1160},28,[25,1162,971],{"class":268},[25,1164,1166,1169],{"class":27,"line":1165},29,[25,1167,1168],{"class":275},"  \"devDependencies\"",[25,1170,956],{"class":268},[25,1172,1174,1177,1179,1182],{"class":27,"line":1173},30,[25,1175,1176],{"class":275},"    \"@types/node\"",[25,1178,279],{"class":268},[25,1180,1181],{"class":297},"\"^26.6.6\"",[25,1183,286],{"class":268},[25,1185,1187,1190,1192,1195],{"class":27,"line":1186},31,[25,1188,1189],{"class":275},"    \"typescript\"",[25,1191,279],{"class":268},[25,1193,1194],{"class":297},"\"^7.0.2\"",[25,1196,286],{"class":268},[25,1198,1200,1203,1205,1208],{"class":27,"line":1199},32,[25,1201,1202],{"class":275},"    \"vite\"",[25,1204,279],{"class":268},[25,1206,1207],{"class":297},"\"npm:@voidzero-dev/vite-plus-core@^1.4.0\"",[25,1209,286],{"class":268},[25,1211,1213,1216,1218],{"class":27,"line":1212},33,[25,1214,1215],{"class":275},"    \"vite-plus\"",[25,1217,279],{"class":268},[25,1219,1220],{"class":297},"\"^1.4.0\"\n",[25,1222,1224],{"class":27,"line":1223},34,[25,1225,1226],{"class":268},"  }\n",[25,1228,1230],{"class":27,"line":1229},35,[25,1231,382],{"class":268},[11,1233,1234,1235,1238,1239,1241],{},"First, the ",[22,1236,1237],{},"name"," uses the scope we talked about at the beginning, so remember to replace ",[22,1240,156],{}," with your npm username.",[11,1243,1244],{},"Then, there are three keys that do the heavy lifting for a CLI:",[636,1246,1247,1263,1275],{},[639,1248,1249,1252,1253,1256,1257,1260,1261,150],{},[22,1250,1251],{},"bin"," maps a command name to a file. When someone runs ",[22,1254,1255],{},"npx @username/howfar",", npm executes ",[22,1258,1259],{},"dist/howfar.mjs",". If they install the package globally, the command they type is still just ",[22,1262,129],{},[639,1264,1265,1268,1269,1271,1272,150],{},[22,1266,1267],{},"files"," limits what gets published to the ",[22,1270,189],{}," folder. Nobody needs our TypeScript sources or tests in their ",[22,1273,1274],{},"node_modules",[639,1276,1277,1280,1281,1284],{},[22,1278,1279],{},"prepublishOnly"," runs the build right before ",[22,1282,1283],{},"npm publish",", so you can never publish stale output.",[11,1286,1287],{},"Next, let's add the TypeScript config:",[15,1289,1292],{"className":259,"code":1290,"filename":1291,"language":261,"meta":20,"style":20},"{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"NodeNext\",\n    \"moduleResolution\": \"NodeNext\",\n    \"outDir\": \"dist\",\n    \"rootDir\": \".\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true,\n    \"verbatimModuleSyntax\": true,\n    \"noUncheckedIndexedAccess\": true,\n    \"types\": [\"node\"]\n  },\n  \"include\": [\"bin\", \"commands\", \"lib\"]\n}\n","tsconfig.json",[22,1293,1294,1298,1305,1317,1329,1340,1351,1363,1374,1385,1396,1407,1418,1431,1435,1457],{"__ignoreMap":20},[25,1295,1296],{"class":27,"line":28},[25,1297,269],{"class":268},[25,1299,1300,1303],{"class":27,"line":272},[25,1301,1302],{"class":275},"  \"compilerOptions\"",[25,1304,956],{"class":268},[25,1306,1307,1310,1312,1315],{"class":27,"line":289},[25,1308,1309],{"class":275},"    \"target\"",[25,1311,279],{"class":268},[25,1313,1314],{"class":297},"\"ES2022\"",[25,1316,286],{"class":268},[25,1318,1319,1322,1324,1327],{"class":27,"line":303},[25,1320,1321],{"class":275},"    \"module\"",[25,1323,279],{"class":268},[25,1325,1326],{"class":297},"\"NodeNext\"",[25,1328,286],{"class":268},[25,1330,1331,1334,1336,1338],{"class":27,"line":316},[25,1332,1333],{"class":275},"    \"moduleResolution\"",[25,1335,279],{"class":268},[25,1337,1326],{"class":297},[25,1339,286],{"class":268},[25,1341,1342,1345,1347,1349],{"class":27,"line":329},[25,1343,1344],{"class":275},"    \"outDir\"",[25,1346,279],{"class":268},[25,1348,982],{"class":297},[25,1350,286],{"class":268},[25,1352,1353,1356,1358,1361],{"class":27,"line":342},[25,1354,1355],{"class":275},"    \"rootDir\"",[25,1357,279],{"class":268},[25,1359,1360],{"class":297},"\".\"",[25,1362,286],{"class":268},[25,1364,1365,1368,1370,1372],{"class":27,"line":355},[25,1366,1367],{"class":275},"    \"strict\"",[25,1369,279],{"class":268},[25,1371,283],{"class":282},[25,1373,286],{"class":268},[25,1375,1376,1379,1381,1383],{"class":27,"line":368},[25,1377,1378],{"class":275},"    \"esModuleInterop\"",[25,1380,279],{"class":268},[25,1382,283],{"class":282},[25,1384,286],{"class":268},[25,1386,1387,1390,1392,1394],{"class":27,"line":379},[25,1388,1389],{"class":275},"    \"skipLibCheck\"",[25,1391,279],{"class":268},[25,1393,283],{"class":282},[25,1395,286],{"class":268},[25,1397,1398,1401,1403,1405],{"class":27,"line":499},[25,1399,1400],{"class":275},"    \"verbatimModuleSyntax\"",[25,1402,279],{"class":268},[25,1404,283],{"class":282},[25,1406,286],{"class":268},[25,1408,1409,1412,1414,1416],{"class":27,"line":509},[25,1410,1411],{"class":275},"    \"noUncheckedIndexedAccess\"",[25,1413,279],{"class":268},[25,1415,283],{"class":282},[25,1417,286],{"class":268},[25,1419,1420,1423,1425,1428],{"class":27,"line":515},[25,1421,1422],{"class":275},"    \"types\"",[25,1424,979],{"class":268},[25,1426,1427],{"class":297},"\"node\"",[25,1429,1430],{"class":268},"]\n",[25,1432,1433],{"class":27,"line":520},[25,1434,971],{"class":268},[25,1436,1437,1440,1442,1445,1447,1450,1452,1455],{"class":27,"line":532},[25,1438,1439],{"class":275},"  \"include\"",[25,1441,979],{"class":268},[25,1443,1444],{"class":297},"\"bin\"",[25,1446,91],{"class":268},[25,1448,1449],{"class":297},"\"commands\"",[25,1451,91],{"class":268},[25,1453,1454],{"class":297},"\"lib\"",[25,1456,1430],{"class":268},[25,1458,1459],{"class":27,"line":544},[25,1460,382],{"class":268},[11,1462,1463,1464,1467,1468,1471,1472,1475,1476,1479],{},"I'd never turn off ",[22,1465,1466],{},"strict"," or ",[22,1469,1470],{},"noUncheckedIndexedAccess",". The second one types ",[22,1473,1474],{},"array[0]"," as ",[22,1477,1478],{},"T | undefined",", which is the truth, and it will catch a whole category of bugs before your users do.",[11,1481,1482,1483,1486,1487,1490,1491,1494],{},"And the ",[22,1484,1485],{},"types"," line matters more than it looks. Since TypeScript 6, the compiler no longer loads every ",[22,1488,1489],{},"@types"," package automatically, so without it, ",[22,1492,1493],{},"process"," is an unknown name and the entry point won't compile.",[11,1496,1497],{},"Now, let's add the Vite+ config:",[15,1499,1504],{"className":1500,"code":1501,"filename":1502,"language":1503,"meta":20,"style":20},"language-ts shiki shiki-themes monokai","import { defineConfig } from 'vite-plus'\n\nexport default defineConfig({\n  fmt: {\n    semi: false,\n    singleQuote: true,\n    ignorePatterns: ['dist/**', '**/*.md'],\n  },\n  lint: {\n    ignorePatterns: ['dist/**'],\n    rules: {\n      curly: ['error', 'all'],\n    },\n  },\n  pack: {\n    entry: ['bin/howfar.ts'],\n    format: ['es'],\n    platform: 'node',\n    target: 'node22',\n  },\n  staged: {\n    '*.{ts,js}': ['vp check --fix', 'vp test related --run'],\n  },\n})\n","vite.config.ts","ts",[22,1505,1506,1520,1526,1540,1545,1555,1564,1579,1583,1588,1596,1601,1616,1620,1624,1629,1639,1649,1659,1669,1673,1678,1695,1699],{"__ignoreMap":20},[25,1507,1508,1511,1514,1517],{"class":27,"line":28},[25,1509,1510],{"class":743},"import",[25,1512,1513],{"class":268}," { defineConfig } ",[25,1515,1516],{"class":743},"from",[25,1518,1519],{"class":35}," 'vite-plus'\n",[25,1521,1522],{"class":27,"line":272},[25,1523,1525],{"emptyLinePlaceholder":1524},true,"\n",[25,1527,1528,1531,1534,1537],{"class":27,"line":289},[25,1529,1530],{"class":743},"export",[25,1532,1533],{"class":743}," default",[25,1535,1536],{"class":31}," defineConfig",[25,1538,1539],{"class":268},"({\n",[25,1541,1542],{"class":27,"line":303},[25,1543,1544],{"class":268},"  fmt: {\n",[25,1546,1547,1550,1553],{"class":27,"line":316},[25,1548,1549],{"class":268},"    semi: ",[25,1551,1552],{"class":282},"false",[25,1554,286],{"class":268},[25,1556,1557,1560,1562],{"class":27,"line":329},[25,1558,1559],{"class":268},"    singleQuote: ",[25,1561,283],{"class":282},[25,1563,286],{"class":268},[25,1565,1566,1569,1572,1574,1577],{"class":27,"line":342},[25,1567,1568],{"class":268},"    ignorePatterns: [",[25,1570,1571],{"class":35},"'dist/**'",[25,1573,91],{"class":268},[25,1575,1576],{"class":35},"'**/*.md'",[25,1578,985],{"class":268},[25,1580,1581],{"class":27,"line":355},[25,1582,971],{"class":268},[25,1584,1585],{"class":27,"line":368},[25,1586,1587],{"class":268},"  lint: {\n",[25,1589,1590,1592,1594],{"class":27,"line":379},[25,1591,1568],{"class":268},[25,1593,1571],{"class":35},[25,1595,985],{"class":268},[25,1597,1598],{"class":27,"line":499},[25,1599,1600],{"class":268},"    rules: {\n",[25,1602,1603,1606,1609,1611,1614],{"class":27,"line":509},[25,1604,1605],{"class":268},"      curly: [",[25,1607,1608],{"class":35},"'error'",[25,1610,91],{"class":268},[25,1612,1613],{"class":35},"'all'",[25,1615,985],{"class":268},[25,1617,1618],{"class":27,"line":515},[25,1619,512],{"class":268},[25,1621,1622],{"class":27,"line":520},[25,1623,971],{"class":268},[25,1625,1626],{"class":27,"line":532},[25,1627,1628],{"class":268},"  pack: {\n",[25,1630,1631,1634,1637],{"class":27,"line":544},[25,1632,1633],{"class":268},"    entry: [",[25,1635,1636],{"class":35},"'bin/howfar.ts'",[25,1638,985],{"class":268},[25,1640,1641,1644,1647],{"class":27,"line":556},[25,1642,1643],{"class":268},"    format: [",[25,1645,1646],{"class":35},"'es'",[25,1648,985],{"class":268},[25,1650,1651,1654,1657],{"class":27,"line":568},[25,1652,1653],{"class":268},"    platform: ",[25,1655,1656],{"class":35},"'node'",[25,1658,286],{"class":268},[25,1660,1661,1664,1667],{"class":27,"line":579},[25,1662,1663],{"class":268},"    target: ",[25,1665,1666],{"class":35},"'node22'",[25,1668,286],{"class":268},[25,1670,1671],{"class":27,"line":589},[25,1672,971],{"class":268},[25,1674,1675],{"class":27,"line":595},[25,1676,1677],{"class":268},"  staged: {\n",[25,1679,1680,1683,1685,1688,1690,1693],{"class":27,"line":601},[25,1681,1682],{"class":35},"    '*.{ts,js}'",[25,1684,979],{"class":268},[25,1686,1687],{"class":35},"'vp check --fix'",[25,1689,91],{"class":268},[25,1691,1692],{"class":35},"'vp test related --run'",[25,1694,985],{"class":268},[25,1696,1697],{"class":27,"line":1102},[25,1698,971],{"class":268},[25,1700,1701],{"class":27,"line":1110},[25,1702,1703],{"class":268},"})\n",[11,1705,1706,1707,1710,1711,1714,1715,1718,1719,1721,1722,150],{},"Here, the ",[22,1708,1709],{},"pack"," block is the important one. It tells Vite+ to take ",[22,1712,1713],{},"bin/howfar.ts",", follow every import, and bundle the result into a single ES module for Node 22. The ",[22,1716,1717],{},"staged"," block sets up a pre-commit hook that formats and lints the files you're about to commit, then runs the tests that import them. The ",[22,1720,196],{}," script we added earlier installs that hook the first time you run ",[22,1723,857],{},[11,1725,1726,1727,770],{},"Finally, let's add a ",[22,1728,1729],{},".gitignore",[15,1731,1734],{"className":1732,"code":1733,"filename":1729,"language":230,"meta":20},[228],"node_modules/\ndist/\n",[22,1735,1733],{"__ignoreMap":20},[11,1737,1738,1739,1741,1742,1744],{},"Then, let's run ",[22,1740,857],{}," once more so the ",[22,1743,196],{}," script installs the Git hook. And with that, the setup is done.",[72,1746,1748],{"id":1747},"the-folder-structure","The Folder Structure",[11,1750,1751],{},"Before we write the first command, here's the layout we're building toward. I settled on it after trying a few, and it's the one climail uses too:",[15,1753,1756],{"className":1754,"code":1755,"language":230,"meta":20},[228],"howfar/\n├── bin/\n│   └── howfar.ts        # entry point: wires commands together\n├── commands/\n│   ├── init.ts          # one file per command\n│   └── lookup.ts\n├── lib/\n│   ├── cli.ts           # shared argument parsers\n│   ├── config.ts        # read, validate and write the config file\n│   └── distance.ts      # finds cities and measures between them\n├── tests/\n│   ├── cli.test.ts\n│   ├── distance.test.ts\n│   └── lookup.test.ts\n├── package.json\n├── tsconfig.json\n└── vite.config.ts\n",[22,1757,1755],{"__ignoreMap":20},[11,1759,1760,1761,1764,1765,1768,1769,1772,1773,1775],{},"The layout stays tidy as long as ",[44,1762,1763],{},"commands stay thin and libraries stay thick."," A file in ",[22,1766,1767],{},"commands/"," reads its arguments, calls into ",[22,1770,1771],{},"lib/",", and returns a result. Everything that does actual work lives in ",[22,1774,1771],{},", where it can be imported, reused, and tested on its own, with no terminal involved.",[72,1777,1779],{"id":1778},"the-entry-point","The Entry Point",[11,1781,1782,1783,1786,1787,1789],{},"Okay, let's start writing code. The file in ",[22,1784,1785],{},"bin/"," is what runs when someone types ",[22,1788,129],{},". Its only job is to collect the commands and dispatch to the right one.",[15,1791,1793],{"className":1500,"code":1792,"filename":1713,"language":1503,"meta":20,"style":20},"#!/usr/bin/env node\n\nimport { defineCommand, runCommand, showUsage, type CommandDef } from 'citty'\nimport { lookup } from '../commands/lookup.js'\n\nconst subCommands: Record\u003Cstring, CommandDef\u003Cany>> = {}\n\nconst main = defineCommand({ ...lookup, subCommands })\n\nasync function run() {\n  const argv = process.argv.slice(2)\n  const [name, ...rest] = argv\n  const subCommand = name ? subCommands[name] : undefined\n  const wantsHelp = argv.includes('--help') || argv.includes('-h')\n\n  if (wantsHelp) {\n    await (subCommand ? showUsage(subCommand, main) : showUsage(main))\n\n    return\n  }\n\n  const command = subCommand ?? lookup\n  const { result } = await runCommand(command, { rawArgs: subCommand ? rest : argv })\n\n  if (result !== undefined) {\n    console.log(JSON.stringify(result, null, 2))\n  }\n}\n\nrun().catch((error: unknown) => {\n  console.error(error instanceof Error ? error.message : error)\n  process.exit(1)\n})\n",[22,1794,1795,1801,1805,1823,1835,1839,1878,1882,1903,1907,1921,1946,1963,1985,2022,2026,2034,2057,2061,2066,2070,2074,2091,2119,2123,2139,2166,2170,2174,2178,2209,2236,2251],{"__ignoreMap":20},[25,1796,1797],{"class":27,"line":28},[25,1798,1800],{"class":1799},"snpHw","#!/usr/bin/env node\n",[25,1802,1803],{"class":27,"line":272},[25,1804,1525],{"emptyLinePlaceholder":1524},[25,1806,1807,1809,1812,1815,1818,1820],{"class":27,"line":289},[25,1808,1510],{"class":743},[25,1810,1811],{"class":268}," { defineCommand, runCommand, showUsage, ",[25,1813,1814],{"class":743},"type",[25,1816,1817],{"class":268}," CommandDef } ",[25,1819,1516],{"class":743},[25,1821,1822],{"class":35}," 'citty'\n",[25,1824,1825,1827,1830,1832],{"class":27,"line":303},[25,1826,1510],{"class":743},[25,1828,1829],{"class":268}," { lookup } ",[25,1831,1516],{"class":743},[25,1833,1834],{"class":35}," '../commands/lookup.js'\n",[25,1836,1837],{"class":27,"line":316},[25,1838,1525],{"emptyLinePlaceholder":1524},[25,1840,1841,1844,1847,1849,1853,1856,1859,1861,1864,1866,1869,1872,1875],{"class":27,"line":329},[25,1842,1843],{"class":275},"const",[25,1845,1846],{"class":268}," subCommands",[25,1848,770],{"class":743},[25,1850,1852],{"class":1851},"soZtE"," Record",[25,1854,1855],{"class":268},"\u003C",[25,1857,1858],{"class":275},"string",[25,1860,91],{"class":268},[25,1862,1863],{"class":1851},"CommandDef",[25,1865,1855],{"class":268},[25,1867,1868],{"class":275},"any",[25,1870,1871],{"class":268},">> ",[25,1873,1874],{"class":743},"=",[25,1876,1877],{"class":268}," {}\n",[25,1879,1880],{"class":27,"line":342},[25,1881,1525],{"emptyLinePlaceholder":1524},[25,1883,1884,1886,1889,1891,1894,1897,1900],{"class":27,"line":355},[25,1885,1843],{"class":275},[25,1887,1888],{"class":268}," main ",[25,1890,1874],{"class":743},[25,1892,1893],{"class":31}," defineCommand",[25,1895,1896],{"class":268},"({ ",[25,1898,1899],{"class":743},"...",[25,1901,1902],{"class":268},"lookup, subCommands })\n",[25,1904,1905],{"class":27,"line":368},[25,1906,1525],{"emptyLinePlaceholder":1524},[25,1908,1909,1912,1915,1918],{"class":27,"line":379},[25,1910,1911],{"class":743},"async",[25,1913,1914],{"class":275}," function",[25,1916,1917],{"class":31}," run",[25,1919,1920],{"class":268},"() {\n",[25,1922,1923,1926,1929,1931,1934,1937,1940,1943],{"class":27,"line":499},[25,1924,1925],{"class":275},"  const",[25,1927,1928],{"class":268}," argv ",[25,1930,1874],{"class":743},[25,1932,1933],{"class":268}," process.argv.",[25,1935,1936],{"class":31},"slice",[25,1938,1939],{"class":268},"(",[25,1941,1942],{"class":282},"2",[25,1944,1945],{"class":268},")\n",[25,1947,1948,1950,1953,1955,1958,1960],{"class":27,"line":509},[25,1949,1925],{"class":275},[25,1951,1952],{"class":268}," [name, ",[25,1954,1899],{"class":743},[25,1956,1957],{"class":268},"rest] ",[25,1959,1874],{"class":743},[25,1961,1962],{"class":268}," argv\n",[25,1964,1965,1967,1970,1972,1975,1977,1980,1982],{"class":27,"line":515},[25,1966,1925],{"class":275},[25,1968,1969],{"class":268}," subCommand ",[25,1971,1874],{"class":743},[25,1973,1974],{"class":268}," name ",[25,1976,862],{"class":743},[25,1978,1979],{"class":268}," subCommands[name] ",[25,1981,770],{"class":743},[25,1983,1984],{"class":282}," undefined\n",[25,1986,1987,1989,1992,1994,1997,2000,2002,2005,2008,2011,2013,2015,2017,2020],{"class":27,"line":520},[25,1988,1925],{"class":275},[25,1990,1991],{"class":268}," wantsHelp ",[25,1993,1874],{"class":743},[25,1995,1996],{"class":268}," argv.",[25,1998,1999],{"class":31},"includes",[25,2001,1939],{"class":268},[25,2003,2004],{"class":35},"'--help'",[25,2006,2007],{"class":268},") ",[25,2009,2010],{"class":743},"||",[25,2012,1996],{"class":268},[25,2014,1999],{"class":31},[25,2016,1939],{"class":268},[25,2018,2019],{"class":35},"'-h'",[25,2021,1945],{"class":268},[25,2023,2024],{"class":27,"line":532},[25,2025,1525],{"emptyLinePlaceholder":1524},[25,2027,2028,2031],{"class":27,"line":544},[25,2029,2030],{"class":743},"  if",[25,2032,2033],{"class":268}," (wantsHelp) {\n",[25,2035,2036,2039,2042,2044,2047,2050,2052,2054],{"class":27,"line":556},[25,2037,2038],{"class":743},"    await",[25,2040,2041],{"class":268}," (subCommand ",[25,2043,862],{"class":743},[25,2045,2046],{"class":31}," showUsage",[25,2048,2049],{"class":268},"(subCommand, main) ",[25,2051,770],{"class":743},[25,2053,2046],{"class":31},[25,2055,2056],{"class":268},"(main))\n",[25,2058,2059],{"class":27,"line":568},[25,2060,1525],{"emptyLinePlaceholder":1524},[25,2062,2063],{"class":27,"line":579},[25,2064,2065],{"class":743},"    return\n",[25,2067,2068],{"class":27,"line":589},[25,2069,1226],{"class":268},[25,2071,2072],{"class":27,"line":595},[25,2073,1525],{"emptyLinePlaceholder":1524},[25,2075,2076,2078,2081,2083,2085,2088],{"class":27,"line":601},[25,2077,1925],{"class":275},[25,2079,2080],{"class":268}," command ",[25,2082,1874],{"class":743},[25,2084,1969],{"class":268},[25,2086,2087],{"class":743},"??",[25,2089,2090],{"class":268}," lookup\n",[25,2092,2093,2095,2098,2100,2103,2106,2109,2111,2114,2116],{"class":27,"line":1102},[25,2094,1925],{"class":275},[25,2096,2097],{"class":268}," { result } ",[25,2099,1874],{"class":743},[25,2101,2102],{"class":743}," await",[25,2104,2105],{"class":31}," runCommand",[25,2107,2108],{"class":268},"(command, { rawArgs: subCommand ",[25,2110,862],{"class":743},[25,2112,2113],{"class":268}," rest ",[25,2115,770],{"class":743},[25,2117,2118],{"class":268}," argv })\n",[25,2120,2121],{"class":27,"line":1110},[25,2122,1525],{"emptyLinePlaceholder":1524},[25,2124,2125,2127,2130,2133,2136],{"class":27,"line":1123},[25,2126,2030],{"class":743},[25,2128,2129],{"class":268}," (result ",[25,2131,2132],{"class":743},"!==",[25,2134,2135],{"class":282}," undefined",[25,2137,2138],{"class":268},") {\n",[25,2140,2141,2144,2147,2150,2153,2156,2159,2161,2163],{"class":27,"line":1136},[25,2142,2143],{"class":268},"    console.",[25,2145,2146],{"class":31},"log",[25,2148,2149],{"class":268},"(JSON.",[25,2151,2152],{"class":31},"stringify",[25,2154,2155],{"class":268},"(result, ",[25,2157,2158],{"class":282},"null",[25,2160,91],{"class":268},[25,2162,1942],{"class":282},[25,2164,2165],{"class":268},"))\n",[25,2167,2168],{"class":27,"line":1149},[25,2169,1226],{"class":268},[25,2171,2172],{"class":27,"line":1160},[25,2173,382],{"class":268},[25,2175,2176],{"class":27,"line":1165},[25,2177,1525],{"emptyLinePlaceholder":1524},[25,2179,2180,2183,2186,2189,2192,2196,2198,2201,2203,2206],{"class":27,"line":1173},[25,2181,2182],{"class":31},"run",[25,2184,2185],{"class":268},"().",[25,2187,2188],{"class":31},"catch",[25,2190,2191],{"class":268},"((",[25,2193,2195],{"class":2194},"sW0Xf","error",[25,2197,770],{"class":743},[25,2199,2200],{"class":275}," unknown",[25,2202,2007],{"class":268},[25,2204,2205],{"class":275},"=>",[25,2207,2208],{"class":268}," {\n",[25,2210,2211,2214,2216,2219,2222,2225,2228,2231,2233],{"class":27,"line":1186},[25,2212,2213],{"class":268},"  console.",[25,2215,2195],{"class":31},[25,2217,2218],{"class":268},"(error ",[25,2220,2221],{"class":743},"instanceof",[25,2223,2224],{"class":1851}," Error",[25,2226,2227],{"class":743}," ?",[25,2229,2230],{"class":268}," error.message ",[25,2232,770],{"class":743},[25,2234,2235],{"class":268}," error)\n",[25,2237,2238,2241,2244,2246,2249],{"class":27,"line":1199},[25,2239,2240],{"class":268},"  process.",[25,2242,2243],{"class":31},"exit",[25,2245,1939],{"class":268},[25,2247,2248],{"class":282},"1",[25,2250,1945],{"class":268},[25,2252,2253],{"class":27,"line":1212},[25,2254,1703],{"class":268},[11,2256,2257],{},"Let's break this down:",[636,2259,2260,2275,2281,2299,2311],{},[639,2261,2262,2263,2266,2267,2270,2271,2274],{},"The first line, ",[22,2264,2265],{},"#!/usr/bin/env node",", is the shebang. It means \"execute me with whatever ",[22,2268,2269],{},"node"," is on the user's ",[22,2272,2273],{},"PATH","\". Vite+ keeps it in the bundled output, so the published file is directly executable.",[639,2276,2277,2280],{},[22,2278,2279],{},"process.argv.slice(2)"," drops the first two entries (the Node binary and the script path) and leaves us with what the user actually typed. The first word is either a subcommand name or a city.",[639,2282,2283,2284,2287,2288,2291,2292,2295,2296,2298],{},"If the first word matches a subcommand, we run it with the rest of the arguments. Anything else is a city, so the whole list goes to the default ",[22,2285,2286],{},"lookup"," command. That's what lets users type ",[22,2289,2290],{},"howfar Tokyo"," instead of ",[22,2293,2294],{},"howfar lookup Tokyo",". The subcommand list is empty for now, but ",[22,2297,669],{}," will land there soon.",[639,2300,2301,2304,2305,2307,2308,2310],{},[22,2302,2303],{},"main"," is the ",[22,2306,2286],{}," command with the subcommands attached. We only use it for ",[22,2309,655],{},", so the top-level help screen lists both the city argument and every subcommand.",[639,2312,2313,2314,2317,2318,2321],{},"Every command ",[44,2315,2316],{},"returns"," its result instead of printing it. The entry point is the only place that calls ",[22,2319,2320],{},"console.log",", and it always prints JSON.",[11,2323,2324,2325,2328],{},"That last point is deliberate. When output is JSON, your tool works in a pipeline: ",[22,2326,2327],{},"npx @username/howfar Tokyo | jq .distance",", a shell script, a cron job, or an AI agent that runs your command and reads the result. Plain text is nicer to look at, but much harder to build on. climail prints JSON for exactly this reason, and it's what makes it useful to agents.",[11,2330,2331,2332,2334],{},"And then the ",[22,2333,2188],{}," at the bottom turns any thrown error into a single line on stderr and a non-zero exit code. Without it, a misspelled city would dump a stack trace at the user, which is fine for us and terrible for them.",[159,2336,2337],{},[11,2338,2339,2340,2343,2344,862],{},"Why the ",[22,2341,2342],{},".js"," extension when the file is called ",[22,2345,2346],{},"lookup.ts",[11,2348,2349,2350,2353,2354,2358,2359,2362],{},"That's how ES modules with ",[22,2351,2352],{},"NodeNext"," resolution work: imports point at the file that will exist ",[2355,2356,2357],"em",{},"after"," compilation. TypeScript knows to look for the ",[22,2360,2361],{},".ts"," source, and the bundler does the same. It looks wrong the first time, but then you stop noticing it.",[72,2364,2366],{"id":2365},"the-first-command","The First Command",[11,2368,2369,2370,2373,2374,2376,2377,2379],{},"Each command lives in its own file and exports a ",[22,2371,2372],{},"defineCommand"," object. Here's ",[22,2375,2286],{},", the default command. For now, it takes the city to measure the distance to, and a ",[22,2378,609],{}," flag with the city to measure from:",[15,2381,2384],{"className":1500,"code":2382,"filename":2383,"language":1503,"meta":20,"style":20},"import { defineCommand } from 'citty'\nimport { fetchDistance } from '../lib/distance.js'\n\nconst lookup = defineCommand({\n  meta: { name: 'howfar', description: 'Distance between two cities, as JSON' },\n  args: {\n    city: {\n      type: 'positional',\n      required: true,\n      description: 'City to measure the distance to',\n    },\n    from: {\n      type: 'string',\n      required: true,\n      description: 'City to measure the distance from',\n    },\n  },\n  run: async ({ args }) => {\n    return fetchDistance(args.city, args.from)\n  },\n})\n\nexport { lookup }\n","commands/lookup.ts",[22,2385,2386,2397,2409,2413,2426,2443,2448,2453,2463,2472,2482,2486,2491,2500,2508,2517,2521,2525,2547,2558,2562,2566,2570],{"__ignoreMap":20},[25,2387,2388,2390,2393,2395],{"class":27,"line":28},[25,2389,1510],{"class":743},[25,2391,2392],{"class":268}," { defineCommand } ",[25,2394,1516],{"class":743},[25,2396,1822],{"class":35},[25,2398,2399,2401,2404,2406],{"class":27,"line":272},[25,2400,1510],{"class":743},[25,2402,2403],{"class":268}," { fetchDistance } ",[25,2405,1516],{"class":743},[25,2407,2408],{"class":35}," '../lib/distance.js'\n",[25,2410,2411],{"class":27,"line":289},[25,2412,1525],{"emptyLinePlaceholder":1524},[25,2414,2415,2417,2420,2422,2424],{"class":27,"line":303},[25,2416,1843],{"class":275},[25,2418,2419],{"class":268}," lookup ",[25,2421,1874],{"class":743},[25,2423,1893],{"class":31},[25,2425,1539],{"class":268},[25,2427,2428,2431,2434,2437,2440],{"class":27,"line":316},[25,2429,2430],{"class":268},"  meta: { name: ",[25,2432,2433],{"class":35},"'howfar'",[25,2435,2436],{"class":268},", description: ",[25,2438,2439],{"class":35},"'Distance between two cities, as JSON'",[25,2441,2442],{"class":268}," },\n",[25,2444,2445],{"class":27,"line":329},[25,2446,2447],{"class":268},"  args: {\n",[25,2449,2450],{"class":27,"line":342},[25,2451,2452],{"class":268},"    city: {\n",[25,2454,2455,2458,2461],{"class":27,"line":355},[25,2456,2457],{"class":268},"      type: ",[25,2459,2460],{"class":35},"'positional'",[25,2462,286],{"class":268},[25,2464,2465,2468,2470],{"class":27,"line":368},[25,2466,2467],{"class":268},"      required: ",[25,2469,283],{"class":282},[25,2471,286],{"class":268},[25,2473,2474,2477,2480],{"class":27,"line":379},[25,2475,2476],{"class":268},"      description: ",[25,2478,2479],{"class":35},"'City to measure the distance to'",[25,2481,286],{"class":268},[25,2483,2484],{"class":27,"line":499},[25,2485,512],{"class":268},[25,2487,2488],{"class":27,"line":509},[25,2489,2490],{"class":268},"    from: {\n",[25,2492,2493,2495,2498],{"class":27,"line":515},[25,2494,2457],{"class":268},[25,2496,2497],{"class":35},"'string'",[25,2499,286],{"class":268},[25,2501,2502,2504,2506],{"class":27,"line":520},[25,2503,2467],{"class":268},[25,2505,283],{"class":282},[25,2507,286],{"class":268},[25,2509,2510,2512,2515],{"class":27,"line":532},[25,2511,2476],{"class":268},[25,2513,2514],{"class":35},"'City to measure the distance from'",[25,2516,286],{"class":268},[25,2518,2519],{"class":27,"line":544},[25,2520,512],{"class":268},[25,2522,2523],{"class":27,"line":556},[25,2524,971],{"class":268},[25,2526,2527,2530,2532,2534,2537,2540,2543,2545],{"class":27,"line":568},[25,2528,2529],{"class":31},"  run",[25,2531,279],{"class":268},[25,2533,1911],{"class":743},[25,2535,2536],{"class":268}," ({ ",[25,2538,2539],{"class":2194},"args",[25,2541,2542],{"class":268}," }) ",[25,2544,2205],{"class":275},[25,2546,2208],{"class":268},[25,2548,2549,2552,2555],{"class":27,"line":579},[25,2550,2551],{"class":743},"    return",[25,2553,2554],{"class":31}," fetchDistance",[25,2556,2557],{"class":268},"(args.city, args.from)\n",[25,2559,2560],{"class":27,"line":589},[25,2561,971],{"class":268},[25,2563,2564],{"class":27,"line":595},[25,2565,1703],{"class":268},[25,2567,2568],{"class":27,"line":601},[25,2569,1525],{"emptyLinePlaceholder":1524},[25,2571,2572,2574],{"class":27,"line":1102},[25,2573,1530],{"class":743},[25,2575,2576],{"class":268}," { lookup }\n",[11,2578,2579,2580,2582,2583,2585,2586,2588,2589,2592,2593,2596,2597,2599,2600,1467,2603,2606,2607,2610,2611,2614,2615,2617,2618,2620,2621,2623],{},"The ",[22,2581,2539],{}," object is the whole argument parser. citty reads it to validate input, to generate the help screen, and to type ",[22,2584,2539],{}," inside ",[22,2587,2182],{},". A ",[22,2590,2591],{},"positional"," argument is a bare word, like ",[22,2594,2595],{},"Tokyo",", and a ",[22,2598,1858],{}," argument is a flag, like ",[22,2601,2602],{},"--from Lima",[22,2604,2605],{},"--from=Lima",". Since we marked both as required, ",[22,2608,2609],{},"args.city"," and ",[22,2612,2613],{},"args.from"," are typed as ",[22,2616,1858],{}," in the ",[22,2619,2182],{}," function, with no casting needed. A few lines of declaration, and ",[22,2622,655],{}," already works.",[11,2625,2626,2627,770],{},"Next, let's write the distance logic, which goes in ",[22,2628,1771],{},[15,2630,2633],{"className":1500,"code":2631,"filename":2632,"language":1503,"meta":20,"style":20},"type Place = { name: string; country: string; latitude: number; longitude: number }\n\ntype Unit = 'km' | 'mi'\n\nconst EARTH_RADIUS: Record\u003CUnit, number> = { km: 6371, mi: 3959 }\n\nasync function geocode(city: string): Promise\u003CPlace> {\n  const url = new URL('https://geocoding-api.open-meteo.com/v1/search')\n  url.searchParams.set('name', city)\n  url.searchParams.set('count', '1')\n\n  const response = await fetch(url)\n  const data = (await response.json()) as { results?: Place[] }\n  const place = data.results?.[0]\n\n  if (!place) {\n    throw new Error(`Could not find a city called \"${city}\"`)\n  }\n\n  return place\n}\n\nfunction toRadians(degrees: number): number {\n  return (degrees * Math.PI) / 180\n}\n\n/** Shortest distance over the Earth's surface between two places, using the haversine formula. */\nfunction distanceBetween(a: Place, b: Place, unit: Unit): number {\n  const latitude = toRadians(b.latitude - a.latitude)\n  const longitude = toRadians(b.longitude - a.longitude)\n  const h =\n    Math.sin(latitude / 2) ** 2 +\n    Math.cos(toRadians(a.latitude)) * Math.cos(toRadians(b.latitude)) * Math.sin(longitude / 2) ** 2\n\n  return Math.round(2 * EARTH_RADIUS[unit] * Math.asin(Math.sqrt(h)))\n}\n\nfunction describe(place: Place, from: Place, unit: Unit) {\n  const distance = distanceBetween(from, place, unit)\n\n  return {\n    city: `${place.name}, ${place.country}`,\n    latitude: place.latitude,\n    longitude: place.longitude,\n    distance,\n    unit,\n    summary: `${place.name} is ${distance.toLocaleString('en-US')} ${unit} from ${from.name}`,\n  }\n}\n\nasync function fetchDistance(city: string, from: string, unit: Unit = 'km') {\n  const [place, origin] = await Promise.all([geocode(city), geocode(from)])\n\n  return { ok: true, from: `${origin.name}, ${origin.country}`, ...describe(place, origin, unit) }\n}\n\nexport { geocode, distanceBetween, fetchDistance }\n\nexport type { Place, Unit }\n","lib/distance.ts",[22,2634,2635,2678,2682,2699,2703,2743,2747,2781,2803,2819,2837,2841,2858,2895,2912,2916,2928,2955,2959,2963,2971,2975,2979,3004,3023,3027,3031,3036,3077,3097,3116,3126,3152,3201,3205,3240,3245,3250,3285,3300,3305,3312,3341,3347,3353,3359,3365,3420,3425,3430,3435,3474,3507,3512,3555,3560,3565,3573,3578],{"__ignoreMap":20},[25,2636,2637,2639,2642,2645,2648,2650,2653,2656,2658,2660,2663,2665,2668,2671,2673,2675],{"class":27,"line":28},[25,2638,1814],{"class":275},[25,2640,2641],{"class":1851}," Place",[25,2643,2644],{"class":743}," =",[25,2646,2647],{"class":268}," { name",[25,2649,770],{"class":743},[25,2651,2652],{"class":275}," string",[25,2654,2655],{"class":268},"; country",[25,2657,770],{"class":743},[25,2659,2652],{"class":275},[25,2661,2662],{"class":268},"; latitude",[25,2664,770],{"class":743},[25,2666,2667],{"class":275}," number",[25,2669,2670],{"class":268},"; longitude",[25,2672,770],{"class":743},[25,2674,2667],{"class":275},[25,2676,2677],{"class":268}," }\n",[25,2679,2680],{"class":27,"line":272},[25,2681,1525],{"emptyLinePlaceholder":1524},[25,2683,2684,2686,2689,2691,2694,2696],{"class":27,"line":289},[25,2685,1814],{"class":275},[25,2687,2688],{"class":1851}," Unit",[25,2690,2644],{"class":743},[25,2692,2693],{"class":35}," 'km'",[25,2695,744],{"class":743},[25,2697,2698],{"class":35}," 'mi'\n",[25,2700,2701],{"class":27,"line":303},[25,2702,1525],{"emptyLinePlaceholder":1524},[25,2704,2705,2707,2710,2712,2714,2716,2719,2721,2724,2727,2729,2732,2735,2738,2741],{"class":27,"line":316},[25,2706,1843],{"class":275},[25,2708,2709],{"class":268}," EARTH_RADIUS",[25,2711,770],{"class":743},[25,2713,1852],{"class":1851},[25,2715,1855],{"class":268},[25,2717,2718],{"class":1851},"Unit",[25,2720,91],{"class":268},[25,2722,2723],{"class":275},"number",[25,2725,2726],{"class":268},"> ",[25,2728,1874],{"class":743},[25,2730,2731],{"class":268}," { km: ",[25,2733,2734],{"class":282},"6371",[25,2736,2737],{"class":268},", mi: ",[25,2739,2740],{"class":282},"3959",[25,2742,2677],{"class":268},[25,2744,2745],{"class":27,"line":329},[25,2746,1525],{"emptyLinePlaceholder":1524},[25,2748,2749,2751,2753,2756,2758,2761,2763,2765,2768,2770,2773,2775,2778],{"class":27,"line":342},[25,2750,1911],{"class":743},[25,2752,1914],{"class":275},[25,2754,2755],{"class":31}," geocode",[25,2757,1939],{"class":268},[25,2759,2760],{"class":2194},"city",[25,2762,770],{"class":743},[25,2764,2652],{"class":275},[25,2766,2767],{"class":268},")",[25,2769,770],{"class":743},[25,2771,2772],{"class":1851}," Promise",[25,2774,1855],{"class":268},[25,2776,2777],{"class":1851},"Place",[25,2779,2780],{"class":268},"> {\n",[25,2782,2783,2785,2788,2790,2793,2796,2798,2801],{"class":27,"line":355},[25,2784,1925],{"class":275},[25,2786,2787],{"class":268}," url ",[25,2789,1874],{"class":743},[25,2791,2792],{"class":743}," new",[25,2794,2795],{"class":31}," URL",[25,2797,1939],{"class":268},[25,2799,2800],{"class":35},"'https://geocoding-api.open-meteo.com/v1/search'",[25,2802,1945],{"class":268},[25,2804,2805,2808,2811,2813,2816],{"class":27,"line":368},[25,2806,2807],{"class":268},"  url.searchParams.",[25,2809,2810],{"class":31},"set",[25,2812,1939],{"class":268},[25,2814,2815],{"class":35},"'name'",[25,2817,2818],{"class":268},", city)\n",[25,2820,2821,2823,2825,2827,2830,2832,2835],{"class":27,"line":379},[25,2822,2807],{"class":268},[25,2824,2810],{"class":31},[25,2826,1939],{"class":268},[25,2828,2829],{"class":35},"'count'",[25,2831,91],{"class":268},[25,2833,2834],{"class":35},"'1'",[25,2836,1945],{"class":268},[25,2838,2839],{"class":27,"line":499},[25,2840,1525],{"emptyLinePlaceholder":1524},[25,2842,2843,2845,2848,2850,2852,2855],{"class":27,"line":509},[25,2844,1925],{"class":275},[25,2846,2847],{"class":268}," response ",[25,2849,1874],{"class":743},[25,2851,2102],{"class":743},[25,2853,2854],{"class":31}," fetch",[25,2856,2857],{"class":268},"(url)\n",[25,2859,2860,2862,2865,2867,2870,2873,2876,2878,2881,2884,2887,2890,2892],{"class":27,"line":515},[25,2861,1925],{"class":275},[25,2863,2864],{"class":268}," data ",[25,2866,1874],{"class":743},[25,2868,2869],{"class":268}," (",[25,2871,2872],{"class":743},"await",[25,2874,2875],{"class":268}," response.",[25,2877,261],{"class":31},[25,2879,2880],{"class":268},"()) ",[25,2882,2883],{"class":743},"as",[25,2885,2886],{"class":268}," { results",[25,2888,2889],{"class":743},"?:",[25,2891,2641],{"class":1851},[25,2893,2894],{"class":268},"[] }\n",[25,2896,2897,2899,2902,2904,2907,2910],{"class":27,"line":520},[25,2898,1925],{"class":275},[25,2900,2901],{"class":268}," place ",[25,2903,1874],{"class":743},[25,2905,2906],{"class":268}," data.results?.[",[25,2908,2909],{"class":282},"0",[25,2911,1430],{"class":268},[25,2913,2914],{"class":27,"line":532},[25,2915,1525],{"emptyLinePlaceholder":1524},[25,2917,2918,2920,2922,2925],{"class":27,"line":544},[25,2919,2030],{"class":743},[25,2921,2869],{"class":268},[25,2923,2924],{"class":743},"!",[25,2926,2927],{"class":268},"place) {\n",[25,2929,2930,2933,2935,2937,2939,2942,2945,2947,2950,2953],{"class":27,"line":556},[25,2931,2932],{"class":743},"    throw",[25,2934,2792],{"class":743},[25,2936,2224],{"class":31},[25,2938,1939],{"class":268},[25,2940,2941],{"class":35},"`Could not find a city called \"",[25,2943,2944],{"class":743},"${",[25,2946,2760],{"class":268},[25,2948,2949],{"class":743},"}",[25,2951,2952],{"class":35},"\"`",[25,2954,1945],{"class":268},[25,2956,2957],{"class":27,"line":568},[25,2958,1226],{"class":268},[25,2960,2961],{"class":27,"line":579},[25,2962,1525],{"emptyLinePlaceholder":1524},[25,2964,2965,2968],{"class":27,"line":589},[25,2966,2967],{"class":743},"  return",[25,2969,2970],{"class":268}," place\n",[25,2972,2973],{"class":27,"line":595},[25,2974,382],{"class":268},[25,2976,2977],{"class":27,"line":601},[25,2978,1525],{"emptyLinePlaceholder":1524},[25,2980,2981,2984,2987,2989,2992,2994,2996,2998,3000,3002],{"class":27,"line":1102},[25,2982,2983],{"class":275},"function",[25,2985,2986],{"class":31}," toRadians",[25,2988,1939],{"class":268},[25,2990,2991],{"class":2194},"degrees",[25,2993,770],{"class":743},[25,2995,2667],{"class":275},[25,2997,2767],{"class":268},[25,2999,770],{"class":743},[25,3001,2667],{"class":275},[25,3003,2208],{"class":268},[25,3005,3006,3008,3011,3014,3017,3020],{"class":27,"line":1110},[25,3007,2967],{"class":743},[25,3009,3010],{"class":268}," (degrees ",[25,3012,3013],{"class":743},"*",[25,3015,3016],{"class":268}," Math.PI) ",[25,3018,3019],{"class":743},"/",[25,3021,3022],{"class":282}," 180\n",[25,3024,3025],{"class":27,"line":1123},[25,3026,382],{"class":268},[25,3028,3029],{"class":27,"line":1136},[25,3030,1525],{"emptyLinePlaceholder":1524},[25,3032,3033],{"class":27,"line":1149},[25,3034,3035],{"class":1799},"/** Shortest distance over the Earth's surface between two places, using the haversine formula. */\n",[25,3037,3038,3040,3043,3045,3047,3049,3051,3053,3056,3058,3060,3062,3065,3067,3069,3071,3073,3075],{"class":27,"line":1160},[25,3039,2983],{"class":275},[25,3041,3042],{"class":31}," distanceBetween",[25,3044,1939],{"class":268},[25,3046,60],{"class":2194},[25,3048,770],{"class":743},[25,3050,2641],{"class":1851},[25,3052,91],{"class":268},[25,3054,3055],{"class":2194},"b",[25,3057,770],{"class":743},[25,3059,2641],{"class":1851},[25,3061,91],{"class":268},[25,3063,3064],{"class":2194},"unit",[25,3066,770],{"class":743},[25,3068,2688],{"class":1851},[25,3070,2767],{"class":268},[25,3072,770],{"class":743},[25,3074,2667],{"class":275},[25,3076,2208],{"class":268},[25,3078,3079,3081,3084,3086,3088,3091,3094],{"class":27,"line":1165},[25,3080,1925],{"class":275},[25,3082,3083],{"class":268}," latitude ",[25,3085,1874],{"class":743},[25,3087,2986],{"class":31},[25,3089,3090],{"class":268},"(b.latitude ",[25,3092,3093],{"class":743},"-",[25,3095,3096],{"class":268}," a.latitude)\n",[25,3098,3099,3101,3104,3106,3108,3111,3113],{"class":27,"line":1173},[25,3100,1925],{"class":275},[25,3102,3103],{"class":268}," longitude ",[25,3105,1874],{"class":743},[25,3107,2986],{"class":31},[25,3109,3110],{"class":268},"(b.longitude ",[25,3112,3093],{"class":743},[25,3114,3115],{"class":268}," a.longitude)\n",[25,3117,3118,3120,3123],{"class":27,"line":1186},[25,3119,1925],{"class":275},[25,3121,3122],{"class":268}," h ",[25,3124,3125],{"class":743},"=\n",[25,3127,3128,3131,3134,3137,3139,3142,3144,3147,3149],{"class":27,"line":1199},[25,3129,3130],{"class":268},"    Math.",[25,3132,3133],{"class":31},"sin",[25,3135,3136],{"class":268},"(latitude ",[25,3138,3019],{"class":743},[25,3140,3141],{"class":282}," 2",[25,3143,2007],{"class":268},[25,3145,3146],{"class":743},"**",[25,3148,3141],{"class":282},[25,3150,3151],{"class":743}," +\n",[25,3153,3154,3156,3159,3161,3164,3167,3169,3172,3174,3176,3178,3181,3183,3185,3187,3190,3192,3194,3196,3198],{"class":27,"line":1212},[25,3155,3130],{"class":268},[25,3157,3158],{"class":31},"cos",[25,3160,1939],{"class":268},[25,3162,3163],{"class":31},"toRadians",[25,3165,3166],{"class":268},"(a.latitude)) ",[25,3168,3013],{"class":743},[25,3170,3171],{"class":268}," Math.",[25,3173,3158],{"class":31},[25,3175,1939],{"class":268},[25,3177,3163],{"class":31},[25,3179,3180],{"class":268},"(b.latitude)) ",[25,3182,3013],{"class":743},[25,3184,3171],{"class":268},[25,3186,3133],{"class":31},[25,3188,3189],{"class":268},"(longitude ",[25,3191,3019],{"class":743},[25,3193,3141],{"class":282},[25,3195,2007],{"class":268},[25,3197,3146],{"class":743},[25,3199,3200],{"class":282}," 2\n",[25,3202,3203],{"class":27,"line":1223},[25,3204,1525],{"emptyLinePlaceholder":1524},[25,3206,3207,3209,3211,3214,3216,3218,3221,3224,3226,3228,3231,3234,3237],{"class":27,"line":1229},[25,3208,2967],{"class":743},[25,3210,3171],{"class":268},[25,3212,3213],{"class":31},"round",[25,3215,1939],{"class":268},[25,3217,1942],{"class":282},[25,3219,3220],{"class":743}," *",[25,3222,3223],{"class":268}," EARTH_RADIUS[unit] ",[25,3225,3013],{"class":743},[25,3227,3171],{"class":268},[25,3229,3230],{"class":31},"asin",[25,3232,3233],{"class":268},"(Math.",[25,3235,3236],{"class":31},"sqrt",[25,3238,3239],{"class":268},"(h)))\n",[25,3241,3243],{"class":27,"line":3242},36,[25,3244,382],{"class":268},[25,3246,3248],{"class":27,"line":3247},37,[25,3249,1525],{"emptyLinePlaceholder":1524},[25,3251,3253,3255,3258,3260,3263,3265,3267,3269,3271,3273,3275,3277,3279,3281,3283],{"class":27,"line":3252},38,[25,3254,2983],{"class":275},[25,3256,3257],{"class":31}," describe",[25,3259,1939],{"class":268},[25,3261,3262],{"class":2194},"place",[25,3264,770],{"class":743},[25,3266,2641],{"class":1851},[25,3268,91],{"class":268},[25,3270,1516],{"class":2194},[25,3272,770],{"class":743},[25,3274,2641],{"class":1851},[25,3276,91],{"class":268},[25,3278,3064],{"class":2194},[25,3280,770],{"class":743},[25,3282,2688],{"class":1851},[25,3284,2138],{"class":268},[25,3286,3288,3290,3293,3295,3297],{"class":27,"line":3287},39,[25,3289,1925],{"class":275},[25,3291,3292],{"class":268}," distance ",[25,3294,1874],{"class":743},[25,3296,3042],{"class":31},[25,3298,3299],{"class":268},"(from, place, unit)\n",[25,3301,3303],{"class":27,"line":3302},40,[25,3304,1525],{"emptyLinePlaceholder":1524},[25,3306,3308,3310],{"class":27,"line":3307},41,[25,3309,2967],{"class":743},[25,3311,2208],{"class":268},[25,3313,3315,3318,3321,3323,3326,3328,3330,3332,3335,3337,3339],{"class":27,"line":3314},42,[25,3316,3317],{"class":268},"    city: ",[25,3319,3320],{"class":35},"`",[25,3322,2944],{"class":743},[25,3324,3325],{"class":268},"place.name",[25,3327,2949],{"class":743},[25,3329,91],{"class":35},[25,3331,2944],{"class":743},[25,3333,3334],{"class":268},"place.country",[25,3336,2949],{"class":743},[25,3338,3320],{"class":35},[25,3340,286],{"class":268},[25,3342,3344],{"class":27,"line":3343},43,[25,3345,3346],{"class":268},"    latitude: place.latitude,\n",[25,3348,3350],{"class":27,"line":3349},44,[25,3351,3352],{"class":268},"    longitude: place.longitude,\n",[25,3354,3356],{"class":27,"line":3355},45,[25,3357,3358],{"class":268},"    distance,\n",[25,3360,3362],{"class":27,"line":3361},46,[25,3363,3364],{"class":268},"    unit,\n",[25,3366,3368,3371,3373,3375,3377,3379,3382,3384,3387,3390,3392,3395,3397,3399,3402,3404,3406,3409,3411,3414,3416,3418],{"class":27,"line":3367},47,[25,3369,3370],{"class":268},"    summary: ",[25,3372,3320],{"class":35},[25,3374,2944],{"class":743},[25,3376,3325],{"class":268},[25,3378,2949],{"class":743},[25,3380,3381],{"class":35}," is ",[25,3383,2944],{"class":743},[25,3385,3386],{"class":268},"distance.",[25,3388,3389],{"class":31},"toLocaleString",[25,3391,1939],{"class":268},[25,3393,3394],{"class":35},"'en-US'",[25,3396,2767],{"class":268},[25,3398,2949],{"class":743},[25,3400,3401],{"class":743}," ${",[25,3403,3064],{"class":268},[25,3405,2949],{"class":743},[25,3407,3408],{"class":35}," from ",[25,3410,2944],{"class":743},[25,3412,3413],{"class":268},"from.name",[25,3415,2949],{"class":743},[25,3417,3320],{"class":35},[25,3419,286],{"class":268},[25,3421,3423],{"class":27,"line":3422},48,[25,3424,1226],{"class":268},[25,3426,3428],{"class":27,"line":3427},49,[25,3429,382],{"class":268},[25,3431,3433],{"class":27,"line":3432},50,[25,3434,1525],{"emptyLinePlaceholder":1524},[25,3436,3438,3440,3442,3444,3446,3448,3450,3452,3454,3456,3458,3460,3462,3464,3466,3468,3470,3472],{"class":27,"line":3437},51,[25,3439,1911],{"class":743},[25,3441,1914],{"class":275},[25,3443,2554],{"class":31},[25,3445,1939],{"class":268},[25,3447,2760],{"class":2194},[25,3449,770],{"class":743},[25,3451,2652],{"class":275},[25,3453,91],{"class":268},[25,3455,1516],{"class":2194},[25,3457,770],{"class":743},[25,3459,2652],{"class":275},[25,3461,91],{"class":268},[25,3463,3064],{"class":2194},[25,3465,770],{"class":743},[25,3467,2688],{"class":1851},[25,3469,2644],{"class":743},[25,3471,2693],{"class":35},[25,3473,2138],{"class":268},[25,3475,3477,3479,3482,3484,3486,3488,3490,3493,3496,3499,3502,3504],{"class":27,"line":3476},52,[25,3478,1925],{"class":275},[25,3480,3481],{"class":268}," [place, origin] ",[25,3483,1874],{"class":743},[25,3485,2102],{"class":743},[25,3487,2772],{"class":275},[25,3489,150],{"class":268},[25,3491,3492],{"class":31},"all",[25,3494,3495],{"class":268},"([",[25,3497,3498],{"class":31},"geocode",[25,3500,3501],{"class":268},"(city), ",[25,3503,3498],{"class":31},[25,3505,3506],{"class":268},"(from)])\n",[25,3508,3510],{"class":27,"line":3509},53,[25,3511,1525],{"emptyLinePlaceholder":1524},[25,3513,3515,3517,3520,3522,3525,3527,3529,3532,3534,3536,3538,3541,3543,3545,3547,3549,3552],{"class":27,"line":3514},54,[25,3516,2967],{"class":743},[25,3518,3519],{"class":268}," { ok: ",[25,3521,283],{"class":282},[25,3523,3524],{"class":268},", from: ",[25,3526,3320],{"class":35},[25,3528,2944],{"class":743},[25,3530,3531],{"class":268},"origin.name",[25,3533,2949],{"class":743},[25,3535,91],{"class":35},[25,3537,2944],{"class":743},[25,3539,3540],{"class":268},"origin.country",[25,3542,2949],{"class":743},[25,3544,3320],{"class":35},[25,3546,91],{"class":268},[25,3548,1899],{"class":743},[25,3550,3551],{"class":31},"describe",[25,3553,3554],{"class":268},"(place, origin, unit) }\n",[25,3556,3558],{"class":27,"line":3557},55,[25,3559,382],{"class":268},[25,3561,3563],{"class":27,"line":3562},56,[25,3564,1525],{"emptyLinePlaceholder":1524},[25,3566,3568,3570],{"class":27,"line":3567},57,[25,3569,1530],{"class":743},[25,3571,3572],{"class":268}," { geocode, distanceBetween, fetchDistance }\n",[25,3574,3576],{"class":27,"line":3575},58,[25,3577,1525],{"emptyLinePlaceholder":1524},[25,3579,3581,3583,3586],{"class":27,"line":3580},59,[25,3582,1530],{"class":743},[25,3584,3585],{"class":743}," type",[25,3587,3588],{"class":268}," { Place, Unit }\n",[11,3590,3591,3592,3595,3596,3599,3600,3602,3603,3606,3607,3610],{},"The geocoding API gives us each city's latitude and longitude, and ",[22,3593,3594],{},"distanceBetween"," does the rest. It uses the ",[44,3597,3598],{},"haversine formula",", which takes two points on a sphere and returns the length of the shortest path between them along its surface. The formula works with angles in radians, so ",[22,3601,3163],{}," converts the degrees we get from the API first. Then, multiplying by the radius of the Earth in kilometers or miles gives us the distance in that unit. And since ",[22,3604,3605],{},"fetchDistance"," geocodes both cities with ",[22,3608,3609],{},"Promise.all",", the two requests run in parallel.",[159,3612,3613],{},[11,3614,3615],{},"Why not just subtract the coordinates?",[11,3617,3618],{},"Because a degree of longitude doesn't have a fixed length. At the equator it's about 111 km, and it shrinks to zero at the poles, where every meridian meets. The haversine formula accounts for that. It does treat the Earth as a perfect sphere, which it isn't, so the result can be off by up to about 0.5%. For \"how far is Tokyo?\", that's close enough.",[11,3620,3621,3622,3625],{},"Nothing in this file knows it's part of a CLI. It takes strings, returns objects, and throws a plain ",[22,3623,3624],{},"Error"," when something goes wrong. That's what makes it easy to test later, and it's why the \"thin commands, thick libraries\" rule matters.",[11,3627,3628],{},"Alright, it's time to try it. Let's build and run:",[15,3630,3632],{"className":17,"code":3631,"language":19,"meta":20,"style":20},"npm run build\nnode dist/howfar.mjs Tokyo --from \"Buenos Aires\"\n",[22,3633,3634,3643],{"__ignoreMap":20},[25,3635,3636,3638,3640],{"class":27,"line":28},[25,3637,50],{"class":31},[25,3639,1917],{"class":35},[25,3641,3642],{"class":35}," build\n",[25,3644,3645,3647,3650,3653,3656],{"class":27,"line":272},[25,3646,2269],{"class":31},[25,3648,3649],{"class":35}," dist/howfar.mjs",[25,3651,3652],{"class":35}," Tokyo",[25,3654,3655],{"class":282}," --from",[25,3657,3658],{"class":35}," \"Buenos Aires\"\n",[15,3660,3661],{"className":259,"code":260,"language":261,"meta":20,"style":20},[22,3662,3663,3667,3677,3687,3697,3707,3717,3727,3737,3745],{"__ignoreMap":20},[25,3664,3665],{"class":27,"line":28},[25,3666,269],{"class":268},[25,3668,3669,3671,3673,3675],{"class":27,"line":272},[25,3670,276],{"class":275},[25,3672,279],{"class":268},[25,3674,283],{"class":282},[25,3676,286],{"class":268},[25,3678,3679,3681,3683,3685],{"class":27,"line":289},[25,3680,292],{"class":275},[25,3682,279],{"class":268},[25,3684,298],{"class":297},[25,3686,286],{"class":268},[25,3688,3689,3691,3693,3695],{"class":27,"line":303},[25,3690,306],{"class":275},[25,3692,279],{"class":268},[25,3694,311],{"class":297},[25,3696,286],{"class":268},[25,3698,3699,3701,3703,3705],{"class":27,"line":316},[25,3700,319],{"class":275},[25,3702,279],{"class":268},[25,3704,324],{"class":282},[25,3706,286],{"class":268},[25,3708,3709,3711,3713,3715],{"class":27,"line":329},[25,3710,332],{"class":275},[25,3712,279],{"class":268},[25,3714,337],{"class":282},[25,3716,286],{"class":268},[25,3718,3719,3721,3723,3725],{"class":27,"line":342},[25,3720,345],{"class":275},[25,3722,279],{"class":268},[25,3724,350],{"class":282},[25,3726,286],{"class":268},[25,3728,3729,3731,3733,3735],{"class":27,"line":355},[25,3730,358],{"class":275},[25,3732,279],{"class":268},[25,3734,363],{"class":297},[25,3736,286],{"class":268},[25,3738,3739,3741,3743],{"class":27,"line":368},[25,3740,371],{"class":275},[25,3742,279],{"class":268},[25,3744,376],{"class":297},[25,3746,3747],{"class":27,"line":379},[25,3748,382],{"class":268},[11,3750,3751],{},"We also get the help screen for free:",[15,3753,3755],{"className":17,"code":3754,"language":19,"meta":20,"style":20},"node dist/howfar.mjs --help\n",[22,3756,3757],{"__ignoreMap":20},[25,3758,3759,3761,3763],{"class":27,"line":28},[25,3760,2269],{"class":31},[25,3762,3649],{"class":35},[25,3764,3765],{"class":282}," --help\n",[15,3767,3770],{"className":3768,"code":3769,"language":230,"meta":20},[228],"Distance between two cities, as JSON (howfar)\n\nUSAGE howfar [OPTIONS] \u003CCITY> --from=\u003Cfrom>\n\nARGUMENTS\n\n  CITY    City to measure the distance to (Required)\n\nOPTIONS\n\n  --from=\u003Cfrom>    City to measure the distance from (Required)\n",[22,3771,3769],{"__ignoreMap":20},[11,3773,3774,3775,3777],{},"Every command we add from here follows the same shape: one file, one ",[22,3776,2372],{},", one returned result.",[72,3779,3781],{"id":3780},"a-config-file-and-an-init-wizard","A Config File and an Init Wizard",[11,3783,3784,3785,3788,3789,3791,3792,3794],{},"Typing ",[22,3786,3787],{},"--from \"Buenos Aires\""," on every run gets old fast. Real tools remember your settings, so we'll store your city and preferred unit in a config file. After that, ",[22,3790,609],{}," becomes optional, and every lookup measures from home unless you say otherwise. Then, we'll add the ",[22,3793,669],{}," command that asks for them.",[11,3796,3797],{},"Let's start with the config module. rc9 handles the file, and zod handles the shape:",[15,3799,3802],{"className":1500,"code":3800,"filename":3801,"language":1503,"meta":20,"style":20},"import { z } from 'zod'\nimport { readUserConfig, writeUserConfig } from 'rc9'\n\n// Lives at ~/.config/howfar.conf so the tool works from any directory.\nconst RC_NAME = 'howfar.conf'\n\nconst configSchema = z.object({\n  home: z.string(),\n  unit: z.enum(['km', 'mi']).default('km'),\n})\n\ntype Config = z.infer\u003Ctypeof configSchema>\n\nfunction loadConfig(): Config | null {\n  const raw = readUserConfig(RC_NAME)\n\n  if (!raw.home) {\n    return null\n  }\n\n  const result = configSchema.safeParse(raw)\n\n  if (!result.success) {\n    throw new Error(`Configuration validation failed:\\n${z.prettifyError(result.error)}`)\n  }\n\n  return result.data\n}\n\nfunction resolveConfig(from?: string) {\n  const config = loadConfig()\n  const origin = from ?? config?.home\n\n  if (!origin) {\n    throw new Error('No starting city. Run \"npx @username/howfar init\" or pass --from.')\n  }\n\n  return { from: origin, unit: config?.unit ?? 'km' }\n}\n\nfunction saveConfig(config: Config) {\n  writeUserConfig(config, RC_NAME)\n}\n\nexport { loadConfig, resolveConfig, saveConfig }\n\nexport type { Config }\n","lib/config.ts",[22,3803,3804,3816,3828,3832,3837,3849,3853,3870,3880,3911,3915,3919,3944,3948,3969,3984,3988,3999,4006,4010,4014,4032,4036,4047,4080,4084,4088,4095,4099,4103,4120,4134,4150,4154,4165,4180,4184,4188,4201,4205,4209,4227,4235,4239,4243,4250,4254],{"__ignoreMap":20},[25,3805,3806,3808,3811,3813],{"class":27,"line":28},[25,3807,1510],{"class":743},[25,3809,3810],{"class":268}," { z } ",[25,3812,1516],{"class":743},[25,3814,3815],{"class":35}," 'zod'\n",[25,3817,3818,3820,3823,3825],{"class":27,"line":272},[25,3819,1510],{"class":743},[25,3821,3822],{"class":268}," { readUserConfig, writeUserConfig } ",[25,3824,1516],{"class":743},[25,3826,3827],{"class":35}," 'rc9'\n",[25,3829,3830],{"class":27,"line":289},[25,3831,1525],{"emptyLinePlaceholder":1524},[25,3833,3834],{"class":27,"line":303},[25,3835,3836],{"class":1799},"// Lives at ~/.config/howfar.conf so the tool works from any directory.\n",[25,3838,3839,3841,3844,3846],{"class":27,"line":316},[25,3840,1843],{"class":275},[25,3842,3843],{"class":268}," RC_NAME ",[25,3845,1874],{"class":743},[25,3847,3848],{"class":35}," 'howfar.conf'\n",[25,3850,3851],{"class":27,"line":329},[25,3852,1525],{"emptyLinePlaceholder":1524},[25,3854,3855,3857,3860,3862,3865,3868],{"class":27,"line":342},[25,3856,1843],{"class":275},[25,3858,3859],{"class":268}," configSchema ",[25,3861,1874],{"class":743},[25,3863,3864],{"class":268}," z.",[25,3866,3867],{"class":31},"object",[25,3869,1539],{"class":268},[25,3871,3872,3875,3877],{"class":27,"line":355},[25,3873,3874],{"class":268},"  home: z.",[25,3876,1858],{"class":31},[25,3878,3879],{"class":268},"(),\n",[25,3881,3882,3885,3888,3890,3893,3895,3898,3901,3904,3906,3908],{"class":27,"line":368},[25,3883,3884],{"class":268},"  unit: z.",[25,3886,3887],{"class":31},"enum",[25,3889,3495],{"class":268},[25,3891,3892],{"class":35},"'km'",[25,3894,91],{"class":268},[25,3896,3897],{"class":35},"'mi'",[25,3899,3900],{"class":268},"]).",[25,3902,3903],{"class":31},"default",[25,3905,1939],{"class":268},[25,3907,3892],{"class":35},[25,3909,3910],{"class":268},"),\n",[25,3912,3913],{"class":27,"line":379},[25,3914,1703],{"class":268},[25,3916,3917],{"class":27,"line":499},[25,3918,1525],{"emptyLinePlaceholder":1524},[25,3920,3921,3923,3926,3928,3931,3933,3936,3938,3941],{"class":27,"line":509},[25,3922,1814],{"class":275},[25,3924,3925],{"class":1851}," Config",[25,3927,2644],{"class":743},[25,3929,3930],{"class":1851}," z",[25,3932,150],{"class":268},[25,3934,3935],{"class":1851},"infer",[25,3937,1855],{"class":268},[25,3939,3940],{"class":743},"typeof",[25,3942,3943],{"class":268}," configSchema>\n",[25,3945,3946],{"class":27,"line":515},[25,3947,1525],{"emptyLinePlaceholder":1524},[25,3949,3950,3952,3955,3958,3960,3962,3964,3967],{"class":27,"line":520},[25,3951,2983],{"class":275},[25,3953,3954],{"class":31}," loadConfig",[25,3956,3957],{"class":268},"()",[25,3959,770],{"class":743},[25,3961,3925],{"class":1851},[25,3963,744],{"class":743},[25,3965,3966],{"class":275}," null",[25,3968,2208],{"class":268},[25,3970,3971,3973,3976,3978,3981],{"class":27,"line":532},[25,3972,1925],{"class":275},[25,3974,3975],{"class":268}," raw ",[25,3977,1874],{"class":743},[25,3979,3980],{"class":31}," readUserConfig",[25,3982,3983],{"class":268},"(RC_NAME)\n",[25,3985,3986],{"class":27,"line":544},[25,3987,1525],{"emptyLinePlaceholder":1524},[25,3989,3990,3992,3994,3996],{"class":27,"line":556},[25,3991,2030],{"class":743},[25,3993,2869],{"class":268},[25,3995,2924],{"class":743},[25,3997,3998],{"class":268},"raw.home) {\n",[25,4000,4001,4003],{"class":27,"line":568},[25,4002,2551],{"class":743},[25,4004,4005],{"class":282}," null\n",[25,4007,4008],{"class":27,"line":579},[25,4009,1226],{"class":268},[25,4011,4012],{"class":27,"line":589},[25,4013,1525],{"emptyLinePlaceholder":1524},[25,4015,4016,4018,4021,4023,4026,4029],{"class":27,"line":595},[25,4017,1925],{"class":275},[25,4019,4020],{"class":268}," result ",[25,4022,1874],{"class":743},[25,4024,4025],{"class":268}," configSchema.",[25,4027,4028],{"class":31},"safeParse",[25,4030,4031],{"class":268},"(raw)\n",[25,4033,4034],{"class":27,"line":601},[25,4035,1525],{"emptyLinePlaceholder":1524},[25,4037,4038,4040,4042,4044],{"class":27,"line":1102},[25,4039,2030],{"class":743},[25,4041,2869],{"class":268},[25,4043,2924],{"class":743},[25,4045,4046],{"class":268},"result.success) {\n",[25,4048,4049,4051,4053,4055,4057,4060,4063,4065,4068,4071,4074,4076,4078],{"class":27,"line":1110},[25,4050,2932],{"class":743},[25,4052,2792],{"class":743},[25,4054,2224],{"class":31},[25,4056,1939],{"class":268},[25,4058,4059],{"class":35},"`Configuration validation failed:",[25,4061,4062],{"class":282},"\\n",[25,4064,2944],{"class":743},[25,4066,4067],{"class":268},"z.",[25,4069,4070],{"class":31},"prettifyError",[25,4072,4073],{"class":268},"(result.error)",[25,4075,2949],{"class":743},[25,4077,3320],{"class":35},[25,4079,1945],{"class":268},[25,4081,4082],{"class":27,"line":1123},[25,4083,1226],{"class":268},[25,4085,4086],{"class":27,"line":1136},[25,4087,1525],{"emptyLinePlaceholder":1524},[25,4089,4090,4092],{"class":27,"line":1149},[25,4091,2967],{"class":743},[25,4093,4094],{"class":268}," result.data\n",[25,4096,4097],{"class":27,"line":1160},[25,4098,382],{"class":268},[25,4100,4101],{"class":27,"line":1165},[25,4102,1525],{"emptyLinePlaceholder":1524},[25,4104,4105,4107,4110,4112,4114,4116,4118],{"class":27,"line":1173},[25,4106,2983],{"class":275},[25,4108,4109],{"class":31}," resolveConfig",[25,4111,1939],{"class":268},[25,4113,1516],{"class":2194},[25,4115,2889],{"class":743},[25,4117,2652],{"class":275},[25,4119,2138],{"class":268},[25,4121,4122,4124,4127,4129,4131],{"class":27,"line":1186},[25,4123,1925],{"class":275},[25,4125,4126],{"class":268}," config ",[25,4128,1874],{"class":743},[25,4130,3954],{"class":31},[25,4132,4133],{"class":268},"()\n",[25,4135,4136,4138,4141,4143,4145,4147],{"class":27,"line":1199},[25,4137,1925],{"class":275},[25,4139,4140],{"class":268}," origin ",[25,4142,1874],{"class":743},[25,4144,3408],{"class":268},[25,4146,2087],{"class":743},[25,4148,4149],{"class":268}," config?.home\n",[25,4151,4152],{"class":27,"line":1212},[25,4153,1525],{"emptyLinePlaceholder":1524},[25,4155,4156,4158,4160,4162],{"class":27,"line":1223},[25,4157,2030],{"class":743},[25,4159,2869],{"class":268},[25,4161,2924],{"class":743},[25,4163,4164],{"class":268},"origin) {\n",[25,4166,4167,4169,4171,4173,4175,4178],{"class":27,"line":1229},[25,4168,2932],{"class":743},[25,4170,2792],{"class":743},[25,4172,2224],{"class":31},[25,4174,1939],{"class":268},[25,4176,4177],{"class":35},"'No starting city. Run \"npx @username/howfar init\" or pass --from.'",[25,4179,1945],{"class":268},[25,4181,4182],{"class":27,"line":3242},[25,4183,1226],{"class":268},[25,4185,4186],{"class":27,"line":3247},[25,4187,1525],{"emptyLinePlaceholder":1524},[25,4189,4190,4192,4195,4197,4199],{"class":27,"line":3252},[25,4191,2967],{"class":743},[25,4193,4194],{"class":268}," { from: origin, unit: config?.unit ",[25,4196,2087],{"class":743},[25,4198,2693],{"class":35},[25,4200,2677],{"class":268},[25,4202,4203],{"class":27,"line":3287},[25,4204,382],{"class":268},[25,4206,4207],{"class":27,"line":3302},[25,4208,1525],{"emptyLinePlaceholder":1524},[25,4210,4211,4213,4216,4218,4221,4223,4225],{"class":27,"line":3307},[25,4212,2983],{"class":275},[25,4214,4215],{"class":31}," saveConfig",[25,4217,1939],{"class":268},[25,4219,4220],{"class":2194},"config",[25,4222,770],{"class":743},[25,4224,3925],{"class":1851},[25,4226,2138],{"class":268},[25,4228,4229,4232],{"class":27,"line":3314},[25,4230,4231],{"class":31},"  writeUserConfig",[25,4233,4234],{"class":268},"(config, RC_NAME)\n",[25,4236,4237],{"class":27,"line":3343},[25,4238,382],{"class":268},[25,4240,4241],{"class":27,"line":3349},[25,4242,1525],{"emptyLinePlaceholder":1524},[25,4244,4245,4247],{"class":27,"line":3355},[25,4246,1530],{"class":743},[25,4248,4249],{"class":268}," { loadConfig, resolveConfig, saveConfig }\n",[25,4251,4252],{"class":27,"line":3361},[25,4253,1525],{"emptyLinePlaceholder":1524},[25,4255,4256,4258,4260],{"class":27,"line":3367},[25,4257,1530],{"class":743},[25,4259,3585],{"class":743},[25,4261,4262],{"class":268}," { Config }\n",[11,4264,4265],{},"Here's what's happening:",[636,4267,4268,4286,4300,4312],{},[639,4269,4270,4273,4274,4277,4278,4281,4282,4285],{},[22,4271,4272],{},"readUserConfig"," looks for ",[22,4275,4276],{},"howfar.conf"," in ",[22,4279,4280],{},"~/.config"," (or wherever ",[22,4283,4284],{},"$XDG_CONFIG_HOME"," points). We never build that path ourselves, so it's correct on macOS, Linux, and Windows.",[639,4287,4288,4289,4291,4292,4295,4296,4299],{},"The file on disk is just text. zod's ",[22,4290,4028],{}," is where we turn it into a ",[22,4293,4294],{},"Config"," we can trust. If someone edits the file by hand and types ",[22,4297,4298],{},"unit=miles",", the tool stops right there, with an error that names the field and the values it accepts.",[639,4301,4302,4305,4306,4308,4309,4311],{},[22,4303,4304],{},"loadConfig"," returns ",[22,4307,2158],{}," when nothing is configured. The ",[22,4310,669],{}," wizard uses it to prefill the prompts with existing values when you run it again.",[639,4313,4314,4317,4318,4320],{},[22,4315,4316],{},"resolveConfig"," is what commands use. When you pass ",[22,4319,609],{},", that city wins. Without it, the tool measures from your home city. With neither, it throws a helpful error instead of guessing.",[11,4322,4323,4324,770],{},"Here's the error for that hand-edited ",[22,4325,4298],{},[15,4327,4330],{"className":4328,"code":4329,"language":230,"meta":20},[228],"Configuration validation failed:\n✖ Invalid option: expected one of \"km\"|\"mi\"\n  → at unit\n",[22,4331,4329],{"__ignoreMap":20},[11,4333,4334],{},"With the config in place, we can build the wizard:",[15,4336,4339],{"className":1500,"code":4337,"filename":4338,"language":1503,"meta":20,"style":20},"import { defineCommand } from 'citty'\nimport { intro, outro, text, select, isCancel, cancel, log } from '@clack/prompts'\nimport { loadConfig, saveConfig } from '../lib/config.js'\n\nfunction required(value: string | undefined) {\n  return value ? undefined : 'Required'\n}\n\nasync function runInit() {\n  intro('howfar setup')\n\n  const existing = loadConfig()\n\n  const home = await text({\n    message: 'Your city',\n    placeholder: 'Buenos Aires',\n    initialValue: existing?.home ?? '',\n    validate: required,\n  })\n  if (isCancel(home)) {\n    return cancel('Setup cancelled')\n  }\n\n  const unit = await select({\n    message: 'Distance unit',\n    options: [\n      { value: 'km', label: 'Kilometers' },\n      { value: 'mi', label: 'Miles' },\n    ],\n    initialValue: existing?.unit ?? 'km',\n  })\n  if (isCancel(unit)) {\n    return cancel('Setup cancelled')\n  }\n\n  saveConfig({ home, unit })\n\n  log.success('Saved config to ~/.config/howfar.conf')\n  outro('Done. Try: npx @username/howfar Tokyo')\n}\n\nconst init = defineCommand({\n  meta: { name: 'init', description: 'Setup wizard for your city' },\n  run: () => runInit(),\n})\n\nexport { init }\n","commands/init.ts",[22,4340,4341,4351,4363,4375,4379,4401,4418,4422,4426,4437,4449,4453,4466,4470,4486,4496,4506,4518,4523,4528,4540,4554,4558,4562,4578,4587,4592,4607,4620,4625,4636,4640,4651,4663,4667,4671,4679,4683,4698,4710,4714,4718,4731,4745,4758,4762,4766],{"__ignoreMap":20},[25,4342,4343,4345,4347,4349],{"class":27,"line":28},[25,4344,1510],{"class":743},[25,4346,2392],{"class":268},[25,4348,1516],{"class":743},[25,4350,1822],{"class":35},[25,4352,4353,4355,4358,4360],{"class":27,"line":272},[25,4354,1510],{"class":743},[25,4356,4357],{"class":268}," { intro, outro, text, select, isCancel, cancel, log } ",[25,4359,1516],{"class":743},[25,4361,4362],{"class":35}," '@clack/prompts'\n",[25,4364,4365,4367,4370,4372],{"class":27,"line":289},[25,4366,1510],{"class":743},[25,4368,4369],{"class":268}," { loadConfig, saveConfig } ",[25,4371,1516],{"class":743},[25,4373,4374],{"class":35}," '../lib/config.js'\n",[25,4376,4377],{"class":27,"line":303},[25,4378,1525],{"emptyLinePlaceholder":1524},[25,4380,4381,4383,4386,4388,4391,4393,4395,4397,4399],{"class":27,"line":316},[25,4382,2983],{"class":275},[25,4384,4385],{"class":31}," required",[25,4387,1939],{"class":268},[25,4389,4390],{"class":2194},"value",[25,4392,770],{"class":743},[25,4394,2652],{"class":275},[25,4396,744],{"class":743},[25,4398,2135],{"class":275},[25,4400,2138],{"class":268},[25,4402,4403,4405,4408,4410,4412,4415],{"class":27,"line":329},[25,4404,2967],{"class":743},[25,4406,4407],{"class":268}," value ",[25,4409,862],{"class":743},[25,4411,2135],{"class":282},[25,4413,4414],{"class":743}," :",[25,4416,4417],{"class":35}," 'Required'\n",[25,4419,4420],{"class":27,"line":342},[25,4421,382],{"class":268},[25,4423,4424],{"class":27,"line":355},[25,4425,1525],{"emptyLinePlaceholder":1524},[25,4427,4428,4430,4432,4435],{"class":27,"line":368},[25,4429,1911],{"class":743},[25,4431,1914],{"class":275},[25,4433,4434],{"class":31}," runInit",[25,4436,1920],{"class":268},[25,4438,4439,4442,4444,4447],{"class":27,"line":379},[25,4440,4441],{"class":31},"  intro",[25,4443,1939],{"class":268},[25,4445,4446],{"class":35},"'howfar setup'",[25,4448,1945],{"class":268},[25,4450,4451],{"class":27,"line":499},[25,4452,1525],{"emptyLinePlaceholder":1524},[25,4454,4455,4457,4460,4462,4464],{"class":27,"line":509},[25,4456,1925],{"class":275},[25,4458,4459],{"class":268}," existing ",[25,4461,1874],{"class":743},[25,4463,3954],{"class":31},[25,4465,4133],{"class":268},[25,4467,4468],{"class":27,"line":515},[25,4469,1525],{"emptyLinePlaceholder":1524},[25,4471,4472,4474,4477,4479,4481,4484],{"class":27,"line":520},[25,4473,1925],{"class":275},[25,4475,4476],{"class":268}," home ",[25,4478,1874],{"class":743},[25,4480,2102],{"class":743},[25,4482,4483],{"class":31}," text",[25,4485,1539],{"class":268},[25,4487,4488,4491,4494],{"class":27,"line":532},[25,4489,4490],{"class":268},"    message: ",[25,4492,4493],{"class":35},"'Your city'",[25,4495,286],{"class":268},[25,4497,4498,4501,4504],{"class":27,"line":544},[25,4499,4500],{"class":268},"    placeholder: ",[25,4502,4503],{"class":35},"'Buenos Aires'",[25,4505,286],{"class":268},[25,4507,4508,4511,4513,4516],{"class":27,"line":556},[25,4509,4510],{"class":268},"    initialValue: existing?.home ",[25,4512,2087],{"class":743},[25,4514,4515],{"class":35}," ''",[25,4517,286],{"class":268},[25,4519,4520],{"class":27,"line":568},[25,4521,4522],{"class":268},"    validate: required,\n",[25,4524,4525],{"class":27,"line":579},[25,4526,4527],{"class":268},"  })\n",[25,4529,4530,4532,4534,4537],{"class":27,"line":589},[25,4531,2030],{"class":743},[25,4533,2869],{"class":268},[25,4535,4536],{"class":31},"isCancel",[25,4538,4539],{"class":268},"(home)) {\n",[25,4541,4542,4544,4547,4549,4552],{"class":27,"line":595},[25,4543,2551],{"class":743},[25,4545,4546],{"class":31}," cancel",[25,4548,1939],{"class":268},[25,4550,4551],{"class":35},"'Setup cancelled'",[25,4553,1945],{"class":268},[25,4555,4556],{"class":27,"line":601},[25,4557,1226],{"class":268},[25,4559,4560],{"class":27,"line":1102},[25,4561,1525],{"emptyLinePlaceholder":1524},[25,4563,4564,4566,4569,4571,4573,4576],{"class":27,"line":1110},[25,4565,1925],{"class":275},[25,4567,4568],{"class":268}," unit ",[25,4570,1874],{"class":743},[25,4572,2102],{"class":743},[25,4574,4575],{"class":31}," select",[25,4577,1539],{"class":268},[25,4579,4580,4582,4585],{"class":27,"line":1123},[25,4581,4490],{"class":268},[25,4583,4584],{"class":35},"'Distance unit'",[25,4586,286],{"class":268},[25,4588,4589],{"class":27,"line":1136},[25,4590,4591],{"class":268},"    options: [\n",[25,4593,4594,4597,4599,4602,4605],{"class":27,"line":1149},[25,4595,4596],{"class":268},"      { value: ",[25,4598,3892],{"class":35},[25,4600,4601],{"class":268},", label: ",[25,4603,4604],{"class":35},"'Kilometers'",[25,4606,2442],{"class":268},[25,4608,4609,4611,4613,4615,4618],{"class":27,"line":1160},[25,4610,4596],{"class":268},[25,4612,3897],{"class":35},[25,4614,4601],{"class":268},[25,4616,4617],{"class":35},"'Miles'",[25,4619,2442],{"class":268},[25,4621,4622],{"class":27,"line":1165},[25,4623,4624],{"class":268},"    ],\n",[25,4626,4627,4630,4632,4634],{"class":27,"line":1173},[25,4628,4629],{"class":268},"    initialValue: existing?.unit ",[25,4631,2087],{"class":743},[25,4633,2693],{"class":35},[25,4635,286],{"class":268},[25,4637,4638],{"class":27,"line":1186},[25,4639,4527],{"class":268},[25,4641,4642,4644,4646,4648],{"class":27,"line":1199},[25,4643,2030],{"class":743},[25,4645,2869],{"class":268},[25,4647,4536],{"class":31},[25,4649,4650],{"class":268},"(unit)) {\n",[25,4652,4653,4655,4657,4659,4661],{"class":27,"line":1212},[25,4654,2551],{"class":743},[25,4656,4546],{"class":31},[25,4658,1939],{"class":268},[25,4660,4551],{"class":35},[25,4662,1945],{"class":268},[25,4664,4665],{"class":27,"line":1223},[25,4666,1226],{"class":268},[25,4668,4669],{"class":27,"line":1229},[25,4670,1525],{"emptyLinePlaceholder":1524},[25,4672,4673,4676],{"class":27,"line":3242},[25,4674,4675],{"class":31},"  saveConfig",[25,4677,4678],{"class":268},"({ home, unit })\n",[25,4680,4681],{"class":27,"line":3247},[25,4682,1525],{"emptyLinePlaceholder":1524},[25,4684,4685,4688,4691,4693,4696],{"class":27,"line":3252},[25,4686,4687],{"class":268},"  log.",[25,4689,4690],{"class":31},"success",[25,4692,1939],{"class":268},[25,4694,4695],{"class":35},"'Saved config to ~/.config/howfar.conf'",[25,4697,1945],{"class":268},[25,4699,4700,4703,4705,4708],{"class":27,"line":3287},[25,4701,4702],{"class":31},"  outro",[25,4704,1939],{"class":268},[25,4706,4707],{"class":35},"'Done. Try: npx @username/howfar Tokyo'",[25,4709,1945],{"class":268},[25,4711,4712],{"class":27,"line":3302},[25,4713,382],{"class":268},[25,4715,4716],{"class":27,"line":3307},[25,4717,1525],{"emptyLinePlaceholder":1524},[25,4719,4720,4722,4725,4727,4729],{"class":27,"line":3314},[25,4721,1843],{"class":275},[25,4723,4724],{"class":268}," init ",[25,4726,1874],{"class":743},[25,4728,1893],{"class":31},[25,4730,1539],{"class":268},[25,4732,4733,4735,4738,4740,4743],{"class":27,"line":3343},[25,4734,2430],{"class":268},[25,4736,4737],{"class":35},"'init'",[25,4739,2436],{"class":268},[25,4741,4742],{"class":35},"'Setup wizard for your city'",[25,4744,2442],{"class":268},[25,4746,4747,4749,4752,4754,4756],{"class":27,"line":3349},[25,4748,2529],{"class":31},[25,4750,4751],{"class":268},": () ",[25,4753,2205],{"class":275},[25,4755,4434],{"class":31},[25,4757,3879],{"class":268},[25,4759,4760],{"class":27,"line":3355},[25,4761,1703],{"class":268},[25,4763,4764],{"class":27,"line":3361},[25,4765,1525],{"emptyLinePlaceholder":1524},[25,4767,4768,4770],{"class":27,"line":3367},[25,4769,1530],{"class":743},[25,4771,4772],{"class":268}," { init }\n",[11,4774,4775,4776,4778,4779,4781,4782,4785],{},"There are two details worth pointing out here. First, every prompt is followed by an ",[22,4777,4536],{}," check, because the user can press Ctrl+C at any point and clack returns a cancel symbol instead of a value. Without that check, you'd save a cancel symbol as someone's city. Second, ",[22,4780,669],{}," returns nothing, so the entry point prints nothing. The wizard draws its own UI, so a JSON blob after the ",[22,4783,4784],{},"outro"," line would look broken.",[11,4787,4788,4789,4791,4792,4794,4795,4797],{},"Next, let's update ",[22,4790,2286],{}," to use the config. ",[22,4793,609],{}," is no longer required, and ",[22,4796,4316],{}," decides where to measure from:",[15,4799,4801],{"className":1500,"code":4800,"filename":2383,"language":1503,"meta":20,"style":20},"import { defineCommand } from 'citty'\nimport { resolveConfig } from '../lib/config.js'\nimport { fetchDistance } from '../lib/distance.js'\n\nconst lookup = defineCommand({\n  meta: { name: 'howfar', description: 'Distance from your city to another, as JSON' },\n  args: {\n    city: {\n      type: 'positional',\n      required: true,\n      description: 'City to measure the distance to',\n    },\n    from: {\n      type: 'string',\n      required: false,\n      description: 'City to measure the distance from (defaults to yours)',\n    },\n  },\n  run: async ({ args }) => {\n    const { from, unit } = resolveConfig(args.from)\n\n    return fetchDistance(args.city, from, unit)\n  },\n})\n\nexport { lookup }\n",[22,4802,4803,4813,4824,4834,4838,4850,4863,4867,4871,4879,4887,4895,4899,4903,4911,4919,4928,4932,4936,4954,4969,4973,4982,4986,4990,4994],{"__ignoreMap":20},[25,4804,4805,4807,4809,4811],{"class":27,"line":28},[25,4806,1510],{"class":743},[25,4808,2392],{"class":268},[25,4810,1516],{"class":743},[25,4812,1822],{"class":35},[25,4814,4815,4817,4820,4822],{"class":27,"line":272},[25,4816,1510],{"class":743},[25,4818,4819],{"class":268}," { resolveConfig } ",[25,4821,1516],{"class":743},[25,4823,4374],{"class":35},[25,4825,4826,4828,4830,4832],{"class":27,"line":289},[25,4827,1510],{"class":743},[25,4829,2403],{"class":268},[25,4831,1516],{"class":743},[25,4833,2408],{"class":35},[25,4835,4836],{"class":27,"line":303},[25,4837,1525],{"emptyLinePlaceholder":1524},[25,4839,4840,4842,4844,4846,4848],{"class":27,"line":316},[25,4841,1843],{"class":275},[25,4843,2419],{"class":268},[25,4845,1874],{"class":743},[25,4847,1893],{"class":31},[25,4849,1539],{"class":268},[25,4851,4852,4854,4856,4858,4861],{"class":27,"line":329},[25,4853,2430],{"class":268},[25,4855,2433],{"class":35},[25,4857,2436],{"class":268},[25,4859,4860],{"class":35},"'Distance from your city to another, as JSON'",[25,4862,2442],{"class":268},[25,4864,4865],{"class":27,"line":342},[25,4866,2447],{"class":268},[25,4868,4869],{"class":27,"line":355},[25,4870,2452],{"class":268},[25,4872,4873,4875,4877],{"class":27,"line":368},[25,4874,2457],{"class":268},[25,4876,2460],{"class":35},[25,4878,286],{"class":268},[25,4880,4881,4883,4885],{"class":27,"line":379},[25,4882,2467],{"class":268},[25,4884,283],{"class":282},[25,4886,286],{"class":268},[25,4888,4889,4891,4893],{"class":27,"line":499},[25,4890,2476],{"class":268},[25,4892,2479],{"class":35},[25,4894,286],{"class":268},[25,4896,4897],{"class":27,"line":509},[25,4898,512],{"class":268},[25,4900,4901],{"class":27,"line":515},[25,4902,2490],{"class":268},[25,4904,4905,4907,4909],{"class":27,"line":520},[25,4906,2457],{"class":268},[25,4908,2497],{"class":35},[25,4910,286],{"class":268},[25,4912,4913,4915,4917],{"class":27,"line":532},[25,4914,2467],{"class":268},[25,4916,1552],{"class":282},[25,4918,286],{"class":268},[25,4920,4921,4923,4926],{"class":27,"line":544},[25,4922,2476],{"class":268},[25,4924,4925],{"class":35},"'City to measure the distance from (defaults to yours)'",[25,4927,286],{"class":268},[25,4929,4930],{"class":27,"line":556},[25,4931,512],{"class":268},[25,4933,4934],{"class":27,"line":568},[25,4935,971],{"class":268},[25,4937,4938,4940,4942,4944,4946,4948,4950,4952],{"class":27,"line":579},[25,4939,2529],{"class":31},[25,4941,279],{"class":268},[25,4943,1911],{"class":743},[25,4945,2536],{"class":268},[25,4947,2539],{"class":2194},[25,4949,2542],{"class":268},[25,4951,2205],{"class":275},[25,4953,2208],{"class":268},[25,4955,4956,4959,4962,4964,4966],{"class":27,"line":589},[25,4957,4958],{"class":275},"    const",[25,4960,4961],{"class":268}," { from, unit } ",[25,4963,1874],{"class":743},[25,4965,4109],{"class":31},[25,4967,4968],{"class":268},"(args.from)\n",[25,4970,4971],{"class":27,"line":595},[25,4972,1525],{"emptyLinePlaceholder":1524},[25,4974,4975,4977,4979],{"class":27,"line":601},[25,4976,2551],{"class":743},[25,4978,2554],{"class":31},[25,4980,4981],{"class":268},"(args.city, from, unit)\n",[25,4983,4984],{"class":27,"line":1102},[25,4985,971],{"class":268},[25,4987,4988],{"class":27,"line":1110},[25,4989,1703],{"class":268},[25,4991,4992],{"class":27,"line":1123},[25,4993,1525],{"emptyLinePlaceholder":1524},[25,4995,4996,4998],{"class":27,"line":1136},[25,4997,1530],{"class":743},[25,4999,2576],{"class":268},[11,5001,5002,5003,5005,5006,5008,5009],{},"Notice that ",[22,5004,2632],{}," didn't change at all. ",[22,5007,3605],{}," already took a starting city and a unit, so the config only had to decide which values to pass. ",[44,5010,5011],{},"That's the payoff of thin commands.",[11,5013,5014,5015,5017],{},"Then, let's register ",[22,5016,669],{}," in the entry point:",[15,5019,5021],{"className":1500,"code":5020,"filename":1713,"language":1503,"meta":20,"style":20},"import { init } from '../commands/init.js'\nimport { lookup } from '../commands/lookup.js'\n\nconst subCommands: Record\u003Cstring, CommandDef\u003Cany>> = {\n  init,\n}\n",[22,5022,5023,5035,5045,5049,5077,5082],{"__ignoreMap":20},[25,5024,5025,5027,5030,5032],{"class":27,"line":28},[25,5026,1510],{"class":743},[25,5028,5029],{"class":268}," { init } ",[25,5031,1516],{"class":743},[25,5033,5034],{"class":35}," '../commands/init.js'\n",[25,5036,5037,5039,5041,5043],{"class":27,"line":272},[25,5038,1510],{"class":743},[25,5040,1829],{"class":268},[25,5042,1516],{"class":743},[25,5044,1834],{"class":35},[25,5046,5047],{"class":27,"line":289},[25,5048,1525],{"emptyLinePlaceholder":1524},[25,5050,5051,5053,5055,5057,5059,5061,5063,5065,5067,5069,5071,5073,5075],{"class":27,"line":303},[25,5052,1843],{"class":275},[25,5054,1846],{"class":268},[25,5056,770],{"class":743},[25,5058,1852],{"class":1851},[25,5060,1855],{"class":268},[25,5062,1858],{"class":275},[25,5064,91],{"class":268},[25,5066,1863],{"class":1851},[25,5068,1855],{"class":268},[25,5070,1868],{"class":275},[25,5072,1871],{"class":268},[25,5074,1874],{"class":743},[25,5076,2208],{"class":268},[25,5078,5079],{"class":27,"line":316},[25,5080,5081],{"class":268},"  init,\n",[25,5083,5084],{"class":27,"line":329},[25,5085,382],{"class":268},[11,5087,5088,5089,770],{},"That's all it takes. Let's build, run the wizard once, and measure Tokyo again, this time without ",[22,5090,609],{},[15,5092,5094],{"className":17,"code":5093,"language":19,"meta":20,"style":20},"npm run build\nnode dist/howfar.mjs init\nnode dist/howfar.mjs Tokyo\n",[22,5095,5096,5104,5112],{"__ignoreMap":20},[25,5097,5098,5100,5102],{"class":27,"line":28},[25,5099,50],{"class":31},[25,5101,1917],{"class":35},[25,5103,3642],{"class":35},[25,5105,5106,5108,5110],{"class":27,"line":272},[25,5107,2269],{"class":31},[25,5109,3649],{"class":35},[25,5111,221],{"class":35},[25,5113,5114,5116,5118],{"class":27,"line":289},[25,5115,2269],{"class":31},[25,5117,3649],{"class":35},[25,5119,39],{"class":35},[15,5121,5122],{"className":259,"code":260,"language":261,"meta":20,"style":20},[22,5123,5124,5128,5138,5148,5158,5168,5178,5188,5198,5206],{"__ignoreMap":20},[25,5125,5126],{"class":27,"line":28},[25,5127,269],{"class":268},[25,5129,5130,5132,5134,5136],{"class":27,"line":272},[25,5131,276],{"class":275},[25,5133,279],{"class":268},[25,5135,283],{"class":282},[25,5137,286],{"class":268},[25,5139,5140,5142,5144,5146],{"class":27,"line":289},[25,5141,292],{"class":275},[25,5143,279],{"class":268},[25,5145,298],{"class":297},[25,5147,286],{"class":268},[25,5149,5150,5152,5154,5156],{"class":27,"line":303},[25,5151,306],{"class":275},[25,5153,279],{"class":268},[25,5155,311],{"class":297},[25,5157,286],{"class":268},[25,5159,5160,5162,5164,5166],{"class":27,"line":316},[25,5161,319],{"class":275},[25,5163,279],{"class":268},[25,5165,324],{"class":282},[25,5167,286],{"class":268},[25,5169,5170,5172,5174,5176],{"class":27,"line":329},[25,5171,332],{"class":275},[25,5173,279],{"class":268},[25,5175,337],{"class":282},[25,5177,286],{"class":268},[25,5179,5180,5182,5184,5186],{"class":27,"line":342},[25,5181,345],{"class":275},[25,5183,279],{"class":268},[25,5185,350],{"class":282},[25,5187,286],{"class":268},[25,5189,5190,5192,5194,5196],{"class":27,"line":355},[25,5191,358],{"class":275},[25,5193,279],{"class":268},[25,5195,363],{"class":297},[25,5197,286],{"class":268},[25,5199,5200,5202,5204],{"class":27,"line":368},[25,5201,371],{"class":275},[25,5203,279],{"class":268},[25,5205,376],{"class":297},[25,5207,5208],{"class":27,"line":379},[25,5209,382],{"class":268},[11,5211,5212,5213,5215],{},"We get the same result, and from now on, ",[22,5214,609],{}," is only for the times we want to measure from somewhere else.",[72,5217,5219],{"id":5218},"multiple-cities-and-validation","Multiple Cities and Validation",[11,5221,5222,5223,5226],{},"Alright, now we're going to add the second feature: several cities at once, each with its distance from yours. This is where beginners usually pile the parsing into ",[22,5224,5225],{},"run()",", next to everything else, and a month later, nobody wants to touch it. The fix is a tiny module for parsing arguments:",[15,5228,5231],{"className":1500,"code":5229,"filename":5230,"language":1503,"meta":20,"style":20},"/** Split a comma-separated list into one or more city names. */\nfunction parseCities(value: string): [string, ...string[]] {\n  const [first, ...rest] = value.split(',').map((city) => city.trim())\n\n  if (!first || rest.some((city) => city === '')) {\n    throw new Error(`Expected a comma-separated list of cities, got \"${value}\"`)\n  }\n\n  return [first, ...rest]\n}\n\nexport { parseCities }\n","lib/cli.ts",[22,5232,5233,5238,5271,5318,5322,5360,5383,5387,5391,5402,5406,5410],{"__ignoreMap":20},[25,5234,5235],{"class":27,"line":28},[25,5236,5237],{"class":1799},"/** Split a comma-separated list into one or more city names. */\n",[25,5239,5240,5242,5245,5247,5249,5251,5253,5255,5257,5260,5262,5264,5266,5268],{"class":27,"line":272},[25,5241,2983],{"class":275},[25,5243,5244],{"class":31}," parseCities",[25,5246,1939],{"class":268},[25,5248,4390],{"class":2194},[25,5250,770],{"class":743},[25,5252,2652],{"class":275},[25,5254,2767],{"class":268},[25,5256,770],{"class":743},[25,5258,5259],{"class":268}," [",[25,5261,1858],{"class":275},[25,5263,91],{"class":268},[25,5265,1899],{"class":743},[25,5267,1858],{"class":275},[25,5269,5270],{"class":268},"[]] {\n",[25,5272,5273,5275,5278,5280,5282,5284,5287,5290,5292,5295,5298,5301,5303,5305,5307,5309,5312,5315],{"class":27,"line":289},[25,5274,1925],{"class":275},[25,5276,5277],{"class":268}," [first, ",[25,5279,1899],{"class":743},[25,5281,1957],{"class":268},[25,5283,1874],{"class":743},[25,5285,5286],{"class":268}," value.",[25,5288,5289],{"class":31},"split",[25,5291,1939],{"class":268},[25,5293,5294],{"class":35},"','",[25,5296,5297],{"class":268},").",[25,5299,5300],{"class":31},"map",[25,5302,2191],{"class":268},[25,5304,2760],{"class":2194},[25,5306,2007],{"class":268},[25,5308,2205],{"class":275},[25,5310,5311],{"class":268}," city.",[25,5313,5314],{"class":31},"trim",[25,5316,5317],{"class":268},"())\n",[25,5319,5320],{"class":27,"line":303},[25,5321,1525],{"emptyLinePlaceholder":1524},[25,5323,5324,5326,5328,5330,5333,5335,5338,5341,5343,5345,5347,5349,5352,5355,5357],{"class":27,"line":316},[25,5325,2030],{"class":743},[25,5327,2869],{"class":268},[25,5329,2924],{"class":743},[25,5331,5332],{"class":268},"first ",[25,5334,2010],{"class":743},[25,5336,5337],{"class":268}," rest.",[25,5339,5340],{"class":31},"some",[25,5342,2191],{"class":268},[25,5344,2760],{"class":2194},[25,5346,2007],{"class":268},[25,5348,2205],{"class":275},[25,5350,5351],{"class":268}," city ",[25,5353,5354],{"class":743},"===",[25,5356,4515],{"class":35},[25,5358,5359],{"class":268},")) {\n",[25,5361,5362,5364,5366,5368,5370,5373,5375,5377,5379,5381],{"class":27,"line":329},[25,5363,2932],{"class":743},[25,5365,2792],{"class":743},[25,5367,2224],{"class":31},[25,5369,1939],{"class":268},[25,5371,5372],{"class":35},"`Expected a comma-separated list of cities, got \"",[25,5374,2944],{"class":743},[25,5376,4390],{"class":268},[25,5378,2949],{"class":743},[25,5380,2952],{"class":35},[25,5382,1945],{"class":268},[25,5384,5385],{"class":27,"line":342},[25,5386,1226],{"class":268},[25,5388,5389],{"class":27,"line":355},[25,5390,1525],{"emptyLinePlaceholder":1524},[25,5392,5393,5395,5397,5399],{"class":27,"line":368},[25,5394,2967],{"class":743},[25,5396,5277],{"class":268},[25,5398,1899],{"class":743},[25,5400,5401],{"class":268},"rest]\n",[25,5403,5404],{"class":27,"line":379},[25,5405,382],{"class":268},[25,5407,5408],{"class":27,"line":499},[25,5409,1525],{"emptyLinePlaceholder":1524},[25,5411,5412,5414],{"class":27,"line":509},[25,5413,1530],{"class":743},[25,5415,5416],{"class":268}," { parseCities }\n",[11,5418,5419,5420,5423,5424,5427,5428,5430,5431,5433],{},"The return type, ",[22,5421,5422],{},"[string, ...string[]]",", says there's always at least one city. That's what lets the command read ",[22,5425,5426],{},"cities[0]"," as a ",[22,5429,1858],{}," without ",[22,5432,1470],{}," complaining.",[159,5435,5436],{},[11,5437,5438],{},"Why throw on an empty city instead of skipping it?",[11,5440,5441,5442,5445],{},"Because ",[22,5443,5444],{},"Tokyo,,Lima"," is almost always a typo. Silently dropping the empty entry hides the mistake, while a clear error tells the user (or the agent) exactly what went wrong. Parsing the raw string myself costs a few lines and gives me full control over that message.",[11,5447,5448,5449,5452,5453,5455,5456,770],{},"Next, let's add a ",[22,5450,5451],{},"fetchDistances"," function to ",[22,5454,2632],{},", right below ",[22,5457,3605],{},[15,5459,5461],{"className":1500,"code":5460,"filename":2632,"language":1503,"meta":20,"style":20},"async function fetchDistances(cities: string[], from: string, unit: Unit = 'km') {\n  const [places, origin] = await Promise.all([Promise.all(cities.map(geocode)), geocode(from)])\n\n  return {\n    ok: true,\n    from: `${origin.name}, ${origin.country}`,\n    cities: places.map((place) => describe(place, origin, unit)),\n  }\n}\n\nexport { geocode, distanceBetween, fetchDistance, fetchDistances }\n",[22,5462,5463,5504,5542,5546,5552,5561,5586,5606,5610,5614,5618],{"__ignoreMap":20},[25,5464,5465,5467,5469,5472,5474,5477,5479,5481,5484,5486,5488,5490,5492,5494,5496,5498,5500,5502],{"class":27,"line":28},[25,5466,1911],{"class":743},[25,5468,1914],{"class":275},[25,5470,5471],{"class":31}," fetchDistances",[25,5473,1939],{"class":268},[25,5475,5476],{"class":2194},"cities",[25,5478,770],{"class":743},[25,5480,2652],{"class":275},[25,5482,5483],{"class":268},"[], ",[25,5485,1516],{"class":2194},[25,5487,770],{"class":743},[25,5489,2652],{"class":275},[25,5491,91],{"class":268},[25,5493,3064],{"class":2194},[25,5495,770],{"class":743},[25,5497,2688],{"class":1851},[25,5499,2644],{"class":743},[25,5501,2693],{"class":35},[25,5503,2138],{"class":268},[25,5505,5506,5508,5511,5513,5515,5517,5519,5521,5523,5526,5528,5530,5533,5535,5538,5540],{"class":27,"line":272},[25,5507,1925],{"class":275},[25,5509,5510],{"class":268}," [places, origin] ",[25,5512,1874],{"class":743},[25,5514,2102],{"class":743},[25,5516,2772],{"class":275},[25,5518,150],{"class":268},[25,5520,3492],{"class":31},[25,5522,3495],{"class":268},[25,5524,5525],{"class":275},"Promise",[25,5527,150],{"class":268},[25,5529,3492],{"class":31},[25,5531,5532],{"class":268},"(cities.",[25,5534,5300],{"class":31},[25,5536,5537],{"class":268},"(geocode)), ",[25,5539,3498],{"class":31},[25,5541,3506],{"class":268},[25,5543,5544],{"class":27,"line":289},[25,5545,1525],{"emptyLinePlaceholder":1524},[25,5547,5548,5550],{"class":27,"line":303},[25,5549,2967],{"class":743},[25,5551,2208],{"class":268},[25,5553,5554,5557,5559],{"class":27,"line":316},[25,5555,5556],{"class":268},"    ok: ",[25,5558,283],{"class":282},[25,5560,286],{"class":268},[25,5562,5563,5566,5568,5570,5572,5574,5576,5578,5580,5582,5584],{"class":27,"line":329},[25,5564,5565],{"class":268},"    from: ",[25,5567,3320],{"class":35},[25,5569,2944],{"class":743},[25,5571,3531],{"class":268},[25,5573,2949],{"class":743},[25,5575,91],{"class":35},[25,5577,2944],{"class":743},[25,5579,3540],{"class":268},[25,5581,2949],{"class":743},[25,5583,3320],{"class":35},[25,5585,286],{"class":268},[25,5587,5588,5591,5593,5595,5597,5599,5601,5603],{"class":27,"line":342},[25,5589,5590],{"class":268},"    cities: places.",[25,5592,5300],{"class":31},[25,5594,2191],{"class":268},[25,5596,3262],{"class":2194},[25,5598,2007],{"class":268},[25,5600,2205],{"class":275},[25,5602,3257],{"class":31},[25,5604,5605],{"class":268},"(place, origin, unit)),\n",[25,5607,5608],{"class":27,"line":355},[25,5609,1226],{"class":268},[25,5611,5612],{"class":27,"line":368},[25,5613,382],{"class":268},[25,5615,5616],{"class":27,"line":379},[25,5617,1525],{"emptyLinePlaceholder":1524},[25,5619,5620,5622],{"class":27,"line":499},[25,5621,1530],{"class":743},[25,5623,5624],{"class":268}," { geocode, distanceBetween, fetchDistance, fetchDistances }\n",[11,5626,5627],{},"The starting city and the whole list are geocoded in parallel, so measuring five cities takes about as long as measuring one. The starting city is also geocoded only once, no matter how many cities we measure.",[11,5629,5630],{},"And then the command itself, which is now almost entirely wiring:",[15,5632,5634],{"className":1500,"code":5633,"filename":2383,"language":1503,"meta":20,"style":20},"import { defineCommand } from 'citty'\nimport { resolveConfig } from '../lib/config.js'\nimport { parseCities } from '../lib/cli.js'\nimport { fetchDistance, fetchDistances } from '../lib/distance.js'\n\nconst lookup = defineCommand({\n  meta: { name: 'howfar', description: 'Distance from your city to one or more cities, as JSON' },\n  args: {\n    city: {\n      type: 'positional',\n      required: true,\n      description: 'City, or several separated by commas',\n    },\n    from: {\n      type: 'string',\n      required: false,\n      description: 'City to measure the distance from (defaults to yours)',\n    },\n  },\n  run: async ({ args }) => {\n    const { from, unit } = resolveConfig(args.from)\n    const cities = parseCities(args.city)\n\n    return cities.length === 1\n      ? fetchDistance(cities[0], from, unit)\n      : fetchDistances(cities, from, unit)\n  },\n})\n\nexport { lookup }\n",[22,5635,5636,5646,5656,5668,5679,5683,5695,5708,5712,5716,5724,5732,5741,5745,5749,5757,5765,5773,5777,5781,5799,5811,5825,5829,5841,5856,5866,5870,5874,5878],{"__ignoreMap":20},[25,5637,5638,5640,5642,5644],{"class":27,"line":28},[25,5639,1510],{"class":743},[25,5641,2392],{"class":268},[25,5643,1516],{"class":743},[25,5645,1822],{"class":35},[25,5647,5648,5650,5652,5654],{"class":27,"line":272},[25,5649,1510],{"class":743},[25,5651,4819],{"class":268},[25,5653,1516],{"class":743},[25,5655,4374],{"class":35},[25,5657,5658,5660,5663,5665],{"class":27,"line":289},[25,5659,1510],{"class":743},[25,5661,5662],{"class":268}," { parseCities } ",[25,5664,1516],{"class":743},[25,5666,5667],{"class":35}," '../lib/cli.js'\n",[25,5669,5670,5672,5675,5677],{"class":27,"line":303},[25,5671,1510],{"class":743},[25,5673,5674],{"class":268}," { fetchDistance, fetchDistances } ",[25,5676,1516],{"class":743},[25,5678,2408],{"class":35},[25,5680,5681],{"class":27,"line":316},[25,5682,1525],{"emptyLinePlaceholder":1524},[25,5684,5685,5687,5689,5691,5693],{"class":27,"line":329},[25,5686,1843],{"class":275},[25,5688,2419],{"class":268},[25,5690,1874],{"class":743},[25,5692,1893],{"class":31},[25,5694,1539],{"class":268},[25,5696,5697,5699,5701,5703,5706],{"class":27,"line":342},[25,5698,2430],{"class":268},[25,5700,2433],{"class":35},[25,5702,2436],{"class":268},[25,5704,5705],{"class":35},"'Distance from your city to one or more cities, as JSON'",[25,5707,2442],{"class":268},[25,5709,5710],{"class":27,"line":355},[25,5711,2447],{"class":268},[25,5713,5714],{"class":27,"line":368},[25,5715,2452],{"class":268},[25,5717,5718,5720,5722],{"class":27,"line":379},[25,5719,2457],{"class":268},[25,5721,2460],{"class":35},[25,5723,286],{"class":268},[25,5725,5726,5728,5730],{"class":27,"line":499},[25,5727,2467],{"class":268},[25,5729,283],{"class":282},[25,5731,286],{"class":268},[25,5733,5734,5736,5739],{"class":27,"line":509},[25,5735,2476],{"class":268},[25,5737,5738],{"class":35},"'City, or several separated by commas'",[25,5740,286],{"class":268},[25,5742,5743],{"class":27,"line":515},[25,5744,512],{"class":268},[25,5746,5747],{"class":27,"line":520},[25,5748,2490],{"class":268},[25,5750,5751,5753,5755],{"class":27,"line":532},[25,5752,2457],{"class":268},[25,5754,2497],{"class":35},[25,5756,286],{"class":268},[25,5758,5759,5761,5763],{"class":27,"line":544},[25,5760,2467],{"class":268},[25,5762,1552],{"class":282},[25,5764,286],{"class":268},[25,5766,5767,5769,5771],{"class":27,"line":556},[25,5768,2476],{"class":268},[25,5770,4925],{"class":35},[25,5772,286],{"class":268},[25,5774,5775],{"class":27,"line":568},[25,5776,512],{"class":268},[25,5778,5779],{"class":27,"line":579},[25,5780,971],{"class":268},[25,5782,5783,5785,5787,5789,5791,5793,5795,5797],{"class":27,"line":589},[25,5784,2529],{"class":31},[25,5786,279],{"class":268},[25,5788,1911],{"class":743},[25,5790,2536],{"class":268},[25,5792,2539],{"class":2194},[25,5794,2542],{"class":268},[25,5796,2205],{"class":275},[25,5798,2208],{"class":268},[25,5800,5801,5803,5805,5807,5809],{"class":27,"line":595},[25,5802,4958],{"class":275},[25,5804,4961],{"class":268},[25,5806,1874],{"class":743},[25,5808,4109],{"class":31},[25,5810,4968],{"class":268},[25,5812,5813,5815,5818,5820,5822],{"class":27,"line":601},[25,5814,4958],{"class":275},[25,5816,5817],{"class":268}," cities ",[25,5819,1874],{"class":743},[25,5821,5244],{"class":31},[25,5823,5824],{"class":268},"(args.city)\n",[25,5826,5827],{"class":27,"line":1102},[25,5828,1525],{"emptyLinePlaceholder":1524},[25,5830,5831,5833,5836,5838],{"class":27,"line":1110},[25,5832,2551],{"class":743},[25,5834,5835],{"class":268}," cities.length ",[25,5837,5354],{"class":743},[25,5839,5840],{"class":282}," 1\n",[25,5842,5843,5846,5848,5851,5853],{"class":27,"line":1123},[25,5844,5845],{"class":743},"      ?",[25,5847,2554],{"class":31},[25,5849,5850],{"class":268},"(cities[",[25,5852,2909],{"class":282},[25,5854,5855],{"class":268},"], from, unit)\n",[25,5857,5858,5861,5863],{"class":27,"line":1136},[25,5859,5860],{"class":743},"      :",[25,5862,5471],{"class":31},[25,5864,5865],{"class":268},"(cities, from, unit)\n",[25,5867,5868],{"class":27,"line":1149},[25,5869,971],{"class":268},[25,5871,5872],{"class":27,"line":1160},[25,5873,1703],{"class":268},[25,5875,5876],{"class":27,"line":1165},[25,5877,1525],{"emptyLinePlaceholder":1524},[25,5879,5880,5882],{"class":27,"line":1173},[25,5881,1530],{"class":743},[25,5883,2576],{"class":268},[11,5885,5886],{},"Let's rebuild and try it:",[15,5888,5890],{"className":17,"code":5889,"language":19,"meta":20,"style":20},"node dist/howfar.mjs \"Tokyo, San Francisco\"\n",[22,5891,5892],{"__ignoreMap":20},[25,5893,5894,5896,5898],{"class":27,"line":28},[25,5895,2269],{"class":31},[25,5897,3649],{"class":35},[25,5899,399],{"class":35},[15,5901,5902],{"className":259,"code":402,"language":261,"meta":20,"style":20},[22,5903,5904,5908,5918,5928,5934,5938,5948,5958,5968,5978,5988,5996,6000,6004,6014,6024,6034,6044,6054,6062,6066,6070],{"__ignoreMap":20},[25,5905,5906],{"class":27,"line":28},[25,5907,269],{"class":268},[25,5909,5910,5912,5914,5916],{"class":27,"line":272},[25,5911,276],{"class":275},[25,5913,279],{"class":268},[25,5915,283],{"class":282},[25,5917,286],{"class":268},[25,5919,5920,5922,5924,5926],{"class":27,"line":289},[25,5921,292],{"class":275},[25,5923,279],{"class":268},[25,5925,298],{"class":297},[25,5927,286],{"class":268},[25,5929,5930,5932],{"class":27,"line":303},[25,5931,433],{"class":275},[25,5933,436],{"class":268},[25,5935,5936],{"class":27,"line":316},[25,5937,441],{"class":268},[25,5939,5940,5942,5944,5946],{"class":27,"line":329},[25,5941,446],{"class":275},[25,5943,279],{"class":268},[25,5945,311],{"class":297},[25,5947,286],{"class":268},[25,5949,5950,5952,5954,5956],{"class":27,"line":342},[25,5951,457],{"class":275},[25,5953,279],{"class":268},[25,5955,324],{"class":282},[25,5957,286],{"class":268},[25,5959,5960,5962,5964,5966],{"class":27,"line":355},[25,5961,468],{"class":275},[25,5963,279],{"class":268},[25,5965,337],{"class":282},[25,5967,286],{"class":268},[25,5969,5970,5972,5974,5976],{"class":27,"line":368},[25,5971,479],{"class":275},[25,5973,279],{"class":268},[25,5975,350],{"class":282},[25,5977,286],{"class":268},[25,5979,5980,5982,5984,5986],{"class":27,"line":379},[25,5981,490],{"class":275},[25,5983,279],{"class":268},[25,5985,363],{"class":297},[25,5987,286],{"class":268},[25,5989,5990,5992,5994],{"class":27,"line":499},[25,5991,502],{"class":275},[25,5993,279],{"class":268},[25,5995,376],{"class":297},[25,5997,5998],{"class":27,"line":509},[25,5999,512],{"class":268},[25,6001,6002],{"class":27,"line":515},[25,6003,441],{"class":268},[25,6005,6006,6008,6010,6012],{"class":27,"line":520},[25,6007,446],{"class":275},[25,6009,279],{"class":268},[25,6011,527],{"class":297},[25,6013,286],{"class":268},[25,6015,6016,6018,6020,6022],{"class":27,"line":532},[25,6017,457],{"class":275},[25,6019,279],{"class":268},[25,6021,539],{"class":282},[25,6023,286],{"class":268},[25,6025,6026,6028,6030,6032],{"class":27,"line":544},[25,6027,468],{"class":275},[25,6029,279],{"class":268},[25,6031,551],{"class":282},[25,6033,286],{"class":268},[25,6035,6036,6038,6040,6042],{"class":27,"line":556},[25,6037,479],{"class":275},[25,6039,279],{"class":268},[25,6041,563],{"class":282},[25,6043,286],{"class":268},[25,6045,6046,6048,6050,6052],{"class":27,"line":568},[25,6047,490],{"class":275},[25,6049,279],{"class":268},[25,6051,363],{"class":297},[25,6053,286],{"class":268},[25,6055,6056,6058,6060],{"class":27,"line":579},[25,6057,502],{"class":275},[25,6059,279],{"class":268},[25,6061,586],{"class":297},[25,6063,6064],{"class":27,"line":589},[25,6065,592],{"class":268},[25,6067,6068],{"class":27,"line":595},[25,6069,598],{"class":268},[25,6071,6072],{"class":27,"line":601},[25,6073,382],{"class":268},[11,6075,6076],{},"That's a second feature, and it took five minutes because the structure was already there.",[72,6078,6080],{"id":6079},"adding-tests","Adding Tests",[11,6082,6083,6084,6086],{},"Now let's make sure this keeps working. Because the logic lives in ",[22,6085,1771],{}," and the commands are thin, the tests are short. Vite+ ships Vitest, so there's nothing to install.",[11,6088,6089],{},"Let's start with the pure functions. First, the city parser:",[15,6091,6094],{"className":1500,"code":6092,"filename":6093,"language":1503,"meta":20,"style":20},"import { describe, expect, it } from 'vitest'\nimport { parseCities } from '../lib/cli.js'\n\ndescribe('parseCities', () => {\n  it('returns a single city', () => {\n    expect(parseCities('Tokyo')).toEqual(['Tokyo'])\n  })\n\n  it('splits and trims several cities', () => {\n    expect(parseCities(' Tokyo ,San Francisco, Lima')).toEqual(['Tokyo', 'San Francisco', 'Lima'])\n  })\n\n  it.each(['', ' , ', 'Tokyo,,Lima'])('rejects %j', (value) => {\n    expect(() => parseCities(value)).toThrow('Expected a comma-separated list of cities')\n  })\n})\n","tests/cli.test.ts",[22,6095,6096,6108,6118,6122,6138,6154,6182,6186,6190,6205,6238,6242,6246,6286,6310,6314],{"__ignoreMap":20},[25,6097,6098,6100,6103,6105],{"class":27,"line":28},[25,6099,1510],{"class":743},[25,6101,6102],{"class":268}," { describe, expect, it } ",[25,6104,1516],{"class":743},[25,6106,6107],{"class":35}," 'vitest'\n",[25,6109,6110,6112,6114,6116],{"class":27,"line":272},[25,6111,1510],{"class":743},[25,6113,5662],{"class":268},[25,6115,1516],{"class":743},[25,6117,5667],{"class":35},[25,6119,6120],{"class":27,"line":289},[25,6121,1525],{"emptyLinePlaceholder":1524},[25,6123,6124,6126,6128,6131,6134,6136],{"class":27,"line":303},[25,6125,3551],{"class":31},[25,6127,1939],{"class":268},[25,6129,6130],{"class":35},"'parseCities'",[25,6132,6133],{"class":268},", () ",[25,6135,2205],{"class":275},[25,6137,2208],{"class":268},[25,6139,6140,6143,6145,6148,6150,6152],{"class":27,"line":316},[25,6141,6142],{"class":31},"  it",[25,6144,1939],{"class":268},[25,6146,6147],{"class":35},"'returns a single city'",[25,6149,6133],{"class":268},[25,6151,2205],{"class":275},[25,6153,2208],{"class":268},[25,6155,6156,6159,6161,6164,6166,6169,6172,6175,6177,6179],{"class":27,"line":329},[25,6157,6158],{"class":31},"    expect",[25,6160,1939],{"class":268},[25,6162,6163],{"class":31},"parseCities",[25,6165,1939],{"class":268},[25,6167,6168],{"class":35},"'Tokyo'",[25,6170,6171],{"class":268},")).",[25,6173,6174],{"class":31},"toEqual",[25,6176,3495],{"class":268},[25,6178,6168],{"class":35},[25,6180,6181],{"class":268},"])\n",[25,6183,6184],{"class":27,"line":342},[25,6185,4527],{"class":268},[25,6187,6188],{"class":27,"line":355},[25,6189,1525],{"emptyLinePlaceholder":1524},[25,6191,6192,6194,6196,6199,6201,6203],{"class":27,"line":368},[25,6193,6142],{"class":31},[25,6195,1939],{"class":268},[25,6197,6198],{"class":35},"'splits and trims several cities'",[25,6200,6133],{"class":268},[25,6202,2205],{"class":275},[25,6204,2208],{"class":268},[25,6206,6207,6209,6211,6213,6215,6218,6220,6222,6224,6226,6228,6231,6233,6236],{"class":27,"line":379},[25,6208,6158],{"class":31},[25,6210,1939],{"class":268},[25,6212,6163],{"class":31},[25,6214,1939],{"class":268},[25,6216,6217],{"class":35},"' Tokyo ,San Francisco, Lima'",[25,6219,6171],{"class":268},[25,6221,6174],{"class":31},[25,6223,3495],{"class":268},[25,6225,6168],{"class":35},[25,6227,91],{"class":268},[25,6229,6230],{"class":35},"'San Francisco'",[25,6232,91],{"class":268},[25,6234,6235],{"class":35},"'Lima'",[25,6237,6181],{"class":268},[25,6239,6240],{"class":27,"line":499},[25,6241,4527],{"class":268},[25,6243,6244],{"class":27,"line":509},[25,6245,1525],{"emptyLinePlaceholder":1524},[25,6247,6248,6251,6254,6256,6259,6261,6264,6266,6269,6272,6275,6278,6280,6282,6284],{"class":27,"line":515},[25,6249,6250],{"class":268},"  it.",[25,6252,6253],{"class":31},"each",[25,6255,3495],{"class":268},[25,6257,6258],{"class":35},"''",[25,6260,91],{"class":268},[25,6262,6263],{"class":35},"' , '",[25,6265,91],{"class":268},[25,6267,6268],{"class":35},"'Tokyo,,Lima'",[25,6270,6271],{"class":268},"])(",[25,6273,6274],{"class":35},"'rejects %j'",[25,6276,6277],{"class":268},", (",[25,6279,4390],{"class":2194},[25,6281,2007],{"class":268},[25,6283,2205],{"class":275},[25,6285,2208],{"class":268},[25,6287,6288,6290,6293,6295,6297,6300,6303,6305,6308],{"class":27,"line":520},[25,6289,6158],{"class":31},[25,6291,6292],{"class":268},"(() ",[25,6294,2205],{"class":275},[25,6296,5244],{"class":31},[25,6298,6299],{"class":268},"(value)).",[25,6301,6302],{"class":31},"toThrow",[25,6304,1939],{"class":268},[25,6306,6307],{"class":35},"'Expected a comma-separated list of cities'",[25,6309,1945],{"class":268},[25,6311,6312],{"class":27,"line":532},[25,6313,4527],{"class":268},[25,6315,6316],{"class":27,"line":544},[25,6317,1703],{"class":268},[11,6319,6320,6321,6323],{},"Then, the distance math. ",[22,6322,3594],{}," takes two places and returns a number, so we can pass it coordinates directly, with no network request and nothing to mock:",[15,6325,6328],{"className":1500,"code":6326,"filename":6327,"language":1503,"meta":20,"style":20},"import { describe, expect, it } from 'vitest'\nimport { distanceBetween } from '../lib/distance.js'\n\nconst buenosAires = {\n  name: 'Buenos Aires',\n  country: 'Argentina',\n  latitude: -34.61315,\n  longitude: -58.37723,\n}\nconst tokyo = { name: 'Tokyo', country: 'Japan', latitude: 35.6895, longitude: 139.69171 }\n\ndescribe('distanceBetween', () => {\n  it('measures the distance in kilometers', () => {\n    expect(distanceBetween(buenosAires, tokyo, 'km')).toBe(18370)\n  })\n\n  it('measures the distance in miles', () => {\n    expect(distanceBetween(buenosAires, tokyo, 'mi')).toBe(11415)\n  })\n\n  it('returns zero for the same place', () => {\n    expect(distanceBetween(tokyo, tokyo, 'km')).toBe(0)\n  })\n})\n","tests/distance.test.ts",[22,6329,6330,6340,6351,6355,6366,6375,6385,6397,6409,6413,6445,6449,6464,6479,6503,6507,6511,6526,6549,6553,6557,6572,6595,6599],{"__ignoreMap":20},[25,6331,6332,6334,6336,6338],{"class":27,"line":28},[25,6333,1510],{"class":743},[25,6335,6102],{"class":268},[25,6337,1516],{"class":743},[25,6339,6107],{"class":35},[25,6341,6342,6344,6347,6349],{"class":27,"line":272},[25,6343,1510],{"class":743},[25,6345,6346],{"class":268}," { distanceBetween } ",[25,6348,1516],{"class":743},[25,6350,2408],{"class":35},[25,6352,6353],{"class":27,"line":289},[25,6354,1525],{"emptyLinePlaceholder":1524},[25,6356,6357,6359,6362,6364],{"class":27,"line":303},[25,6358,1843],{"class":275},[25,6360,6361],{"class":268}," buenosAires ",[25,6363,1874],{"class":743},[25,6365,2208],{"class":268},[25,6367,6368,6371,6373],{"class":27,"line":316},[25,6369,6370],{"class":268},"  name: ",[25,6372,4503],{"class":35},[25,6374,286],{"class":268},[25,6376,6377,6380,6383],{"class":27,"line":329},[25,6378,6379],{"class":268},"  country: ",[25,6381,6382],{"class":35},"'Argentina'",[25,6384,286],{"class":268},[25,6386,6387,6390,6392,6395],{"class":27,"line":342},[25,6388,6389],{"class":268},"  latitude: ",[25,6391,3093],{"class":743},[25,6393,6394],{"class":282},"34.61315",[25,6396,286],{"class":268},[25,6398,6399,6402,6404,6407],{"class":27,"line":355},[25,6400,6401],{"class":268},"  longitude: ",[25,6403,3093],{"class":743},[25,6405,6406],{"class":282},"58.37723",[25,6408,286],{"class":268},[25,6410,6411],{"class":27,"line":368},[25,6412,382],{"class":268},[25,6414,6415,6417,6420,6422,6425,6427,6430,6433,6436,6438,6441,6443],{"class":27,"line":379},[25,6416,1843],{"class":275},[25,6418,6419],{"class":268}," tokyo ",[25,6421,1874],{"class":743},[25,6423,6424],{"class":268}," { name: ",[25,6426,6168],{"class":35},[25,6428,6429],{"class":268},", country: ",[25,6431,6432],{"class":35},"'Japan'",[25,6434,6435],{"class":268},", latitude: ",[25,6437,324],{"class":282},[25,6439,6440],{"class":268},", longitude: ",[25,6442,337],{"class":282},[25,6444,2677],{"class":268},[25,6446,6447],{"class":27,"line":499},[25,6448,1525],{"emptyLinePlaceholder":1524},[25,6450,6451,6453,6455,6458,6460,6462],{"class":27,"line":509},[25,6452,3551],{"class":31},[25,6454,1939],{"class":268},[25,6456,6457],{"class":35},"'distanceBetween'",[25,6459,6133],{"class":268},[25,6461,2205],{"class":275},[25,6463,2208],{"class":268},[25,6465,6466,6468,6470,6473,6475,6477],{"class":27,"line":515},[25,6467,6142],{"class":31},[25,6469,1939],{"class":268},[25,6471,6472],{"class":35},"'measures the distance in kilometers'",[25,6474,6133],{"class":268},[25,6476,2205],{"class":275},[25,6478,2208],{"class":268},[25,6480,6481,6483,6485,6487,6490,6492,6494,6497,6499,6501],{"class":27,"line":520},[25,6482,6158],{"class":31},[25,6484,1939],{"class":268},[25,6486,3594],{"class":31},[25,6488,6489],{"class":268},"(buenosAires, tokyo, ",[25,6491,3892],{"class":35},[25,6493,6171],{"class":268},[25,6495,6496],{"class":31},"toBe",[25,6498,1939],{"class":268},[25,6500,350],{"class":282},[25,6502,1945],{"class":268},[25,6504,6505],{"class":27,"line":532},[25,6506,4527],{"class":268},[25,6508,6509],{"class":27,"line":544},[25,6510,1525],{"emptyLinePlaceholder":1524},[25,6512,6513,6515,6517,6520,6522,6524],{"class":27,"line":556},[25,6514,6142],{"class":31},[25,6516,1939],{"class":268},[25,6518,6519],{"class":35},"'measures the distance in miles'",[25,6521,6133],{"class":268},[25,6523,2205],{"class":275},[25,6525,2208],{"class":268},[25,6527,6528,6530,6532,6534,6536,6538,6540,6542,6544,6547],{"class":27,"line":568},[25,6529,6158],{"class":31},[25,6531,1939],{"class":268},[25,6533,3594],{"class":31},[25,6535,6489],{"class":268},[25,6537,3897],{"class":35},[25,6539,6171],{"class":268},[25,6541,6496],{"class":31},[25,6543,1939],{"class":268},[25,6545,6546],{"class":282},"11415",[25,6548,1945],{"class":268},[25,6550,6551],{"class":27,"line":579},[25,6552,4527],{"class":268},[25,6554,6555],{"class":27,"line":589},[25,6556,1525],{"emptyLinePlaceholder":1524},[25,6558,6559,6561,6563,6566,6568,6570],{"class":27,"line":595},[25,6560,6142],{"class":31},[25,6562,1939],{"class":268},[25,6564,6565],{"class":35},"'returns zero for the same place'",[25,6567,6133],{"class":268},[25,6569,2205],{"class":275},[25,6571,2208],{"class":268},[25,6573,6574,6576,6578,6580,6583,6585,6587,6589,6591,6593],{"class":27,"line":601},[25,6575,6158],{"class":31},[25,6577,1939],{"class":268},[25,6579,3594],{"class":31},[25,6581,6582],{"class":268},"(tokyo, tokyo, ",[25,6584,3892],{"class":35},[25,6586,6171],{"class":268},[25,6588,6496],{"class":31},[25,6590,1939],{"class":268},[25,6592,2909],{"class":282},[25,6594,1945],{"class":268},[25,6596,6597],{"class":27,"line":1102},[25,6598,4527],{"class":268},[25,6600,6601],{"class":27,"line":1110},[25,6602,1703],{"class":268},[11,6604,6605,6606,6609],{},"Then, let's write a command test. Here, the trick is that citty's ",[22,6607,6608],{},"runCommand"," accepts a raw argument array, so we can drive a command exactly the way the terminal would, without spawning a process. We mock the distance module so no network request happens, and the config module so the test never reads the real config file on your machine:",[15,6611,6614],{"className":1500,"code":6612,"filename":6613,"language":1503,"meta":20,"style":20},"import { describe, expect, it, vi } from 'vitest'\nimport { runCommand } from 'citty'\nimport { lookup } from '../commands/lookup.js'\nimport { fetchDistance, fetchDistances } from '../lib/distance.js'\n\nvi.mock('../lib/config.js', () => ({\n  resolveConfig: (from?: string) => ({ from: from ?? 'Lisbon', unit: 'km' }),\n}))\n\nvi.mock('../lib/distance.js', () => ({\n  fetchDistance: vi.fn(async () => ({ ok: true })),\n  fetchDistances: vi.fn(async () => ({ ok: true })),\n}))\n\ndescribe('lookup', () => {\n  it('measures from your city by default', async () => {\n    await runCommand(lookup, { rawArgs: ['Tokyo'] })\n\n    expect(fetchDistance).toHaveBeenCalledWith('Tokyo', 'Lisbon', 'km')\n  })\n\n  it('measures from another city with --from', async () => {\n    await runCommand(lookup, { rawArgs: ['Tokyo', '--from', 'Lima'] })\n\n    expect(fetchDistance).toHaveBeenCalledWith('Tokyo', 'Lima', 'km')\n  })\n\n  it('measures several cities', async () => {\n    await runCommand(lookup, { rawArgs: ['Tokyo, San Francisco'] })\n\n    expect(fetchDistances).toHaveBeenCalledWith(['Tokyo', 'San Francisco'], 'Lisbon', 'km')\n  })\n})\n","tests/lookup.test.ts",[22,6615,6616,6627,6638,6648,6658,6662,6682,6716,6721,6725,6742,6767,6788,6792,6796,6811,6830,6844,6848,6873,6877,6881,6900,6921,6925,6947,6951,6955,6974,6987,6991,7019,7023],{"__ignoreMap":20},[25,6617,6618,6620,6623,6625],{"class":27,"line":28},[25,6619,1510],{"class":743},[25,6621,6622],{"class":268}," { describe, expect, it, vi } ",[25,6624,1516],{"class":743},[25,6626,6107],{"class":35},[25,6628,6629,6631,6634,6636],{"class":27,"line":272},[25,6630,1510],{"class":743},[25,6632,6633],{"class":268}," { runCommand } ",[25,6635,1516],{"class":743},[25,6637,1822],{"class":35},[25,6639,6640,6642,6644,6646],{"class":27,"line":289},[25,6641,1510],{"class":743},[25,6643,1829],{"class":268},[25,6645,1516],{"class":743},[25,6647,1834],{"class":35},[25,6649,6650,6652,6654,6656],{"class":27,"line":303},[25,6651,1510],{"class":743},[25,6653,5674],{"class":268},[25,6655,1516],{"class":743},[25,6657,2408],{"class":35},[25,6659,6660],{"class":27,"line":316},[25,6661,1525],{"emptyLinePlaceholder":1524},[25,6663,6664,6667,6670,6672,6675,6677,6679],{"class":27,"line":329},[25,6665,6666],{"class":268},"vi.",[25,6668,6669],{"class":31},"mock",[25,6671,1939],{"class":268},[25,6673,6674],{"class":35},"'../lib/config.js'",[25,6676,6133],{"class":268},[25,6678,2205],{"class":275},[25,6680,6681],{"class":268}," ({\n",[25,6683,6684,6687,6690,6692,6694,6696,6698,6700,6703,6705,6708,6711,6713],{"class":27,"line":342},[25,6685,6686],{"class":31},"  resolveConfig",[25,6688,6689],{"class":268},": (",[25,6691,1516],{"class":2194},[25,6693,2889],{"class":743},[25,6695,2652],{"class":275},[25,6697,2007],{"class":268},[25,6699,2205],{"class":275},[25,6701,6702],{"class":268}," ({ from: from ",[25,6704,2087],{"class":743},[25,6706,6707],{"class":35}," 'Lisbon'",[25,6709,6710],{"class":268},", unit: ",[25,6712,3892],{"class":35},[25,6714,6715],{"class":268}," }),\n",[25,6717,6718],{"class":27,"line":355},[25,6719,6720],{"class":268},"}))\n",[25,6722,6723],{"class":27,"line":368},[25,6724,1525],{"emptyLinePlaceholder":1524},[25,6726,6727,6729,6731,6733,6736,6738,6740],{"class":27,"line":379},[25,6728,6666],{"class":268},[25,6730,6669],{"class":31},[25,6732,1939],{"class":268},[25,6734,6735],{"class":35},"'../lib/distance.js'",[25,6737,6133],{"class":268},[25,6739,2205],{"class":275},[25,6741,6681],{"class":268},[25,6743,6744,6747,6750,6752,6754,6757,6759,6762,6764],{"class":27,"line":499},[25,6745,6746],{"class":268},"  fetchDistance: vi.",[25,6748,6749],{"class":31},"fn",[25,6751,1939],{"class":268},[25,6753,1911],{"class":743},[25,6755,6756],{"class":268}," () ",[25,6758,2205],{"class":275},[25,6760,6761],{"class":268}," ({ ok: ",[25,6763,283],{"class":282},[25,6765,6766],{"class":268}," })),\n",[25,6768,6769,6772,6774,6776,6778,6780,6782,6784,6786],{"class":27,"line":509},[25,6770,6771],{"class":268},"  fetchDistances: vi.",[25,6773,6749],{"class":31},[25,6775,1939],{"class":268},[25,6777,1911],{"class":743},[25,6779,6756],{"class":268},[25,6781,2205],{"class":275},[25,6783,6761],{"class":268},[25,6785,283],{"class":282},[25,6787,6766],{"class":268},[25,6789,6790],{"class":27,"line":515},[25,6791,6720],{"class":268},[25,6793,6794],{"class":27,"line":520},[25,6795,1525],{"emptyLinePlaceholder":1524},[25,6797,6798,6800,6802,6805,6807,6809],{"class":27,"line":532},[25,6799,3551],{"class":31},[25,6801,1939],{"class":268},[25,6803,6804],{"class":35},"'lookup'",[25,6806,6133],{"class":268},[25,6808,2205],{"class":275},[25,6810,2208],{"class":268},[25,6812,6813,6815,6817,6820,6822,6824,6826,6828],{"class":27,"line":544},[25,6814,6142],{"class":31},[25,6816,1939],{"class":268},[25,6818,6819],{"class":35},"'measures from your city by default'",[25,6821,91],{"class":268},[25,6823,1911],{"class":743},[25,6825,6756],{"class":268},[25,6827,2205],{"class":275},[25,6829,2208],{"class":268},[25,6831,6832,6834,6836,6839,6841],{"class":27,"line":556},[25,6833,2038],{"class":743},[25,6835,2105],{"class":31},[25,6837,6838],{"class":268},"(lookup, { rawArgs: [",[25,6840,6168],{"class":35},[25,6842,6843],{"class":268},"] })\n",[25,6845,6846],{"class":27,"line":568},[25,6847,1525],{"emptyLinePlaceholder":1524},[25,6849,6850,6852,6855,6858,6860,6862,6864,6867,6869,6871],{"class":27,"line":579},[25,6851,6158],{"class":31},[25,6853,6854],{"class":268},"(fetchDistance).",[25,6856,6857],{"class":31},"toHaveBeenCalledWith",[25,6859,1939],{"class":268},[25,6861,6168],{"class":35},[25,6863,91],{"class":268},[25,6865,6866],{"class":35},"'Lisbon'",[25,6868,91],{"class":268},[25,6870,3892],{"class":35},[25,6872,1945],{"class":268},[25,6874,6875],{"class":27,"line":589},[25,6876,4527],{"class":268},[25,6878,6879],{"class":27,"line":595},[25,6880,1525],{"emptyLinePlaceholder":1524},[25,6882,6883,6885,6887,6890,6892,6894,6896,6898],{"class":27,"line":601},[25,6884,6142],{"class":31},[25,6886,1939],{"class":268},[25,6888,6889],{"class":35},"'measures from another city with --from'",[25,6891,91],{"class":268},[25,6893,1911],{"class":743},[25,6895,6756],{"class":268},[25,6897,2205],{"class":275},[25,6899,2208],{"class":268},[25,6901,6902,6904,6906,6908,6910,6912,6915,6917,6919],{"class":27,"line":1102},[25,6903,2038],{"class":743},[25,6905,2105],{"class":31},[25,6907,6838],{"class":268},[25,6909,6168],{"class":35},[25,6911,91],{"class":268},[25,6913,6914],{"class":35},"'--from'",[25,6916,91],{"class":268},[25,6918,6235],{"class":35},[25,6920,6843],{"class":268},[25,6922,6923],{"class":27,"line":1110},[25,6924,1525],{"emptyLinePlaceholder":1524},[25,6926,6927,6929,6931,6933,6935,6937,6939,6941,6943,6945],{"class":27,"line":1123},[25,6928,6158],{"class":31},[25,6930,6854],{"class":268},[25,6932,6857],{"class":31},[25,6934,1939],{"class":268},[25,6936,6168],{"class":35},[25,6938,91],{"class":268},[25,6940,6235],{"class":35},[25,6942,91],{"class":268},[25,6944,3892],{"class":35},[25,6946,1945],{"class":268},[25,6948,6949],{"class":27,"line":1136},[25,6950,4527],{"class":268},[25,6952,6953],{"class":27,"line":1149},[25,6954,1525],{"emptyLinePlaceholder":1524},[25,6956,6957,6959,6961,6964,6966,6968,6970,6972],{"class":27,"line":1160},[25,6958,6142],{"class":31},[25,6960,1939],{"class":268},[25,6962,6963],{"class":35},"'measures several cities'",[25,6965,91],{"class":268},[25,6967,1911],{"class":743},[25,6969,6756],{"class":268},[25,6971,2205],{"class":275},[25,6973,2208],{"class":268},[25,6975,6976,6978,6980,6982,6985],{"class":27,"line":1165},[25,6977,2038],{"class":743},[25,6979,2105],{"class":31},[25,6981,6838],{"class":268},[25,6983,6984],{"class":35},"'Tokyo, San Francisco'",[25,6986,6843],{"class":268},[25,6988,6989],{"class":27,"line":1173},[25,6990,1525],{"emptyLinePlaceholder":1524},[25,6992,6993,6995,6998,7000,7002,7004,7006,7008,7011,7013,7015,7017],{"class":27,"line":1186},[25,6994,6158],{"class":31},[25,6996,6997],{"class":268},"(fetchDistances).",[25,6999,6857],{"class":31},[25,7001,3495],{"class":268},[25,7003,6168],{"class":35},[25,7005,91],{"class":268},[25,7007,6230],{"class":35},[25,7009,7010],{"class":268},"], ",[25,7012,6866],{"class":35},[25,7014,91],{"class":268},[25,7016,3892],{"class":35},[25,7018,1945],{"class":268},[25,7020,7021],{"class":27,"line":1199},[25,7022,4527],{"class":268},[25,7024,7025],{"class":27,"line":1212},[25,7026,1703],{"class":268},[11,7028,7029],{},"Now, let's run them:",[15,7031,7033],{"className":17,"code":7032,"language":19,"meta":20,"style":20},"npm test\n",[22,7034,7035],{"__ignoreMap":20},[25,7036,7037,7039],{"class":27,"line":28},[25,7038,50],{"class":31},[25,7040,7041],{"class":35}," test\n",[15,7043,7046],{"className":7044,"code":7045,"language":230,"meta":20},[228]," ✓ tests/cli.test.ts (5 tests)\n ✓ tests/lookup.test.ts (3 tests)\n ✓ tests/distance.test.ts (3 tests)\n\n Test Files  3 passed (3)\n      Tests  11 passed (11)\n",[22,7047,7045],{"__ignoreMap":20},[11,7049,7050,7051,7053],{},"And remember the ",[22,7052,1717],{}," block from the Vite+ config we set up earlier? From now on, every commit formats and lints the files you touched and runs the tests that import them. If a test fails, the commit is rejected. I've had that hook catch more bugs than I'd like to admit.",[72,7055,7057],{"id":7056},"publishing-the-package","Publishing the Package",[11,7059,7060],{},"Alright, the last step. Before publishing, it's a good idea to check that the name is free:",[15,7062,7064],{"className":17,"code":7063,"language":19,"meta":20,"style":20},"npm view @username/howfar\n",[22,7065,7066],{"__ignoreMap":20},[25,7067,7068,7070,7073],{"class":27,"line":28},[25,7069,50],{"class":31},[25,7071,7072],{"class":35}," view",[25,7074,7075],{"class":35}," @username/howfar\n",[11,7077,7078,7079,7083],{},"If that returns a package, you'll need to pick another name. Then, let's log in and publish. If you don't have an npm account yet, you can create one at ",[60,7080,97],{"href":7081,"rel":7082},"https://www.npmjs.com/signup",[96]," first:",[15,7085,7087],{"className":17,"code":7086,"language":19,"meta":20,"style":20},"npm login\nnpm publish --access public\n",[22,7088,7089,7096],{"__ignoreMap":20},[25,7090,7091,7093],{"class":27,"line":28},[25,7092,50],{"class":31},[25,7094,7095],{"class":35}," login\n",[25,7097,7098,7100,7103,7106],{"class":27,"line":272},[25,7099,50],{"class":31},[25,7101,7102],{"class":35}," publish",[25,7104,7105],{"class":282}," --access",[25,7107,7108],{"class":35}," public\n",[11,7110,2579,7111,7114,7115,7117,7118,7121,7122,7124,7125,7127],{},[22,7112,7113],{},"--access public"," flag is only needed the first time, because scoped packages default to private. And that's it. The ",[22,7116,1279],{}," script runs the type check and ",[22,7119,7120],{},"vp pack",", and the ",[22,7123,1267],{}," field makes sure only ",[22,7126,189],{}," goes up. A minute later, anyone with Node installed can run:",[15,7129,7131],{"className":17,"code":7130,"language":19,"meta":20,"style":20},"npx @username/howfar init\nnpx @username/howfar Tokyo\n",[22,7132,7133,7142],{"__ignoreMap":20},[25,7134,7135,7137,7140],{"class":27,"line":28},[25,7136,32],{"class":31},[25,7138,7139],{"class":35}," @username/howfar",[25,7141,221],{"class":35},[25,7143,7144,7146,7148],{"class":27,"line":272},[25,7145,32],{"class":31},[25,7147,7139],{"class":35},[25,7149,39],{"class":35},[11,7151,7152,7153,7155],{},"npm downloads the package into a cache, finds the ",[22,7154,1251],{}," entry, and runs it. The user never installs anything globally or builds anything.",[11,7157,7158],{},"Later, to ship a new version, you can bump the number and publish again:",[15,7160,7162],{"className":17,"code":7161,"language":19,"meta":20,"style":20},"npm version patch\nnpm publish\n",[22,7163,7164,7174],{"__ignoreMap":20},[25,7165,7166,7168,7171],{"class":27,"line":28},[25,7167,50],{"class":31},[25,7169,7170],{"class":35}," version",[25,7172,7173],{"class":35}," patch\n",[25,7175,7176,7178],{"class":27,"line":272},[25,7177,50],{"class":31},[25,7179,7180],{"class":35}," publish\n",[72,7182,7184],{"id":7183},"where-to-go-from-here","Where to Go From Here",[11,7186,7187,7188,7190,7191,7193,7194,7197,7198,7200,7201,7203],{},"Everything in howfar maps one-to-one onto climail, which is a much bigger tool. climail has thirteen commands instead of two, an IMAP client instead of a geocoding API, and a config with two nested blocks instead of two fields. The ",[22,7189,1785],{}," file is almost identical. The ",[22,7192,5230],{}," file has a ",[22,7195,7196],{},"parseCount"," where we have ",[22,7199,6163],{},". The ",[22,7202,669],{}," wizard asks for a host and a password instead of a city. Same skeleton, more code.",[11,7205,7206],{},"So when your tool needs to grow, you already know where things go:",[636,7208,7209,7214,7219,7224],{},[639,7210,7211,7212,150],{},"A new feature is a new file in ",[22,7213,1767],{},[639,7215,7216,7217,150],{},"Logic that two commands share moves to ",[22,7218,1771],{},[639,7220,7221,7222,150],{},"A new setting is a new field in the zod schema and a new prompt in ",[22,7223,669],{},[639,7225,7226,7227,7229],{},"A new argument that needs validation gets a parse function in ",[22,7228,5230],{},", with a test next to it.",[72,7231,7233],{"id":7232},"in-closing","In Closing",[11,7235,7236,7237,7239],{},"We started from an empty folder and ended with a published ",[22,7238,32],{}," command that has a default command, a flag, a subcommand, a help screen, a setup wizard, a validated config file, tests, and a pre-commit hook. The distance part was about seventy lines. The rest is a structure you can copy into your next tool tomorrow.",[11,7241,7242],{},"And the next time someone asks how far Tokyo is, you won't need to drop any pins.",[11,7244,7245,7246,150],{},"If you turn one of your own scripts into a tool, I'd love to hear what you built! I'm ",[60,7247,7250],{"href":7248,"rel":7249},"https://x.com/nicodevs",[96],"@nicodevs",[11,7252,7253],{},"Until next time!",[7255,7256,7257],"style",{},"html pre.shiki code .sHkqI, html code.shiki .sHkqI{--shiki-default:#A6E22E}html pre.shiki code .s_Ekj, html code.shiki .s_Ekj{--shiki-default:#E6DB74}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sCdxs, html code.shiki .sCdxs{--shiki-default:#F8F8F2}html pre.shiki code .sOx1s, html code.shiki .sOx1s{--shiki-default:#66D9EF;--shiki-default-font-style:italic}html pre.shiki code .s7s5_, html code.shiki .s7s5_{--shiki-default:#AE81FF}html pre.shiki code .susgL, html code.shiki .susgL{--shiki-default:#CFCFC2}html pre.shiki code .s8I7P, html code.shiki .s8I7P{--shiki-default:#F92672}html pre.shiki code .sYf5A, html code.shiki .sYf5A{--shiki-default:#66D9EF}html pre.shiki code .snpHw, html code.shiki .snpHw{--shiki-default:#88846F}html pre.shiki code .soZtE, html code.shiki .soZtE{--shiki-default:#A6E22E;--shiki-default-text-decoration:underline}html pre.shiki code .sW0Xf, html code.shiki .sW0Xf{--shiki-default:#FD971F;--shiki-default-font-style:italic}",{"title":20,"searchDepth":272,"depth":272,"links":7259},[7260,7261,7262,7263,7264,7265,7266,7267,7268,7269,7270,7271,7272],{"id":74,"depth":272,"text":75},{"id":203,"depth":272,"text":204},{"id":624,"depth":272,"text":625},{"id":717,"depth":272,"text":718},{"id":1747,"depth":272,"text":1748},{"id":1778,"depth":272,"text":1779},{"id":2365,"depth":272,"text":2366},{"id":3780,"depth":272,"text":3781},{"id":5218,"depth":272,"text":5219},{"id":6079,"depth":272,"text":6080},{"id":7056,"depth":272,"text":7057},{"id":7183,"depth":272,"text":7184},{"id":7232,"depth":272,"text":7233},"2026-11-01","From an empty folder to a published npx command. Learn the structure I use for my own CLIs: citty for commands, clack for prompts, rc9 and zod for config, and Vite+ for linting, testing and bundling.",false,"md","/img/blog/build-command-line-tools-in-typescript-a-step-by-step-guide.png",{},"/blog/build-command-line-tools-in-typescript-a-step-by-step-guide",{"title":6,"description":7274},"blog/build-command-line-tools-in-typescript-a-step-by-step-guide","631-WscK5647TTHTso_3tEZCYZAyePraJCpAIz71M7g",{"id":7284,"title":7285,"body":7286,"category":7313,"date":7314,"description":7290,"draft":7275,"extension":7276,"image":7315,"meta":7316,"navigation":1524,"path":7317,"seo":7318,"stem":7319,"tighten":1524,"__hash__":7320},"blog/blog/web-workers-a-second-thread-for-your-javascript.md","Web Workers: A Second Thread for Your JavaScript",{"type":8,"value":7287,"toc":7311},[7288,7291,7300,7303],[11,7289,7290],{},"JavaScript runs on a single thread. Give it a heavy task, like resizing a large photo before uploading it, and the page freezes until it finishes.",[11,7292,7293,7294,7299],{},"Web Workers solve this by running that work on a second thread. In this article for ",[60,7295,7298],{"href":7296,"rel":7297},"https://tighten.com",[96],"Tighten",", I cover how they work, their two main limitations, how they differ from Service Workers, and how to use one to resize and compress images in the browser before they reach your server.",[11,7301,7302],{},"Read the full article here:",[7304,7305,7308],"article-preview",{"image":7306,"link":7307,"title":7285},"https://tighten.com/assets/images/insights/web-workers-a-second-thread-for-your-javascript-preview.jpg","https://tighten.com/insights/web-workers-a-second-thread-for-your-javascript/",[11,7309,7310],{},"Suppose you have a web app that lets users upload photos. Cool! But there's a catch: photos straight from a phone camera can easily be around 8 MB each. On a weak mobile connection, uploading the full-size file can be painfully slow for them, and expensive for you.",{"title":20,"searchDepth":272,"depth":272,"links":7312},[],"JavaScript","2026-09-21","/img/blog/web-workers-a-second-thread-for-your-javascript.png",{},"/blog/web-workers-a-second-thread-for-your-javascript",{"title":7285,"description":7290},"blog/web-workers-a-second-thread-for-your-javascript","y3SUXoJPmVOBMKdgNEzLNSaJPaSGkhKMQueHzuujzl0",{"id":7322,"title":7323,"body":7324,"category":7347,"date":7348,"description":7328,"draft":7275,"extension":7276,"image":7349,"meta":7350,"navigation":1524,"path":7351,"seo":7352,"stem":7353,"tighten":1524,"__hash__":7354},"blog/blog/run-ai-in-the-browser-a-practical-guide-to-transformers-js.md","Run AI in the Browser: A Practical Guide to Transformers.js",{"type":8,"value":7325,"toc":7345},[7326,7329,7336,7338],[11,7327,7328],{},"Transformers.js lets you run open source AI models directly in the browser. No API keys, no server round trips, and it keeps working offline once the model is cached.",[11,7330,7331,7332,7335],{},"I wrote a guide for ",[60,7333,7298],{"href":7296,"rel":7334},[96]," on how it works, which browsers support it, what to expect from small models, and how to build a grammar checker that runs entirely on the user's device.",[11,7337,7302],{},[7304,7339,7342],{"image":7340,"link":7341,"title":7323},"https://tighten.com/assets/images/insights/run-ai-in-the-browser-a-practical-guide-to-transformers-js-preview.jpg","https://tighten.com/insights/run-ai-in-the-browser-a-practical-guide-to-transformers-js/",[11,7343,7344],{},"Imagine you need to integrate AI into your web app. Let's say you want to quickly translate text. Preferably, you'd like to use something free and open source (you don't want any surprise bills at the end of the month). One more thing: people use your app while traveling, so it must continue working when they have poor connections or no connection at all.",{"title":20,"searchDepth":272,"depth":272,"links":7346},[],"AI","2026-09-03","/img/blog/run-ai-in-the-browser-a-practical-guide-to-transformers-js.png",{},"/blog/run-ai-in-the-browser-a-practical-guide-to-transformers-js",{"title":7323,"description":7328},"blog/run-ai-in-the-browser-a-practical-guide-to-transformers-js","x_41mO5AOnw12R9hYDKPz_VfUPUqdnopJv_EEqtOxCM",{"id":7356,"title":7357,"body":7358,"category":7347,"date":7379,"description":7362,"draft":7275,"extension":7276,"image":7380,"meta":7381,"navigation":1524,"path":7382,"seo":7383,"stem":7384,"tighten":1524,"__hash__":7385},"blog/blog/build-your-own-ai-powered-slack-bot-with-the-laravel-ai-sdk.md","Build Your Own AI-Powered Slack Bot with the Laravel AI SDK",{"type":8,"value":7359,"toc":7377},[7360,7363,7366,7373],[11,7361,7362],{},"You can build your own AI teammate and talk to it via Slack! 🤖",[11,7364,7365],{},"Sure, you can use a service, but building your own means you own the memory, choose the model, and can tweak it to fit your needs.",[11,7367,7368,7369,7372],{},"Learn how in my latest article for ",[60,7370,7298],{"href":7296,"rel":7371},[96]," (Spoiler alert: Laravel AI SDK 🔥)",[7304,7374],{"image":7375,"link":7376,"title":7357},"https://tighten.com/assets/images/insights/build-your-own-ai-powered-slack-bot-with-the-laravel-ai-sdk-preview.jpg","https://tighten.com/insights/build-your-own-ai-powered-slack-bot-with-the-laravel-ai-sdk/",{"title":20,"searchDepth":272,"depth":272,"links":7378},[],"2026-08-26","/img/blog/build-your-own-ai-powered-slack-bot-with-the-laravel-ai-sdk.png",{},"/blog/build-your-own-ai-powered-slack-bot-with-the-laravel-ai-sdk",{"title":7357,"description":7362},"blog/build-your-own-ai-powered-slack-bot-with-the-laravel-ai-sdk","7tTbzmSWADzFKiLWDjyF_KR0vwbNimwP82vZeL1fVFE",{"id":5,"title":6,"body":7387,"category":46,"date":7273,"description":7274,"draft":7275,"extension":7276,"image":7277,"meta":13384,"navigation":1524,"path":7279,"seo":13385,"stem":7281,"tighten":7275,"__hash__":7282},{"type":8,"value":7388,"toc":13369},[7389,7391,7403,7411,7415,7417,7419,7421,7423,7438,7444,7462,7466,7470,7482,7492,7494,7496,7508,7510,7515,7517,7522,7524,7536,7626,7628,7640,7814,7820,7825,7827,7832,7868,7877,7882,7884,7888,7904,7916,7976,7984,7990,7994,8276,8282,8284,8310,8312,8462,8472,8480,8482,8648,8660,8664,8669,8675,8677,8679,8684,8694,8696,8702,9070,9072,9110,9114,9118,9126,9134,9136,9144,9312,9340,9344,10142,10154,10158,10160,10164,10166,10190,10280,10282,10294,10299,10303,10305,10313,10315,10721,10723,10757,10761,10766,10768,11154,11162,11170,11364,11372,11376,11440,11444,11472,11562,11566,11568,11572,11738,11748,11752,11756,11764,11918,11920,11922,12160,12162,12174,12348,12350,12352,12356,12358,12556,12560,12814,12818,13200,13202,13212,13217,13221,13223,13225,13237,13242,13262,13274,13294,13298,13300,13318,13320,13332,13334,13352,13354,13358,13360,13365,13367],[11,7390,13],{},[15,7392,7393],{"className":17,"code":18,"language":19,"meta":20,"style":20},[22,7394,7395],{"__ignoreMap":20},[25,7396,7397,7399,7401],{"class":27,"line":28},[25,7398,32],{"class":31},[25,7400,36],{"class":35},[25,7402,39],{"class":35},[11,7404,42,7405,47,7407,51,7409,55],{},[44,7406,46],{},[44,7408,50],{},[44,7410,54],{},[11,7412,58,7413,64],{},[60,7414,63],{"href":62},[11,7416,67],{},[11,7418,70],{},[72,7420,75],{"id":74},[11,7422,78],{},[11,7424,81,7425,84,7427,87,7429,91,7431,98,7434,102,7436,106],{},[44,7426,54],{},[44,7428,50],{},[44,7430,90],{},[60,7432,97],{"href":94,"rel":7433},[96],[22,7435,101],{},[22,7437,105],{},[11,7439,7440,111,7442,115],{},[44,7441,32],{},[22,7443,114],{},[11,7445,118,7446,122,7448,126,7450,130,7452,134,7454,138,7456,142,7458,146,7460,150],{},[22,7447,121],{},[44,7449,125],{},[22,7451,129],{},[22,7453,133],{},[22,7455,137],{},[22,7457,141],{},[22,7459,145],{},[22,7461,149],{},[11,7463,153,7464,157],{},[22,7465,156],{},[159,7467,7468],{},[11,7469,163],{},[11,7471,166,7472,91,7474,173,7476,177,7478,180,7480,183],{},[22,7473,169],{},[22,7475,172],{},[22,7477,176],{},[22,7479,129],{},[22,7481,141],{},[11,7483,186,7484,190,7486,193,7488,197,7490,200],{},[22,7485,189],{},[22,7487,189],{},[22,7489,196],{},[22,7491,196],{},[72,7493,204],{"id":203},[11,7495,207],{},[15,7497,7498],{"className":17,"code":210,"language":19,"meta":20,"style":20},[22,7499,7500],{"__ignoreMap":20},[25,7501,7502,7504,7506],{"class":27,"line":28},[25,7503,32],{"class":31},[25,7505,36],{"class":35},[25,7507,221],{"class":35},[11,7509,224],{},[15,7511,7513],{"className":7512,"code":229,"language":230,"meta":20},[228],[22,7514,229],{"__ignoreMap":20},[11,7516,235],{},[15,7518,7520],{"className":7519,"code":239,"language":230,"meta":20},[228],[22,7521,239],{"__ignoreMap":20},[11,7523,244],{},[15,7525,7526],{"className":17,"code":18,"language":19,"meta":20,"style":20},[22,7527,7528],{"__ignoreMap":20},[25,7529,7530,7532,7534],{"class":27,"line":28},[25,7531,32],{"class":31},[25,7533,36],{"class":35},[25,7535,39],{"class":35},[15,7537,7538],{"className":259,"code":260,"language":261,"meta":20,"style":20},[22,7539,7540,7544,7554,7564,7574,7584,7594,7604,7614,7622],{"__ignoreMap":20},[25,7541,7542],{"class":27,"line":28},[25,7543,269],{"class":268},[25,7545,7546,7548,7550,7552],{"class":27,"line":272},[25,7547,276],{"class":275},[25,7549,279],{"class":268},[25,7551,283],{"class":282},[25,7553,286],{"class":268},[25,7555,7556,7558,7560,7562],{"class":27,"line":289},[25,7557,292],{"class":275},[25,7559,279],{"class":268},[25,7561,298],{"class":297},[25,7563,286],{"class":268},[25,7565,7566,7568,7570,7572],{"class":27,"line":303},[25,7567,306],{"class":275},[25,7569,279],{"class":268},[25,7571,311],{"class":297},[25,7573,286],{"class":268},[25,7575,7576,7578,7580,7582],{"class":27,"line":316},[25,7577,319],{"class":275},[25,7579,279],{"class":268},[25,7581,324],{"class":282},[25,7583,286],{"class":268},[25,7585,7586,7588,7590,7592],{"class":27,"line":329},[25,7587,332],{"class":275},[25,7589,279],{"class":268},[25,7591,337],{"class":282},[25,7593,286],{"class":268},[25,7595,7596,7598,7600,7602],{"class":27,"line":342},[25,7597,345],{"class":275},[25,7599,279],{"class":268},[25,7601,350],{"class":282},[25,7603,286],{"class":268},[25,7605,7606,7608,7610,7612],{"class":27,"line":355},[25,7607,358],{"class":275},[25,7609,279],{"class":268},[25,7611,363],{"class":297},[25,7613,286],{"class":268},[25,7615,7616,7618,7620],{"class":27,"line":368},[25,7617,371],{"class":275},[25,7619,279],{"class":268},[25,7621,376],{"class":297},[25,7623,7624],{"class":27,"line":379},[25,7625,382],{"class":268},[11,7627,385],{},[15,7629,7630],{"className":17,"code":388,"language":19,"meta":20,"style":20},[22,7631,7632],{"__ignoreMap":20},[25,7633,7634,7636,7638],{"class":27,"line":28},[25,7635,32],{"class":31},[25,7637,36],{"class":35},[25,7639,399],{"class":35},[15,7641,7642],{"className":259,"code":402,"language":261,"meta":20,"style":20},[22,7643,7644,7648,7658,7668,7674,7678,7688,7698,7708,7718,7728,7736,7740,7744,7754,7764,7774,7784,7794,7802,7806,7810],{"__ignoreMap":20},[25,7645,7646],{"class":27,"line":28},[25,7647,269],{"class":268},[25,7649,7650,7652,7654,7656],{"class":27,"line":272},[25,7651,276],{"class":275},[25,7653,279],{"class":268},[25,7655,283],{"class":282},[25,7657,286],{"class":268},[25,7659,7660,7662,7664,7666],{"class":27,"line":289},[25,7661,292],{"class":275},[25,7663,279],{"class":268},[25,7665,298],{"class":297},[25,7667,286],{"class":268},[25,7669,7670,7672],{"class":27,"line":303},[25,7671,433],{"class":275},[25,7673,436],{"class":268},[25,7675,7676],{"class":27,"line":316},[25,7677,441],{"class":268},[25,7679,7680,7682,7684,7686],{"class":27,"line":329},[25,7681,446],{"class":275},[25,7683,279],{"class":268},[25,7685,311],{"class":297},[25,7687,286],{"class":268},[25,7689,7690,7692,7694,7696],{"class":27,"line":342},[25,7691,457],{"class":275},[25,7693,279],{"class":268},[25,7695,324],{"class":282},[25,7697,286],{"class":268},[25,7699,7700,7702,7704,7706],{"class":27,"line":355},[25,7701,468],{"class":275},[25,7703,279],{"class":268},[25,7705,337],{"class":282},[25,7707,286],{"class":268},[25,7709,7710,7712,7714,7716],{"class":27,"line":368},[25,7711,479],{"class":275},[25,7713,279],{"class":268},[25,7715,350],{"class":282},[25,7717,286],{"class":268},[25,7719,7720,7722,7724,7726],{"class":27,"line":379},[25,7721,490],{"class":275},[25,7723,279],{"class":268},[25,7725,363],{"class":297},[25,7727,286],{"class":268},[25,7729,7730,7732,7734],{"class":27,"line":499},[25,7731,502],{"class":275},[25,7733,279],{"class":268},[25,7735,376],{"class":297},[25,7737,7738],{"class":27,"line":509},[25,7739,512],{"class":268},[25,7741,7742],{"class":27,"line":515},[25,7743,441],{"class":268},[25,7745,7746,7748,7750,7752],{"class":27,"line":520},[25,7747,446],{"class":275},[25,7749,279],{"class":268},[25,7751,527],{"class":297},[25,7753,286],{"class":268},[25,7755,7756,7758,7760,7762],{"class":27,"line":532},[25,7757,457],{"class":275},[25,7759,279],{"class":268},[25,7761,539],{"class":282},[25,7763,286],{"class":268},[25,7765,7766,7768,7770,7772],{"class":27,"line":544},[25,7767,468],{"class":275},[25,7769,279],{"class":268},[25,7771,551],{"class":282},[25,7773,286],{"class":268},[25,7775,7776,7778,7780,7782],{"class":27,"line":556},[25,7777,479],{"class":275},[25,7779,279],{"class":268},[25,7781,563],{"class":282},[25,7783,286],{"class":268},[25,7785,7786,7788,7790,7792],{"class":27,"line":568},[25,7787,490],{"class":275},[25,7789,279],{"class":268},[25,7791,363],{"class":297},[25,7793,286],{"class":268},[25,7795,7796,7798,7800],{"class":27,"line":579},[25,7797,502],{"class":275},[25,7799,279],{"class":268},[25,7801,586],{"class":297},[25,7803,7804],{"class":27,"line":589},[25,7805,592],{"class":268},[25,7807,7808],{"class":27,"line":595},[25,7809,598],{"class":268},[25,7811,7812],{"class":27,"line":601},[25,7813,382],{"class":268},[11,7815,606,7816,610,7818,150],{},[22,7817,609],{},[22,7819,613],{},[11,7821,616,7822,150],{},[60,7823,621],{"href":619,"rel":7824},[96],[72,7826,625],{"id":624},[11,7828,628,7829,634],{},[60,7830,633],{"href":631,"rel":7831},[96],[636,7833,7834,7845,7854,7861],{},[639,7835,7836,648,7841,652,7843,656],{},[44,7837,7838],{},[60,7839,647],{"href":645,"rel":7840},[96],[22,7842,651],{},[22,7844,655],{},[639,7846,7847,666,7852,670],{},[44,7848,7849],{},[60,7850,665],{"href":663,"rel":7851},[96],[22,7853,669],{},[639,7855,7856,680],{},[44,7857,7858],{},[60,7859,679],{"href":677,"rel":7860},[96],[639,7862,7863,690],{},[44,7864,7865],{},[60,7866,689],{"href":687,"rel":7867},[96],[11,7869,693,7870,701,7875,705],{},[44,7871,7872],{},[60,7873,700],{"href":698,"rel":7874},[96],[22,7876,704],{},[11,7878,708,7879,714],{},[60,7880,713],{"href":711,"rel":7881},[96],[72,7883,718],{"id":717},[11,7885,721,7886,724],{},[22,7887,704],{},[15,7889,7890],{"className":17,"code":727,"language":19,"meta":20,"style":20},[22,7891,7892],{"__ignoreMap":20},[25,7893,7894,7896,7898,7900,7902],{"class":27,"line":28},[25,7895,734],{"class":31},[25,7897,737],{"class":282},[25,7899,740],{"class":35},[25,7901,744],{"class":743},[25,7903,747],{"class":31},[11,7905,750,7906,754,7908,758,7910,762,7912,766,7914,770],{},[22,7907,753],{},[22,7909,757],{},[22,7911,761],{},[22,7913,765],{},[22,7915,769],{},[15,7917,7918],{"className":17,"code":773,"language":19,"meta":20,"style":20},[22,7919,7920,7932,7938,7946,7960],{"__ignoreMap":20},[25,7921,7922,7924,7926,7928,7930],{"class":27,"line":28},[25,7923,780],{"class":31},[25,7925,783],{"class":35},[25,7927,786],{"class":268},[25,7929,790],{"class":789},[25,7931,793],{"class":35},[25,7933,7934,7936],{"class":27,"line":272},[25,7935,798],{"class":31},[25,7937,221],{"class":35},[25,7939,7940,7942,7944],{"class":27,"line":289},[25,7941,50],{"class":31},[25,7943,807],{"class":35},[25,7945,810],{"class":282},[25,7947,7948,7950,7952,7954,7956,7958],{"class":27,"line":303},[25,7949,50],{"class":31},[25,7951,817],{"class":35},[25,7953,820],{"class":35},[25,7955,823],{"class":35},[25,7957,826],{"class":35},[25,7959,829],{"class":35},[25,7961,7962,7964,7966,7968,7970,7972,7974],{"class":27,"line":316},[25,7963,50],{"class":31},[25,7965,817],{"class":35},[25,7967,838],{"class":282},[25,7969,841],{"class":35},[25,7971,844],{"class":35},[25,7973,847],{"class":35},[25,7975,850],{"class":35},[159,7977,7978],{},[11,7979,7980,858,7982,862],{},[22,7981,857],{},[22,7983,861],{},[11,7985,865,7986,868,7988,872],{},[22,7987,753],{},[22,7989,871],{},[11,7991,875,7992,879],{},[22,7993,878],{},[15,7995,7996],{"className":259,"code":882,"filename":878,"language":261,"meta":20,"style":20},[22,7997,7998,8002,8012,8022,8032,8042,8052,8058,8066,8070,8080,8086,8094,8098,8104,8114,8124,8134,8144,8154,8164,8172,8176,8182,8192,8202,8212,8220,8224,8230,8240,8250,8260,8268,8272],{"__ignoreMap":20},[25,7999,8000],{"class":27,"line":28},[25,8001,269],{"class":268},[25,8003,8004,8006,8008,8010],{"class":27,"line":272},[25,8005,893],{"class":275},[25,8007,279],{"class":268},[25,8009,898],{"class":297},[25,8011,286],{"class":268},[25,8013,8014,8016,8018,8020],{"class":27,"line":289},[25,8015,905],{"class":275},[25,8017,279],{"class":268},[25,8019,910],{"class":297},[25,8021,286],{"class":268},[25,8023,8024,8026,8028,8030],{"class":27,"line":303},[25,8025,917],{"class":275},[25,8027,279],{"class":268},[25,8029,922],{"class":297},[25,8031,286],{"class":268},[25,8033,8034,8036,8038,8040],{"class":27,"line":316},[25,8035,929],{"class":275},[25,8037,279],{"class":268},[25,8039,934],{"class":297},[25,8041,286],{"class":268},[25,8043,8044,8046,8048,8050],{"class":27,"line":329},[25,8045,941],{"class":275},[25,8047,279],{"class":268},[25,8049,946],{"class":297},[25,8051,286],{"class":268},[25,8053,8054,8056],{"class":27,"line":342},[25,8055,953],{"class":275},[25,8057,956],{"class":268},[25,8059,8060,8062,8064],{"class":27,"line":355},[25,8061,961],{"class":275},[25,8063,279],{"class":268},[25,8065,966],{"class":297},[25,8067,8068],{"class":27,"line":368},[25,8069,971],{"class":268},[25,8071,8072,8074,8076,8078],{"class":27,"line":379},[25,8073,976],{"class":275},[25,8075,979],{"class":268},[25,8077,982],{"class":297},[25,8079,985],{"class":268},[25,8081,8082,8084],{"class":27,"line":499},[25,8083,990],{"class":275},[25,8085,956],{"class":268},[25,8087,8088,8090,8092],{"class":27,"line":509},[25,8089,997],{"class":275},[25,8091,279],{"class":268},[25,8093,1002],{"class":297},[25,8095,8096],{"class":27,"line":515},[25,8097,971],{"class":268},[25,8099,8100,8102],{"class":27,"line":520},[25,8101,1011],{"class":275},[25,8103,956],{"class":268},[25,8105,8106,8108,8110,8112],{"class":27,"line":532},[25,8107,1018],{"class":275},[25,8109,279],{"class":268},[25,8111,1023],{"class":297},[25,8113,286],{"class":268},[25,8115,8116,8118,8120,8122],{"class":27,"line":544},[25,8117,1030],{"class":275},[25,8119,279],{"class":268},[25,8121,1035],{"class":297},[25,8123,286],{"class":268},[25,8125,8126,8128,8130,8132],{"class":27,"line":556},[25,8127,1042],{"class":275},[25,8129,279],{"class":268},[25,8131,1047],{"class":297},[25,8133,286],{"class":268},[25,8135,8136,8138,8140,8142],{"class":27,"line":568},[25,8137,1054],{"class":275},[25,8139,279],{"class":268},[25,8141,1059],{"class":297},[25,8143,286],{"class":268},[25,8145,8146,8148,8150,8152],{"class":27,"line":579},[25,8147,1066],{"class":275},[25,8149,279],{"class":268},[25,8151,1071],{"class":297},[25,8153,286],{"class":268},[25,8155,8156,8158,8160,8162],{"class":27,"line":589},[25,8157,1078],{"class":275},[25,8159,279],{"class":268},[25,8161,1083],{"class":297},[25,8163,286],{"class":268},[25,8165,8166,8168,8170],{"class":27,"line":595},[25,8167,1090],{"class":275},[25,8169,279],{"class":268},[25,8171,1095],{"class":297},[25,8173,8174],{"class":27,"line":601},[25,8175,971],{"class":268},[25,8177,8178,8180],{"class":27,"line":1102},[25,8179,1105],{"class":275},[25,8181,956],{"class":268},[25,8183,8184,8186,8188,8190],{"class":27,"line":1110},[25,8185,1113],{"class":275},[25,8187,279],{"class":268},[25,8189,1118],{"class":297},[25,8191,286],{"class":268},[25,8193,8194,8196,8198,8200],{"class":27,"line":1123},[25,8195,1126],{"class":275},[25,8197,279],{"class":268},[25,8199,1131],{"class":297},[25,8201,286],{"class":268},[25,8203,8204,8206,8208,8210],{"class":27,"line":1136},[25,8205,1139],{"class":275},[25,8207,279],{"class":268},[25,8209,1144],{"class":297},[25,8211,286],{"class":268},[25,8213,8214,8216,8218],{"class":27,"line":1149},[25,8215,1152],{"class":275},[25,8217,279],{"class":268},[25,8219,1157],{"class":297},[25,8221,8222],{"class":27,"line":1160},[25,8223,971],{"class":268},[25,8225,8226,8228],{"class":27,"line":1165},[25,8227,1168],{"class":275},[25,8229,956],{"class":268},[25,8231,8232,8234,8236,8238],{"class":27,"line":1173},[25,8233,1176],{"class":275},[25,8235,279],{"class":268},[25,8237,1181],{"class":297},[25,8239,286],{"class":268},[25,8241,8242,8244,8246,8248],{"class":27,"line":1186},[25,8243,1189],{"class":275},[25,8245,279],{"class":268},[25,8247,1194],{"class":297},[25,8249,286],{"class":268},[25,8251,8252,8254,8256,8258],{"class":27,"line":1199},[25,8253,1202],{"class":275},[25,8255,279],{"class":268},[25,8257,1207],{"class":297},[25,8259,286],{"class":268},[25,8261,8262,8264,8266],{"class":27,"line":1212},[25,8263,1215],{"class":275},[25,8265,279],{"class":268},[25,8267,1220],{"class":297},[25,8269,8270],{"class":27,"line":1223},[25,8271,1226],{"class":268},[25,8273,8274],{"class":27,"line":1229},[25,8275,382],{"class":268},[11,8277,1234,8278,1238,8280,1241],{},[22,8279,1237],{},[22,8281,156],{},[11,8283,1244],{},[636,8285,8286,8296,8304],{},[639,8287,8288,1252,8290,1256,8292,1260,8294,150],{},[22,8289,1251],{},[22,8291,1255],{},[22,8293,1259],{},[22,8295,129],{},[639,8297,8298,1268,8300,1271,8302,150],{},[22,8299,1267],{},[22,8301,189],{},[22,8303,1274],{},[639,8305,8306,1280,8308,1284],{},[22,8307,1279],{},[22,8309,1283],{},[11,8311,1287],{},[15,8313,8314],{"className":259,"code":1290,"filename":1291,"language":261,"meta":20,"style":20},[22,8315,8316,8320,8326,8336,8346,8356,8366,8376,8386,8396,8406,8416,8426,8436,8440,8458],{"__ignoreMap":20},[25,8317,8318],{"class":27,"line":28},[25,8319,269],{"class":268},[25,8321,8322,8324],{"class":27,"line":272},[25,8323,1302],{"class":275},[25,8325,956],{"class":268},[25,8327,8328,8330,8332,8334],{"class":27,"line":289},[25,8329,1309],{"class":275},[25,8331,279],{"class":268},[25,8333,1314],{"class":297},[25,8335,286],{"class":268},[25,8337,8338,8340,8342,8344],{"class":27,"line":303},[25,8339,1321],{"class":275},[25,8341,279],{"class":268},[25,8343,1326],{"class":297},[25,8345,286],{"class":268},[25,8347,8348,8350,8352,8354],{"class":27,"line":316},[25,8349,1333],{"class":275},[25,8351,279],{"class":268},[25,8353,1326],{"class":297},[25,8355,286],{"class":268},[25,8357,8358,8360,8362,8364],{"class":27,"line":329},[25,8359,1344],{"class":275},[25,8361,279],{"class":268},[25,8363,982],{"class":297},[25,8365,286],{"class":268},[25,8367,8368,8370,8372,8374],{"class":27,"line":342},[25,8369,1355],{"class":275},[25,8371,279],{"class":268},[25,8373,1360],{"class":297},[25,8375,286],{"class":268},[25,8377,8378,8380,8382,8384],{"class":27,"line":355},[25,8379,1367],{"class":275},[25,8381,279],{"class":268},[25,8383,283],{"class":282},[25,8385,286],{"class":268},[25,8387,8388,8390,8392,8394],{"class":27,"line":368},[25,8389,1378],{"class":275},[25,8391,279],{"class":268},[25,8393,283],{"class":282},[25,8395,286],{"class":268},[25,8397,8398,8400,8402,8404],{"class":27,"line":379},[25,8399,1389],{"class":275},[25,8401,279],{"class":268},[25,8403,283],{"class":282},[25,8405,286],{"class":268},[25,8407,8408,8410,8412,8414],{"class":27,"line":499},[25,8409,1400],{"class":275},[25,8411,279],{"class":268},[25,8413,283],{"class":282},[25,8415,286],{"class":268},[25,8417,8418,8420,8422,8424],{"class":27,"line":509},[25,8419,1411],{"class":275},[25,8421,279],{"class":268},[25,8423,283],{"class":282},[25,8425,286],{"class":268},[25,8427,8428,8430,8432,8434],{"class":27,"line":515},[25,8429,1422],{"class":275},[25,8431,979],{"class":268},[25,8433,1427],{"class":297},[25,8435,1430],{"class":268},[25,8437,8438],{"class":27,"line":520},[25,8439,971],{"class":268},[25,8441,8442,8444,8446,8448,8450,8452,8454,8456],{"class":27,"line":532},[25,8443,1439],{"class":275},[25,8445,979],{"class":268},[25,8447,1444],{"class":297},[25,8449,91],{"class":268},[25,8451,1449],{"class":297},[25,8453,91],{"class":268},[25,8455,1454],{"class":297},[25,8457,1430],{"class":268},[25,8459,8460],{"class":27,"line":544},[25,8461,382],{"class":268},[11,8463,1463,8464,1467,8466,1471,8468,1475,8470,1479],{},[22,8465,1466],{},[22,8467,1470],{},[22,8469,1474],{},[22,8471,1478],{},[11,8473,1482,8474,1486,8476,1490,8478,1494],{},[22,8475,1485],{},[22,8477,1489],{},[22,8479,1493],{},[11,8481,1497],{},[15,8483,8484],{"className":1500,"code":1501,"filename":1502,"language":1503,"meta":20,"style":20},[22,8485,8486,8496,8500,8510,8514,8522,8530,8542,8546,8550,8558,8562,8574,8578,8582,8586,8594,8602,8610,8618,8622,8626,8640,8644],{"__ignoreMap":20},[25,8487,8488,8490,8492,8494],{"class":27,"line":28},[25,8489,1510],{"class":743},[25,8491,1513],{"class":268},[25,8493,1516],{"class":743},[25,8495,1519],{"class":35},[25,8497,8498],{"class":27,"line":272},[25,8499,1525],{"emptyLinePlaceholder":1524},[25,8501,8502,8504,8506,8508],{"class":27,"line":289},[25,8503,1530],{"class":743},[25,8505,1533],{"class":743},[25,8507,1536],{"class":31},[25,8509,1539],{"class":268},[25,8511,8512],{"class":27,"line":303},[25,8513,1544],{"class":268},[25,8515,8516,8518,8520],{"class":27,"line":316},[25,8517,1549],{"class":268},[25,8519,1552],{"class":282},[25,8521,286],{"class":268},[25,8523,8524,8526,8528],{"class":27,"line":329},[25,8525,1559],{"class":268},[25,8527,283],{"class":282},[25,8529,286],{"class":268},[25,8531,8532,8534,8536,8538,8540],{"class":27,"line":342},[25,8533,1568],{"class":268},[25,8535,1571],{"class":35},[25,8537,91],{"class":268},[25,8539,1576],{"class":35},[25,8541,985],{"class":268},[25,8543,8544],{"class":27,"line":355},[25,8545,971],{"class":268},[25,8547,8548],{"class":27,"line":368},[25,8549,1587],{"class":268},[25,8551,8552,8554,8556],{"class":27,"line":379},[25,8553,1568],{"class":268},[25,8555,1571],{"class":35},[25,8557,985],{"class":268},[25,8559,8560],{"class":27,"line":499},[25,8561,1600],{"class":268},[25,8563,8564,8566,8568,8570,8572],{"class":27,"line":509},[25,8565,1605],{"class":268},[25,8567,1608],{"class":35},[25,8569,91],{"class":268},[25,8571,1613],{"class":35},[25,8573,985],{"class":268},[25,8575,8576],{"class":27,"line":515},[25,8577,512],{"class":268},[25,8579,8580],{"class":27,"line":520},[25,8581,971],{"class":268},[25,8583,8584],{"class":27,"line":532},[25,8585,1628],{"class":268},[25,8587,8588,8590,8592],{"class":27,"line":544},[25,8589,1633],{"class":268},[25,8591,1636],{"class":35},[25,8593,985],{"class":268},[25,8595,8596,8598,8600],{"class":27,"line":556},[25,8597,1643],{"class":268},[25,8599,1646],{"class":35},[25,8601,985],{"class":268},[25,8603,8604,8606,8608],{"class":27,"line":568},[25,8605,1653],{"class":268},[25,8607,1656],{"class":35},[25,8609,286],{"class":268},[25,8611,8612,8614,8616],{"class":27,"line":579},[25,8613,1663],{"class":268},[25,8615,1666],{"class":35},[25,8617,286],{"class":268},[25,8619,8620],{"class":27,"line":589},[25,8621,971],{"class":268},[25,8623,8624],{"class":27,"line":595},[25,8625,1677],{"class":268},[25,8627,8628,8630,8632,8634,8636,8638],{"class":27,"line":601},[25,8629,1682],{"class":35},[25,8631,979],{"class":268},[25,8633,1687],{"class":35},[25,8635,91],{"class":268},[25,8637,1692],{"class":35},[25,8639,985],{"class":268},[25,8641,8642],{"class":27,"line":1102},[25,8643,971],{"class":268},[25,8645,8646],{"class":27,"line":1110},[25,8647,1703],{"class":268},[11,8649,1706,8650,1710,8652,1714,8654,1718,8656,1721,8658,150],{},[22,8651,1709],{},[22,8653,1713],{},[22,8655,1717],{},[22,8657,196],{},[22,8659,857],{},[11,8661,1726,8662,770],{},[22,8663,1729],{},[15,8665,8667],{"className":8666,"code":1733,"filename":1729,"language":230,"meta":20},[228],[22,8668,1733],{"__ignoreMap":20},[11,8670,1738,8671,1741,8673,1744],{},[22,8672,857],{},[22,8674,196],{},[72,8676,1748],{"id":1747},[11,8678,1751],{},[15,8680,8682],{"className":8681,"code":1755,"language":230,"meta":20},[228],[22,8683,1755],{"__ignoreMap":20},[11,8685,1760,8686,1764,8688,1768,8690,1772,8692,1775],{},[44,8687,1763],{},[22,8689,1767],{},[22,8691,1771],{},[22,8693,1771],{},[72,8695,1779],{"id":1778},[11,8697,1782,8698,1786,8700,1789],{},[22,8699,1785],{},[22,8701,129],{},[15,8703,8704],{"className":1500,"code":1792,"filename":1713,"language":1503,"meta":20,"style":20},[22,8705,8706,8710,8714,8728,8738,8742,8770,8774,8790,8794,8804,8822,8836,8854,8884,8888,8894,8912,8916,8920,8924,8928,8942,8964,8968,8980,9000,9004,9008,9012,9034,9054,9066],{"__ignoreMap":20},[25,8707,8708],{"class":27,"line":28},[25,8709,1800],{"class":1799},[25,8711,8712],{"class":27,"line":272},[25,8713,1525],{"emptyLinePlaceholder":1524},[25,8715,8716,8718,8720,8722,8724,8726],{"class":27,"line":289},[25,8717,1510],{"class":743},[25,8719,1811],{"class":268},[25,8721,1814],{"class":743},[25,8723,1817],{"class":268},[25,8725,1516],{"class":743},[25,8727,1822],{"class":35},[25,8729,8730,8732,8734,8736],{"class":27,"line":303},[25,8731,1510],{"class":743},[25,8733,1829],{"class":268},[25,8735,1516],{"class":743},[25,8737,1834],{"class":35},[25,8739,8740],{"class":27,"line":316},[25,8741,1525],{"emptyLinePlaceholder":1524},[25,8743,8744,8746,8748,8750,8752,8754,8756,8758,8760,8762,8764,8766,8768],{"class":27,"line":329},[25,8745,1843],{"class":275},[25,8747,1846],{"class":268},[25,8749,770],{"class":743},[25,8751,1852],{"class":1851},[25,8753,1855],{"class":268},[25,8755,1858],{"class":275},[25,8757,91],{"class":268},[25,8759,1863],{"class":1851},[25,8761,1855],{"class":268},[25,8763,1868],{"class":275},[25,8765,1871],{"class":268},[25,8767,1874],{"class":743},[25,8769,1877],{"class":268},[25,8771,8772],{"class":27,"line":342},[25,8773,1525],{"emptyLinePlaceholder":1524},[25,8775,8776,8778,8780,8782,8784,8786,8788],{"class":27,"line":355},[25,8777,1843],{"class":275},[25,8779,1888],{"class":268},[25,8781,1874],{"class":743},[25,8783,1893],{"class":31},[25,8785,1896],{"class":268},[25,8787,1899],{"class":743},[25,8789,1902],{"class":268},[25,8791,8792],{"class":27,"line":368},[25,8793,1525],{"emptyLinePlaceholder":1524},[25,8795,8796,8798,8800,8802],{"class":27,"line":379},[25,8797,1911],{"class":743},[25,8799,1914],{"class":275},[25,8801,1917],{"class":31},[25,8803,1920],{"class":268},[25,8805,8806,8808,8810,8812,8814,8816,8818,8820],{"class":27,"line":499},[25,8807,1925],{"class":275},[25,8809,1928],{"class":268},[25,8811,1874],{"class":743},[25,8813,1933],{"class":268},[25,8815,1936],{"class":31},[25,8817,1939],{"class":268},[25,8819,1942],{"class":282},[25,8821,1945],{"class":268},[25,8823,8824,8826,8828,8830,8832,8834],{"class":27,"line":509},[25,8825,1925],{"class":275},[25,8827,1952],{"class":268},[25,8829,1899],{"class":743},[25,8831,1957],{"class":268},[25,8833,1874],{"class":743},[25,8835,1962],{"class":268},[25,8837,8838,8840,8842,8844,8846,8848,8850,8852],{"class":27,"line":515},[25,8839,1925],{"class":275},[25,8841,1969],{"class":268},[25,8843,1874],{"class":743},[25,8845,1974],{"class":268},[25,8847,862],{"class":743},[25,8849,1979],{"class":268},[25,8851,770],{"class":743},[25,8853,1984],{"class":282},[25,8855,8856,8858,8860,8862,8864,8866,8868,8870,8872,8874,8876,8878,8880,8882],{"class":27,"line":520},[25,8857,1925],{"class":275},[25,8859,1991],{"class":268},[25,8861,1874],{"class":743},[25,8863,1996],{"class":268},[25,8865,1999],{"class":31},[25,8867,1939],{"class":268},[25,8869,2004],{"class":35},[25,8871,2007],{"class":268},[25,8873,2010],{"class":743},[25,8875,1996],{"class":268},[25,8877,1999],{"class":31},[25,8879,1939],{"class":268},[25,8881,2019],{"class":35},[25,8883,1945],{"class":268},[25,8885,8886],{"class":27,"line":532},[25,8887,1525],{"emptyLinePlaceholder":1524},[25,8889,8890,8892],{"class":27,"line":544},[25,8891,2030],{"class":743},[25,8893,2033],{"class":268},[25,8895,8896,8898,8900,8902,8904,8906,8908,8910],{"class":27,"line":556},[25,8897,2038],{"class":743},[25,8899,2041],{"class":268},[25,8901,862],{"class":743},[25,8903,2046],{"class":31},[25,8905,2049],{"class":268},[25,8907,770],{"class":743},[25,8909,2046],{"class":31},[25,8911,2056],{"class":268},[25,8913,8914],{"class":27,"line":568},[25,8915,1525],{"emptyLinePlaceholder":1524},[25,8917,8918],{"class":27,"line":579},[25,8919,2065],{"class":743},[25,8921,8922],{"class":27,"line":589},[25,8923,1226],{"class":268},[25,8925,8926],{"class":27,"line":595},[25,8927,1525],{"emptyLinePlaceholder":1524},[25,8929,8930,8932,8934,8936,8938,8940],{"class":27,"line":601},[25,8931,1925],{"class":275},[25,8933,2080],{"class":268},[25,8935,1874],{"class":743},[25,8937,1969],{"class":268},[25,8939,2087],{"class":743},[25,8941,2090],{"class":268},[25,8943,8944,8946,8948,8950,8952,8954,8956,8958,8960,8962],{"class":27,"line":1102},[25,8945,1925],{"class":275},[25,8947,2097],{"class":268},[25,8949,1874],{"class":743},[25,8951,2102],{"class":743},[25,8953,2105],{"class":31},[25,8955,2108],{"class":268},[25,8957,862],{"class":743},[25,8959,2113],{"class":268},[25,8961,770],{"class":743},[25,8963,2118],{"class":268},[25,8965,8966],{"class":27,"line":1110},[25,8967,1525],{"emptyLinePlaceholder":1524},[25,8969,8970,8972,8974,8976,8978],{"class":27,"line":1123},[25,8971,2030],{"class":743},[25,8973,2129],{"class":268},[25,8975,2132],{"class":743},[25,8977,2135],{"class":282},[25,8979,2138],{"class":268},[25,8981,8982,8984,8986,8988,8990,8992,8994,8996,8998],{"class":27,"line":1136},[25,8983,2143],{"class":268},[25,8985,2146],{"class":31},[25,8987,2149],{"class":268},[25,8989,2152],{"class":31},[25,8991,2155],{"class":268},[25,8993,2158],{"class":282},[25,8995,91],{"class":268},[25,8997,1942],{"class":282},[25,8999,2165],{"class":268},[25,9001,9002],{"class":27,"line":1149},[25,9003,1226],{"class":268},[25,9005,9006],{"class":27,"line":1160},[25,9007,382],{"class":268},[25,9009,9010],{"class":27,"line":1165},[25,9011,1525],{"emptyLinePlaceholder":1524},[25,9013,9014,9016,9018,9020,9022,9024,9026,9028,9030,9032],{"class":27,"line":1173},[25,9015,2182],{"class":31},[25,9017,2185],{"class":268},[25,9019,2188],{"class":31},[25,9021,2191],{"class":268},[25,9023,2195],{"class":2194},[25,9025,770],{"class":743},[25,9027,2200],{"class":275},[25,9029,2007],{"class":268},[25,9031,2205],{"class":275},[25,9033,2208],{"class":268},[25,9035,9036,9038,9040,9042,9044,9046,9048,9050,9052],{"class":27,"line":1186},[25,9037,2213],{"class":268},[25,9039,2195],{"class":31},[25,9041,2218],{"class":268},[25,9043,2221],{"class":743},[25,9045,2224],{"class":1851},[25,9047,2227],{"class":743},[25,9049,2230],{"class":268},[25,9051,770],{"class":743},[25,9053,2235],{"class":268},[25,9055,9056,9058,9060,9062,9064],{"class":27,"line":1199},[25,9057,2240],{"class":268},[25,9059,2243],{"class":31},[25,9061,1939],{"class":268},[25,9063,2248],{"class":282},[25,9065,1945],{"class":268},[25,9067,9068],{"class":27,"line":1212},[25,9069,1703],{"class":268},[11,9071,2257],{},[636,9073,9074,9082,9086,9096,9104],{},[639,9075,2262,9076,2266,9078,2270,9080,2274],{},[22,9077,2265],{},[22,9079,2269],{},[22,9081,2273],{},[639,9083,9084,2280],{},[22,9085,2279],{},[639,9087,2283,9088,2287,9090,2291,9092,2295,9094,2298],{},[22,9089,2286],{},[22,9091,2290],{},[22,9093,2294],{},[22,9095,669],{},[639,9097,9098,2304,9100,2307,9102,2310],{},[22,9099,2303],{},[22,9101,2286],{},[22,9103,655],{},[639,9105,2313,9106,2317,9108,2321],{},[44,9107,2316],{},[22,9109,2320],{},[11,9111,2324,9112,2328],{},[22,9113,2327],{},[11,9115,2331,9116,2334],{},[22,9117,2188],{},[159,9119,9120],{},[11,9121,2339,9122,2343,9124,862],{},[22,9123,2342],{},[22,9125,2346],{},[11,9127,2349,9128,2353,9130,2358,9132,2362],{},[22,9129,2352],{},[2355,9131,2357],{},[22,9133,2361],{},[72,9135,2366],{"id":2365},[11,9137,2369,9138,2373,9140,2376,9142,2379],{},[22,9139,2372],{},[22,9141,2286],{},[22,9143,609],{},[15,9145,9146],{"className":1500,"code":2382,"filename":2383,"language":1503,"meta":20,"style":20},[22,9147,9148,9158,9168,9172,9184,9196,9200,9204,9212,9220,9228,9232,9236,9244,9252,9260,9264,9268,9286,9294,9298,9302,9306],{"__ignoreMap":20},[25,9149,9150,9152,9154,9156],{"class":27,"line":28},[25,9151,1510],{"class":743},[25,9153,2392],{"class":268},[25,9155,1516],{"class":743},[25,9157,1822],{"class":35},[25,9159,9160,9162,9164,9166],{"class":27,"line":272},[25,9161,1510],{"class":743},[25,9163,2403],{"class":268},[25,9165,1516],{"class":743},[25,9167,2408],{"class":35},[25,9169,9170],{"class":27,"line":289},[25,9171,1525],{"emptyLinePlaceholder":1524},[25,9173,9174,9176,9178,9180,9182],{"class":27,"line":303},[25,9175,1843],{"class":275},[25,9177,2419],{"class":268},[25,9179,1874],{"class":743},[25,9181,1893],{"class":31},[25,9183,1539],{"class":268},[25,9185,9186,9188,9190,9192,9194],{"class":27,"line":316},[25,9187,2430],{"class":268},[25,9189,2433],{"class":35},[25,9191,2436],{"class":268},[25,9193,2439],{"class":35},[25,9195,2442],{"class":268},[25,9197,9198],{"class":27,"line":329},[25,9199,2447],{"class":268},[25,9201,9202],{"class":27,"line":342},[25,9203,2452],{"class":268},[25,9205,9206,9208,9210],{"class":27,"line":355},[25,9207,2457],{"class":268},[25,9209,2460],{"class":35},[25,9211,286],{"class":268},[25,9213,9214,9216,9218],{"class":27,"line":368},[25,9215,2467],{"class":268},[25,9217,283],{"class":282},[25,9219,286],{"class":268},[25,9221,9222,9224,9226],{"class":27,"line":379},[25,9223,2476],{"class":268},[25,9225,2479],{"class":35},[25,9227,286],{"class":268},[25,9229,9230],{"class":27,"line":499},[25,9231,512],{"class":268},[25,9233,9234],{"class":27,"line":509},[25,9235,2490],{"class":268},[25,9237,9238,9240,9242],{"class":27,"line":515},[25,9239,2457],{"class":268},[25,9241,2497],{"class":35},[25,9243,286],{"class":268},[25,9245,9246,9248,9250],{"class":27,"line":520},[25,9247,2467],{"class":268},[25,9249,283],{"class":282},[25,9251,286],{"class":268},[25,9253,9254,9256,9258],{"class":27,"line":532},[25,9255,2476],{"class":268},[25,9257,2514],{"class":35},[25,9259,286],{"class":268},[25,9261,9262],{"class":27,"line":544},[25,9263,512],{"class":268},[25,9265,9266],{"class":27,"line":556},[25,9267,971],{"class":268},[25,9269,9270,9272,9274,9276,9278,9280,9282,9284],{"class":27,"line":568},[25,9271,2529],{"class":31},[25,9273,279],{"class":268},[25,9275,1911],{"class":743},[25,9277,2536],{"class":268},[25,9279,2539],{"class":2194},[25,9281,2542],{"class":268},[25,9283,2205],{"class":275},[25,9285,2208],{"class":268},[25,9287,9288,9290,9292],{"class":27,"line":579},[25,9289,2551],{"class":743},[25,9291,2554],{"class":31},[25,9293,2557],{"class":268},[25,9295,9296],{"class":27,"line":589},[25,9297,971],{"class":268},[25,9299,9300],{"class":27,"line":595},[25,9301,1703],{"class":268},[25,9303,9304],{"class":27,"line":601},[25,9305,1525],{"emptyLinePlaceholder":1524},[25,9307,9308,9310],{"class":27,"line":1102},[25,9309,1530],{"class":743},[25,9311,2576],{"class":268},[11,9313,2579,9314,2582,9316,2585,9318,2588,9320,2592,9322,2596,9324,2599,9326,1467,9328,2606,9330,2610,9332,2614,9334,2617,9336,2620,9338,2623],{},[22,9315,2539],{},[22,9317,2539],{},[22,9319,2182],{},[22,9321,2591],{},[22,9323,2595],{},[22,9325,1858],{},[22,9327,2602],{},[22,9329,2605],{},[22,9331,2609],{},[22,9333,2613],{},[22,9335,1858],{},[22,9337,2182],{},[22,9339,655],{},[11,9341,2626,9342,770],{},[22,9343,1771],{},[15,9345,9346],{"className":1500,"code":2631,"filename":2632,"language":1503,"meta":20,"style":20},[22,9347,9348,9382,9386,9400,9404,9436,9440,9468,9486,9498,9514,9518,9532,9560,9574,9578,9588,9610,9614,9618,9624,9628,9632,9654,9668,9672,9676,9680,9718,9734,9750,9758,9778,9820,9824,9852,9856,9860,9892,9904,9908,9914,9938,9942,9946,9950,9954,10000,10004,10008,10012,10050,10076,10080,10116,10120,10124,10130,10134],{"__ignoreMap":20},[25,9349,9350,9352,9354,9356,9358,9360,9362,9364,9366,9368,9370,9372,9374,9376,9378,9380],{"class":27,"line":28},[25,9351,1814],{"class":275},[25,9353,2641],{"class":1851},[25,9355,2644],{"class":743},[25,9357,2647],{"class":268},[25,9359,770],{"class":743},[25,9361,2652],{"class":275},[25,9363,2655],{"class":268},[25,9365,770],{"class":743},[25,9367,2652],{"class":275},[25,9369,2662],{"class":268},[25,9371,770],{"class":743},[25,9373,2667],{"class":275},[25,9375,2670],{"class":268},[25,9377,770],{"class":743},[25,9379,2667],{"class":275},[25,9381,2677],{"class":268},[25,9383,9384],{"class":27,"line":272},[25,9385,1525],{"emptyLinePlaceholder":1524},[25,9387,9388,9390,9392,9394,9396,9398],{"class":27,"line":289},[25,9389,1814],{"class":275},[25,9391,2688],{"class":1851},[25,9393,2644],{"class":743},[25,9395,2693],{"class":35},[25,9397,744],{"class":743},[25,9399,2698],{"class":35},[25,9401,9402],{"class":27,"line":303},[25,9403,1525],{"emptyLinePlaceholder":1524},[25,9405,9406,9408,9410,9412,9414,9416,9418,9420,9422,9424,9426,9428,9430,9432,9434],{"class":27,"line":316},[25,9407,1843],{"class":275},[25,9409,2709],{"class":268},[25,9411,770],{"class":743},[25,9413,1852],{"class":1851},[25,9415,1855],{"class":268},[25,9417,2718],{"class":1851},[25,9419,91],{"class":268},[25,9421,2723],{"class":275},[25,9423,2726],{"class":268},[25,9425,1874],{"class":743},[25,9427,2731],{"class":268},[25,9429,2734],{"class":282},[25,9431,2737],{"class":268},[25,9433,2740],{"class":282},[25,9435,2677],{"class":268},[25,9437,9438],{"class":27,"line":329},[25,9439,1525],{"emptyLinePlaceholder":1524},[25,9441,9442,9444,9446,9448,9450,9452,9454,9456,9458,9460,9462,9464,9466],{"class":27,"line":342},[25,9443,1911],{"class":743},[25,9445,1914],{"class":275},[25,9447,2755],{"class":31},[25,9449,1939],{"class":268},[25,9451,2760],{"class":2194},[25,9453,770],{"class":743},[25,9455,2652],{"class":275},[25,9457,2767],{"class":268},[25,9459,770],{"class":743},[25,9461,2772],{"class":1851},[25,9463,1855],{"class":268},[25,9465,2777],{"class":1851},[25,9467,2780],{"class":268},[25,9469,9470,9472,9474,9476,9478,9480,9482,9484],{"class":27,"line":355},[25,9471,1925],{"class":275},[25,9473,2787],{"class":268},[25,9475,1874],{"class":743},[25,9477,2792],{"class":743},[25,9479,2795],{"class":31},[25,9481,1939],{"class":268},[25,9483,2800],{"class":35},[25,9485,1945],{"class":268},[25,9487,9488,9490,9492,9494,9496],{"class":27,"line":368},[25,9489,2807],{"class":268},[25,9491,2810],{"class":31},[25,9493,1939],{"class":268},[25,9495,2815],{"class":35},[25,9497,2818],{"class":268},[25,9499,9500,9502,9504,9506,9508,9510,9512],{"class":27,"line":379},[25,9501,2807],{"class":268},[25,9503,2810],{"class":31},[25,9505,1939],{"class":268},[25,9507,2829],{"class":35},[25,9509,91],{"class":268},[25,9511,2834],{"class":35},[25,9513,1945],{"class":268},[25,9515,9516],{"class":27,"line":499},[25,9517,1525],{"emptyLinePlaceholder":1524},[25,9519,9520,9522,9524,9526,9528,9530],{"class":27,"line":509},[25,9521,1925],{"class":275},[25,9523,2847],{"class":268},[25,9525,1874],{"class":743},[25,9527,2102],{"class":743},[25,9529,2854],{"class":31},[25,9531,2857],{"class":268},[25,9533,9534,9536,9538,9540,9542,9544,9546,9548,9550,9552,9554,9556,9558],{"class":27,"line":515},[25,9535,1925],{"class":275},[25,9537,2864],{"class":268},[25,9539,1874],{"class":743},[25,9541,2869],{"class":268},[25,9543,2872],{"class":743},[25,9545,2875],{"class":268},[25,9547,261],{"class":31},[25,9549,2880],{"class":268},[25,9551,2883],{"class":743},[25,9553,2886],{"class":268},[25,9555,2889],{"class":743},[25,9557,2641],{"class":1851},[25,9559,2894],{"class":268},[25,9561,9562,9564,9566,9568,9570,9572],{"class":27,"line":520},[25,9563,1925],{"class":275},[25,9565,2901],{"class":268},[25,9567,1874],{"class":743},[25,9569,2906],{"class":268},[25,9571,2909],{"class":282},[25,9573,1430],{"class":268},[25,9575,9576],{"class":27,"line":532},[25,9577,1525],{"emptyLinePlaceholder":1524},[25,9579,9580,9582,9584,9586],{"class":27,"line":544},[25,9581,2030],{"class":743},[25,9583,2869],{"class":268},[25,9585,2924],{"class":743},[25,9587,2927],{"class":268},[25,9589,9590,9592,9594,9596,9598,9600,9602,9604,9606,9608],{"class":27,"line":556},[25,9591,2932],{"class":743},[25,9593,2792],{"class":743},[25,9595,2224],{"class":31},[25,9597,1939],{"class":268},[25,9599,2941],{"class":35},[25,9601,2944],{"class":743},[25,9603,2760],{"class":268},[25,9605,2949],{"class":743},[25,9607,2952],{"class":35},[25,9609,1945],{"class":268},[25,9611,9612],{"class":27,"line":568},[25,9613,1226],{"class":268},[25,9615,9616],{"class":27,"line":579},[25,9617,1525],{"emptyLinePlaceholder":1524},[25,9619,9620,9622],{"class":27,"line":589},[25,9621,2967],{"class":743},[25,9623,2970],{"class":268},[25,9625,9626],{"class":27,"line":595},[25,9627,382],{"class":268},[25,9629,9630],{"class":27,"line":601},[25,9631,1525],{"emptyLinePlaceholder":1524},[25,9633,9634,9636,9638,9640,9642,9644,9646,9648,9650,9652],{"class":27,"line":1102},[25,9635,2983],{"class":275},[25,9637,2986],{"class":31},[25,9639,1939],{"class":268},[25,9641,2991],{"class":2194},[25,9643,770],{"class":743},[25,9645,2667],{"class":275},[25,9647,2767],{"class":268},[25,9649,770],{"class":743},[25,9651,2667],{"class":275},[25,9653,2208],{"class":268},[25,9655,9656,9658,9660,9662,9664,9666],{"class":27,"line":1110},[25,9657,2967],{"class":743},[25,9659,3010],{"class":268},[25,9661,3013],{"class":743},[25,9663,3016],{"class":268},[25,9665,3019],{"class":743},[25,9667,3022],{"class":282},[25,9669,9670],{"class":27,"line":1123},[25,9671,382],{"class":268},[25,9673,9674],{"class":27,"line":1136},[25,9675,1525],{"emptyLinePlaceholder":1524},[25,9677,9678],{"class":27,"line":1149},[25,9679,3035],{"class":1799},[25,9681,9682,9684,9686,9688,9690,9692,9694,9696,9698,9700,9702,9704,9706,9708,9710,9712,9714,9716],{"class":27,"line":1160},[25,9683,2983],{"class":275},[25,9685,3042],{"class":31},[25,9687,1939],{"class":268},[25,9689,60],{"class":2194},[25,9691,770],{"class":743},[25,9693,2641],{"class":1851},[25,9695,91],{"class":268},[25,9697,3055],{"class":2194},[25,9699,770],{"class":743},[25,9701,2641],{"class":1851},[25,9703,91],{"class":268},[25,9705,3064],{"class":2194},[25,9707,770],{"class":743},[25,9709,2688],{"class":1851},[25,9711,2767],{"class":268},[25,9713,770],{"class":743},[25,9715,2667],{"class":275},[25,9717,2208],{"class":268},[25,9719,9720,9722,9724,9726,9728,9730,9732],{"class":27,"line":1165},[25,9721,1925],{"class":275},[25,9723,3083],{"class":268},[25,9725,1874],{"class":743},[25,9727,2986],{"class":31},[25,9729,3090],{"class":268},[25,9731,3093],{"class":743},[25,9733,3096],{"class":268},[25,9735,9736,9738,9740,9742,9744,9746,9748],{"class":27,"line":1173},[25,9737,1925],{"class":275},[25,9739,3103],{"class":268},[25,9741,1874],{"class":743},[25,9743,2986],{"class":31},[25,9745,3110],{"class":268},[25,9747,3093],{"class":743},[25,9749,3115],{"class":268},[25,9751,9752,9754,9756],{"class":27,"line":1186},[25,9753,1925],{"class":275},[25,9755,3122],{"class":268},[25,9757,3125],{"class":743},[25,9759,9760,9762,9764,9766,9768,9770,9772,9774,9776],{"class":27,"line":1199},[25,9761,3130],{"class":268},[25,9763,3133],{"class":31},[25,9765,3136],{"class":268},[25,9767,3019],{"class":743},[25,9769,3141],{"class":282},[25,9771,2007],{"class":268},[25,9773,3146],{"class":743},[25,9775,3141],{"class":282},[25,9777,3151],{"class":743},[25,9779,9780,9782,9784,9786,9788,9790,9792,9794,9796,9798,9800,9802,9804,9806,9808,9810,9812,9814,9816,9818],{"class":27,"line":1212},[25,9781,3130],{"class":268},[25,9783,3158],{"class":31},[25,9785,1939],{"class":268},[25,9787,3163],{"class":31},[25,9789,3166],{"class":268},[25,9791,3013],{"class":743},[25,9793,3171],{"class":268},[25,9795,3158],{"class":31},[25,9797,1939],{"class":268},[25,9799,3163],{"class":31},[25,9801,3180],{"class":268},[25,9803,3013],{"class":743},[25,9805,3171],{"class":268},[25,9807,3133],{"class":31},[25,9809,3189],{"class":268},[25,9811,3019],{"class":743},[25,9813,3141],{"class":282},[25,9815,2007],{"class":268},[25,9817,3146],{"class":743},[25,9819,3200],{"class":282},[25,9821,9822],{"class":27,"line":1223},[25,9823,1525],{"emptyLinePlaceholder":1524},[25,9825,9826,9828,9830,9832,9834,9836,9838,9840,9842,9844,9846,9848,9850],{"class":27,"line":1229},[25,9827,2967],{"class":743},[25,9829,3171],{"class":268},[25,9831,3213],{"class":31},[25,9833,1939],{"class":268},[25,9835,1942],{"class":282},[25,9837,3220],{"class":743},[25,9839,3223],{"class":268},[25,9841,3013],{"class":743},[25,9843,3171],{"class":268},[25,9845,3230],{"class":31},[25,9847,3233],{"class":268},[25,9849,3236],{"class":31},[25,9851,3239],{"class":268},[25,9853,9854],{"class":27,"line":3242},[25,9855,382],{"class":268},[25,9857,9858],{"class":27,"line":3247},[25,9859,1525],{"emptyLinePlaceholder":1524},[25,9861,9862,9864,9866,9868,9870,9872,9874,9876,9878,9880,9882,9884,9886,9888,9890],{"class":27,"line":3252},[25,9863,2983],{"class":275},[25,9865,3257],{"class":31},[25,9867,1939],{"class":268},[25,9869,3262],{"class":2194},[25,9871,770],{"class":743},[25,9873,2641],{"class":1851},[25,9875,91],{"class":268},[25,9877,1516],{"class":2194},[25,9879,770],{"class":743},[25,9881,2641],{"class":1851},[25,9883,91],{"class":268},[25,9885,3064],{"class":2194},[25,9887,770],{"class":743},[25,9889,2688],{"class":1851},[25,9891,2138],{"class":268},[25,9893,9894,9896,9898,9900,9902],{"class":27,"line":3287},[25,9895,1925],{"class":275},[25,9897,3292],{"class":268},[25,9899,1874],{"class":743},[25,9901,3042],{"class":31},[25,9903,3299],{"class":268},[25,9905,9906],{"class":27,"line":3302},[25,9907,1525],{"emptyLinePlaceholder":1524},[25,9909,9910,9912],{"class":27,"line":3307},[25,9911,2967],{"class":743},[25,9913,2208],{"class":268},[25,9915,9916,9918,9920,9922,9924,9926,9928,9930,9932,9934,9936],{"class":27,"line":3314},[25,9917,3317],{"class":268},[25,9919,3320],{"class":35},[25,9921,2944],{"class":743},[25,9923,3325],{"class":268},[25,9925,2949],{"class":743},[25,9927,91],{"class":35},[25,9929,2944],{"class":743},[25,9931,3334],{"class":268},[25,9933,2949],{"class":743},[25,9935,3320],{"class":35},[25,9937,286],{"class":268},[25,9939,9940],{"class":27,"line":3343},[25,9941,3346],{"class":268},[25,9943,9944],{"class":27,"line":3349},[25,9945,3352],{"class":268},[25,9947,9948],{"class":27,"line":3355},[25,9949,3358],{"class":268},[25,9951,9952],{"class":27,"line":3361},[25,9953,3364],{"class":268},[25,9955,9956,9958,9960,9962,9964,9966,9968,9970,9972,9974,9976,9978,9980,9982,9984,9986,9988,9990,9992,9994,9996,9998],{"class":27,"line":3367},[25,9957,3370],{"class":268},[25,9959,3320],{"class":35},[25,9961,2944],{"class":743},[25,9963,3325],{"class":268},[25,9965,2949],{"class":743},[25,9967,3381],{"class":35},[25,9969,2944],{"class":743},[25,9971,3386],{"class":268},[25,9973,3389],{"class":31},[25,9975,1939],{"class":268},[25,9977,3394],{"class":35},[25,9979,2767],{"class":268},[25,9981,2949],{"class":743},[25,9983,3401],{"class":743},[25,9985,3064],{"class":268},[25,9987,2949],{"class":743},[25,9989,3408],{"class":35},[25,9991,2944],{"class":743},[25,9993,3413],{"class":268},[25,9995,2949],{"class":743},[25,9997,3320],{"class":35},[25,9999,286],{"class":268},[25,10001,10002],{"class":27,"line":3422},[25,10003,1226],{"class":268},[25,10005,10006],{"class":27,"line":3427},[25,10007,382],{"class":268},[25,10009,10010],{"class":27,"line":3432},[25,10011,1525],{"emptyLinePlaceholder":1524},[25,10013,10014,10016,10018,10020,10022,10024,10026,10028,10030,10032,10034,10036,10038,10040,10042,10044,10046,10048],{"class":27,"line":3437},[25,10015,1911],{"class":743},[25,10017,1914],{"class":275},[25,10019,2554],{"class":31},[25,10021,1939],{"class":268},[25,10023,2760],{"class":2194},[25,10025,770],{"class":743},[25,10027,2652],{"class":275},[25,10029,91],{"class":268},[25,10031,1516],{"class":2194},[25,10033,770],{"class":743},[25,10035,2652],{"class":275},[25,10037,91],{"class":268},[25,10039,3064],{"class":2194},[25,10041,770],{"class":743},[25,10043,2688],{"class":1851},[25,10045,2644],{"class":743},[25,10047,2693],{"class":35},[25,10049,2138],{"class":268},[25,10051,10052,10054,10056,10058,10060,10062,10064,10066,10068,10070,10072,10074],{"class":27,"line":3476},[25,10053,1925],{"class":275},[25,10055,3481],{"class":268},[25,10057,1874],{"class":743},[25,10059,2102],{"class":743},[25,10061,2772],{"class":275},[25,10063,150],{"class":268},[25,10065,3492],{"class":31},[25,10067,3495],{"class":268},[25,10069,3498],{"class":31},[25,10071,3501],{"class":268},[25,10073,3498],{"class":31},[25,10075,3506],{"class":268},[25,10077,10078],{"class":27,"line":3509},[25,10079,1525],{"emptyLinePlaceholder":1524},[25,10081,10082,10084,10086,10088,10090,10092,10094,10096,10098,10100,10102,10104,10106,10108,10110,10112,10114],{"class":27,"line":3514},[25,10083,2967],{"class":743},[25,10085,3519],{"class":268},[25,10087,283],{"class":282},[25,10089,3524],{"class":268},[25,10091,3320],{"class":35},[25,10093,2944],{"class":743},[25,10095,3531],{"class":268},[25,10097,2949],{"class":743},[25,10099,91],{"class":35},[25,10101,2944],{"class":743},[25,10103,3540],{"class":268},[25,10105,2949],{"class":743},[25,10107,3320],{"class":35},[25,10109,91],{"class":268},[25,10111,1899],{"class":743},[25,10113,3551],{"class":31},[25,10115,3554],{"class":268},[25,10117,10118],{"class":27,"line":3557},[25,10119,382],{"class":268},[25,10121,10122],{"class":27,"line":3562},[25,10123,1525],{"emptyLinePlaceholder":1524},[25,10125,10126,10128],{"class":27,"line":3567},[25,10127,1530],{"class":743},[25,10129,3572],{"class":268},[25,10131,10132],{"class":27,"line":3575},[25,10133,1525],{"emptyLinePlaceholder":1524},[25,10135,10136,10138,10140],{"class":27,"line":3580},[25,10137,1530],{"class":743},[25,10139,3585],{"class":743},[25,10141,3588],{"class":268},[11,10143,3591,10144,3595,10146,3599,10148,3602,10150,3606,10152,3610],{},[22,10145,3594],{},[44,10147,3598],{},[22,10149,3163],{},[22,10151,3605],{},[22,10153,3609],{},[159,10155,10156],{},[11,10157,3615],{},[11,10159,3618],{},[11,10161,3621,10162,3625],{},[22,10163,3624],{},[11,10165,3628],{},[15,10167,10168],{"className":17,"code":3631,"language":19,"meta":20,"style":20},[22,10169,10170,10178],{"__ignoreMap":20},[25,10171,10172,10174,10176],{"class":27,"line":28},[25,10173,50],{"class":31},[25,10175,1917],{"class":35},[25,10177,3642],{"class":35},[25,10179,10180,10182,10184,10186,10188],{"class":27,"line":272},[25,10181,2269],{"class":31},[25,10183,3649],{"class":35},[25,10185,3652],{"class":35},[25,10187,3655],{"class":282},[25,10189,3658],{"class":35},[15,10191,10192],{"className":259,"code":260,"language":261,"meta":20,"style":20},[22,10193,10194,10198,10208,10218,10228,10238,10248,10258,10268,10276],{"__ignoreMap":20},[25,10195,10196],{"class":27,"line":28},[25,10197,269],{"class":268},[25,10199,10200,10202,10204,10206],{"class":27,"line":272},[25,10201,276],{"class":275},[25,10203,279],{"class":268},[25,10205,283],{"class":282},[25,10207,286],{"class":268},[25,10209,10210,10212,10214,10216],{"class":27,"line":289},[25,10211,292],{"class":275},[25,10213,279],{"class":268},[25,10215,298],{"class":297},[25,10217,286],{"class":268},[25,10219,10220,10222,10224,10226],{"class":27,"line":303},[25,10221,306],{"class":275},[25,10223,279],{"class":268},[25,10225,311],{"class":297},[25,10227,286],{"class":268},[25,10229,10230,10232,10234,10236],{"class":27,"line":316},[25,10231,319],{"class":275},[25,10233,279],{"class":268},[25,10235,324],{"class":282},[25,10237,286],{"class":268},[25,10239,10240,10242,10244,10246],{"class":27,"line":329},[25,10241,332],{"class":275},[25,10243,279],{"class":268},[25,10245,337],{"class":282},[25,10247,286],{"class":268},[25,10249,10250,10252,10254,10256],{"class":27,"line":342},[25,10251,345],{"class":275},[25,10253,279],{"class":268},[25,10255,350],{"class":282},[25,10257,286],{"class":268},[25,10259,10260,10262,10264,10266],{"class":27,"line":355},[25,10261,358],{"class":275},[25,10263,279],{"class":268},[25,10265,363],{"class":297},[25,10267,286],{"class":268},[25,10269,10270,10272,10274],{"class":27,"line":368},[25,10271,371],{"class":275},[25,10273,279],{"class":268},[25,10275,376],{"class":297},[25,10277,10278],{"class":27,"line":379},[25,10279,382],{"class":268},[11,10281,3751],{},[15,10283,10284],{"className":17,"code":3754,"language":19,"meta":20,"style":20},[22,10285,10286],{"__ignoreMap":20},[25,10287,10288,10290,10292],{"class":27,"line":28},[25,10289,2269],{"class":31},[25,10291,3649],{"class":35},[25,10293,3765],{"class":282},[15,10295,10297],{"className":10296,"code":3769,"language":230,"meta":20},[228],[22,10298,3769],{"__ignoreMap":20},[11,10300,3774,10301,3777],{},[22,10302,2372],{},[72,10304,3781],{"id":3780},[11,10306,3784,10307,3788,10309,3791,10311,3794],{},[22,10308,3787],{},[22,10310,609],{},[22,10312,669],{},[11,10314,3797],{},[15,10316,10317],{"className":1500,"code":3800,"filename":3801,"language":1503,"meta":20,"style":20},[22,10318,10319,10329,10339,10343,10347,10357,10361,10375,10383,10407,10411,10415,10435,10439,10457,10469,10473,10483,10489,10493,10497,10511,10515,10525,10553,10557,10561,10567,10571,10575,10591,10603,10617,10621,10631,10645,10649,10653,10665,10669,10673,10689,10695,10699,10703,10709,10713],{"__ignoreMap":20},[25,10320,10321,10323,10325,10327],{"class":27,"line":28},[25,10322,1510],{"class":743},[25,10324,3810],{"class":268},[25,10326,1516],{"class":743},[25,10328,3815],{"class":35},[25,10330,10331,10333,10335,10337],{"class":27,"line":272},[25,10332,1510],{"class":743},[25,10334,3822],{"class":268},[25,10336,1516],{"class":743},[25,10338,3827],{"class":35},[25,10340,10341],{"class":27,"line":289},[25,10342,1525],{"emptyLinePlaceholder":1524},[25,10344,10345],{"class":27,"line":303},[25,10346,3836],{"class":1799},[25,10348,10349,10351,10353,10355],{"class":27,"line":316},[25,10350,1843],{"class":275},[25,10352,3843],{"class":268},[25,10354,1874],{"class":743},[25,10356,3848],{"class":35},[25,10358,10359],{"class":27,"line":329},[25,10360,1525],{"emptyLinePlaceholder":1524},[25,10362,10363,10365,10367,10369,10371,10373],{"class":27,"line":342},[25,10364,1843],{"class":275},[25,10366,3859],{"class":268},[25,10368,1874],{"class":743},[25,10370,3864],{"class":268},[25,10372,3867],{"class":31},[25,10374,1539],{"class":268},[25,10376,10377,10379,10381],{"class":27,"line":355},[25,10378,3874],{"class":268},[25,10380,1858],{"class":31},[25,10382,3879],{"class":268},[25,10384,10385,10387,10389,10391,10393,10395,10397,10399,10401,10403,10405],{"class":27,"line":368},[25,10386,3884],{"class":268},[25,10388,3887],{"class":31},[25,10390,3495],{"class":268},[25,10392,3892],{"class":35},[25,10394,91],{"class":268},[25,10396,3897],{"class":35},[25,10398,3900],{"class":268},[25,10400,3903],{"class":31},[25,10402,1939],{"class":268},[25,10404,3892],{"class":35},[25,10406,3910],{"class":268},[25,10408,10409],{"class":27,"line":379},[25,10410,1703],{"class":268},[25,10412,10413],{"class":27,"line":499},[25,10414,1525],{"emptyLinePlaceholder":1524},[25,10416,10417,10419,10421,10423,10425,10427,10429,10431,10433],{"class":27,"line":509},[25,10418,1814],{"class":275},[25,10420,3925],{"class":1851},[25,10422,2644],{"class":743},[25,10424,3930],{"class":1851},[25,10426,150],{"class":268},[25,10428,3935],{"class":1851},[25,10430,1855],{"class":268},[25,10432,3940],{"class":743},[25,10434,3943],{"class":268},[25,10436,10437],{"class":27,"line":515},[25,10438,1525],{"emptyLinePlaceholder":1524},[25,10440,10441,10443,10445,10447,10449,10451,10453,10455],{"class":27,"line":520},[25,10442,2983],{"class":275},[25,10444,3954],{"class":31},[25,10446,3957],{"class":268},[25,10448,770],{"class":743},[25,10450,3925],{"class":1851},[25,10452,744],{"class":743},[25,10454,3966],{"class":275},[25,10456,2208],{"class":268},[25,10458,10459,10461,10463,10465,10467],{"class":27,"line":532},[25,10460,1925],{"class":275},[25,10462,3975],{"class":268},[25,10464,1874],{"class":743},[25,10466,3980],{"class":31},[25,10468,3983],{"class":268},[25,10470,10471],{"class":27,"line":544},[25,10472,1525],{"emptyLinePlaceholder":1524},[25,10474,10475,10477,10479,10481],{"class":27,"line":556},[25,10476,2030],{"class":743},[25,10478,2869],{"class":268},[25,10480,2924],{"class":743},[25,10482,3998],{"class":268},[25,10484,10485,10487],{"class":27,"line":568},[25,10486,2551],{"class":743},[25,10488,4005],{"class":282},[25,10490,10491],{"class":27,"line":579},[25,10492,1226],{"class":268},[25,10494,10495],{"class":27,"line":589},[25,10496,1525],{"emptyLinePlaceholder":1524},[25,10498,10499,10501,10503,10505,10507,10509],{"class":27,"line":595},[25,10500,1925],{"class":275},[25,10502,4020],{"class":268},[25,10504,1874],{"class":743},[25,10506,4025],{"class":268},[25,10508,4028],{"class":31},[25,10510,4031],{"class":268},[25,10512,10513],{"class":27,"line":601},[25,10514,1525],{"emptyLinePlaceholder":1524},[25,10516,10517,10519,10521,10523],{"class":27,"line":1102},[25,10518,2030],{"class":743},[25,10520,2869],{"class":268},[25,10522,2924],{"class":743},[25,10524,4046],{"class":268},[25,10526,10527,10529,10531,10533,10535,10537,10539,10541,10543,10545,10547,10549,10551],{"class":27,"line":1110},[25,10528,2932],{"class":743},[25,10530,2792],{"class":743},[25,10532,2224],{"class":31},[25,10534,1939],{"class":268},[25,10536,4059],{"class":35},[25,10538,4062],{"class":282},[25,10540,2944],{"class":743},[25,10542,4067],{"class":268},[25,10544,4070],{"class":31},[25,10546,4073],{"class":268},[25,10548,2949],{"class":743},[25,10550,3320],{"class":35},[25,10552,1945],{"class":268},[25,10554,10555],{"class":27,"line":1123},[25,10556,1226],{"class":268},[25,10558,10559],{"class":27,"line":1136},[25,10560,1525],{"emptyLinePlaceholder":1524},[25,10562,10563,10565],{"class":27,"line":1149},[25,10564,2967],{"class":743},[25,10566,4094],{"class":268},[25,10568,10569],{"class":27,"line":1160},[25,10570,382],{"class":268},[25,10572,10573],{"class":27,"line":1165},[25,10574,1525],{"emptyLinePlaceholder":1524},[25,10576,10577,10579,10581,10583,10585,10587,10589],{"class":27,"line":1173},[25,10578,2983],{"class":275},[25,10580,4109],{"class":31},[25,10582,1939],{"class":268},[25,10584,1516],{"class":2194},[25,10586,2889],{"class":743},[25,10588,2652],{"class":275},[25,10590,2138],{"class":268},[25,10592,10593,10595,10597,10599,10601],{"class":27,"line":1186},[25,10594,1925],{"class":275},[25,10596,4126],{"class":268},[25,10598,1874],{"class":743},[25,10600,3954],{"class":31},[25,10602,4133],{"class":268},[25,10604,10605,10607,10609,10611,10613,10615],{"class":27,"line":1199},[25,10606,1925],{"class":275},[25,10608,4140],{"class":268},[25,10610,1874],{"class":743},[25,10612,3408],{"class":268},[25,10614,2087],{"class":743},[25,10616,4149],{"class":268},[25,10618,10619],{"class":27,"line":1212},[25,10620,1525],{"emptyLinePlaceholder":1524},[25,10622,10623,10625,10627,10629],{"class":27,"line":1223},[25,10624,2030],{"class":743},[25,10626,2869],{"class":268},[25,10628,2924],{"class":743},[25,10630,4164],{"class":268},[25,10632,10633,10635,10637,10639,10641,10643],{"class":27,"line":1229},[25,10634,2932],{"class":743},[25,10636,2792],{"class":743},[25,10638,2224],{"class":31},[25,10640,1939],{"class":268},[25,10642,4177],{"class":35},[25,10644,1945],{"class":268},[25,10646,10647],{"class":27,"line":3242},[25,10648,1226],{"class":268},[25,10650,10651],{"class":27,"line":3247},[25,10652,1525],{"emptyLinePlaceholder":1524},[25,10654,10655,10657,10659,10661,10663],{"class":27,"line":3252},[25,10656,2967],{"class":743},[25,10658,4194],{"class":268},[25,10660,2087],{"class":743},[25,10662,2693],{"class":35},[25,10664,2677],{"class":268},[25,10666,10667],{"class":27,"line":3287},[25,10668,382],{"class":268},[25,10670,10671],{"class":27,"line":3302},[25,10672,1525],{"emptyLinePlaceholder":1524},[25,10674,10675,10677,10679,10681,10683,10685,10687],{"class":27,"line":3307},[25,10676,2983],{"class":275},[25,10678,4215],{"class":31},[25,10680,1939],{"class":268},[25,10682,4220],{"class":2194},[25,10684,770],{"class":743},[25,10686,3925],{"class":1851},[25,10688,2138],{"class":268},[25,10690,10691,10693],{"class":27,"line":3314},[25,10692,4231],{"class":31},[25,10694,4234],{"class":268},[25,10696,10697],{"class":27,"line":3343},[25,10698,382],{"class":268},[25,10700,10701],{"class":27,"line":3349},[25,10702,1525],{"emptyLinePlaceholder":1524},[25,10704,10705,10707],{"class":27,"line":3355},[25,10706,1530],{"class":743},[25,10708,4249],{"class":268},[25,10710,10711],{"class":27,"line":3361},[25,10712,1525],{"emptyLinePlaceholder":1524},[25,10714,10715,10717,10719],{"class":27,"line":3367},[25,10716,1530],{"class":743},[25,10718,3585],{"class":743},[25,10720,4262],{"class":268},[11,10722,4265],{},[636,10724,10725,10735,10743,10751],{},[639,10726,10727,4273,10729,4277,10731,4281,10733,4285],{},[22,10728,4272],{},[22,10730,4276],{},[22,10732,4280],{},[22,10734,4284],{},[639,10736,4288,10737,4291,10739,4295,10741,4299],{},[22,10738,4028],{},[22,10740,4294],{},[22,10742,4298],{},[639,10744,10745,4305,10747,4308,10749,4311],{},[22,10746,4304],{},[22,10748,2158],{},[22,10750,669],{},[639,10752,10753,4317,10755,4320],{},[22,10754,4316],{},[22,10756,609],{},[11,10758,4323,10759,770],{},[22,10760,4298],{},[15,10762,10764],{"className":10763,"code":4329,"language":230,"meta":20},[228],[22,10765,4329],{"__ignoreMap":20},[11,10767,4334],{},[15,10769,10770],{"className":1500,"code":4337,"filename":4338,"language":1503,"meta":20,"style":20},[22,10771,10772,10782,10792,10802,10806,10826,10840,10844,10848,10858,10868,10872,10884,10888,10902,10910,10918,10928,10932,10936,10946,10958,10962,10966,10980,10988,10992,11004,11016,11020,11030,11034,11044,11056,11060,11064,11070,11074,11086,11096,11100,11104,11116,11128,11140,11144,11148],{"__ignoreMap":20},[25,10773,10774,10776,10778,10780],{"class":27,"line":28},[25,10775,1510],{"class":743},[25,10777,2392],{"class":268},[25,10779,1516],{"class":743},[25,10781,1822],{"class":35},[25,10783,10784,10786,10788,10790],{"class":27,"line":272},[25,10785,1510],{"class":743},[25,10787,4357],{"class":268},[25,10789,1516],{"class":743},[25,10791,4362],{"class":35},[25,10793,10794,10796,10798,10800],{"class":27,"line":289},[25,10795,1510],{"class":743},[25,10797,4369],{"class":268},[25,10799,1516],{"class":743},[25,10801,4374],{"class":35},[25,10803,10804],{"class":27,"line":303},[25,10805,1525],{"emptyLinePlaceholder":1524},[25,10807,10808,10810,10812,10814,10816,10818,10820,10822,10824],{"class":27,"line":316},[25,10809,2983],{"class":275},[25,10811,4385],{"class":31},[25,10813,1939],{"class":268},[25,10815,4390],{"class":2194},[25,10817,770],{"class":743},[25,10819,2652],{"class":275},[25,10821,744],{"class":743},[25,10823,2135],{"class":275},[25,10825,2138],{"class":268},[25,10827,10828,10830,10832,10834,10836,10838],{"class":27,"line":329},[25,10829,2967],{"class":743},[25,10831,4407],{"class":268},[25,10833,862],{"class":743},[25,10835,2135],{"class":282},[25,10837,4414],{"class":743},[25,10839,4417],{"class":35},[25,10841,10842],{"class":27,"line":342},[25,10843,382],{"class":268},[25,10845,10846],{"class":27,"line":355},[25,10847,1525],{"emptyLinePlaceholder":1524},[25,10849,10850,10852,10854,10856],{"class":27,"line":368},[25,10851,1911],{"class":743},[25,10853,1914],{"class":275},[25,10855,4434],{"class":31},[25,10857,1920],{"class":268},[25,10859,10860,10862,10864,10866],{"class":27,"line":379},[25,10861,4441],{"class":31},[25,10863,1939],{"class":268},[25,10865,4446],{"class":35},[25,10867,1945],{"class":268},[25,10869,10870],{"class":27,"line":499},[25,10871,1525],{"emptyLinePlaceholder":1524},[25,10873,10874,10876,10878,10880,10882],{"class":27,"line":509},[25,10875,1925],{"class":275},[25,10877,4459],{"class":268},[25,10879,1874],{"class":743},[25,10881,3954],{"class":31},[25,10883,4133],{"class":268},[25,10885,10886],{"class":27,"line":515},[25,10887,1525],{"emptyLinePlaceholder":1524},[25,10889,10890,10892,10894,10896,10898,10900],{"class":27,"line":520},[25,10891,1925],{"class":275},[25,10893,4476],{"class":268},[25,10895,1874],{"class":743},[25,10897,2102],{"class":743},[25,10899,4483],{"class":31},[25,10901,1539],{"class":268},[25,10903,10904,10906,10908],{"class":27,"line":532},[25,10905,4490],{"class":268},[25,10907,4493],{"class":35},[25,10909,286],{"class":268},[25,10911,10912,10914,10916],{"class":27,"line":544},[25,10913,4500],{"class":268},[25,10915,4503],{"class":35},[25,10917,286],{"class":268},[25,10919,10920,10922,10924,10926],{"class":27,"line":556},[25,10921,4510],{"class":268},[25,10923,2087],{"class":743},[25,10925,4515],{"class":35},[25,10927,286],{"class":268},[25,10929,10930],{"class":27,"line":568},[25,10931,4522],{"class":268},[25,10933,10934],{"class":27,"line":579},[25,10935,4527],{"class":268},[25,10937,10938,10940,10942,10944],{"class":27,"line":589},[25,10939,2030],{"class":743},[25,10941,2869],{"class":268},[25,10943,4536],{"class":31},[25,10945,4539],{"class":268},[25,10947,10948,10950,10952,10954,10956],{"class":27,"line":595},[25,10949,2551],{"class":743},[25,10951,4546],{"class":31},[25,10953,1939],{"class":268},[25,10955,4551],{"class":35},[25,10957,1945],{"class":268},[25,10959,10960],{"class":27,"line":601},[25,10961,1226],{"class":268},[25,10963,10964],{"class":27,"line":1102},[25,10965,1525],{"emptyLinePlaceholder":1524},[25,10967,10968,10970,10972,10974,10976,10978],{"class":27,"line":1110},[25,10969,1925],{"class":275},[25,10971,4568],{"class":268},[25,10973,1874],{"class":743},[25,10975,2102],{"class":743},[25,10977,4575],{"class":31},[25,10979,1539],{"class":268},[25,10981,10982,10984,10986],{"class":27,"line":1123},[25,10983,4490],{"class":268},[25,10985,4584],{"class":35},[25,10987,286],{"class":268},[25,10989,10990],{"class":27,"line":1136},[25,10991,4591],{"class":268},[25,10993,10994,10996,10998,11000,11002],{"class":27,"line":1149},[25,10995,4596],{"class":268},[25,10997,3892],{"class":35},[25,10999,4601],{"class":268},[25,11001,4604],{"class":35},[25,11003,2442],{"class":268},[25,11005,11006,11008,11010,11012,11014],{"class":27,"line":1160},[25,11007,4596],{"class":268},[25,11009,3897],{"class":35},[25,11011,4601],{"class":268},[25,11013,4617],{"class":35},[25,11015,2442],{"class":268},[25,11017,11018],{"class":27,"line":1165},[25,11019,4624],{"class":268},[25,11021,11022,11024,11026,11028],{"class":27,"line":1173},[25,11023,4629],{"class":268},[25,11025,2087],{"class":743},[25,11027,2693],{"class":35},[25,11029,286],{"class":268},[25,11031,11032],{"class":27,"line":1186},[25,11033,4527],{"class":268},[25,11035,11036,11038,11040,11042],{"class":27,"line":1199},[25,11037,2030],{"class":743},[25,11039,2869],{"class":268},[25,11041,4536],{"class":31},[25,11043,4650],{"class":268},[25,11045,11046,11048,11050,11052,11054],{"class":27,"line":1212},[25,11047,2551],{"class":743},[25,11049,4546],{"class":31},[25,11051,1939],{"class":268},[25,11053,4551],{"class":35},[25,11055,1945],{"class":268},[25,11057,11058],{"class":27,"line":1223},[25,11059,1226],{"class":268},[25,11061,11062],{"class":27,"line":1229},[25,11063,1525],{"emptyLinePlaceholder":1524},[25,11065,11066,11068],{"class":27,"line":3242},[25,11067,4675],{"class":31},[25,11069,4678],{"class":268},[25,11071,11072],{"class":27,"line":3247},[25,11073,1525],{"emptyLinePlaceholder":1524},[25,11075,11076,11078,11080,11082,11084],{"class":27,"line":3252},[25,11077,4687],{"class":268},[25,11079,4690],{"class":31},[25,11081,1939],{"class":268},[25,11083,4695],{"class":35},[25,11085,1945],{"class":268},[25,11087,11088,11090,11092,11094],{"class":27,"line":3287},[25,11089,4702],{"class":31},[25,11091,1939],{"class":268},[25,11093,4707],{"class":35},[25,11095,1945],{"class":268},[25,11097,11098],{"class":27,"line":3302},[25,11099,382],{"class":268},[25,11101,11102],{"class":27,"line":3307},[25,11103,1525],{"emptyLinePlaceholder":1524},[25,11105,11106,11108,11110,11112,11114],{"class":27,"line":3314},[25,11107,1843],{"class":275},[25,11109,4724],{"class":268},[25,11111,1874],{"class":743},[25,11113,1893],{"class":31},[25,11115,1539],{"class":268},[25,11117,11118,11120,11122,11124,11126],{"class":27,"line":3343},[25,11119,2430],{"class":268},[25,11121,4737],{"class":35},[25,11123,2436],{"class":268},[25,11125,4742],{"class":35},[25,11127,2442],{"class":268},[25,11129,11130,11132,11134,11136,11138],{"class":27,"line":3349},[25,11131,2529],{"class":31},[25,11133,4751],{"class":268},[25,11135,2205],{"class":275},[25,11137,4434],{"class":31},[25,11139,3879],{"class":268},[25,11141,11142],{"class":27,"line":3355},[25,11143,1703],{"class":268},[25,11145,11146],{"class":27,"line":3361},[25,11147,1525],{"emptyLinePlaceholder":1524},[25,11149,11150,11152],{"class":27,"line":3367},[25,11151,1530],{"class":743},[25,11153,4772],{"class":268},[11,11155,4775,11156,4778,11158,4781,11160,4785],{},[22,11157,4536],{},[22,11159,669],{},[22,11161,4784],{},[11,11163,4788,11164,4791,11166,4794,11168,4797],{},[22,11165,2286],{},[22,11167,609],{},[22,11169,4316],{},[15,11171,11172],{"className":1500,"code":4800,"filename":2383,"language":1503,"meta":20,"style":20},[22,11173,11174,11184,11194,11204,11208,11220,11232,11236,11240,11248,11256,11264,11268,11272,11280,11288,11296,11300,11304,11322,11334,11338,11346,11350,11354,11358],{"__ignoreMap":20},[25,11175,11176,11178,11180,11182],{"class":27,"line":28},[25,11177,1510],{"class":743},[25,11179,2392],{"class":268},[25,11181,1516],{"class":743},[25,11183,1822],{"class":35},[25,11185,11186,11188,11190,11192],{"class":27,"line":272},[25,11187,1510],{"class":743},[25,11189,4819],{"class":268},[25,11191,1516],{"class":743},[25,11193,4374],{"class":35},[25,11195,11196,11198,11200,11202],{"class":27,"line":289},[25,11197,1510],{"class":743},[25,11199,2403],{"class":268},[25,11201,1516],{"class":743},[25,11203,2408],{"class":35},[25,11205,11206],{"class":27,"line":303},[25,11207,1525],{"emptyLinePlaceholder":1524},[25,11209,11210,11212,11214,11216,11218],{"class":27,"line":316},[25,11211,1843],{"class":275},[25,11213,2419],{"class":268},[25,11215,1874],{"class":743},[25,11217,1893],{"class":31},[25,11219,1539],{"class":268},[25,11221,11222,11224,11226,11228,11230],{"class":27,"line":329},[25,11223,2430],{"class":268},[25,11225,2433],{"class":35},[25,11227,2436],{"class":268},[25,11229,4860],{"class":35},[25,11231,2442],{"class":268},[25,11233,11234],{"class":27,"line":342},[25,11235,2447],{"class":268},[25,11237,11238],{"class":27,"line":355},[25,11239,2452],{"class":268},[25,11241,11242,11244,11246],{"class":27,"line":368},[25,11243,2457],{"class":268},[25,11245,2460],{"class":35},[25,11247,286],{"class":268},[25,11249,11250,11252,11254],{"class":27,"line":379},[25,11251,2467],{"class":268},[25,11253,283],{"class":282},[25,11255,286],{"class":268},[25,11257,11258,11260,11262],{"class":27,"line":499},[25,11259,2476],{"class":268},[25,11261,2479],{"class":35},[25,11263,286],{"class":268},[25,11265,11266],{"class":27,"line":509},[25,11267,512],{"class":268},[25,11269,11270],{"class":27,"line":515},[25,11271,2490],{"class":268},[25,11273,11274,11276,11278],{"class":27,"line":520},[25,11275,2457],{"class":268},[25,11277,2497],{"class":35},[25,11279,286],{"class":268},[25,11281,11282,11284,11286],{"class":27,"line":532},[25,11283,2467],{"class":268},[25,11285,1552],{"class":282},[25,11287,286],{"class":268},[25,11289,11290,11292,11294],{"class":27,"line":544},[25,11291,2476],{"class":268},[25,11293,4925],{"class":35},[25,11295,286],{"class":268},[25,11297,11298],{"class":27,"line":556},[25,11299,512],{"class":268},[25,11301,11302],{"class":27,"line":568},[25,11303,971],{"class":268},[25,11305,11306,11308,11310,11312,11314,11316,11318,11320],{"class":27,"line":579},[25,11307,2529],{"class":31},[25,11309,279],{"class":268},[25,11311,1911],{"class":743},[25,11313,2536],{"class":268},[25,11315,2539],{"class":2194},[25,11317,2542],{"class":268},[25,11319,2205],{"class":275},[25,11321,2208],{"class":268},[25,11323,11324,11326,11328,11330,11332],{"class":27,"line":589},[25,11325,4958],{"class":275},[25,11327,4961],{"class":268},[25,11329,1874],{"class":743},[25,11331,4109],{"class":31},[25,11333,4968],{"class":268},[25,11335,11336],{"class":27,"line":595},[25,11337,1525],{"emptyLinePlaceholder":1524},[25,11339,11340,11342,11344],{"class":27,"line":601},[25,11341,2551],{"class":743},[25,11343,2554],{"class":31},[25,11345,4981],{"class":268},[25,11347,11348],{"class":27,"line":1102},[25,11349,971],{"class":268},[25,11351,11352],{"class":27,"line":1110},[25,11353,1703],{"class":268},[25,11355,11356],{"class":27,"line":1123},[25,11357,1525],{"emptyLinePlaceholder":1524},[25,11359,11360,11362],{"class":27,"line":1136},[25,11361,1530],{"class":743},[25,11363,2576],{"class":268},[11,11365,5002,11366,5005,11368,5008,11370],{},[22,11367,2632],{},[22,11369,3605],{},[44,11371,5011],{},[11,11373,5014,11374,5017],{},[22,11375,669],{},[15,11377,11378],{"className":1500,"code":5020,"filename":1713,"language":1503,"meta":20,"style":20},[22,11379,11380,11390,11400,11404,11432,11436],{"__ignoreMap":20},[25,11381,11382,11384,11386,11388],{"class":27,"line":28},[25,11383,1510],{"class":743},[25,11385,5029],{"class":268},[25,11387,1516],{"class":743},[25,11389,5034],{"class":35},[25,11391,11392,11394,11396,11398],{"class":27,"line":272},[25,11393,1510],{"class":743},[25,11395,1829],{"class":268},[25,11397,1516],{"class":743},[25,11399,1834],{"class":35},[25,11401,11402],{"class":27,"line":289},[25,11403,1525],{"emptyLinePlaceholder":1524},[25,11405,11406,11408,11410,11412,11414,11416,11418,11420,11422,11424,11426,11428,11430],{"class":27,"line":303},[25,11407,1843],{"class":275},[25,11409,1846],{"class":268},[25,11411,770],{"class":743},[25,11413,1852],{"class":1851},[25,11415,1855],{"class":268},[25,11417,1858],{"class":275},[25,11419,91],{"class":268},[25,11421,1863],{"class":1851},[25,11423,1855],{"class":268},[25,11425,1868],{"class":275},[25,11427,1871],{"class":268},[25,11429,1874],{"class":743},[25,11431,2208],{"class":268},[25,11433,11434],{"class":27,"line":316},[25,11435,5081],{"class":268},[25,11437,11438],{"class":27,"line":329},[25,11439,382],{"class":268},[11,11441,5088,11442,770],{},[22,11443,609],{},[15,11445,11446],{"className":17,"code":5093,"language":19,"meta":20,"style":20},[22,11447,11448,11456,11464],{"__ignoreMap":20},[25,11449,11450,11452,11454],{"class":27,"line":28},[25,11451,50],{"class":31},[25,11453,1917],{"class":35},[25,11455,3642],{"class":35},[25,11457,11458,11460,11462],{"class":27,"line":272},[25,11459,2269],{"class":31},[25,11461,3649],{"class":35},[25,11463,221],{"class":35},[25,11465,11466,11468,11470],{"class":27,"line":289},[25,11467,2269],{"class":31},[25,11469,3649],{"class":35},[25,11471,39],{"class":35},[15,11473,11474],{"className":259,"code":260,"language":261,"meta":20,"style":20},[22,11475,11476,11480,11490,11500,11510,11520,11530,11540,11550,11558],{"__ignoreMap":20},[25,11477,11478],{"class":27,"line":28},[25,11479,269],{"class":268},[25,11481,11482,11484,11486,11488],{"class":27,"line":272},[25,11483,276],{"class":275},[25,11485,279],{"class":268},[25,11487,283],{"class":282},[25,11489,286],{"class":268},[25,11491,11492,11494,11496,11498],{"class":27,"line":289},[25,11493,292],{"class":275},[25,11495,279],{"class":268},[25,11497,298],{"class":297},[25,11499,286],{"class":268},[25,11501,11502,11504,11506,11508],{"class":27,"line":303},[25,11503,306],{"class":275},[25,11505,279],{"class":268},[25,11507,311],{"class":297},[25,11509,286],{"class":268},[25,11511,11512,11514,11516,11518],{"class":27,"line":316},[25,11513,319],{"class":275},[25,11515,279],{"class":268},[25,11517,324],{"class":282},[25,11519,286],{"class":268},[25,11521,11522,11524,11526,11528],{"class":27,"line":329},[25,11523,332],{"class":275},[25,11525,279],{"class":268},[25,11527,337],{"class":282},[25,11529,286],{"class":268},[25,11531,11532,11534,11536,11538],{"class":27,"line":342},[25,11533,345],{"class":275},[25,11535,279],{"class":268},[25,11537,350],{"class":282},[25,11539,286],{"class":268},[25,11541,11542,11544,11546,11548],{"class":27,"line":355},[25,11543,358],{"class":275},[25,11545,279],{"class":268},[25,11547,363],{"class":297},[25,11549,286],{"class":268},[25,11551,11552,11554,11556],{"class":27,"line":368},[25,11553,371],{"class":275},[25,11555,279],{"class":268},[25,11557,376],{"class":297},[25,11559,11560],{"class":27,"line":379},[25,11561,382],{"class":268},[11,11563,5212,11564,5215],{},[22,11565,609],{},[72,11567,5219],{"id":5218},[11,11569,5222,11570,5226],{},[22,11571,5225],{},[15,11573,11574],{"className":1500,"code":5229,"filename":5230,"language":1503,"meta":20,"style":20},[22,11575,11576,11580,11610,11648,11652,11684,11706,11710,11714,11724,11728,11732],{"__ignoreMap":20},[25,11577,11578],{"class":27,"line":28},[25,11579,5237],{"class":1799},[25,11581,11582,11584,11586,11588,11590,11592,11594,11596,11598,11600,11602,11604,11606,11608],{"class":27,"line":272},[25,11583,2983],{"class":275},[25,11585,5244],{"class":31},[25,11587,1939],{"class":268},[25,11589,4390],{"class":2194},[25,11591,770],{"class":743},[25,11593,2652],{"class":275},[25,11595,2767],{"class":268},[25,11597,770],{"class":743},[25,11599,5259],{"class":268},[25,11601,1858],{"class":275},[25,11603,91],{"class":268},[25,11605,1899],{"class":743},[25,11607,1858],{"class":275},[25,11609,5270],{"class":268},[25,11611,11612,11614,11616,11618,11620,11622,11624,11626,11628,11630,11632,11634,11636,11638,11640,11642,11644,11646],{"class":27,"line":289},[25,11613,1925],{"class":275},[25,11615,5277],{"class":268},[25,11617,1899],{"class":743},[25,11619,1957],{"class":268},[25,11621,1874],{"class":743},[25,11623,5286],{"class":268},[25,11625,5289],{"class":31},[25,11627,1939],{"class":268},[25,11629,5294],{"class":35},[25,11631,5297],{"class":268},[25,11633,5300],{"class":31},[25,11635,2191],{"class":268},[25,11637,2760],{"class":2194},[25,11639,2007],{"class":268},[25,11641,2205],{"class":275},[25,11643,5311],{"class":268},[25,11645,5314],{"class":31},[25,11647,5317],{"class":268},[25,11649,11650],{"class":27,"line":303},[25,11651,1525],{"emptyLinePlaceholder":1524},[25,11653,11654,11656,11658,11660,11662,11664,11666,11668,11670,11672,11674,11676,11678,11680,11682],{"class":27,"line":316},[25,11655,2030],{"class":743},[25,11657,2869],{"class":268},[25,11659,2924],{"class":743},[25,11661,5332],{"class":268},[25,11663,2010],{"class":743},[25,11665,5337],{"class":268},[25,11667,5340],{"class":31},[25,11669,2191],{"class":268},[25,11671,2760],{"class":2194},[25,11673,2007],{"class":268},[25,11675,2205],{"class":275},[25,11677,5351],{"class":268},[25,11679,5354],{"class":743},[25,11681,4515],{"class":35},[25,11683,5359],{"class":268},[25,11685,11686,11688,11690,11692,11694,11696,11698,11700,11702,11704],{"class":27,"line":329},[25,11687,2932],{"class":743},[25,11689,2792],{"class":743},[25,11691,2224],{"class":31},[25,11693,1939],{"class":268},[25,11695,5372],{"class":35},[25,11697,2944],{"class":743},[25,11699,4390],{"class":268},[25,11701,2949],{"class":743},[25,11703,2952],{"class":35},[25,11705,1945],{"class":268},[25,11707,11708],{"class":27,"line":342},[25,11709,1226],{"class":268},[25,11711,11712],{"class":27,"line":355},[25,11713,1525],{"emptyLinePlaceholder":1524},[25,11715,11716,11718,11720,11722],{"class":27,"line":368},[25,11717,2967],{"class":743},[25,11719,5277],{"class":268},[25,11721,1899],{"class":743},[25,11723,5401],{"class":268},[25,11725,11726],{"class":27,"line":379},[25,11727,382],{"class":268},[25,11729,11730],{"class":27,"line":499},[25,11731,1525],{"emptyLinePlaceholder":1524},[25,11733,11734,11736],{"class":27,"line":509},[25,11735,1530],{"class":743},[25,11737,5416],{"class":268},[11,11739,5419,11740,5423,11742,5427,11744,5430,11746,5433],{},[22,11741,5422],{},[22,11743,5426],{},[22,11745,1858],{},[22,11747,1470],{},[159,11749,11750],{},[11,11751,5438],{},[11,11753,5441,11754,5445],{},[22,11755,5444],{},[11,11757,5448,11758,5452,11760,5455,11762,770],{},[22,11759,5451],{},[22,11761,2632],{},[22,11763,3605],{},[15,11765,11766],{"className":1500,"code":5460,"filename":2632,"language":1503,"meta":20,"style":20},[22,11767,11768,11806,11840,11844,11850,11858,11882,11900,11904,11908,11912],{"__ignoreMap":20},[25,11769,11770,11772,11774,11776,11778,11780,11782,11784,11786,11788,11790,11792,11794,11796,11798,11800,11802,11804],{"class":27,"line":28},[25,11771,1911],{"class":743},[25,11773,1914],{"class":275},[25,11775,5471],{"class":31},[25,11777,1939],{"class":268},[25,11779,5476],{"class":2194},[25,11781,770],{"class":743},[25,11783,2652],{"class":275},[25,11785,5483],{"class":268},[25,11787,1516],{"class":2194},[25,11789,770],{"class":743},[25,11791,2652],{"class":275},[25,11793,91],{"class":268},[25,11795,3064],{"class":2194},[25,11797,770],{"class":743},[25,11799,2688],{"class":1851},[25,11801,2644],{"class":743},[25,11803,2693],{"class":35},[25,11805,2138],{"class":268},[25,11807,11808,11810,11812,11814,11816,11818,11820,11822,11824,11826,11828,11830,11832,11834,11836,11838],{"class":27,"line":272},[25,11809,1925],{"class":275},[25,11811,5510],{"class":268},[25,11813,1874],{"class":743},[25,11815,2102],{"class":743},[25,11817,2772],{"class":275},[25,11819,150],{"class":268},[25,11821,3492],{"class":31},[25,11823,3495],{"class":268},[25,11825,5525],{"class":275},[25,11827,150],{"class":268},[25,11829,3492],{"class":31},[25,11831,5532],{"class":268},[25,11833,5300],{"class":31},[25,11835,5537],{"class":268},[25,11837,3498],{"class":31},[25,11839,3506],{"class":268},[25,11841,11842],{"class":27,"line":289},[25,11843,1525],{"emptyLinePlaceholder":1524},[25,11845,11846,11848],{"class":27,"line":303},[25,11847,2967],{"class":743},[25,11849,2208],{"class":268},[25,11851,11852,11854,11856],{"class":27,"line":316},[25,11853,5556],{"class":268},[25,11855,283],{"class":282},[25,11857,286],{"class":268},[25,11859,11860,11862,11864,11866,11868,11870,11872,11874,11876,11878,11880],{"class":27,"line":329},[25,11861,5565],{"class":268},[25,11863,3320],{"class":35},[25,11865,2944],{"class":743},[25,11867,3531],{"class":268},[25,11869,2949],{"class":743},[25,11871,91],{"class":35},[25,11873,2944],{"class":743},[25,11875,3540],{"class":268},[25,11877,2949],{"class":743},[25,11879,3320],{"class":35},[25,11881,286],{"class":268},[25,11883,11884,11886,11888,11890,11892,11894,11896,11898],{"class":27,"line":342},[25,11885,5590],{"class":268},[25,11887,5300],{"class":31},[25,11889,2191],{"class":268},[25,11891,3262],{"class":2194},[25,11893,2007],{"class":268},[25,11895,2205],{"class":275},[25,11897,3257],{"class":31},[25,11899,5605],{"class":268},[25,11901,11902],{"class":27,"line":355},[25,11903,1226],{"class":268},[25,11905,11906],{"class":27,"line":368},[25,11907,382],{"class":268},[25,11909,11910],{"class":27,"line":379},[25,11911,1525],{"emptyLinePlaceholder":1524},[25,11913,11914,11916],{"class":27,"line":499},[25,11915,1530],{"class":743},[25,11917,5624],{"class":268},[11,11919,5627],{},[11,11921,5630],{},[15,11923,11924],{"className":1500,"code":5633,"filename":2383,"language":1503,"meta":20,"style":20},[22,11925,11926,11936,11946,11956,11966,11970,11982,11994,11998,12002,12010,12018,12026,12030,12034,12042,12050,12058,12062,12066,12084,12096,12108,12112,12122,12134,12142,12146,12150,12154],{"__ignoreMap":20},[25,11927,11928,11930,11932,11934],{"class":27,"line":28},[25,11929,1510],{"class":743},[25,11931,2392],{"class":268},[25,11933,1516],{"class":743},[25,11935,1822],{"class":35},[25,11937,11938,11940,11942,11944],{"class":27,"line":272},[25,11939,1510],{"class":743},[25,11941,4819],{"class":268},[25,11943,1516],{"class":743},[25,11945,4374],{"class":35},[25,11947,11948,11950,11952,11954],{"class":27,"line":289},[25,11949,1510],{"class":743},[25,11951,5662],{"class":268},[25,11953,1516],{"class":743},[25,11955,5667],{"class":35},[25,11957,11958,11960,11962,11964],{"class":27,"line":303},[25,11959,1510],{"class":743},[25,11961,5674],{"class":268},[25,11963,1516],{"class":743},[25,11965,2408],{"class":35},[25,11967,11968],{"class":27,"line":316},[25,11969,1525],{"emptyLinePlaceholder":1524},[25,11971,11972,11974,11976,11978,11980],{"class":27,"line":329},[25,11973,1843],{"class":275},[25,11975,2419],{"class":268},[25,11977,1874],{"class":743},[25,11979,1893],{"class":31},[25,11981,1539],{"class":268},[25,11983,11984,11986,11988,11990,11992],{"class":27,"line":342},[25,11985,2430],{"class":268},[25,11987,2433],{"class":35},[25,11989,2436],{"class":268},[25,11991,5705],{"class":35},[25,11993,2442],{"class":268},[25,11995,11996],{"class":27,"line":355},[25,11997,2447],{"class":268},[25,11999,12000],{"class":27,"line":368},[25,12001,2452],{"class":268},[25,12003,12004,12006,12008],{"class":27,"line":379},[25,12005,2457],{"class":268},[25,12007,2460],{"class":35},[25,12009,286],{"class":268},[25,12011,12012,12014,12016],{"class":27,"line":499},[25,12013,2467],{"class":268},[25,12015,283],{"class":282},[25,12017,286],{"class":268},[25,12019,12020,12022,12024],{"class":27,"line":509},[25,12021,2476],{"class":268},[25,12023,5738],{"class":35},[25,12025,286],{"class":268},[25,12027,12028],{"class":27,"line":515},[25,12029,512],{"class":268},[25,12031,12032],{"class":27,"line":520},[25,12033,2490],{"class":268},[25,12035,12036,12038,12040],{"class":27,"line":532},[25,12037,2457],{"class":268},[25,12039,2497],{"class":35},[25,12041,286],{"class":268},[25,12043,12044,12046,12048],{"class":27,"line":544},[25,12045,2467],{"class":268},[25,12047,1552],{"class":282},[25,12049,286],{"class":268},[25,12051,12052,12054,12056],{"class":27,"line":556},[25,12053,2476],{"class":268},[25,12055,4925],{"class":35},[25,12057,286],{"class":268},[25,12059,12060],{"class":27,"line":568},[25,12061,512],{"class":268},[25,12063,12064],{"class":27,"line":579},[25,12065,971],{"class":268},[25,12067,12068,12070,12072,12074,12076,12078,12080,12082],{"class":27,"line":589},[25,12069,2529],{"class":31},[25,12071,279],{"class":268},[25,12073,1911],{"class":743},[25,12075,2536],{"class":268},[25,12077,2539],{"class":2194},[25,12079,2542],{"class":268},[25,12081,2205],{"class":275},[25,12083,2208],{"class":268},[25,12085,12086,12088,12090,12092,12094],{"class":27,"line":595},[25,12087,4958],{"class":275},[25,12089,4961],{"class":268},[25,12091,1874],{"class":743},[25,12093,4109],{"class":31},[25,12095,4968],{"class":268},[25,12097,12098,12100,12102,12104,12106],{"class":27,"line":601},[25,12099,4958],{"class":275},[25,12101,5817],{"class":268},[25,12103,1874],{"class":743},[25,12105,5244],{"class":31},[25,12107,5824],{"class":268},[25,12109,12110],{"class":27,"line":1102},[25,12111,1525],{"emptyLinePlaceholder":1524},[25,12113,12114,12116,12118,12120],{"class":27,"line":1110},[25,12115,2551],{"class":743},[25,12117,5835],{"class":268},[25,12119,5354],{"class":743},[25,12121,5840],{"class":282},[25,12123,12124,12126,12128,12130,12132],{"class":27,"line":1123},[25,12125,5845],{"class":743},[25,12127,2554],{"class":31},[25,12129,5850],{"class":268},[25,12131,2909],{"class":282},[25,12133,5855],{"class":268},[25,12135,12136,12138,12140],{"class":27,"line":1136},[25,12137,5860],{"class":743},[25,12139,5471],{"class":31},[25,12141,5865],{"class":268},[25,12143,12144],{"class":27,"line":1149},[25,12145,971],{"class":268},[25,12147,12148],{"class":27,"line":1160},[25,12149,1703],{"class":268},[25,12151,12152],{"class":27,"line":1165},[25,12153,1525],{"emptyLinePlaceholder":1524},[25,12155,12156,12158],{"class":27,"line":1173},[25,12157,1530],{"class":743},[25,12159,2576],{"class":268},[11,12161,5886],{},[15,12163,12164],{"className":17,"code":5889,"language":19,"meta":20,"style":20},[22,12165,12166],{"__ignoreMap":20},[25,12167,12168,12170,12172],{"class":27,"line":28},[25,12169,2269],{"class":31},[25,12171,3649],{"class":35},[25,12173,399],{"class":35},[15,12175,12176],{"className":259,"code":402,"language":261,"meta":20,"style":20},[22,12177,12178,12182,12192,12202,12208,12212,12222,12232,12242,12252,12262,12270,12274,12278,12288,12298,12308,12318,12328,12336,12340,12344],{"__ignoreMap":20},[25,12179,12180],{"class":27,"line":28},[25,12181,269],{"class":268},[25,12183,12184,12186,12188,12190],{"class":27,"line":272},[25,12185,276],{"class":275},[25,12187,279],{"class":268},[25,12189,283],{"class":282},[25,12191,286],{"class":268},[25,12193,12194,12196,12198,12200],{"class":27,"line":289},[25,12195,292],{"class":275},[25,12197,279],{"class":268},[25,12199,298],{"class":297},[25,12201,286],{"class":268},[25,12203,12204,12206],{"class":27,"line":303},[25,12205,433],{"class":275},[25,12207,436],{"class":268},[25,12209,12210],{"class":27,"line":316},[25,12211,441],{"class":268},[25,12213,12214,12216,12218,12220],{"class":27,"line":329},[25,12215,446],{"class":275},[25,12217,279],{"class":268},[25,12219,311],{"class":297},[25,12221,286],{"class":268},[25,12223,12224,12226,12228,12230],{"class":27,"line":342},[25,12225,457],{"class":275},[25,12227,279],{"class":268},[25,12229,324],{"class":282},[25,12231,286],{"class":268},[25,12233,12234,12236,12238,12240],{"class":27,"line":355},[25,12235,468],{"class":275},[25,12237,279],{"class":268},[25,12239,337],{"class":282},[25,12241,286],{"class":268},[25,12243,12244,12246,12248,12250],{"class":27,"line":368},[25,12245,479],{"class":275},[25,12247,279],{"class":268},[25,12249,350],{"class":282},[25,12251,286],{"class":268},[25,12253,12254,12256,12258,12260],{"class":27,"line":379},[25,12255,490],{"class":275},[25,12257,279],{"class":268},[25,12259,363],{"class":297},[25,12261,286],{"class":268},[25,12263,12264,12266,12268],{"class":27,"line":499},[25,12265,502],{"class":275},[25,12267,279],{"class":268},[25,12269,376],{"class":297},[25,12271,12272],{"class":27,"line":509},[25,12273,512],{"class":268},[25,12275,12276],{"class":27,"line":515},[25,12277,441],{"class":268},[25,12279,12280,12282,12284,12286],{"class":27,"line":520},[25,12281,446],{"class":275},[25,12283,279],{"class":268},[25,12285,527],{"class":297},[25,12287,286],{"class":268},[25,12289,12290,12292,12294,12296],{"class":27,"line":532},[25,12291,457],{"class":275},[25,12293,279],{"class":268},[25,12295,539],{"class":282},[25,12297,286],{"class":268},[25,12299,12300,12302,12304,12306],{"class":27,"line":544},[25,12301,468],{"class":275},[25,12303,279],{"class":268},[25,12305,551],{"class":282},[25,12307,286],{"class":268},[25,12309,12310,12312,12314,12316],{"class":27,"line":556},[25,12311,479],{"class":275},[25,12313,279],{"class":268},[25,12315,563],{"class":282},[25,12317,286],{"class":268},[25,12319,12320,12322,12324,12326],{"class":27,"line":568},[25,12321,490],{"class":275},[25,12323,279],{"class":268},[25,12325,363],{"class":297},[25,12327,286],{"class":268},[25,12329,12330,12332,12334],{"class":27,"line":579},[25,12331,502],{"class":275},[25,12333,279],{"class":268},[25,12335,586],{"class":297},[25,12337,12338],{"class":27,"line":589},[25,12339,592],{"class":268},[25,12341,12342],{"class":27,"line":595},[25,12343,598],{"class":268},[25,12345,12346],{"class":27,"line":601},[25,12347,382],{"class":268},[11,12349,6076],{},[72,12351,6080],{"id":6079},[11,12353,6083,12354,6086],{},[22,12355,1771],{},[11,12357,6089],{},[15,12359,12360],{"className":1500,"code":6092,"filename":6093,"language":1503,"meta":20,"style":20},[22,12361,12362,12372,12382,12386,12400,12414,12436,12440,12444,12458,12488,12492,12496,12528,12548,12552],{"__ignoreMap":20},[25,12363,12364,12366,12368,12370],{"class":27,"line":28},[25,12365,1510],{"class":743},[25,12367,6102],{"class":268},[25,12369,1516],{"class":743},[25,12371,6107],{"class":35},[25,12373,12374,12376,12378,12380],{"class":27,"line":272},[25,12375,1510],{"class":743},[25,12377,5662],{"class":268},[25,12379,1516],{"class":743},[25,12381,5667],{"class":35},[25,12383,12384],{"class":27,"line":289},[25,12385,1525],{"emptyLinePlaceholder":1524},[25,12387,12388,12390,12392,12394,12396,12398],{"class":27,"line":303},[25,12389,3551],{"class":31},[25,12391,1939],{"class":268},[25,12393,6130],{"class":35},[25,12395,6133],{"class":268},[25,12397,2205],{"class":275},[25,12399,2208],{"class":268},[25,12401,12402,12404,12406,12408,12410,12412],{"class":27,"line":316},[25,12403,6142],{"class":31},[25,12405,1939],{"class":268},[25,12407,6147],{"class":35},[25,12409,6133],{"class":268},[25,12411,2205],{"class":275},[25,12413,2208],{"class":268},[25,12415,12416,12418,12420,12422,12424,12426,12428,12430,12432,12434],{"class":27,"line":329},[25,12417,6158],{"class":31},[25,12419,1939],{"class":268},[25,12421,6163],{"class":31},[25,12423,1939],{"class":268},[25,12425,6168],{"class":35},[25,12427,6171],{"class":268},[25,12429,6174],{"class":31},[25,12431,3495],{"class":268},[25,12433,6168],{"class":35},[25,12435,6181],{"class":268},[25,12437,12438],{"class":27,"line":342},[25,12439,4527],{"class":268},[25,12441,12442],{"class":27,"line":355},[25,12443,1525],{"emptyLinePlaceholder":1524},[25,12445,12446,12448,12450,12452,12454,12456],{"class":27,"line":368},[25,12447,6142],{"class":31},[25,12449,1939],{"class":268},[25,12451,6198],{"class":35},[25,12453,6133],{"class":268},[25,12455,2205],{"class":275},[25,12457,2208],{"class":268},[25,12459,12460,12462,12464,12466,12468,12470,12472,12474,12476,12478,12480,12482,12484,12486],{"class":27,"line":379},[25,12461,6158],{"class":31},[25,12463,1939],{"class":268},[25,12465,6163],{"class":31},[25,12467,1939],{"class":268},[25,12469,6217],{"class":35},[25,12471,6171],{"class":268},[25,12473,6174],{"class":31},[25,12475,3495],{"class":268},[25,12477,6168],{"class":35},[25,12479,91],{"class":268},[25,12481,6230],{"class":35},[25,12483,91],{"class":268},[25,12485,6235],{"class":35},[25,12487,6181],{"class":268},[25,12489,12490],{"class":27,"line":499},[25,12491,4527],{"class":268},[25,12493,12494],{"class":27,"line":509},[25,12495,1525],{"emptyLinePlaceholder":1524},[25,12497,12498,12500,12502,12504,12506,12508,12510,12512,12514,12516,12518,12520,12522,12524,12526],{"class":27,"line":515},[25,12499,6250],{"class":268},[25,12501,6253],{"class":31},[25,12503,3495],{"class":268},[25,12505,6258],{"class":35},[25,12507,91],{"class":268},[25,12509,6263],{"class":35},[25,12511,91],{"class":268},[25,12513,6268],{"class":35},[25,12515,6271],{"class":268},[25,12517,6274],{"class":35},[25,12519,6277],{"class":268},[25,12521,4390],{"class":2194},[25,12523,2007],{"class":268},[25,12525,2205],{"class":275},[25,12527,2208],{"class":268},[25,12529,12530,12532,12534,12536,12538,12540,12542,12544,12546],{"class":27,"line":520},[25,12531,6158],{"class":31},[25,12533,6292],{"class":268},[25,12535,2205],{"class":275},[25,12537,5244],{"class":31},[25,12539,6299],{"class":268},[25,12541,6302],{"class":31},[25,12543,1939],{"class":268},[25,12545,6307],{"class":35},[25,12547,1945],{"class":268},[25,12549,12550],{"class":27,"line":532},[25,12551,4527],{"class":268},[25,12553,12554],{"class":27,"line":544},[25,12555,1703],{"class":268},[11,12557,6320,12558,6323],{},[22,12559,3594],{},[15,12561,12562],{"className":1500,"code":6326,"filename":6327,"language":1503,"meta":20,"style":20},[22,12563,12564,12574,12584,12588,12598,12606,12614,12624,12634,12638,12664,12668,12682,12696,12718,12722,12726,12740,12762,12766,12770,12784,12806,12810],{"__ignoreMap":20},[25,12565,12566,12568,12570,12572],{"class":27,"line":28},[25,12567,1510],{"class":743},[25,12569,6102],{"class":268},[25,12571,1516],{"class":743},[25,12573,6107],{"class":35},[25,12575,12576,12578,12580,12582],{"class":27,"line":272},[25,12577,1510],{"class":743},[25,12579,6346],{"class":268},[25,12581,1516],{"class":743},[25,12583,2408],{"class":35},[25,12585,12586],{"class":27,"line":289},[25,12587,1525],{"emptyLinePlaceholder":1524},[25,12589,12590,12592,12594,12596],{"class":27,"line":303},[25,12591,1843],{"class":275},[25,12593,6361],{"class":268},[25,12595,1874],{"class":743},[25,12597,2208],{"class":268},[25,12599,12600,12602,12604],{"class":27,"line":316},[25,12601,6370],{"class":268},[25,12603,4503],{"class":35},[25,12605,286],{"class":268},[25,12607,12608,12610,12612],{"class":27,"line":329},[25,12609,6379],{"class":268},[25,12611,6382],{"class":35},[25,12613,286],{"class":268},[25,12615,12616,12618,12620,12622],{"class":27,"line":342},[25,12617,6389],{"class":268},[25,12619,3093],{"class":743},[25,12621,6394],{"class":282},[25,12623,286],{"class":268},[25,12625,12626,12628,12630,12632],{"class":27,"line":355},[25,12627,6401],{"class":268},[25,12629,3093],{"class":743},[25,12631,6406],{"class":282},[25,12633,286],{"class":268},[25,12635,12636],{"class":27,"line":368},[25,12637,382],{"class":268},[25,12639,12640,12642,12644,12646,12648,12650,12652,12654,12656,12658,12660,12662],{"class":27,"line":379},[25,12641,1843],{"class":275},[25,12643,6419],{"class":268},[25,12645,1874],{"class":743},[25,12647,6424],{"class":268},[25,12649,6168],{"class":35},[25,12651,6429],{"class":268},[25,12653,6432],{"class":35},[25,12655,6435],{"class":268},[25,12657,324],{"class":282},[25,12659,6440],{"class":268},[25,12661,337],{"class":282},[25,12663,2677],{"class":268},[25,12665,12666],{"class":27,"line":499},[25,12667,1525],{"emptyLinePlaceholder":1524},[25,12669,12670,12672,12674,12676,12678,12680],{"class":27,"line":509},[25,12671,3551],{"class":31},[25,12673,1939],{"class":268},[25,12675,6457],{"class":35},[25,12677,6133],{"class":268},[25,12679,2205],{"class":275},[25,12681,2208],{"class":268},[25,12683,12684,12686,12688,12690,12692,12694],{"class":27,"line":515},[25,12685,6142],{"class":31},[25,12687,1939],{"class":268},[25,12689,6472],{"class":35},[25,12691,6133],{"class":268},[25,12693,2205],{"class":275},[25,12695,2208],{"class":268},[25,12697,12698,12700,12702,12704,12706,12708,12710,12712,12714,12716],{"class":27,"line":520},[25,12699,6158],{"class":31},[25,12701,1939],{"class":268},[25,12703,3594],{"class":31},[25,12705,6489],{"class":268},[25,12707,3892],{"class":35},[25,12709,6171],{"class":268},[25,12711,6496],{"class":31},[25,12713,1939],{"class":268},[25,12715,350],{"class":282},[25,12717,1945],{"class":268},[25,12719,12720],{"class":27,"line":532},[25,12721,4527],{"class":268},[25,12723,12724],{"class":27,"line":544},[25,12725,1525],{"emptyLinePlaceholder":1524},[25,12727,12728,12730,12732,12734,12736,12738],{"class":27,"line":556},[25,12729,6142],{"class":31},[25,12731,1939],{"class":268},[25,12733,6519],{"class":35},[25,12735,6133],{"class":268},[25,12737,2205],{"class":275},[25,12739,2208],{"class":268},[25,12741,12742,12744,12746,12748,12750,12752,12754,12756,12758,12760],{"class":27,"line":568},[25,12743,6158],{"class":31},[25,12745,1939],{"class":268},[25,12747,3594],{"class":31},[25,12749,6489],{"class":268},[25,12751,3897],{"class":35},[25,12753,6171],{"class":268},[25,12755,6496],{"class":31},[25,12757,1939],{"class":268},[25,12759,6546],{"class":282},[25,12761,1945],{"class":268},[25,12763,12764],{"class":27,"line":579},[25,12765,4527],{"class":268},[25,12767,12768],{"class":27,"line":589},[25,12769,1525],{"emptyLinePlaceholder":1524},[25,12771,12772,12774,12776,12778,12780,12782],{"class":27,"line":595},[25,12773,6142],{"class":31},[25,12775,1939],{"class":268},[25,12777,6565],{"class":35},[25,12779,6133],{"class":268},[25,12781,2205],{"class":275},[25,12783,2208],{"class":268},[25,12785,12786,12788,12790,12792,12794,12796,12798,12800,12802,12804],{"class":27,"line":601},[25,12787,6158],{"class":31},[25,12789,1939],{"class":268},[25,12791,3594],{"class":31},[25,12793,6582],{"class":268},[25,12795,3892],{"class":35},[25,12797,6171],{"class":268},[25,12799,6496],{"class":31},[25,12801,1939],{"class":268},[25,12803,2909],{"class":282},[25,12805,1945],{"class":268},[25,12807,12808],{"class":27,"line":1102},[25,12809,4527],{"class":268},[25,12811,12812],{"class":27,"line":1110},[25,12813,1703],{"class":268},[11,12815,6605,12816,6609],{},[22,12817,6608],{},[15,12819,12820],{"className":1500,"code":6612,"filename":6613,"language":1503,"meta":20,"style":20},[22,12821,12822,12832,12842,12852,12862,12866,12882,12910,12914,12918,12934,12954,12974,12978,12982,12996,13014,13026,13030,13052,13056,13060,13078,13098,13102,13124,13128,13132,13150,13162,13166,13192,13196],{"__ignoreMap":20},[25,12823,12824,12826,12828,12830],{"class":27,"line":28},[25,12825,1510],{"class":743},[25,12827,6622],{"class":268},[25,12829,1516],{"class":743},[25,12831,6107],{"class":35},[25,12833,12834,12836,12838,12840],{"class":27,"line":272},[25,12835,1510],{"class":743},[25,12837,6633],{"class":268},[25,12839,1516],{"class":743},[25,12841,1822],{"class":35},[25,12843,12844,12846,12848,12850],{"class":27,"line":289},[25,12845,1510],{"class":743},[25,12847,1829],{"class":268},[25,12849,1516],{"class":743},[25,12851,1834],{"class":35},[25,12853,12854,12856,12858,12860],{"class":27,"line":303},[25,12855,1510],{"class":743},[25,12857,5674],{"class":268},[25,12859,1516],{"class":743},[25,12861,2408],{"class":35},[25,12863,12864],{"class":27,"line":316},[25,12865,1525],{"emptyLinePlaceholder":1524},[25,12867,12868,12870,12872,12874,12876,12878,12880],{"class":27,"line":329},[25,12869,6666],{"class":268},[25,12871,6669],{"class":31},[25,12873,1939],{"class":268},[25,12875,6674],{"class":35},[25,12877,6133],{"class":268},[25,12879,2205],{"class":275},[25,12881,6681],{"class":268},[25,12883,12884,12886,12888,12890,12892,12894,12896,12898,12900,12902,12904,12906,12908],{"class":27,"line":342},[25,12885,6686],{"class":31},[25,12887,6689],{"class":268},[25,12889,1516],{"class":2194},[25,12891,2889],{"class":743},[25,12893,2652],{"class":275},[25,12895,2007],{"class":268},[25,12897,2205],{"class":275},[25,12899,6702],{"class":268},[25,12901,2087],{"class":743},[25,12903,6707],{"class":35},[25,12905,6710],{"class":268},[25,12907,3892],{"class":35},[25,12909,6715],{"class":268},[25,12911,12912],{"class":27,"line":355},[25,12913,6720],{"class":268},[25,12915,12916],{"class":27,"line":368},[25,12917,1525],{"emptyLinePlaceholder":1524},[25,12919,12920,12922,12924,12926,12928,12930,12932],{"class":27,"line":379},[25,12921,6666],{"class":268},[25,12923,6669],{"class":31},[25,12925,1939],{"class":268},[25,12927,6735],{"class":35},[25,12929,6133],{"class":268},[25,12931,2205],{"class":275},[25,12933,6681],{"class":268},[25,12935,12936,12938,12940,12942,12944,12946,12948,12950,12952],{"class":27,"line":499},[25,12937,6746],{"class":268},[25,12939,6749],{"class":31},[25,12941,1939],{"class":268},[25,12943,1911],{"class":743},[25,12945,6756],{"class":268},[25,12947,2205],{"class":275},[25,12949,6761],{"class":268},[25,12951,283],{"class":282},[25,12953,6766],{"class":268},[25,12955,12956,12958,12960,12962,12964,12966,12968,12970,12972],{"class":27,"line":509},[25,12957,6771],{"class":268},[25,12959,6749],{"class":31},[25,12961,1939],{"class":268},[25,12963,1911],{"class":743},[25,12965,6756],{"class":268},[25,12967,2205],{"class":275},[25,12969,6761],{"class":268},[25,12971,283],{"class":282},[25,12973,6766],{"class":268},[25,12975,12976],{"class":27,"line":515},[25,12977,6720],{"class":268},[25,12979,12980],{"class":27,"line":520},[25,12981,1525],{"emptyLinePlaceholder":1524},[25,12983,12984,12986,12988,12990,12992,12994],{"class":27,"line":532},[25,12985,3551],{"class":31},[25,12987,1939],{"class":268},[25,12989,6804],{"class":35},[25,12991,6133],{"class":268},[25,12993,2205],{"class":275},[25,12995,2208],{"class":268},[25,12997,12998,13000,13002,13004,13006,13008,13010,13012],{"class":27,"line":544},[25,12999,6142],{"class":31},[25,13001,1939],{"class":268},[25,13003,6819],{"class":35},[25,13005,91],{"class":268},[25,13007,1911],{"class":743},[25,13009,6756],{"class":268},[25,13011,2205],{"class":275},[25,13013,2208],{"class":268},[25,13015,13016,13018,13020,13022,13024],{"class":27,"line":556},[25,13017,2038],{"class":743},[25,13019,2105],{"class":31},[25,13021,6838],{"class":268},[25,13023,6168],{"class":35},[25,13025,6843],{"class":268},[25,13027,13028],{"class":27,"line":568},[25,13029,1525],{"emptyLinePlaceholder":1524},[25,13031,13032,13034,13036,13038,13040,13042,13044,13046,13048,13050],{"class":27,"line":579},[25,13033,6158],{"class":31},[25,13035,6854],{"class":268},[25,13037,6857],{"class":31},[25,13039,1939],{"class":268},[25,13041,6168],{"class":35},[25,13043,91],{"class":268},[25,13045,6866],{"class":35},[25,13047,91],{"class":268},[25,13049,3892],{"class":35},[25,13051,1945],{"class":268},[25,13053,13054],{"class":27,"line":589},[25,13055,4527],{"class":268},[25,13057,13058],{"class":27,"line":595},[25,13059,1525],{"emptyLinePlaceholder":1524},[25,13061,13062,13064,13066,13068,13070,13072,13074,13076],{"class":27,"line":601},[25,13063,6142],{"class":31},[25,13065,1939],{"class":268},[25,13067,6889],{"class":35},[25,13069,91],{"class":268},[25,13071,1911],{"class":743},[25,13073,6756],{"class":268},[25,13075,2205],{"class":275},[25,13077,2208],{"class":268},[25,13079,13080,13082,13084,13086,13088,13090,13092,13094,13096],{"class":27,"line":1102},[25,13081,2038],{"class":743},[25,13083,2105],{"class":31},[25,13085,6838],{"class":268},[25,13087,6168],{"class":35},[25,13089,91],{"class":268},[25,13091,6914],{"class":35},[25,13093,91],{"class":268},[25,13095,6235],{"class":35},[25,13097,6843],{"class":268},[25,13099,13100],{"class":27,"line":1110},[25,13101,1525],{"emptyLinePlaceholder":1524},[25,13103,13104,13106,13108,13110,13112,13114,13116,13118,13120,13122],{"class":27,"line":1123},[25,13105,6158],{"class":31},[25,13107,6854],{"class":268},[25,13109,6857],{"class":31},[25,13111,1939],{"class":268},[25,13113,6168],{"class":35},[25,13115,91],{"class":268},[25,13117,6235],{"class":35},[25,13119,91],{"class":268},[25,13121,3892],{"class":35},[25,13123,1945],{"class":268},[25,13125,13126],{"class":27,"line":1136},[25,13127,4527],{"class":268},[25,13129,13130],{"class":27,"line":1149},[25,13131,1525],{"emptyLinePlaceholder":1524},[25,13133,13134,13136,13138,13140,13142,13144,13146,13148],{"class":27,"line":1160},[25,13135,6142],{"class":31},[25,13137,1939],{"class":268},[25,13139,6963],{"class":35},[25,13141,91],{"class":268},[25,13143,1911],{"class":743},[25,13145,6756],{"class":268},[25,13147,2205],{"class":275},[25,13149,2208],{"class":268},[25,13151,13152,13154,13156,13158,13160],{"class":27,"line":1165},[25,13153,2038],{"class":743},[25,13155,2105],{"class":31},[25,13157,6838],{"class":268},[25,13159,6984],{"class":35},[25,13161,6843],{"class":268},[25,13163,13164],{"class":27,"line":1173},[25,13165,1525],{"emptyLinePlaceholder":1524},[25,13167,13168,13170,13172,13174,13176,13178,13180,13182,13184,13186,13188,13190],{"class":27,"line":1186},[25,13169,6158],{"class":31},[25,13171,6997],{"class":268},[25,13173,6857],{"class":31},[25,13175,3495],{"class":268},[25,13177,6168],{"class":35},[25,13179,91],{"class":268},[25,13181,6230],{"class":35},[25,13183,7010],{"class":268},[25,13185,6866],{"class":35},[25,13187,91],{"class":268},[25,13189,3892],{"class":35},[25,13191,1945],{"class":268},[25,13193,13194],{"class":27,"line":1199},[25,13195,4527],{"class":268},[25,13197,13198],{"class":27,"line":1212},[25,13199,1703],{"class":268},[11,13201,7029],{},[15,13203,13204],{"className":17,"code":7032,"language":19,"meta":20,"style":20},[22,13205,13206],{"__ignoreMap":20},[25,13207,13208,13210],{"class":27,"line":28},[25,13209,50],{"class":31},[25,13211,7041],{"class":35},[15,13213,13215],{"className":13214,"code":7045,"language":230,"meta":20},[228],[22,13216,7045],{"__ignoreMap":20},[11,13218,7050,13219,7053],{},[22,13220,1717],{},[72,13222,7057],{"id":7056},[11,13224,7060],{},[15,13226,13227],{"className":17,"code":7063,"language":19,"meta":20,"style":20},[22,13228,13229],{"__ignoreMap":20},[25,13230,13231,13233,13235],{"class":27,"line":28},[25,13232,50],{"class":31},[25,13234,7072],{"class":35},[25,13236,7075],{"class":35},[11,13238,7078,13239,7083],{},[60,13240,97],{"href":7081,"rel":13241},[96],[15,13243,13244],{"className":17,"code":7086,"language":19,"meta":20,"style":20},[22,13245,13246,13252],{"__ignoreMap":20},[25,13247,13248,13250],{"class":27,"line":28},[25,13249,50],{"class":31},[25,13251,7095],{"class":35},[25,13253,13254,13256,13258,13260],{"class":27,"line":272},[25,13255,50],{"class":31},[25,13257,7102],{"class":35},[25,13259,7105],{"class":282},[25,13261,7108],{"class":35},[11,13263,2579,13264,7114,13266,7117,13268,7121,13270,7124,13272,7127],{},[22,13265,7113],{},[22,13267,1279],{},[22,13269,7120],{},[22,13271,1267],{},[22,13273,189],{},[15,13275,13276],{"className":17,"code":7130,"language":19,"meta":20,"style":20},[22,13277,13278,13286],{"__ignoreMap":20},[25,13279,13280,13282,13284],{"class":27,"line":28},[25,13281,32],{"class":31},[25,13283,7139],{"class":35},[25,13285,221],{"class":35},[25,13287,13288,13290,13292],{"class":27,"line":272},[25,13289,32],{"class":31},[25,13291,7139],{"class":35},[25,13293,39],{"class":35},[11,13295,7152,13296,7155],{},[22,13297,1251],{},[11,13299,7158],{},[15,13301,13302],{"className":17,"code":7161,"language":19,"meta":20,"style":20},[22,13303,13304,13312],{"__ignoreMap":20},[25,13305,13306,13308,13310],{"class":27,"line":28},[25,13307,50],{"class":31},[25,13309,7170],{"class":35},[25,13311,7173],{"class":35},[25,13313,13314,13316],{"class":27,"line":272},[25,13315,50],{"class":31},[25,13317,7180],{"class":35},[72,13319,7184],{"id":7183},[11,13321,7187,13322,7190,13324,7193,13326,7197,13328,7200,13330,7203],{},[22,13323,1785],{},[22,13325,5230],{},[22,13327,7196],{},[22,13329,6163],{},[22,13331,669],{},[11,13333,7206],{},[636,13335,13336,13340,13344,13348],{},[639,13337,7211,13338,150],{},[22,13339,1767],{},[639,13341,7216,13342,150],{},[22,13343,1771],{},[639,13345,7221,13346,150],{},[22,13347,669],{},[639,13349,7226,13350,7229],{},[22,13351,5230],{},[72,13353,7233],{"id":7232},[11,13355,7236,13356,7239],{},[22,13357,32],{},[11,13359,7242],{},[11,13361,7245,13362,150],{},[60,13363,7250],{"href":7248,"rel":13364},[96],[11,13366,7253],{},[7255,13368,7257],{},{"title":20,"searchDepth":272,"depth":272,"links":13370},[13371,13372,13373,13374,13375,13376,13377,13378,13379,13380,13381,13382,13383],{"id":74,"depth":272,"text":75},{"id":203,"depth":272,"text":204},{"id":624,"depth":272,"text":625},{"id":717,"depth":272,"text":718},{"id":1747,"depth":272,"text":1748},{"id":1778,"depth":272,"text":1779},{"id":2365,"depth":272,"text":2366},{"id":3780,"depth":272,"text":3781},{"id":5218,"depth":272,"text":5219},{"id":6079,"depth":272,"text":6080},{"id":7056,"depth":272,"text":7057},{"id":7183,"depth":272,"text":7184},{"id":7232,"depth":272,"text":7233},{},{"title":6,"description":7274},[13387],{"id":13388,"title":13389,"body":13390,"category":46,"date":13513,"description":13394,"draft":7275,"extension":7276,"image":13514,"meta":13515,"navigation":1524,"path":13516,"seo":13517,"stem":13518,"tighten":1524,"__hash__":13519},"blog/blog/form-validation-with-type-inference-made-easy-with-zod-the-best-sidekick-for-typescript.md","Form Validation With Type Inference Made Easy With Zod, The Best Sidekick For Typescript",{"type":8,"value":13391,"toc":13511},[13392,13395,13402,13494,13497,13505,13508],[11,13393,13394],{},"Zod is amazing! You can use it to define the schema of any object and validate it. Form data? No problem. Nested arrays and objects? We've got you covered. Custom data types? Yeah!",[11,13396,13397,13398,13401],{},"And if you're new to TypeScript, Zod can help you define types in a more intuitive way: define the object schema using Zod functions, then use ",[22,13399,13400],{},"z.infer"," to infer the types.",[15,13403,13405],{"className":1500,"code":13404,"language":1503,"meta":20,"style":20},"const taskSchema = z.object({\n    title: z.string(),\n    points: z.number(),\n    completed: z.boolean(),\n    comment: z.string().optional()\n})\n\ntype Task = z.infer\u003Ctypeof taskSchema>\n",[22,13406,13407,13422,13431,13440,13450,13464,13468,13472],{"__ignoreMap":20},[25,13408,13409,13411,13414,13416,13418,13420],{"class":27,"line":28},[25,13410,1843],{"class":275},[25,13412,13413],{"class":268}," taskSchema ",[25,13415,1874],{"class":743},[25,13417,3864],{"class":268},[25,13419,3867],{"class":31},[25,13421,1539],{"class":268},[25,13423,13424,13427,13429],{"class":27,"line":272},[25,13425,13426],{"class":268},"    title: z.",[25,13428,1858],{"class":31},[25,13430,3879],{"class":268},[25,13432,13433,13436,13438],{"class":27,"line":289},[25,13434,13435],{"class":268},"    points: z.",[25,13437,2723],{"class":31},[25,13439,3879],{"class":268},[25,13441,13442,13445,13448],{"class":27,"line":303},[25,13443,13444],{"class":268},"    completed: z.",[25,13446,13447],{"class":31},"boolean",[25,13449,3879],{"class":268},[25,13451,13452,13455,13457,13459,13462],{"class":27,"line":316},[25,13453,13454],{"class":268},"    comment: z.",[25,13456,1858],{"class":31},[25,13458,2185],{"class":268},[25,13460,13461],{"class":31},"optional",[25,13463,4133],{"class":268},[25,13465,13466],{"class":27,"line":329},[25,13467,1703],{"class":268},[25,13469,13470],{"class":27,"line":342},[25,13471,1525],{"emptyLinePlaceholder":1524},[25,13473,13474,13476,13479,13481,13483,13485,13487,13489,13491],{"class":27,"line":355},[25,13475,1814],{"class":275},[25,13477,13478],{"class":1851}," Task",[25,13480,2644],{"class":743},[25,13482,3930],{"class":1851},[25,13484,150],{"class":268},[25,13486,3935],{"class":1851},[25,13488,1855],{"class":268},[25,13490,3940],{"class":743},[25,13492,13493],{"class":268}," taskSchema>\n",[11,13495,13496],{},"Read all about it in my article on Tighten's blog. Click the box below:",[7304,13498,13502],{"image":13499,"link":13500,"title":13501},"https://tighten.com/assets/images/insights/form-validation-with-type-inference-made-easy-with-zod-the-best-sidekick-for-typescript-preview.jpg","https://tighten.com/insights/form-validation-with-type-inference-made-easy-with-zod-the-best-sidekick-for-typescript/","Form Validation with Type Inference Made Easy with Zod, the Best Sidekick for TypeScript",[11,13503,13504],{},"Server-side validation is a must, but client-side validation is also crucial: when a user attempts to submit a form, providing instant feedback and highlighting the fields with invalid data can be an invaluable guide to help them get things done.",[11,13506,13507],{},"And yes, the library gets its name from the Superman villain. Great!",[7255,13509,13510],{},"html pre.shiki code .sOx1s, html code.shiki .sOx1s{--shiki-default:#66D9EF;--shiki-default-font-style:italic}html pre.shiki code .sCdxs, html code.shiki .sCdxs{--shiki-default:#F8F8F2}html pre.shiki code .s8I7P, html code.shiki .s8I7P{--shiki-default:#F92672}html pre.shiki code .sHkqI, html code.shiki .sHkqI{--shiki-default:#A6E22E}html pre.shiki code .soZtE, html code.shiki .soZtE{--shiki-default:#A6E22E;--shiki-default-text-decoration:underline}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":20,"searchDepth":272,"depth":272,"links":13512},[],"2024-03-29","/img/blog/zod.png",{},"/blog/form-validation-with-type-inference-made-easy-with-zod-the-best-sidekick-for-typescript",{"title":13389,"description":13394},"blog/form-validation-with-type-inference-made-easy-with-zod-the-best-sidekick-for-typescript","wX4usiPS8ijaJY89gCvcUGEqGCA07E6rVakbfcP4dzU",1793579681904]