[{"data":1,"prerenderedAt":671},["ShallowReactive",2],{"docs-navigation:en":3,"content-page:docs:-EYKn5R0hlCkwZnoVpLUlzHkJoKKmoCRpZ1mh-PPp9w":195,"content-page-surround:docs:-EYKn5R0hlCkwZnoVpLUlzHkJoKKmoCRpZ1mh-PPp9w":662,"i-lucide:clipboard":667},[4,54,74],{"title":5,"page":6,"canonicalKey":7,"locale":8,"id":9,"draft":6,"icon":10,"sidebar":11,"children":12},"Guides",false,"1","en","content:en:1.docs:1.guides:.navigation.yml","lucide:route","section",[13,19,26,33,40,47],{"title":14,"id":15,"canonicalKey":16,"locale":8,"draft":6,"icon":17,"path":18},"Install Guild Wars on Mac","content:en:1.docs:1.guides:1.install.md","1\u002F1","lucide:download","\u002Fdocs\u002Fguides\u002Finstall",{"title":20,"id":21,"canonicalKey":22,"locale":8,"draft":6,"navigation":23,"icon":24,"path":25},"Accounts & mobile linking","content:en:1.docs:1.guides:2.accounts.md","1\u002F2",{"title":20},"lucide:key-round","\u002Fdocs\u002Fguides\u002Faccounts",{"title":27,"id":28,"canonicalKey":29,"locale":8,"draft":6,"navigation":30,"icon":31,"path":32},"Play on Mac: options","content:en:1.docs:1.guides:3.play-guild-wars-on-mac.md","1\u002F3",{"title":27},"lucide:scale","\u002Fdocs\u002Fguides\u002Fplay-guild-wars-on-mac",{"title":34,"id":35,"canonicalKey":36,"locale":8,"draft":6,"navigation":37,"icon":38,"path":39},"Performance","content:en:1.docs:1.guides:4.performance.md","1\u002F4",{"title":34},"lucide:gauge","\u002Fdocs\u002Fguides\u002Fperformance",{"title":41,"id":42,"canonicalKey":43,"locale":8,"draft":6,"navigation":44,"icon":45,"path":46},"Templates","content:en:1.docs:1.guides:5.templates.md","1\u002F5",{"title":41},"lucide:bookmark","\u002Fdocs\u002Fguides\u002Ftemplates",{"title":48,"id":49,"canonicalKey":50,"locale":8,"draft":6,"navigation":51,"icon":52,"path":53},"Troubleshooting","content:en:1.docs:1.guides:6.troubleshooting.md","1\u002F6",{"title":48},"lucide:wrench","\u002Fdocs\u002Fguides\u002Ftroubleshooting",{"title":55,"page":6,"canonicalKey":56,"locale":8,"id":57,"draft":6,"icon":58,"sidebar":59,"children":60},"Project","2","content:en:1.docs:2.project:.navigation.yml","lucide:shield-check","group",[61,67],{"title":62,"id":63,"canonicalKey":64,"locale":8,"draft":6,"navigation":65,"icon":58,"path":66},"Safety & account risk","content:en:1.docs:2.project:1.safety.md","2\u002F1",{"title":62},"\u002Fdocs\u002Fproject\u002Fsafety",{"title":68,"id":69,"canonicalKey":70,"locale":8,"draft":6,"navigation":71,"icon":72,"path":73},"About & credits","content:en:1.docs:2.project:2.about.md","2\u002F2",{"title":68},"lucide:users","\u002Fdocs\u002Fproject\u002Fabout",{"title":75,"page":6,"canonicalKey":76,"locale":8,"id":77,"draft":6,"icon":78,"sidebar":11,"children":79},"For ArenaNet","3","content:en:1.docs:3.upstream:.navigation.yml","lucide:send",[80,87,94,120,146,158,177],{"title":81,"id":82,"canonicalKey":83,"locale":8,"draft":6,"navigation":84,"icon":85,"path":86},"Introduction","content:en:1.docs:3.upstream:1.introduction.md","3\u002F1",{"title":81},"lucide:book-open-check","\u002Fdocs\u002Fupstream\u002Fintroduction",{"title":88,"id":89,"canonicalKey":90,"locale":8,"draft":6,"navigation":91,"icon":92,"path":93},"Request summary","content:en:1.docs:3.upstream:2.request-summary.md","3\u002F2",{"title":88},"lucide:list-checks","\u002Fdocs\u002Fupstream\u002Frequest-summary",{"title":95,"page":6,"canonicalKey":96,"locale":8,"id":97,"draft":6,"icon":98,"sidebar":59,"children":99},"File system","3\u002F3","content:en:1.docs:3.upstream:3.filesystem:.navigation.yml","lucide:folder-x",[100,106,113],{"title":101,"id":102,"canonicalKey":103,"locale":8,"draft":6,"navigation":104,"icon":98,"path":105},"File routines (UR-01…04)","content:en:1.docs:3.upstream:3.filesystem:1.unimplemented-routines.md","3\u002F3\u002F1",{"title":101},"\u002Fdocs\u002Fupstream\u002Ffilesystem\u002Funimplemented-routines",{"title":107,"id":108,"canonicalKey":109,"locale":8,"draft":6,"navigation":110,"icon":111,"path":112},"RemoveExtension (UR-05)","content:en:1.docs:3.upstream:3.filesystem:2.path-remove-extension.md","3\u002F3\u002F2",{"title":107},"lucide:scissors","\u002Fdocs\u002Fupstream\u002Ffilesystem\u002Fpath-remove-extension",{"title":114,"id":115,"canonicalKey":116,"locale":8,"draft":6,"navigation":117,"icon":118,"path":119},"File::Open mode (UR-06)","content:en:1.docs:3.upstream:3.filesystem:3.file-open-mode.md","3\u002F3\u002F3",{"title":114},"lucide:file-plus-2","\u002Fdocs\u002Fupstream\u002Ffilesystem\u002Ffile-open-mode",{"title":121,"page":6,"canonicalKey":122,"locale":8,"id":123,"draft":6,"icon":124,"sidebar":59,"children":125},"Input","3\u002F4","content:en:1.docs:3.upstream:4.input:.navigation.yml","lucide:mouse-pointer-click",[126,132,139],{"title":127,"id":128,"canonicalKey":129,"locale":8,"draft":6,"navigation":130,"icon":124,"path":131},"Double-click (UR-07)","content:en:1.docs:3.upstream:4.input:1.double-click-flag.md","3\u002F4\u002F1",{"title":127},"\u002Fdocs\u002Fupstream\u002Finput\u002Fdouble-click-flag",{"title":133,"id":134,"canonicalKey":135,"locale":8,"draft":6,"navigation":136,"icon":137,"path":138},"Key labels (UR-08)","content:en:1.docs:3.upstream:4.input:2.key-labels.md","3\u002F4\u002F2",{"title":133},"lucide:keyboard","\u002Fdocs\u002Fupstream\u002Finput\u002Fkey-labels",{"title":140,"id":141,"canonicalKey":142,"locale":8,"draft":6,"navigation":143,"icon":144,"path":145},"Cursor re-test (UR-09)","content:en:1.docs:3.upstream:4.input:3.cursor-re-evaluation.md","3\u002F4\u002F3",{"title":140},"lucide:pointer","\u002Fdocs\u002Fupstream\u002Finput\u002Fcursor-re-evaluation",{"title":147,"page":6,"canonicalKey":148,"locale":8,"id":149,"draft":6,"icon":150,"sidebar":59,"children":151},"Runtime","3\u002F5","content:en:1.docs:3.upstream:5.runtime:.navigation.yml","lucide:cpu",[152],{"title":153,"id":154,"canonicalKey":155,"locale":8,"draft":6,"navigation":156,"icon":150,"path":157},"Heap maximum (UR-10)","content:en:1.docs:3.upstream:5.runtime:1.heap-maximum.md","3\u002F5\u002F1",{"title":153},"\u002Fdocs\u002Fupstream\u002Fruntime\u002Fheap-maximum",{"title":159,"page":6,"canonicalKey":160,"locale":8,"id":161,"draft":6,"icon":162,"sidebar":59,"children":163},"Interface proposals","3\u002F6","content:en:1.docs:3.upstream:6.proposals:.navigation.yml","lucide:plug",[164,171],{"title":165,"id":166,"canonicalKey":167,"locale":8,"draft":6,"navigation":168,"icon":169,"path":170},"Build identity (UR-11)","content:en:1.docs:3.upstream:6.proposals:1.build-identification.md","3\u002F6\u002F1",{"title":165},"lucide:fingerprint","\u002Fdocs\u002Fupstream\u002Fproposals\u002Fbuild-identification",{"title":172,"id":173,"canonicalKey":174,"locale":8,"draft":6,"navigation":175,"icon":162,"path":176},"Host interface (UR-12)","content:en:1.docs:3.upstream:6.proposals:2.platform-host-interface.md","3\u002F6\u002F2",{"title":172},"\u002Fdocs\u002Fupstream\u002Fproposals\u002Fplatform-host-interface",{"title":178,"page":6,"canonicalKey":179,"locale":8,"id":180,"draft":6,"icon":181,"sidebar":59,"children":182},"Reference","3\u002F7","content:en:1.docs:3.upstream:7.reference:.navigation.yml","lucide:microscope",[183,189],{"title":184,"id":185,"canonicalKey":186,"locale":8,"draft":6,"navigation":187,"icon":52,"path":188},"Our workarounds","content:en:1.docs:3.upstream:7.reference:1.our-workarounds.md","3\u002F7\u002F1",{"title":184},"\u002Fdocs\u002Fupstream\u002Freference\u002Four-workarounds",{"title":190,"id":191,"canonicalKey":192,"locale":8,"draft":6,"navigation":193,"icon":181,"path":194},"Verification method","content:en:1.docs:3.upstream:7.reference:2.verification-method.md","3\u002F7\u002F2",{"title":190},"\u002Fdocs\u002Fupstream\u002Freference\u002Fverification-method",{"title":196,"ref":197,"description":198,"icon":111,"updated":199,"navigation":200,"body":201,"type":647,"id":108,"canonicalKey":109,"draft":6,"partial":6,"locale":8,"collection":648,"navigationFile":6,"file":649,"route":655,"resolution":659},"UR-05: Path::RemoveExtension drops the last character","docs\u002Fupstream\u002Ffilesystem\u002Fpath-remove-extension","The remove-extension helper passes a filename length that is one too short. Every name that has an extension loses its last character.","2026-08-04",{"title":107},{"type":202,"children":203,"toc":631},"root",[204,218,237,262,279,298,305,310,377,382,388,407,417,436,442,447,453,529,535,540,597,602,608,626],{"type":205,"tag":206,"props":207,"children":208},"element","p",{},[209,216],{"type":205,"tag":210,"props":211,"children":212},"code",{},[213],{"type":214,"value":215},"text","Path::RemoveExtension",{"type":214,"value":217}," removes the extension and also the last character of\nthe file name. The defect only occurs when the path has an extension.",{"type":205,"tag":206,"props":219,"children":220},{},[221,223,228,230,235],{"type":214,"value":222},"Build used for the measurements below: 38797,\n",{"type":205,"tag":210,"props":224,"children":225},{},[226],{"type":214,"value":227},"3229678d3fd7d2f0e309530086a614d97f02e7eeb3ca12650ababfd2eb360817",{"type":214,"value":229},". We first\nfound the defect on build\n",{"type":205,"tag":210,"props":231,"children":232},{},[233],{"type":214,"value":234},"b0319704f3072d6948a66026a35af5eb0af12b48d70986783c293e7c77e98483",{"type":214,"value":236},"; it's\npresent on both, and function 457 is the helper on both.",{"type":205,"tag":206,"props":238,"children":239},{},[240,246,248,253,255,260],{"type":205,"tag":241,"props":242,"children":243},"strong",{},[244],{"type":214,"value":245},"Function 457",{"type":214,"value":247},", ",{"type":205,"tag":210,"props":249,"children":250},{},[251],{"type":214,"value":252},"Path::RemoveExtension(dst, src, chars)",{"type":214,"value":254},", in\n",{"type":205,"tag":210,"props":256,"children":257},{},[258],{"type":214,"value":259},"Base\u002FRtl\u002FPath.cpp",{"type":214,"value":261},".",{"type":205,"tag":206,"props":263,"children":264},{},[265,270,272,277],{"type":205,"tag":241,"props":266,"children":267},{},[268],{"type":214,"value":269},"Fix:",{"type":214,"value":271}," low effort, medium blast radius — the change is one length value, but\nthe template scan and ",{"type":205,"tag":210,"props":273,"children":274},{},[275],{"type":214,"value":276},"MdlTex.cpp",{"type":214,"value":278}," both call this helper, so anything that\ndepends on the current short result changes behaviour. We found no such code,\nbut we haven't read every caller.",{"type":205,"tag":206,"props":280,"children":281},{},[282,284,289,291,296],{"type":214,"value":283},"The function splits the path with ",{"type":205,"tag":210,"props":285,"children":286},{},[287],{"type":214,"value":288},"_wsplitpath",{"type":214,"value":290}," (function 411), then rebuilds\nit with ",{"type":205,"tag":210,"props":292,"children":293},{},[294],{"type":214,"value":295},"_wmakepath",{"type":214,"value":297}," (function 412) and a null extension. The filename length\nit passes to the split is one too short.",{"type":205,"tag":299,"props":300,"children":302},"h2",{"id":301},"what-the-client-does-now",[303],{"type":214,"value":304},"What the client does now",{"type":205,"tag":206,"props":306,"children":307},{},[308],{"type":214,"value":309},"We called the shipped function directly with six inputs:",{"type":205,"tag":311,"props":312,"children":315},"pre",{"language":214,"class":313,"tabindex":314},"shiki shiki-themes light-plus dark-plus dark:dark-plus","0",[316],{"type":205,"tag":210,"props":317,"children":319},{"class":318},"language-text",[320,331,333,341,342,350,351,359,360,368,369],{"type":205,"tag":321,"props":322,"children":325},"span",{"class":323,"style":324},"line","display: inline",[326],{"type":205,"tag":321,"props":327,"children":328},{},[329],{"type":214,"value":330},"Path::RemoveExtension(\"\\Healer.txt\")        = \"\\Heale\"         expected \"\\Healer\"",{"type":214,"value":332},"\n",{"type":205,"tag":321,"props":334,"children":335},{"class":323,"style":324},[336],{"type":205,"tag":321,"props":337,"children":338},{},[339],{"type":214,"value":340},"Path::RemoveExtension(\"\\Warrior.txt\")       = \"\\Warrio\"        expected \"\\Warrior\"",{"type":214,"value":332},{"type":205,"tag":321,"props":343,"children":344},{"class":323,"style":324},[345],{"type":205,"tag":321,"props":346,"children":347},{},[348],{"type":214,"value":349},"Path::RemoveExtension(\"\\Builds\\Healer.txt\") = \"\\Builds\\Heale\"  expected \"\\Builds\\Healer\"",{"type":214,"value":332},{"type":205,"tag":321,"props":352,"children":353},{"class":323,"style":324},[354],{"type":205,"tag":321,"props":355,"children":356},{},[357],{"type":214,"value":358},"Path::RemoveExtension(\"Healer.txt\")         = \"Heale\"          expected \"Healer\"",{"type":214,"value":332},{"type":205,"tag":321,"props":361,"children":362},{"class":323,"style":324},[363],{"type":205,"tag":321,"props":364,"children":365},{},[366],{"type":214,"value":367},"Path::RemoveExtension(\"\\My.Build.txt\")      = \"\\My.Buil\"       expected \"\\My.Build\"",{"type":214,"value":332},{"type":205,"tag":321,"props":370,"children":371},{"class":323,"style":324},[372],{"type":205,"tag":321,"props":373,"children":374},{},[375],{"type":214,"value":376},"Path::RemoveExtension(\"\\Healer\")            = \"\\Healer\"        correct, no extension",{"type":205,"tag":206,"props":378,"children":379},{},[380],{"type":214,"value":381},"The last line is correct: with no extension there's nothing to remove, so the\nlength error never fires. The fifth line shows the defect also applies to\nnames containing a dot — the function removes the last extension plus one more\ncharacter.",{"type":205,"tag":299,"props":383,"children":385},{"id":384},"why-this-matters",[386],{"type":214,"value":387},"Why this matters",{"type":205,"tag":206,"props":389,"children":390},{},[391,393,398,400,405],{"type":214,"value":392},"Function 9747 calls this helper for every template it enumerates. Once ",{"type":205,"tag":210,"props":394,"children":395},{},[396],{"type":214,"value":397},"UR-02",{"type":214,"value":399},"\nand ",{"type":205,"tag":210,"props":401,"children":402},{},[403],{"type":214,"value":404},"UR-03",{"type":214,"value":406}," are fixed and the template list works, every listed name will be\none character short — the load path builds a file path from that name and\ncan't find the file.",{"type":205,"tag":206,"props":408,"children":409},{},[410,412,416],{"type":214,"value":411},"The same helper serves ",{"type":205,"tag":210,"props":413,"children":414},{},[415],{"type":214,"value":276},{"type":214,"value":261},{"type":205,"tag":418,"props":419,"children":421},"warning",{"title":420},"This defect hides behind UR-02",[422,424,428,430,434],{"type":214,"value":423},"You can't see this defect today, because the template list is always empty.\nFix ",{"type":205,"tag":210,"props":425,"children":426},{},[427],{"type":214,"value":397},{"type":214,"value":429}," and ",{"type":205,"tag":210,"props":431,"children":432},{},[433],{"type":214,"value":404},{"type":214,"value":435}," and it becomes visible at once — plan all three\ntogether.",{"type":205,"tag":299,"props":437,"children":439},{"id":438},"expected-behaviour",[440],{"type":214,"value":441},"Expected behaviour",{"type":205,"tag":206,"props":443,"children":444},{},[445],{"type":214,"value":446},"Return the directory and the file name without the extension, keeping the file\nname complete.",{"type":205,"tag":299,"props":448,"children":450},{"id":449},"acceptance-criteria",[451],{"type":214,"value":452},"Acceptance criteria",{"type":205,"tag":454,"props":455,"children":456},"ul",{},[457,474,489,504,519,524],{"type":205,"tag":458,"props":459,"children":460},"li",{},[461,466,468,473],{"type":205,"tag":210,"props":462,"children":463},{},[464],{"type":214,"value":465},"Path::RemoveExtension(\"\\Healer.txt\")",{"type":214,"value":467}," returns ",{"type":205,"tag":210,"props":469,"children":470},{},[471],{"type":214,"value":472},"\"\\Healer\"",{"type":214,"value":261},{"type":205,"tag":458,"props":475,"children":476},{},[477,482,483,488],{"type":205,"tag":210,"props":478,"children":479},{},[480],{"type":214,"value":481},"Path::RemoveExtension(\"\\Builds\\Healer.txt\")",{"type":214,"value":467},{"type":205,"tag":210,"props":484,"children":485},{},[486],{"type":214,"value":487},"\"\\Builds\\Healer\"",{"type":214,"value":261},{"type":205,"tag":458,"props":490,"children":491},{},[492,497,498,502],{"type":205,"tag":210,"props":493,"children":494},{},[495],{"type":214,"value":496},"Path::RemoveExtension(\"\\Healer\")",{"type":214,"value":467},{"type":205,"tag":210,"props":499,"children":500},{},[501],{"type":214,"value":472},{"type":214,"value":503},", as it does today.",{"type":205,"tag":458,"props":505,"children":506},{},[507,512,513,518],{"type":205,"tag":210,"props":508,"children":509},{},[510],{"type":214,"value":511},"Path::RemoveExtension(\"\\My.Build.txt\")",{"type":214,"value":467},{"type":205,"tag":210,"props":514,"children":515},{},[516],{"type":214,"value":517},"\"\\My.Build\"",{"type":214,"value":261},{"type":205,"tag":458,"props":520,"children":521},{},[522],{"type":214,"value":523},"The template list shows the exact name that the player typed.",{"type":205,"tag":458,"props":525,"children":526},{},[527],{"type":214,"value":528},"The player can load a template directly from the list.",{"type":205,"tag":299,"props":530,"children":532},{"id":531},"how-to-reproduce",[533],{"type":214,"value":534},"How to reproduce",{"type":205,"tag":206,"props":536,"children":537},{},[538],{"type":214,"value":539},"You can confirm this one on its own; it doesn't depend on the other defects.",{"type":205,"tag":541,"props":542,"children":544},"steps",{"mode":543},"numbered",[545,552,557,563,574,580],{"type":205,"tag":546,"props":547,"children":549},"h3",{"id":548},"how-to-reproduce-add-an-export",[550],{"type":214,"value":551},"Add an export",{"type":205,"tag":206,"props":553,"children":554},{},[555],{"type":214,"value":556},"Append an export entry for function 457 to the module.",{"type":205,"tag":546,"props":558,"children":560},{"id":559},"how-to-reproduce-call-it",[561],{"type":214,"value":562},"Call it",{"type":205,"tag":206,"props":564,"children":565},{},[566,568,573],{"type":214,"value":567},"Instantiate the module in Node with stub imports. Call the function with\n",{"type":205,"tag":210,"props":569,"children":570},{},[571],{"type":214,"value":572},"\"\\Healer.txt\"",{"type":214,"value":261},{"type":205,"tag":546,"props":575,"children":577},{"id":576},"how-to-reproduce-read-the-result",[578],{"type":214,"value":579},"Read the result",{"type":205,"tag":206,"props":581,"children":582},{},[583,585,590,592,596],{"type":214,"value":584},"The function returns ",{"type":205,"tag":210,"props":586,"children":587},{},[588],{"type":214,"value":589},"\"\\Heale\"",{"type":214,"value":591},". The expected result is ",{"type":205,"tag":210,"props":593,"children":594},{},[595],{"type":214,"value":472},{"type":214,"value":261},{"type":205,"tag":206,"props":598,"children":599},{},[600],{"type":214,"value":601},"The path helpers are pure — they need no game state and no initialised UI.",{"type":205,"tag":299,"props":603,"children":605},{"id":604},"our-workaround-today",[606],{"type":214,"value":607},"Our workaround today",{"type":205,"tag":206,"props":609,"children":610},{},[611,613,618,620,624],{"type":214,"value":612},"Our bridge returns entry names ",{"type":205,"tag":241,"props":614,"children":615},{},[616],{"type":214,"value":617},"without",{"type":214,"value":619}," an extension, so the client calls\n",{"type":205,"tag":210,"props":621,"children":622},{},[623],{"type":214,"value":215},{"type":214,"value":625}," on a name that has nothing to remove and the bug never\nfires.",{"type":205,"tag":206,"props":627,"children":628},{},[629],{"type":214,"value":630},"This stays correct after a fix — removing an absent extension does nothing —\nso nothing on our side has to change on the same day.",{"title":632,"searchDepth":633,"depth":633,"links":634},"",4,[635,637,638,639,640,646],{"id":301,"depth":636,"text":304},2,{"id":384,"depth":636,"text":387},{"id":438,"depth":636,"text":441},{"id":449,"depth":636,"text":452},{"id":531,"depth":636,"text":534,"children":641},[642,644,645],{"id":548,"depth":643,"text":551},3,{"id":559,"depth":643,"text":562},{"id":576,"depth":643,"text":579},{"id":604,"depth":636,"text":607},"markdown","docs",{"source":650,"path":651,"stem":652,"dir":653,"extension":654},"content","en\u002F1.docs\u002F3.upstream\u002F3.filesystem\u002F2.path-remove-extension.md","en\u002F1.docs\u002F3.upstream\u002F3.filesystem\u002F2.path-remove-extension","filesystem","md",{"requestedPath":112,"resolvedPath":112,"alternates":656},[657],{"locale":8,"path":112,"source":658},"variant",{"requested":660,"resolved":661,"usedFallback":6},{"locale":8},{"locale":8},{"previous":663,"next":665},{"title":101,"id":102,"canonicalKey":103,"locale":8,"draft":6,"navigation":664,"path":105},{"title":101},{"title":114,"id":115,"canonicalKey":116,"locale":8,"draft":6,"navigation":666,"path":119},{"title":114},{"left":668,"top":668,"width":669,"height":669,"rotate":668,"vFlip":6,"hFlip":6,"body":670},0,24,"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Crect width=\"8\" height=\"4\" x=\"8\" y=\"2\" rx=\"1\" ry=\"1\"\u002F>\u003Cpath d=\"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2\"\u002F>\u003C\u002Fg>",1786362927640]