[{"data":1,"prerenderedAt":1179},["ShallowReactive",2],{"page-\u002Fformat\u002Fgetting-started\u002Ffor-developers":3,"navigation":815},{"collection":4,"page":5},"docs_en",{"id":6,"title":7,"body":8,"description":807,"extension":808,"meta":809,"navigation":171,"path":810,"rawbody":811,"seo":812,"stem":813,"__hash__":814},"docs_en\u002Fformat\u002F1.getting-started\u002F3.for-developers.md","For developers",{"type":9,"value":10,"toc":798},"minimark",[11,33,38,95,312,328,332,335,343,365,369,496,515,519,612,619,623,643,751,755,773,777,794],[12,13,14,15,19,20,25,26,32],"p",{},"A ",[16,17,18],"code",{},".well"," file is a JSON object with a fixed set of top-level blocks. You can read it with any JSON parser and validate it with the published ",[21,22,24],"a",{"href":23},"\u002Fformat\u002Freference\u002Fjson-schema","JSON Schema"," in any language. In TypeScript or JavaScript, ",[21,27,29],{"href":28},"\u002Fcore",[16,30,31],{},"@welldot\u002Fcore"," gives you types, validation that matches the spec, and the v1 upgrade.",[34,35,37],"h2",{"id":36},"read-and-validate-in-typescript","Read and validate in TypeScript",[39,40,41,66,81],"code-group",{},[42,43,49],"pre",{"className":44,"code":45,"filename":46,"language":47,"meta":48,"style":48},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","pnpm add @welldot\u002Fcore\n","pnpm","bash","",[16,50,51],{"__ignoreMap":48},[52,53,56,59,63],"span",{"class":54,"line":55},"line",1,[52,57,46],{"class":58},"sBMFI",[52,60,62],{"class":61},"sfazB"," add",[52,64,65],{"class":61}," @welldot\u002Fcore\n",[42,67,70],{"className":44,"code":68,"filename":69,"language":47,"meta":48,"style":48},"npm install @welldot\u002Fcore\n","npm",[16,71,72],{"__ignoreMap":48},[52,73,74,76,79],{"class":54,"line":55},[52,75,69],{"class":58},[52,77,78],{"class":61}," install",[52,80,65],{"class":61},[42,82,85],{"className":44,"code":83,"filename":84,"language":47,"meta":48,"style":48},"yarn add @welldot\u002Fcore\n","yarn",[16,86,87],{"__ignoreMap":48},[52,88,89,91,93],{"class":54,"line":55},[52,90,84],{"class":58},[52,92,62],{"class":61},[52,94,65],{"class":61},[42,96,101],{"className":97,"code":98,"filename":99,"language":100,"meta":48,"style":48},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { readFile } from 'node:fs\u002Fpromises';\nimport { parseWell, type Well } from '@welldot\u002Fcore';\n\nconst text = await readFile('PT-01.well', 'utf8');\n\n\u002F\u002F Throws a ZodError (with a path for each problem) when the file is invalid.\n\u002F\u002F A version 1 file is upgraded to v2 on the way in.\nconst well: Well = parseWell(text);\n\nconsole.log(well.name, well.bore_hole.length, well.lithology.length);\n","read.ts","ts",[16,102,103,135,166,173,216,221,228,234,257,262],{"__ignoreMap":48},[52,104,105,109,113,117,120,123,126,129,132],{"class":54,"line":55},[52,106,108],{"class":107},"s7zQu","import",[52,110,112],{"class":111},"sMK4o"," {",[52,114,116],{"class":115},"sTEyZ"," readFile",[52,118,119],{"class":111}," }",[52,121,122],{"class":107}," from",[52,124,125],{"class":111}," '",[52,127,128],{"class":61},"node:fs\u002Fpromises",[52,130,131],{"class":111},"'",[52,133,134],{"class":111},";\n",[52,136,138,140,142,145,148,151,154,156,158,160,162,164],{"class":54,"line":137},2,[52,139,108],{"class":107},[52,141,112],{"class":111},[52,143,144],{"class":115}," parseWell",[52,146,147],{"class":111},",",[52,149,150],{"class":107}," type",[52,152,153],{"class":115}," Well",[52,155,119],{"class":111},[52,157,122],{"class":107},[52,159,125],{"class":111},[52,161,31],{"class":61},[52,163,131],{"class":111},[52,165,134],{"class":111},[52,167,169],{"class":54,"line":168},3,[52,170,172],{"emptyLinePlaceholder":171},true,"\n",[52,174,176,180,183,186,189,192,195,197,200,202,204,206,209,211,214],{"class":54,"line":175},4,[52,177,179],{"class":178},"spNyl","const",[52,181,182],{"class":115}," text ",[52,184,185],{"class":111},"=",[52,187,188],{"class":107}," await",[52,190,116],{"class":191},"s2Zo4",[52,193,194],{"class":115},"(",[52,196,131],{"class":111},[52,198,199],{"class":61},"PT-01.well",[52,201,131],{"class":111},[52,203,147],{"class":111},[52,205,125],{"class":111},[52,207,208],{"class":61},"utf8",[52,210,131],{"class":111},[52,212,213],{"class":115},")",[52,215,134],{"class":111},[52,217,219],{"class":54,"line":218},5,[52,220,172],{"emptyLinePlaceholder":171},[52,222,224],{"class":54,"line":223},6,[52,225,227],{"class":226},"sHwdD","\u002F\u002F Throws a ZodError (with a path for each problem) when the file is invalid.\n",[52,229,231],{"class":54,"line":230},7,[52,232,233],{"class":226},"\u002F\u002F A version 1 file is upgraded to v2 on the way in.\n",[52,235,237,239,242,245,247,250,252,255],{"class":54,"line":236},8,[52,238,179],{"class":178},[52,240,241],{"class":115}," well",[52,243,244],{"class":111},":",[52,246,153],{"class":58},[52,248,249],{"class":111}," =",[52,251,144],{"class":191},[52,253,254],{"class":115},"(text)",[52,256,134],{"class":111},[52,258,260],{"class":54,"line":259},9,[52,261,172],{"emptyLinePlaceholder":171},[52,263,265,268,271,274,277,279,282,284,286,288,291,293,296,298,300,302,305,307,310],{"class":54,"line":264},10,[52,266,267],{"class":115},"console",[52,269,270],{"class":111},".",[52,272,273],{"class":191},"log",[52,275,276],{"class":115},"(well",[52,278,270],{"class":111},[52,280,281],{"class":115},"name",[52,283,147],{"class":111},[52,285,241],{"class":115},[52,287,270],{"class":111},[52,289,290],{"class":115},"bore_hole",[52,292,270],{"class":111},[52,294,295],{"class":115},"length",[52,297,147],{"class":111},[52,299,241],{"class":115},[52,301,270],{"class":111},[52,303,304],{"class":115},"lithology",[52,306,270],{"class":111},[52,308,309],{"class":115},"length)",[52,311,134],{"class":111},[12,313,314,318,319,322,323,327],{},[21,315,317],{"href":316},"\u002Fcore\u002Fguides\u002Fparsing-and-validating","Parsing and validating"," covers the error shape, ",[16,320,321],{},"safeParse"," and legacy files. ",[21,324,326],{"href":325},"\u002Fcore\u002Fguides\u002Fserializing-and-sharing","Serializing and sharing"," covers writing a file back.",[34,329,331],{"id":330},"validate-in-other-languages","Validate in other languages",[12,333,334],{},"The JSON Schema (draft 2020-12) is published at a stable URL:",[42,336,341],{"className":337,"code":339,"language":340,"meta":48},[338],"language-text","https:\u002F\u002Fwelldot.org\u002Fschema\u002Fv2\u002Fwell.schema.json\n","text",[16,342,339],{"__ignoreMap":48},[12,344,345,346,349,350,353,354,357,358,360,361,270],{},"Any JSON Schema validator can use it, for example ",[16,347,348],{},"ajv"," in JavaScript, ",[16,351,352],{},"jsonschema"," in Python or ",[16,355,356],{},"santhosh-tekuri\u002Fjsonschema"," in Go. The schema is generated from the Zod validators of ",[16,359,31],{},", so the two accept the same documents. A few rules can only be checked in code; see ",[21,362,364],{"href":363},"\u002Fformat\u002Fguides\u002Fvalidating","Validating",[34,366,368],{"id":367},"what-the-shape-guarantees","What the shape guarantees",[370,371,372,431,442,456,471,481],"ul",{},[373,374,375,379,380,383,384,387,388,392,393,383,395,383,398,383,401,383,404,383,407,383,410,383,412,383,415,418,419,423,424,427,428,430],"li",{},[376,377,378],"strong",{},"Required fields."," ",[16,381,382],{},"version",", ",[16,385,386],{},"well_type"," (",[21,389,391],{"href":390},"\u002Fformat\u002Fspec\u002Fv2\u002Fformat-reference#core-identity","core identity",") and the construction and geology arrays (",[16,394,290],{},[16,396,397],{},"well_case",[16,399,400],{},"reduction",[16,402,403],{},"well_screen",[16,405,406],{},"surface_case",[16,408,409],{},"hole_fill",[16,411,304],{},[16,413,414],{},"fractures",[16,416,417],{},"caves",", possibly empty) are required. Everything else is optional. See the ",[21,420,422],{"href":421},"\u002Fformat\u002Freference\u002Fobjects\u002Fwell","Well object",". Note that ",[16,425,426],{},"parseWell"," and the generated JSON Schema currently accept a file without ",[16,429,386],{},"; write it anyway.",[373,432,433,436,437,441],{},[376,434,435],{},"Fixed units."," Every number has one canonical unit set by the spec, never by the file (",[21,438,440],{"href":439},"\u002Fformat\u002Fspec\u002Fv2\u002Fformat-reference#units","Units","). Convert on display, not in storage.",[373,443,444,447,448,387,451,455],{},[376,445,446],{},"Absent means unknown."," Optional fields without a value are omitted, never ",[16,449,450],{},"null",[21,452,454],{"href":453},"\u002Fformat\u002Fspec\u002Fv2\u002Fformat-reference#absent-values-since-v24","Absent values",").",[373,457,458,461,462,465,466,470],{},[376,459,460],{},"Unknown members survive."," Readers must preserve fields and blocks they do not recognize, prefixed with ",[16,463,464],{},"x-"," or not (",[21,467,469],{"href":468},"\u002Fformat\u002Fspec\u002Fv2\u002Fformat-reference#extensibility","Extensibility","). Do not strip them on save.",[373,472,473,476,477,455],{},[376,474,475],{},"Open vocabularies."," Most string fields recommend values but accept any string. Show unknown values as they are (",[21,478,480],{"href":479},"\u002Fformat\u002Fspec\u002Fv2\u002Fformat-reference#recommended-vocabularies","Recommended vocabularies",[373,482,483,486,487,490,491,495],{},[376,484,485],{},"String ids, local references."," Records point to each other by string ",[16,488,489],{},"id"," within the same file (",[21,492,494],{"href":493},"\u002Fformat\u002Fspec\u002Fv2\u002Fformat-reference#cross-reference-and-uniqueness-rules","Cross-reference rules","). A dangling reference is a warning, not an error.",[497,498,499],"note",{},[12,500,501,503,504,506,507,509,510,514],{},[16,502,426],{}," in ",[16,505,31],{}," currently accepts a file without ",[16,508,382],{},". The spec says such a file SHOULD be rejected (",[21,511,513],{"href":512},"\u002Fformat\u002Fspec\u002Fv2\u002Fformat-reference#parser-version-handling","parser version handling","), so always write it.",[34,516,518],{"id":517},"parts-of-the-spec-to-read-first","Parts of the spec to read first",[520,521,522,535],"table",{},[523,524,525],"thead",{},[526,527,528,532],"tr",{},[529,530,531],"th",{},"If you are building",[529,533,534],{},"Read",[536,537,538,556,576,595],"tbody",{},[526,539,540,544],{},[541,542,543],"td",{},"A reader or viewer",[541,545,546,383,550,383,554],{},[21,547,549],{"href":548},"\u002Fformat\u002Fspec\u002Fv2\u002Fformat-reference#top-level-structure","Top-level structure",[21,551,553],{"href":552},"\u002Fformat\u002Fspec\u002Fv2\u002Fformat-reference#versioning","Versioning",[21,555,440],{"href":439},[526,557,558,561],{},[541,559,560],{},"An editor",[541,562,563,564,383,568,383,572],{},"the above, plus ",[21,565,567],{"href":566},"\u002Fformat\u002Fspec\u002Fv2\u002Fformat-reference#block-kinds-since-v23","Block kinds",[21,569,571],{"href":570},"\u002Fformat\u002Fspec\u002Fv2\u002Fformat-reference#datetime-conventions","Datetime conventions",[21,573,575],{"href":574},"\u002Fformat\u002Fspec\u002Fv2\u002Fformat-reference#duplicate-ids-within-a-scope","Duplicate ids",[526,577,578,581],{},[541,579,580],{},"A database or registry",[541,582,583,383,585,383,591],{},[21,584,494],{"href":493},[21,586,588],{"href":587},"\u002Fformat\u002Fspec\u002Fv2\u002Fformat-reference#well_id",[16,589,590],{},"well_id",[21,592,594],{"href":593},"\u002Fformat\u002Fspec\u002Fv2\u002Finteroperability","Interoperability",[526,596,597,600],{},[541,598,599],{},"A converter from another format",[541,601,602,383,604,383,608],{},[21,603,440],{"href":439},[21,605,607],{"href":606},"\u002Fformat\u002Fspec\u002Fv2\u002Fformat-reference#precision-and-uncertainty","Precision",[21,609,611],{"href":610},"\u002Fformat\u002Fspec\u002Fv2\u002Foverview#changes-from-v1","Changes from v1",[12,613,614,618],{},[21,615,617],{"href":616},"\u002Fformat\u002Fguides\u002Fbuilding-on-well","Building on .well"," collects the decisions that matter for editors, databases and pipelines.",[34,620,622],{"id":621},"draw-and-analyze","Draw and analyze",[370,624,625,634],{},[373,626,627,633],{},[21,628,630],{"href":629},"\u002Frender",[16,631,632],{},"@welldot\u002Frender"," draws a profile into an SVG element with D3.",[373,635,636,642],{},[21,637,639],{"href":638},"\u002Futils",[16,640,641],{},"@welldot\u002Futils"," computes volumes, drawdown, permit status, production totals and water quality indicators.",[42,644,646],{"className":97,"code":645,"language":100,"meta":48,"style":48},"import { parseWell } from '@welldot\u002Fcore';\nimport { calculateHoleFillVolume, getLatestStaticLevel } from '@welldot\u002Futils';\n\nconst well = parseWell(text);\ncalculateHoleFillVolume('gravel_pack', well); \u002F\u002F m³ of gravel pack\ngetLatestStaticLevel(well); \u002F\u002F m below ground, negative if flowing\n",[16,647,648,668,694,698,713,738],{"__ignoreMap":48},[52,649,650,652,654,656,658,660,662,664,666],{"class":54,"line":55},[52,651,108],{"class":107},[52,653,112],{"class":111},[52,655,144],{"class":115},[52,657,119],{"class":111},[52,659,122],{"class":107},[52,661,125],{"class":111},[52,663,31],{"class":61},[52,665,131],{"class":111},[52,667,134],{"class":111},[52,669,670,672,674,677,679,682,684,686,688,690,692],{"class":54,"line":137},[52,671,108],{"class":107},[52,673,112],{"class":111},[52,675,676],{"class":115}," calculateHoleFillVolume",[52,678,147],{"class":111},[52,680,681],{"class":115}," getLatestStaticLevel",[52,683,119],{"class":111},[52,685,122],{"class":107},[52,687,125],{"class":111},[52,689,641],{"class":61},[52,691,131],{"class":111},[52,693,134],{"class":111},[52,695,696],{"class":54,"line":168},[52,697,172],{"emptyLinePlaceholder":171},[52,699,700,702,705,707,709,711],{"class":54,"line":175},[52,701,179],{"class":178},[52,703,704],{"class":115}," well ",[52,706,185],{"class":111},[52,708,144],{"class":191},[52,710,254],{"class":115},[52,712,134],{"class":111},[52,714,715,718,720,722,725,727,729,732,735],{"class":54,"line":218},[52,716,717],{"class":191},"calculateHoleFillVolume",[52,719,194],{"class":115},[52,721,131],{"class":111},[52,723,724],{"class":61},"gravel_pack",[52,726,131],{"class":111},[52,728,147],{"class":111},[52,730,731],{"class":115}," well)",[52,733,734],{"class":111},";",[52,736,737],{"class":226}," \u002F\u002F m³ of gravel pack\n",[52,739,740,743,746,748],{"class":54,"line":223},[52,741,742],{"class":191},"getLatestStaticLevel",[52,744,745],{"class":115},"(well)",[52,747,734],{"class":111},[52,749,750],{"class":226}," \u002F\u002F m below ground, negative if flowing\n",[34,752,754],{"id":753},"test-data","Test data",[12,756,757,758,762,763,765,766,769,770,270],{},"The 19 ",[21,759,761],{"href":760},"\u002Fformat\u002Freference\u002Fexamples","example wells"," are complete, valid files covering crystalline, karst, sedimentary, flowing, hand-dug and monitoring wells, plus incomplete and inconsistent records. They ship with ",[16,764,31],{}," as ",[16,767,768],{},"@welldot\u002Fcore\u002Fexamples\u002F\u003Cfile>"," and are served at ",[16,771,772],{},"https:\u002F\u002Fwelldot.org\u002Fexamples\u002F\u003Cfile>",[34,774,776],{"id":775},"working-with-an-ai-assistant","Working with an AI assistant",[12,778,779,780,784,785,787,788,270],{},"Point your assistant at this site's ",[21,781,783],{"href":782},"\u002Fai\u002Fmcp","MCP server"," to let it search these docs and validate the ",[16,786,18],{}," files it writes, or give it ",[21,789,791],{"href":790},"\u002Fai\u002Fllms",[16,792,793],{},"\u002Fllms.txt",[795,796,797],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}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 .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":48,"searchDepth":137,"depth":137,"links":799},[800,801,802,803,804,805,806],{"id":36,"depth":137,"text":37},{"id":330,"depth":137,"text":331},{"id":367,"depth":137,"text":368},{"id":517,"depth":137,"text":518},{"id":621,"depth":137,"text":622},{"id":753,"depth":137,"text":754},{"id":775,"depth":137,"text":776},"Read, validate and write .well files from code, what the schema guarantees, and which parts of the spec matter most when you build on the format.","md",{},"\u002Fformat\u002Fgetting-started\u002Ffor-developers","---\ntitle: For developers\ndescription: Read, validate and write .well files from code, what the schema guarantees, and which parts of the spec matter most when you build on the format.\n---\n\nA `.well` file is a JSON object with a fixed set of top-level blocks. You can read it with any JSON parser and validate it with the published [JSON Schema](\u002Fformat\u002Freference\u002Fjson-schema) in any language. In TypeScript or JavaScript, [`@welldot\u002Fcore`](\u002Fcore) gives you types, validation that matches the spec, and the v1 upgrade.\n\n## Read and validate in TypeScript\n\n::code-group\n\n```bash [pnpm]\npnpm add @welldot\u002Fcore\n```\n\n```bash [npm]\nnpm install @welldot\u002Fcore\n```\n\n```bash [yarn]\nyarn add @welldot\u002Fcore\n```\n\n::\n\n```ts [read.ts]\nimport { readFile } from 'node:fs\u002Fpromises';\nimport { parseWell, type Well } from '@welldot\u002Fcore';\n\nconst text = await readFile('PT-01.well', 'utf8');\n\n\u002F\u002F Throws a ZodError (with a path for each problem) when the file is invalid.\n\u002F\u002F A version 1 file is upgraded to v2 on the way in.\nconst well: Well = parseWell(text);\n\nconsole.log(well.name, well.bore_hole.length, well.lithology.length);\n```\n\n[Parsing and validating](\u002Fcore\u002Fguides\u002Fparsing-and-validating) covers the error shape, `safeParse` and legacy files. [Serializing and sharing](\u002Fcore\u002Fguides\u002Fserializing-and-sharing) covers writing a file back.\n\n## Validate in other languages\n\nThe JSON Schema (draft 2020-12) is published at a stable URL:\n\n```text\nhttps:\u002F\u002Fwelldot.org\u002Fschema\u002Fv2\u002Fwell.schema.json\n```\n\nAny JSON Schema validator can use it, for example `ajv` in JavaScript, `jsonschema` in Python or `santhosh-tekuri\u002Fjsonschema` in Go. The schema is generated from the Zod validators of `@welldot\u002Fcore`, so the two accept the same documents. A few rules can only be checked in code; see [Validating](\u002Fformat\u002Fguides\u002Fvalidating).\n\n## What the shape guarantees\n\n- **Required fields.** `version`, `well_type` ([core identity](\u002Fformat\u002Fspec\u002Fv2\u002Fformat-reference#core-identity)) and the construction and geology arrays (`bore_hole`, `well_case`, `reduction`, `well_screen`, `surface_case`, `hole_fill`, `lithology`, `fractures`, `caves`, possibly empty) are required. Everything else is optional. See the [Well object](\u002Fformat\u002Freference\u002Fobjects\u002Fwell). Note that `parseWell` and the generated JSON Schema currently accept a file without `well_type`; write it anyway.\n- **Fixed units.** Every number has one canonical unit set by the spec, never by the file ([Units](\u002Fformat\u002Fspec\u002Fv2\u002Fformat-reference#units)). Convert on display, not in storage.\n- **Absent means unknown.** Optional fields without a value are omitted, never `null` ([Absent values](\u002Fformat\u002Fspec\u002Fv2\u002Fformat-reference#absent-values-since-v24)).\n- **Unknown members survive.** Readers must preserve fields and blocks they do not recognize, prefixed with `x-` or not ([Extensibility](\u002Fformat\u002Fspec\u002Fv2\u002Fformat-reference#extensibility)). Do not strip them on save.\n- **Open vocabularies.** Most string fields recommend values but accept any string. Show unknown values as they are ([Recommended vocabularies](\u002Fformat\u002Fspec\u002Fv2\u002Fformat-reference#recommended-vocabularies)).\n- **String ids, local references.** Records point to each other by string `id` within the same file ([Cross-reference rules](\u002Fformat\u002Fspec\u002Fv2\u002Fformat-reference#cross-reference-and-uniqueness-rules)). A dangling reference is a warning, not an error.\n\n::note\n`parseWell` in `@welldot\u002Fcore` currently accepts a file without `version`. The spec says such a file SHOULD be rejected ([parser version handling](\u002Fformat\u002Fspec\u002Fv2\u002Fformat-reference#parser-version-handling)), so always write it.\n::\n\n## Parts of the spec to read first\n\n| If you are building             | Read                                                                                                                                                                                                                                                 |\n| ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| A reader or viewer              | [Top-level structure](\u002Fformat\u002Fspec\u002Fv2\u002Fformat-reference#top-level-structure), [Versioning](\u002Fformat\u002Fspec\u002Fv2\u002Fformat-reference#versioning), [Units](\u002Fformat\u002Fspec\u002Fv2\u002Fformat-reference#units)                                                              |\n| An editor                       | the above, plus [Block kinds](\u002Fformat\u002Fspec\u002Fv2\u002Fformat-reference#block-kinds-since-v23), [Datetime conventions](\u002Fformat\u002Fspec\u002Fv2\u002Fformat-reference#datetime-conventions), [Duplicate ids](\u002Fformat\u002Fspec\u002Fv2\u002Fformat-reference#duplicate-ids-within-a-scope) |\n| A database or registry          | [Cross-reference rules](\u002Fformat\u002Fspec\u002Fv2\u002Fformat-reference#cross-reference-and-uniqueness-rules), [`well_id`](\u002Fformat\u002Fspec\u002Fv2\u002Fformat-reference#well_id), [Interoperability](\u002Fformat\u002Fspec\u002Fv2\u002Finteroperability)                                          |\n| A converter from another format | [Units](\u002Fformat\u002Fspec\u002Fv2\u002Fformat-reference#units), [Precision](\u002Fformat\u002Fspec\u002Fv2\u002Fformat-reference#precision-and-uncertainty), [Changes from v1](\u002Fformat\u002Fspec\u002Fv2\u002Foverview#changes-from-v1)                                                                |\n\n[Building on .well](\u002Fformat\u002Fguides\u002Fbuilding-on-well) collects the decisions that matter for editors, databases and pipelines.\n\n## Draw and analyze\n\n- [`@welldot\u002Frender`](\u002Frender) draws a profile into an SVG element with D3.\n- [`@welldot\u002Futils`](\u002Futils) computes volumes, drawdown, permit status, production totals and water quality indicators.\n\n```ts\nimport { parseWell } from '@welldot\u002Fcore';\nimport { calculateHoleFillVolume, getLatestStaticLevel } from '@welldot\u002Futils';\n\nconst well = parseWell(text);\ncalculateHoleFillVolume('gravel_pack', well); \u002F\u002F m³ of gravel pack\ngetLatestStaticLevel(well); \u002F\u002F m below ground, negative if flowing\n```\n\n## Test data\n\nThe 19 [example wells](\u002Fformat\u002Freference\u002Fexamples) are complete, valid files covering crystalline, karst, sedimentary, flowing, hand-dug and monitoring wells, plus incomplete and inconsistent records. They ship with `@welldot\u002Fcore` as `@welldot\u002Fcore\u002Fexamples\u002F\u003Cfile>` and are served at `https:\u002F\u002Fwelldot.org\u002Fexamples\u002F\u003Cfile>`.\n\n## Working with an AI assistant\n\nPoint your assistant at this site's [MCP server](\u002Fai\u002Fmcp) to let it search these docs and validate the `.well` files it writes, or give it [`\u002Fllms.txt`](\u002Fai\u002Fllms).\n",{"title":7,"description":807},"format\u002F1.getting-started\u002F3.for-developers","XF4jkzgaGuUkKNrft81YeWbkDd-cZPTerNPuQ6_UneE",{"docs_en":816,"spec":1114,"changelogs":1163},[817,834,853,904,1004,1057],{"title":818,"path":819,"stem":820,"children":821},"Ai","\u002Fai","ai",[822,825,829,832],{"title":823,"path":819,"stem":824},"Introduction","ai\u002Findex",{"title":826,"path":827,"stem":828},"Converting reports with an assistant","\u002Fai\u002Fconversion-skill","ai\u002Fconversion-skill",{"title":830,"path":790,"stem":831},"llms.txt and Markdown pages","ai\u002Fllms",{"title":783,"path":782,"stem":833},"ai\u002Fmcp",{"title":835,"path":836,"stem":837,"children":838},"Contributing","\u002Fcontributing","contributing",[839,841,845,849],{"title":823,"path":836,"stem":840},"contributing\u002Findex",{"title":842,"path":843,"stem":844},"Writing docs","\u002Fcontributing\u002Fwriting-docs","contributing\u002F1.writing-docs",{"title":846,"path":847,"stem":848},"Update rules","\u002Fcontributing\u002Fupdate-rules","contributing\u002F2.update-rules",{"title":850,"path":851,"stem":852},"Content components","\u002Fcontributing\u002Fcomponents","contributing\u002Fcomponents",{"title":854,"path":28,"stem":855,"children":856},"Core","core",[857,859,873,898],{"title":823,"path":28,"stem":858},"core\u002Findex",{"title":860,"path":861,"stem":862,"children":863,"page":872},"Getting Started","\u002Fcore\u002Fgetting-started","core\u002F1.getting-started",[864,868],{"title":865,"path":866,"stem":867},"Installation","\u002Fcore\u002Fgetting-started\u002Finstallation","core\u002F1.getting-started\u002F1.installation",{"title":869,"path":870,"stem":871},"First use","\u002Fcore\u002Fgetting-started\u002Ffirst-use","core\u002F1.getting-started\u002F2.first-use",false,{"title":874,"path":875,"stem":876,"children":877,"page":872},"Guides","\u002Fcore\u002Fguides","core\u002F2.guides",[878,880,882,886,890,894],{"title":317,"path":316,"stem":879},"core\u002F2.guides\u002F1.parsing-and-validating",{"title":326,"path":325,"stem":881},"core\u002F2.guides\u002F2.serializing-and-sharing",{"title":883,"path":884,"stem":885},"Unit conversion","\u002Fcore\u002Fguides\u002Funit-conversion","core\u002F2.guides\u002F3.unit-conversion",{"title":887,"path":888,"stem":889},"Vocabularies and textures","\u002Fcore\u002Fguides\u002Fvocabularies-and-textures","core\u002F2.guides\u002F4.vocabularies-and-textures",{"title":891,"path":892,"stem":893},"Water quality vocabulary","\u002Fcore\u002Fguides\u002Fwater-quality-vocabulary","core\u002F2.guides\u002F5.water-quality-vocabulary",{"title":895,"path":896,"stem":897},"Versions and time zones","\u002Fcore\u002Fguides\u002Fversions-and-time-zones","core\u002F2.guides\u002F6.versions-and-time-zones",{"title":899,"path":900,"stem":901,"children":902},"API reference","\u002Fcore\u002Fapi","core\u002Fapi\u002Findex",[903],{"title":899,"path":900,"stem":901},{"title":905,"path":906,"stem":907,"children":908},"Format","\u002Fformat","format",[909,911,928,956,977,994,1000],{"title":823,"path":906,"stem":910},"format\u002Findex",{"title":860,"path":912,"stem":913,"children":914,"page":872},"\u002Fformat\u002Fgetting-started","format\u002F1.getting-started",[915,919,923,924],{"title":916,"path":917,"stem":918},"What is .well?","\u002Fformat\u002Fgetting-started\u002Fwhat-is-well","format\u002F1.getting-started\u002F1.what-is-well",{"title":920,"path":921,"stem":922},"For geologists","\u002Fformat\u002Fgetting-started\u002Ffor-geologists","format\u002F1.getting-started\u002F2.for-geologists",{"title":7,"path":810,"stem":813},{"title":925,"path":926,"stem":927},"Your first .well file","\u002Fformat\u002Fgetting-started\u002Ffirst-well-file","format\u002F1.getting-started\u002F4.first-well-file",{"title":929,"path":930,"stem":931,"children":932,"page":872},"Concepts","\u002Fformat\u002Fconcepts","format\u002F2.concepts",[933,937,941,945,949,953],{"title":934,"path":935,"stem":936},"Depths and intervals","\u002Fformat\u002Fconcepts\u002Fdepths-and-intervals","format\u002F2.concepts\u002F1.depths-and-intervals",{"title":938,"path":939,"stem":940},"Units and precision","\u002Fformat\u002Fconcepts\u002Funits-and-precision","format\u002F2.concepts\u002F2.units-and-precision",{"title":942,"path":943,"stem":944},"Vocabularies","\u002Fformat\u002Fconcepts\u002Fvocabularies","format\u002F2.concepts\u002F3.vocabularies",{"title":946,"path":947,"stem":948},"Profiles","\u002Fformat\u002Fconcepts\u002Fprofiles","format\u002F2.concepts\u002F4.profiles",{"title":950,"path":951,"stem":952},"Versions and deprecation","\u002Fformat\u002Fconcepts\u002Fversions-and-deprecation","format\u002F2.concepts\u002F5.versions-and-deprecation",{"title":469,"path":954,"stem":955},"\u002Fformat\u002Fconcepts\u002Fextensibility","format\u002F2.concepts\u002F6.extensibility",{"title":874,"path":957,"stem":958,"children":959,"page":872},"\u002Fformat\u002Fguides","format\u002F3.guides",[960,964,968,970,974],{"title":961,"path":962,"stem":963},"Writing a .well by hand","\u002Fformat\u002Fguides\u002Fwriting-by-hand","format\u002F3.guides\u002F1.writing-by-hand",{"title":965,"path":966,"stem":967},"Converting a report","\u002Fformat\u002Fguides\u002Fconverting-a-report","format\u002F3.guides\u002F2.converting-a-report",{"title":364,"path":363,"stem":969},"format\u002F3.guides\u002F3.validating",{"title":971,"path":972,"stem":973},"Extending for your own needs","\u002Fformat\u002Fguides\u002Fextending","format\u002F3.guides\u002F4.extending",{"title":975,"path":616,"stem":976},"Building an editor or database on .well","format\u002F3.guides\u002F5.building-on-well",{"title":978,"path":979,"stem":980,"children":981},"Overview","\u002Fformat\u002Freference","format\u002F4.reference\u002Findex",[982,983,985,988],{"title":978,"path":979,"stem":980},{"title":24,"path":23,"stem":984},"format\u002F4.reference\u002F1.json-schema",{"title":986,"path":760,"stem":987},"Example wells","format\u002F4.reference\u002F2.examples",{"title":989,"path":990,"stem":991,"children":992},"Object reference","\u002Fformat\u002Freference\u002Fobjects","format\u002Freference\u002Fobjects\u002Findex",[993],{"title":989,"path":990,"stem":991},{"title":995,"path":996,"stem":997,"children":998},"About the spec","\u002Fformat\u002Fspec","format\u002F5.spec\u002Findex",[999],{"title":995,"path":996,"stem":997},{"title":1001,"path":1002,"stem":1003},"Changelog","\u002Fformat\u002Fchangelog","format\u002F6.changelog",{"title":1005,"path":629,"stem":1006,"children":1007},"Render","render",[1008,1010,1020,1052],{"title":823,"path":629,"stem":1009},"render\u002Findex",{"title":860,"path":1011,"stem":1012,"children":1013,"page":872},"\u002Frender\u002Fgetting-started","render\u002F1.getting-started",[1014,1017],{"title":865,"path":1015,"stem":1016},"\u002Frender\u002Fgetting-started\u002Finstallation","render\u002F1.getting-started\u002F1.installation",{"title":869,"path":1018,"stem":1019},"\u002Frender\u002Fgetting-started\u002Ffirst-use","render\u002F1.getting-started\u002F2.first-use",{"title":874,"path":1021,"stem":1022,"children":1023,"page":872},"\u002Frender\u002Fguides","render\u002F2.guides",[1024,1028,1032,1036,1040,1044,1048],{"title":1025,"path":1026,"stem":1027},"Panels and layout","\u002Frender\u002Fguides\u002Fpanels-and-layout","render\u002F2.guides\u002F1.panels-and-layout",{"title":1029,"path":1030,"stem":1031},"Layers and labels","\u002Frender\u002Fguides\u002Flayers-and-labels","render\u002F2.guides\u002F2.layers-and-labels",{"title":1033,"path":1034,"stem":1035},"Theming","\u002Frender\u002Fguides\u002Ftheming","render\u002F2.guides\u002F3.theming",{"title":1037,"path":1038,"stem":1039},"Locale and units","\u002Frender\u002Fguides\u002Flocale-and-units","render\u002F2.guides\u002F4.locale-and-units",{"title":1041,"path":1042,"stem":1043},"Legends","\u002Frender\u002Fguides\u002Flegends","render\u002F2.guides\u002F5.legends",{"title":1045,"path":1046,"stem":1047},"Zoom, pan and highlights","\u002Frender\u002Fguides\u002Finteraction","render\u002F2.guides\u002F6.interaction",{"title":1049,"path":1050,"stem":1051},"Using it in a framework","\u002Frender\u002Fguides\u002Fframeworks","render\u002F2.guides\u002F7.frameworks",{"title":899,"path":1053,"stem":1054,"children":1055},"\u002Frender\u002Fapi","render\u002Fapi\u002Findex",[1056],{"title":899,"path":1053,"stem":1054},{"title":1058,"path":638,"stem":1059,"children":1060},"Utils","utils",[1061,1063,1073,1109],{"title":823,"path":638,"stem":1062},"utils\u002Findex",{"title":860,"path":1064,"stem":1065,"children":1066,"page":872},"\u002Futils\u002Fgetting-started","utils\u002F1.getting-started",[1067,1070],{"title":865,"path":1068,"stem":1069},"\u002Futils\u002Fgetting-started\u002Finstallation","utils\u002F1.getting-started\u002F1.installation",{"title":869,"path":1071,"stem":1072},"\u002Futils\u002Fgetting-started\u002Ffirst-use","utils\u002F1.getting-started\u002F2.first-use",{"title":874,"path":1074,"stem":1075,"children":1076,"page":872},"\u002Futils\u002Fguides","utils\u002F2.guides",[1077,1081,1085,1089,1093,1097,1101,1105],{"title":1078,"path":1079,"stem":1080},"Geometry and volumes","\u002Futils\u002Fguides\u002Fgeometry-and-volumes","utils\u002F2.guides\u002F1.geometry-and-volumes",{"title":1082,"path":1083,"stem":1084},"Water levels and pumping tests","\u002Futils\u002Fguides\u002Fpumping-tests","utils\u002F2.guides\u002F2.pumping-tests",{"title":1086,"path":1087,"stem":1088},"Permits","\u002Futils\u002Fguides\u002Fpermits","utils\u002F2.guides\u002F3.permits",{"title":1090,"path":1091,"stem":1092},"Operation and production","\u002Futils\u002Fguides\u002Foperation","utils\u002F2.guides\u002F4.operation",{"title":1094,"path":1095,"stem":1096},"Water quality","\u002Futils\u002Fguides\u002Fwater-quality","utils\u002F2.guides\u002F5.water-quality",{"title":1098,"path":1099,"stem":1100},"Logger import","\u002Futils\u002Fguides\u002Flogger-import","utils\u002F2.guides\u002F6.logger-import",{"title":1102,"path":1103,"stem":1104},"SIAGAS import","\u002Futils\u002Fguides\u002Fsiagas-import","utils\u002F2.guides\u002F7.siagas-import",{"title":1106,"path":1107,"stem":1108},"Formatting","\u002Futils\u002Fguides\u002Fformatting","utils\u002F2.guides\u002F8.formatting",{"title":899,"path":1110,"stem":1111,"children":1112},"\u002Futils\u002Fapi","utils\u002Fapi\u002Findex",[1113],{"title":899,"path":1110,"stem":1111},[1115],{"title":905,"path":906,"stem":907,"children":1116,"page":872},[1117],{"title":1118,"path":996,"stem":1119,"children":1120,"page":872},"Spec","format\u002Fspec",[1121,1130,1139],{"title":1122,"path":1123,"stem":1124,"children":1125,"page":872},"Reference","\u002Fformat\u002Fspec\u002Freference","format\u002Fspec\u002Freference",[1126],{"title":1127,"path":1128,"stem":1129},"FGDC Texture Patterns Reference","\u002Fformat\u002Fspec\u002Freference\u002Ffgdc-textures","format\u002Fspec\u002Freference\u002Ffgdc-textures",{"title":1131,"path":1132,"stem":1133,"children":1134,"page":872},"V1","\u002Fformat\u002Fspec\u002Fv1","format\u002Fspec\u002Fv1",[1135],{"title":1136,"path":1137,"stem":1138},".well File Format Specification","\u002Fformat\u002Fspec\u002Fv1\u002Fwell-format","format\u002Fspec\u002Fv1\u002Fwell-format",{"title":1140,"path":1141,"stem":1142,"children":1143,"page":872},"V2","\u002Fformat\u002Fspec\u002Fv2","format\u002Fspec\u002Fv2",[1144,1148,1151,1155,1159],{"title":1145,"path":1146,"stem":1147},".well File Format Specification — Version 2.4: Format Reference","\u002Fformat\u002Fspec\u002Fv2\u002Fformat-reference","format\u002Fspec\u002Fv2\u002Fformat-reference",{"title":1149,"path":593,"stem":1150},".well File Format Specification — Version 2.4: Interoperability","format\u002Fspec\u002Fv2\u002Finteroperability",{"title":1152,"path":1153,"stem":1154},".well File Format Specification — Version 2.4: Object Schemas","\u002Fformat\u002Fspec\u002Fv2\u002Fobject-schemas","format\u002Fspec\u002Fv2\u002Fobject-schemas",{"title":1156,"path":1157,"stem":1158},".well File Format Specification — Version 2.4: Overview","\u002Fformat\u002Fspec\u002Fv2\u002Foverview","format\u002Fspec\u002Fv2\u002Foverview",{"title":1160,"path":1161,"stem":1162},".well File Format Specification — Version 2.4: Water Quality","\u002Fformat\u002Fspec\u002Fv2\u002Fwater-quality","format\u002Fspec\u002Fv2\u002Fwater-quality",[1164,1169,1174],{"title":854,"path":28,"stem":855,"children":1165,"page":872},[1166],{"title":31,"path":1167,"stem":1168},"\u002Fcore\u002Fchangelog","core\u002FCHANGELOG",{"title":1005,"path":629,"stem":1006,"children":1170,"page":872},[1171],{"title":632,"path":1172,"stem":1173},"\u002Frender\u002Fchangelog","render\u002FCHANGELOG",{"title":1058,"path":638,"stem":1059,"children":1175,"page":872},[1176],{"title":641,"path":1177,"stem":1178},"\u002Futils\u002Fchangelog","utils\u002FCHANGELOG",1793050492599]