{"owner":"jrsoftware","repo":"issrc","hasSkills":true,"totalSkillsCount":14,"totalTokensCount":11296,"categories":["anthropic-skill","root-instruction"],"hasMcp":false,"mcpConfig":null,"found":[".claude/rules/docs.general.md",".claude/rules/docs.ishelp.isetup.md",".claude/rules/docs.ishelp.ispp.md",".claude/rules/docs.ishelp.isxfunc.md",".claude/rules/docs.ishelp.md",".claude/rules/docs.whatsnew.md",".claude/rules/indentation.md",".claude/rules/isl.md",".claude/rules/islzma.md",".claude/rules/iss.md",".claude/rules/pascal.md",".claude/rules/test.md",".claude/rules/unips.md","AGENTS.md"],"skills":{".claude/rules/docs.general.md":"---\r\npaths: [\"whatsnew.htm\", \"ISHelp/isetup.xml\", \"ISHelp/ispp.xml\", \"ISHelp/isx.xml\", \"ISHelp/isxfunc.xml\", \"ISHelp/isxclasses.header*\", \"ISHelp/isxclasses.footer\"]\r\n---\r\n# General documentation conventions for Inno Setup\r\n\r\n## Voice and Tone\r\n\r\n- **Direct and technical.** State facts plainly. Do not hedge or pad with filler.\r\n- **Second person** (\"you\") when addressing the user who writes scripts or configures Setup.\r\n- **Impersonal** when describing system behavior: \"Setup will...\", \"the compiler will...\", \"an exception will be raised if...\".\r\n- **Not chatty.** No rhetorical questions, no \"Note that you might wonder...\". Just state the information.\r\n- **Contractions are used.** Write \"don't\", \"isn't\", \"can't\", \"won't\", \"doesn't\", \"aren't\", \"hasn't\", \"didn't\", \"wouldn't\", \"couldn't\", \"shouldn't\". These are natural and make the text less stiff for non-native readers.\r\n\r\n## Sentence Structure\r\n\r\n- Prefer **short, clear sentences**. One idea per sentence when possible.\r\n- Avoid deeply nested clauses. If a sentence grows complex, split it.\r\n- **Active voice** when possible: \"Setup creates the directory\" rather than \"the directory is created by Setup\". Passive voice is acceptable when the actor is irrelevant or when it reads more naturally: \"An exception will be raised if...\".\r\n- Parenthetical notes are common and acceptable: \"(which can include constants)\", \"(the default setting)\".\r\n\r\n## Vocabulary and Terminology\r\n\r\nUse the established Inno Setup terms consistently. Never substitute synonyms:\r\n\r\n| Correct term | Do not use |\r\n|---|---|\r\n| Setup, the Setup program, the installer | the installation program (note: \"installer\" is also standard for the compiled artifact, such as \"64-bit installers\") |\r\n| Uninstall, the uninstaller | the uninstall program |\r\n| the compiler | the build system, the compilation engine |\r\n| the end user | the customer, the consumer |\r\n| the user | the developer, the script author (when addressing the person writing .iss scripts) |\r\n| support function | helper function, utility function |\r\n| support class | helper class |\r\n| directive | setting, option (for [Setup] section items) |\r\n| parameter | field, property (for section entry items) |\r\n| flag | option, switch (for Flags parameter values) |\r\n| entry | line, row (for a line in a section) |\r\n| section | block, group (for [Setup], [Files], etc.) |\r\n| the Compiler IDE | the editor (\"the IDE\" is acceptable after \"the Compiler IDE\" has been established in the same context, in both ISHelp and whatsnew) |\r\n| Pascal Scripting | the scripting engine (for the feature/topic name; \"Pascal Script\" is acceptable when referring to the RemObjects Pascal Script engine itself) |\r\n| extended-length paths | long paths (use \"also known as super paths\" parenthetically on first mention within a topic; don't use \"super paths\" as a standalone term) |\r\n| menu item | menu option |\r\n| Start menu (but \"Start Menu\" in titles, such as the *Select Start Menu Folder* wizard page) | Start Menu |\r\n| checkbox | check box |\r\n| without a BOM | BOM-less, BOMless |\r\n| the help file | the help |\r\n\r\nAdditional vocabulary rules:\r\n- \"Setup or Uninstall\" or \"the Setup program and uninstaller\" when a feature applies to both. Not \"the installer or uninstaller\".\r\n- \"the user's system\" for the target environment. Not \"the target machine\". \"computer\" is acceptable for restarts (\"restart the computer\") and computer names (\"the name of the computer\").\r\n- \"specified\" is the standard word for parameters and directives: \"the specified file\", \"the specified parameter\". Not \"provided\".\r\n- \"given\" is the standard word for function argument descriptions: \"the given string\", \"the given file name\".\r\n- \"Returns True if...\" is the standard pattern for boolean function descriptions.\r\n- \"cannot\" as one word. Not \"can not\".\r\n- Use \"use\" not \"utilize\".\r\n- Use \"non-zero\" not \"non-zero value\".\r\n- Do not shorten established descriptive terms. Write \"support function\", not \"func\".\r\n- Repeat the same term for the same concept. Do not rotate between synonyms for variety.\r\n\r\n## Punctuation\r\n\r\n- **Oxford (serial) comma:** Use it. \"A, B, and C\", not \"A, B and C\".\r\n- **Periods** at the end of complete sentences, including list items that are complete sentences.\r\n- **No em dashes or en dashes.** Use periods, commas, or parentheses instead.\r\n- **No \"e.g.\"** Use \"for example\" or \"such as\".\r\n- **No \"i.e.\"** Use \"that is\" or rephrase.\r\n- **\"etc.\" is acceptable** but use sparingly.\r\n- **Colons** before examples and lists.\r\n\r\n## Formatting\r\n\r\n- Code identifiers should render as monospace: section names, directive names, parameter names, flag names, constant names, type names, function names, file names, directory names, path values, registry key and value type names, environment variable names, command-line switches, and values like `yes`/`no`/`True`/`False`. In prose, use `<tt>` for this. Inside already-monospace contexts, such as `<pre>`, `<precode>`, or ISPP `<line>` elements, no extra `<tt>` is needed.\r\n- When a code identifier is in a prose link's display text, still make it monospace with `<tt>`:\r\n  - For an internal `<link>`: outside the link if the identifier is the whole display text, inside otherwise.\r\n  - For an `<extlink>`: always inside, because external links get an icon added that must not appear inside the `<tt>` pill.\r\n- `<i>` for emphasis, wizard page names (such as *Select Destination Location*), UI element names, and font names.\r\n- `<b>` sparingly, for important warnings or the word \"NOTE:\".\r\n\r\n## Syntax Highlighting\r\n\r\nThe IDE styler (`Projects/Src/IDE.ScintStylerInnoSetup.pas`) is the source of truth for which token gets which\r\ncategory. Five non-obvious rules:\r\n\r\n- Use `<sec>`, `<evt>`, `<key>`, `<com>`, `<con>`, `<str>`, `<num>`, and `<ispp>` for syntax-highlighted script examples.\r\n- Use `<str>` and `<num>` only in Pascal Script and ISPP contexts. Section directive and parameter string\r\n  values stay plain, with only their inner constants using `<con>`. Number literals include ISPP array indices.\r\n- Use of `<con>` depends on context. Use it for a regular constant (`{app}`) inside a section directive or parameter\r\n  value, including inside a parameter value such as `ExpandConstant('<con>{app}</con>\\...')`,\r\n  but not inside a Pascal string literal, where the whole literal stays `<str>`. An ISPP inline constant\r\n  (`{#...}`) is the exception: it always uses `<ispp>` on the `{#...}` delimiters and directive name (the inner\r\n  expression keeps its own styling), even inside a string literal, because ISPP pre-styles it.\r\n- `<evt>` applies only to the fixed `BasicEventFunctions` set; functions named via event attributes are not bolded.\r\n- `[Messages]`/`[CustomMessages]`/`[LangOptions]`: only the message name is `<key>`; a language prefix is not.\r\n\r\n## Review Guidelines\r\n\r\nWhen reviewing documentation, check for:\r\n\r\n1. **Terminology consistency.** Are the correct Inno Setup terms used? (See the vocabulary table above.)\r\n2. **Factual accuracy.** Does the documentation match the actual code behavior?\r\n3. **Completeness.** Are all parameters, flags, return values, and error conditions documented?\r\n4. **Cross-references.** Are related topics linked?\r\n5. **Code formatting.** Are code identifiers in prose wrapped in `<tt>`? Are examples provided?\r\n6. **Style violations.** Check for: em/en dashes, \"e.g.\", \"i.e.\", synonym rotation, missing Oxford commas, \"can not\" instead of \"cannot\", \"utilize\" instead of \"use\".\r\n7. **Clarity for non-native speakers.** Avoid idioms, complex subordinate clauses, and uncommon vocabulary.\r\n8. **Do not nitpick** about subjective style matters in existing text that is not being changed. Only flag style issues in new or modified text.\r\n",".claude/rules/docs.ishelp.isetup.md":"---\npaths: [\"ISHelp/isetup.xml\"]\n---\n# isetup.xml documentation conventions\n\nThese are specific to `isetup.xml`, which documents the entry sections and [Setup] directives; the general ISHelp conventions in `docs.ishelp.md` apply too.\n\n## Section topic structure\n\nEach entry section topic (such as [Files], [Registry], [Run]) follows this structure:\n1. Opening paragraph: \"This optional section defines...\" or \"This section contains...\".\n2. Introductory notes about default behavior.\n3. Example section with `<precode>`.\n4. \"The following is a list of the supported parameters:\" introducing the parameter list.\n5. Parameters documented with `<paramlist>` / `<param>`.\n6. Links to Common Parameters and Components/Tasks Parameters at the bottom.\n\n## Directive-topic structure\n\nEach [Setup] directive topic uses `<setuptopic>`:\n1. `<setuptopic directive=\"DirectiveName\">`: topic wrapper.\n2. `<setupvalid>`: valid values (optional, omitted when free-form text).\n3. `<setupdefault>`: default value (optional).\n4. `<body>`: opening paragraph, followed by detail paragraphs, notes, examples, and optional \"See also\" links. Common opening patterns: \"This directive specifies...\", \"This tells the compiler...\", \"Controls whether...\", \"If set to [value]...\".\n\n## Parameter documentation\n\nEach parameter follows this pattern:\n1. Description paragraph: what it controls.\n2. Additional detail paragraphs as needed.\n3. Example with `<example><pre>`.\n4. For Flags parameters: \"This parameter is a set of extra options. Multiple options may be used by separating them by spaces. The following options are supported:\" followed by `<flaglist>`.\n\n## Conditional behavior\n\nUse the pattern: \"If [value] is specified, Setup will [action].\" Repeat for each value. Example:\n> If <tt>string</tt> is specified, Setup will create a string (<tt>REG_SZ</tt>) value.\n> If <tt>dword</tt> is specified, Setup will create a 32-bit integer (<tt>REG_DWORD</tt>) value.\n\n## Default values\n\nState defaults explicitly: \"Defaults to [value].\" or \"The default value is [value].\" or \"(the default setting)\".\n",".claude/rules/docs.ishelp.ispp.md":"---\r\npaths: [\"ISHelp/ispp.xml\"]\r\n---\r\n# ispp.xml documentation conventions\r\n\r\nThese are specific to `ispp.xml`; the general ISHelp conventions in `docs.ishelp.md` apply too.\r\n\r\n## Directive documentation\r\n\r\nPreprocessor directives use `<topic>` with `<syntax>`/`<define>`, `<description>`, and `<section>`.\r\n\r\n## Function documentation\r\n\r\nFunctions put the signature in `<section title=\"Prototype\">` (inside `<pre><line>`) and related links in `<section title=\"See also\">`.\r\n\r\nBoolean-like functions are documented as \"Returns non-zero if [condition].\" rather than \"Returns True if [condition], False otherwise.\"\r\n\r\n## Differences from the general conventions\r\n\r\n- **Cross-reference links:** use `<link href=\"topicname\">Display Text</link>`. `ispp.dtd` has no `anchor` attribute; the `href` carries the target.\r\n- **Examples:** examples sit in a bare `<pre>` inside `<section title=\"Examples\">`.\r\n- **Function shorthand:** `<isxfunc>` not available; link ISPP functions with `<link href=\"...\">`.\r\n- **Indentation:** `ispp.xml` is tab-indented, unlike the other ISHelp sources. Keep using tabs; the rules in `indentation.md` do not apply.\r\n",".claude/rules/docs.ishelp.isxfunc.md":"---\r\npaths: [\"ISHelp/isxfunc.xml\"]\r\n---\r\n# isxfunc.xml documentation conventions\r\n\r\nThese are specific to `isxfunc.xml`; the general ISHelp conventions in `docs.ishelp.md` apply too.\r\n\r\n`<link topic=\"...\">` (with optional `anchor`), `<extlink>`, `<sd>`, `<sn>`, and `<isxfunc>` all work as in the general conventions.\r\n\r\n## Function documentation\r\n\r\nEach function follows this pattern:\r\n- `<name>`: Function name.\r\n- `<prototype>`: Full function signature.\r\n- `<description>`: One or more `<p>` elements. First sentence is the key description.\r\n  - For functions returning a value: \"Returns [description of return value].\"\r\n  - For procedures: \"Does [action].\" or imperative form.\r\n  - For boolean functions: \"Returns True if [condition], False otherwise.\"\r\n- `<remarks>` (optional): Additional notes, edge cases, caveats.\r\n- `<seealso>` (optional): Links to related functions.\r\n- `<example>` (optional): Code example.\r\n\r\nStandard description patterns:\r\n- \"Returns the [noun] of [context].\"\r\n- \"Returns True if [condition].\"\r\n- \"Returns a [type] containing [description].\"\r\n- \"Gets/Sets the value of [thing].\"\r\n- \"Creates/Deletes/Removes [thing].\"\r\n- \"An exception will be raised if [error condition].\"\r\n- \"If [condition], [function name] returns [value].\"\r\n\r\n## Differences from the general conventions\r\n\r\n- **Examples:** use `<example>`, which may contain `<pre>`. `isxfunc.dtd` has no `<precode>`.\r\n",".claude/rules/docs.ishelp.md":"---\r\npaths: [\"ISHelp/isetup.xml\", \"ISHelp/isx.xml\", \"ISHelp/isxfunc.xml\", \"ISHelp/isxclasses.header*\", \"ISHelp/isxclasses.footer\", \"ISHelp/ispp.xml\"]\r\n---\r\n# ISHelp documentation conventions\r\n\r\nThese are the general documentation conventions shared by all ISHelp sources. `isetup.xml`, `isx.xml`, and the `isxclasses.*` helpers use `isetup.dtd`; `isxfunc.xml` (`isxfunc.dtd`) and `ispp.xml` (`ispp.dtd`) use their own DTD. They all follow the conventions below, except where a file's own rule file notes a difference or adds file-specific structure: see `docs.ishelp.isetup.md`, `docs.ishelp.isxfunc.md`, and `docs.ishelp.ispp.md`. Prose conventions for all of these files live in `docs.general.md`, not here.\r\n\r\n## Additional formatting\r\n\r\n- `<precode>` for syntax-highlighted section-level and topic-level script examples (such as showing a full [Run] section).\r\n- `<example><pre>` for syntax-highlighted parameter and function examples, which can also be multi-line.\r\n\r\n## Cross-references\r\n\r\n- Use `<link topic=\"topicname\">Display Text</link>`.\r\n- Always link to related topics when mentioning directives, sections, or functions. Do not leave them as plain text if a help topic exists.\r\n- Use the `<sd>Directive</sd>`, `<sn>[Section]</sn>`, and `<isxfunc>FunctionName</isxfunc>` shorthands instead of a `<link>` to a [Setup] directive, section, or support function.\r\n- To specific anchors: `<link topic=\"topicname\" anchor=\"anchorname\">Display Text</link>`.\r\n- External links: `<extlink href=\"url\">Display Text</extlink>`.\r\n",".claude/rules/docs.whatsnew.md":"---\r\npaths: [\"whatsnew.htm\"]\r\n---\r\n# Inno Setup Revision History documentation conventions\r\n\r\n## Additional formatting\r\n\r\n- `<i>Fix:</i>` prefix for bug fix entries.\r\n- `<pre><code class=\"innosetup\">` for syntax-highlighted script examples.\r\n\r\n## Example script references\r\n\r\n- \"See updated <tt><a href=\"...\">ScriptName.iss</a></tt> example script.\"\r\n- \"See updated <tt><a href=\"...\">ScriptName.iss</a></tt> example script for an example.\"\r\n- \"See new <tt><a href=\"...\">ScriptName.iss</a></tt> example script.\"\r\n\r\n## Entry structure\r\n\r\nChangelog entries appear as `<li>` items in `<ul>` lists.\r\n\r\n**New features:**\r\n- \"Added new [type] <tt>Name</tt>.\" or \"Added new [type] <tt>Name</tt> to [context].\"\r\n- \"Added new support functions <tt>Name1</tt>, <tt>Name2</tt>, and <tt>Name3</tt>.\"\r\n- \"Added new support classes <tt>Name1</tt>, <tt>Name2</tt>, and <tt>Name3</tt>.\"\r\n- \"Added new properties <tt>Name1</tt>, <tt>Name2</tt>, and <tt>Name3</tt> to class <tt>ClassName</tt>.\"\r\n- \"Added support for [feature].\"\r\n\r\n**Changes:**\r\n- \"Directive <tt>Name</tt> now defaults to <tt>value</tt>.\"\r\n- \"<tt>Feature</tt> is now [new behavior].\"\r\n- \"Enhanced/Improved/Updated [thing] [description of change].\"\r\n- \"Renamed <tt>OldName</tt> to <tt>NewName</tt>. The old name still works.\"\r\n\r\n**Bug fixes:**\r\n- Always prefixed: \"<i>Fix:</i> Description of what was wrong and what is now correct.\"\r\n- For documentation-only fixes: \"<i>Documentation fix:</i> Description.\"\r\n- Describe the symptom, not just the fix. Include \"broken since X.Y.Z\" or \"broken in X.Y.Z\" when known.\r\n\r\n**Removals:**\r\n- \"Removed support for [feature].\" or \"Support for [feature] has been dropped.\"\r\n- \"Removed [thing]. Use [replacement] instead.\"\r\n\r\n**Deprecations:**\r\n- \"This function is deprecated.\" followed by what to use instead.\r\n- \"The compiler still accepts <tt>OldName</tt> as an alias for <tt>NewName</tt>, but will emit a deprecation warning when used.\"\r\n\r\n## Subcategories\r\n\r\nGroup related changes under subcategory headers using nested lists:\r\n```html\r\n<li>Pascal Scripting:\r\n<ul>\r\n  <li>Added new support function <tt>Foo</tt>.</li>\r\n  <li><i>Fix:</i> <tt>Bar</tt> now works correctly.</li>\r\n</ul>\r\n</li>\r\n```\r\n\r\nStandard subcategory names: \"Compiler IDE:\", \"Pascal Scripting:\", \"ISPP:\", \"Setup:\", \"Compiler:\", \"Command-Line Compiler (ISCC):\", \"Examples:\", \"Security improvement:\", \"Updated documentation:\", and product-specific names such as \"Inno Setup Signature Tool:\". Other one-off names are acceptable when a group of entries warrants its own heading.\r\n\r\n## Catch-all entries\r\n\r\nEnd a version's changes with one of:\r\n- \"Other minor improvements.\"\r\n- \"Minor tweaks.\"\r\n- \"Minor tweaks and fixes.\"\r\n- \"Other minor improvements and fixes.\"\r\n- \"Documentation improvements.\"\r\n\r\n## Security section intro\r\n\r\nWhen there is a security improvements section:\r\n> Updating is recommended, even if you don't plan to use the other enhancements right away. We continually add extra checks to make your installers safer and more reliable. In this version:\r\n",".claude/rules/indentation.md":"---\r\npaths: [\"**/*.pas\", \"**/*.dpr\", \"**/*.dpk\", \"**/*.inc\", \"**/*.iss\", \"**/*.htm\", \"**/*.bat\", \"**/*.c\", \"**/*.h\", \"**/*.dfm\", \"**/*.xml\", \"**/*.dtd\", \"**/*.xsl\", \"**/*.md\", \"**/*.yml\"]\r\n---\r\n# Indentation conventions for all text files\r\n- Use spaces for indentation, not tabs.\r\n- Unless the format requires otherwise (for example, `.md` lists), use two spaces per indentation level.\r\n",".claude/rules/isl.md":"---\r\npaths: [\"Files/Languages/*.isl\", \"Files/Languages/Unofficial/*.isl\"]\r\n---\r\n# Conventions for Inno Setup translation files\r\n\r\nThese files translate `Files/Default.isl` into another language. `Default.isl` is the English baseline and the source of truth for the message set; it changes between Inno Setup versions, so always work from the most recent `Default.isl`, read it fresh, and treat its `[Messages]` and `[CustomMessages]` IDs as authoritative. A translation must stay faithful to its English counterpart: the English is the fixed reference and the ceiling, not something to clarify, complete, or improve.\r\n\r\n## Quality rules\r\n\r\n### File format and structure\r\n- **Encoding.** UTF-8 without a BOM.\r\n- **Newlines.** Windows CRLF throughout.\r\n- **Extension.** `.isl`. The `.islu` extension is obsolete.\r\n- **Compiles cleanly.** The file must compile with no errors and no warnings.\r\n\r\n### Comment header (top-of-file comments)\r\n- The first line is the version line, usually `; *** Inno Setup version X+ ... messages ***`. Keep it consistent with the `Default.isl` header version. It must never be higher than the `Default.isl` version.\r\n- The top of the file must also carry, as comments, the language's English name and the maintainer's name and e-mail address.\r\n\r\n### `[LangOptions]` settings\r\n- **LanguageName.** The language's native name (the name as written in the language itself), not its English name. For example Dutch is `Nederlands`, not `Dutch`. It is shown in the *Select Language* dialog. The obsolete `<HHHH>` escape syntax still works but is no longer needed; write the literal characters directly.\r\n- **LanguageID.** A valid hexadecimal language identifier beginning with `$`, matching the language and its region (for example `$0413` for Dutch (Netherlands), `$0813` for Belgian Dutch). It must not be left at `$0409`, which is the English ID of `Default.isl`. Verify against Microsoft's language-identifier list (https://learn.microsoft.com/en-us/windows/win32/intl/language-identifier-constants-and-strings). If no identifier exists for the language, set it to `0`. Together with `LanguageCodePage` it is used to auto-detect the most appropriate default language, so set it correctly.\r\n- **LanguageCodePage.** The Windows ANSI code page the compiler uses to convert any non-Unicode text in the language's files to Unicode (for example 1252 Western European, 1250 Central European, 1251 Cyrillic, 1253 Greek, 1254 Turkish, 1255 Hebrew, 1256 Arabic, 1257 Baltic, 1258 Vietnamese, 874 Thai, 932 Japanese, 936 Chinese Simplified, 949 Korean, 950 Chinese Traditional). Set it to `0` only when no code page exists for the language (a Unicode-only script such as Hindi, Tamil, Bengali, Armenian, Georgian) or the language uses only ASCII characters. It still matters even though the `.isl` is UTF-8, because it converts non-Unicode files such as a README supplied by the script author. (Text in the `.iss` file itself, such as a `[CustomMessages]` entry, is never converted and must already be Unicode.)\r\n- **RightToLeft.** `RightToLeft=yes` must be set for a right-to-left script (Arabic, Hebrew, Persian (Farsi), Urdu, Uyghur) and must not be set (or `RightToLeft=no`) for a left-to-right language.\r\n- **Fonts** (`DialogFontName`, `DialogFontSize`, `WelcomeFontName`, and so on). `Default.isl` keeps them all commented out. Uncomment only the entries the language genuinely needs to differ; an entry equal to the default stays commented out, so it inherits future default changes. Drop obsolete entries no longer in `Default.isl` (such as `CopyrightFontName`/`CopyrightFontSize`).\r\n\r\n### Sections and message set (compared to `Default.isl`)\r\n- **Translate the existing entries only.** Provide every `[Messages]` and `[CustomMessages]` ID that `Default.isl` defines, translated. Do not add your own custom messages to `[CustomMessages]`, and do not invent new IDs.\r\n- **No missing IDs.** Every ID defined in `Default.isl` must be present.\r\n- **No obsolete IDs.** Do not keep IDs that no longer exist in `Default.isl`.\r\n- **Empty values.** A message that is empty in `Default.isl` must stay empty in the translation, except for the `TranslatorNote` message.\r\n\r\n### Per-message rules (each message compared to its English counterpart)\r\n- **Placeholder integrity.** The same set and count of `%1`..`%9` must be present (the order may differ to suit the target grammar, and an argument may legitimately be duplicated, such as `%1 ... %1 %2`). Keep `%n` line breaks and `%%` literal-percent escapes intact. Preserve the same bracketed runtime placeholders, currently `[name]`, `[name/ver]`, `[mb]`, and `[gb]`. Never drop, add, or malform a placeholder or format specifier.\r\n- **Placeholder grammar.** A placeholder is filled at runtime with a value the translator cannot see or inflect, and which is not always the expected token (a wizard-name `%1`, for example, can be a custom name). Phrase the surrounding text so it reads correctly for any value: keep the placeholder in a slot that needs no inflection of, or grammatical agreement with, the inserted value, and never assume the value's gender, number, or case. If the English drops the value into a slot your language would inflect or agree with, rebuild the clause rather than guessing one form.\r\n- **Accelerator keys.** Keep an `&` accelerator wherever the English has one, and do not add one where the English has none. Drop an accelerator only when it cannot be placed on any letter of the translated text; resolve a collision by moving it to another letter rather than dropping it. Within each accelerator scope every accelerator letter must be unique, compared case-insensitively.\r\n- **No added periods.** Do not add a period to the end of a message that did not have one already. Exception: for languages with their own period character, such as Japanese and Chinese, it was added to the end of messages as needed. Keep a trailing period where the English has one. Exception: Thai and Lao remove trailing periods and question marks. If the English ends with `...`, keep the trailing ellipsis, written either as three dots `...` or as a single ellipsis character `…`. Spacing before the ellipsis follows the target language's typography (for example German puts a space before it, while English does not).\r\n- **Faithful meaning.** Stay as close to the original English as possible. Do not add to or change the meaning of a message to suit personal taste (for example do not append \"Try again one more time.\" to an error message that did not say that).\r\n\r\n### Translation quality (linguistic)\r\n- No spelling or grammar errors.\r\n- No untranslated messages that should have been translated. Some values are legitimately identical to English (`Setup`, `OK`, brand names, placeholder-only messages); only genuine omissions are wrong.\r\n- Consistent terminology: the same concept uses the same term across every message, with consistent button-label style and capitalization.\r\n- Use the language's native standard terminology, taking installer terms from the matching official Setup translation and everything else from Microsoft Terminology plus the language's Style Guide (for example the standard local words for Setup, folder, uninstall, administrator).\r\n- Consistent, language-appropriate tone, formality, casing, punctuation, and quote style (for example German capitalizes nouns and addresses the user formally; Japanese uses full-width punctuation where the platform does).\r\n- Translate naturally. As loose guidance stay near the English length (roughly within about 150 percent), but naturalness wins.\r\n\r\n## Faithfulness check before changing a message\r\n\r\nBefore changing a translated message because it looks wrong, confirm all of these; if any fails, leave it alone:\r\n1. Quote the exact English string. If you can't, you haven't compared against it.\r\n2. The current translation differs from what the English *means*, not from a clearer or more explicit version you imagined. If the English is itself ambiguous, general, or underspecified, an equally ambiguous translation is correct, not a problem.\r\n3. Your change preserves the English meaning. It must not add precision, disambiguation, or detail the English does not have.\r\n4. It is substantive. Awkward-but-acceptable phrasing, debatable terminology, and pure style preferences are nitpicks; leave them.\r\n5. Back-translate both the current text and your replacement into English. Change it only if the current text back-translates to a different meaning than the English *and* your replacement back-translates to the same meaning. If the replacement back-translates to something the English does not say, it adds meaning; drop it.\r\n",".claude/rules/islzma.md":"---\r\npaths: [\"Projects/Src/Compression.LZMACompressor/islzma/**\", \"Projects/Src/Compression.LZMADecompressor/Lzma2Decode/**\"]\r\n---\r\n# Instructions for the native LZMA C code (islzma and Lzma2Decode)\r\n\r\n## Indentation\r\n\r\nThese files keep their existing indentation style; the rules in `indentation.md` do not apply:\r\n- `islzma.c`, `islzma.h`, `islzma_dll.c`, `islzma_exe.c`, `ISLzmaDec.c`, and `test/test.bat` are tab-indented.\r\n- `test/roundtrip.c` is four-space indented.\r\n\r\nDo not reformat these files. When editing, match the surrounding indentation of the file you are in.\r\n",".claude/rules/iss.md":"---\r\npaths: [\"**/*.iss\"]\r\n---\r\n# Coding conventions for Inno Setup script files\r\nInno Setup `.iss` scripts use the `[Code]` section for Pascal Script code. This is RemObjects Pascal Script (ROPS), not modern Delphi. The following rules apply to code in `[Code]` sections.\r\n## Language differences compared to Delphi\r\nMost of these are hard constraints of the ROPS compiler. Violating them causes compile errors.\r\n- No inline `var` or inline `const`. All local variables must be declared in a `var` block before `begin`.\r\n- No local `const` or `type` declarations. Only `var` and `label` blocks are allowed before `begin`.\r\n- No `Exit(Value)` syntax. Assign to `Result` first, then call `Exit` separately.\r\n- No typed constants (`const X: Integer = 1`). Only untyped constants (`const X = 1`).\r\n- No default parameter values.\r\n- No function or procedure overloading.\r\n- No `raise` keyword. Use `RaiseException(Msg)` or `RaiseLastException` instead.\r\n- No `on E: ExceptionType do` in `except` blocks. Use `GetExceptionMessage` to inspect the current exception.\r\n- No script-defined classes. Classes can be used, but only those defined by Inno Setup.\r\n- No variant records.\r\n- `const` parameters are passed by value (copied), and not by reference as in modern Delphi.\r\n- As in Delphi, assigning a dynamic array, or passing it as a value or `const` parameter, shares its elements. A change to an element through one variable is visible through the other. `SetArrayLength` and `SetLength` copy a shared array only when the length changes. Delphi's `SetLength` always copies it. `Copy` doesn't support arrays. To get an array that isn't shared, change its length and change it back, or copy the elements to a new array.\r\n- The `/` operator always returns `Extended`, even when both operands are integers. Use `div` for integer division.\r\n- `Break` and `Continue` are not reserved words. They are ordinary identifiers recognized specially inside loop bodies. A local declaration named `Break` or `Continue` will shadow the loop-control behavior.\r\n- `Low`, `High`, and `SizeOf` must be used with a variable, not a type.\r\n## Conventions (same spirit as the Pascal rules, adapted for ROPS)\r\n- Pre-declare all local variables in the `var` block before `begin`.\r\n- Do not use `with` statements.\r\n- `if` and `begin` should be on the same line.\r\n- `else` and `begin` should be on the same line.\r\n- Do not use `begin..end` for single one-line statement blocks, but always use it when the block spans multiple lines. This includes when the block's single statement spans multiple lines (such as a multi-line `for`), and when a comment on its own line accompanies the statement (a trailing comment on the statement's line does not count).\r\n  Count lines per indentation level: a child statement never adds to its parent's count, so a chain of one-line statements takes no `begin..end` at any level.\r\n  A statement wrapped over continuation lines still counts as one line. But a statement that is genuinely multi-line at its own level (a `begin..end` block, or a control statement with a body, of its own) makes each level above it multi-line too.\r\n- Do not use `Longint` or `LongWord`; use `Integer` or `Cardinal` instead.\r\n- Mark read-only parameters as `const`.\r\n- Do not shorten descriptive names. Write `Expression`, not `Expr`; `MultiFileHandler`, not `MFH`. Conventional short names (`I`, `J`, `S`, `Res`) and established identifiers (`HiWord`) are fine.\r\n## Code editing guidelines\r\n- Do not modify existing comments unless the code they describe is also being changed.\r\n- Keep new comments short and match the style of existing comments in the file.\r\n",".claude/rules/pascal.md":"---\r\npaths: [\"**/*.pas\", \"**/*.dpr\", \"**/*.inc\"]\r\n---\r\n# Coding conventions for Pascal source files\r\n- Always use inline variables instead of pre-declaring them at the start of the function.\r\n  Exception: Delphi 10.4 does not support anonymous array types in inline variable or constant declarations, so pre-declare them.\r\n- Prefer inline constants over inline variables, even for run-time values and not just for compile-time constants.\r\n  Exception: inline constants cannot be passed as `var` parameters, so use an inline variable in that case.\r\n  Inline constants which are an object can still have their properties modified.\r\n  Inline constants use `=` as the assignment operator instead of `:=`. Examples:\r\n  `const MaxCount = MinCount * 2;`\r\n  `const ExpandedFilename = PathExpand(Filenames[I]);`\r\n- Prefer factoring shared code into a routine, or binding the expression to an inline const.\r\n- A routine whose callers all sit inside one routine belongs nested in it, not as a method or a unit-level routine. Keep such helpers siblings at a single level: never nest a helper inside another helper. No exceptions, except a routine assigned to an event stays a method.\r\n- Do not use `with` statements.\r\n- `if` and `begin` should be on the same line.\r\n- `else` and `begin` should be on the same line.\r\n- A `Result` assignment followed by an `Exit` statement should be combined into a single statement. For example: `Exit(ResultValue);`\r\n- Do not use `begin..end` for single one-line statement blocks, but always use it when the block spans multiple lines. This includes when the block's single statement spans multiple lines (such as a multi-line `for`), and when a comment on its own line accompanies the statement (a trailing comment on the statement's line does not count).\r\n  Count lines per indentation level: a child statement never adds to its parent's count, so a chain of one-line statements takes no `begin..end` at any level:\r\n  `for var X in Y do`\r\n  `  if Z(X) then`\r\n  `    Exit(True);`\r\n  A statement wrapped over continuation lines still counts as one line. But a statement that is genuinely multi-line at its own level (a `begin..end` block, or a control statement with a body, of its own) makes each level above it multi-line too.\r\n- Do not use `Longint` or `LongWord`, use `Integer` or `Cardinal` instead.\r\n- Mark read-only parameters as `const`.\r\n- Use Windows units first, then RTL/VCL units, then Components units, then Shared units, then project specific units.\r\n- Class methods should be static when possible.\r\n- Do not shorten descriptive names. Write `Expression`, not `Expr`; `MultiFileHandler`, not `MFH`. Conventional short names (`I`, `J`, `S`, `Res`) and established identifiers (`HiWord`) are fine.\r\n- Comments should be short and match the style of existing comments in the file. Prefer using `{` and `}`, and do not end one-sentence comments with a period.\r\n# Code editing guidelines\r\n- Do not modify existing comments unless the code they describe is also being changed.\r\n- When modifying code that calls Windows APIs, read the actual documentation before writing code. Do not assume parameter semantics based on similar APIs.\r\n- Update Inno Setup copyright header of any file you edit, if the current year is not already included.\r\n- Add tests for new code to the unit's `*.Test.pas` if it exists; otherwise consider creating one if the code is complex enough to warrant testing.\r\n  ISPP and ROPS code is tested by `Script.ISPP.Test.iss` and `Script.ROPS.Test.iss`, not a `*.Test.pas` unit.\r\n# Code review guidelines\r\n- All errors must be checked. Installers should be reliable above all.\r\n- Be alert for `out` parameters: an `out` parameter, like a `var` parameter, is passed by reference. However, with an `out` parameter, the initial value of the referenced variable for managed types, such as strings or arrays, is discarded by the caller before it is passed to the routine. Meanwhile, the initial value for unmanaged types, such as integers or pointers, is ignored. Therefore, for unmanaged types, it is not guaranteed that the initial value of the referenced variable will be overwritten in the routine to which it is passed.\r\n- Be alert for functions not assigning a value to Result: if a function exits without assigning a value to Result or the function name, then the function's return value is undefined, even for managed types.\r\n- Be alert for dynamic-array aliasing: assigning one dynamic array (e.g. `TBytes`) to another makes both reference the same buffer. Unlike strings and static arrays, copy-on-write is not employed, so writes through one alias (including `FillChar`) are visible through the other. Use `Copy(Source)` when an independent buffer is needed.\r\n- Code must be compatible with Delphi 10.4 and later.\r\n- Code must be compatible with 32-bit and 64-bit builds.\r\n- Code must be compatible with Windows 7 and later.\r\n- Do not suggest applying coding conventions to unchanged code.\r\n- Do not suggest changing an inline constant to an inline variable.\r\n- Do not nitpick, especially not about readability or subjective matters. This includes:\r\n  - Comment style or presence of comments.",".claude/rules/test.md":"---\r\npaths: [\"**/*Test.pas\", \"**/*Test.iss\"]\r\n---\r\n# Instructions for adding tests\r\n\r\n## When a correct test fails: allow investigation instead of pure tweaking\r\n\r\nIf a test that looks correct fails at compile time or at runtime, **do not silently adjust it until it passes**. A test that matches spec behavior but fails is evidence of a bug, not a bad test. The right response is:\r\n\r\n1. **Keep the original test** in the test source file, commented out, with a short explanation of the bug it exposed (e.g. `{ bug: 'for I: Byte := 0 to 255' infinite-loops because the loop variable wraps from 255 to 0 }`).\r\n2. **Write an alternate working test** that covers the same functionality without hitting the bug, if one exists. For example, use a narrower range or a different loop structure. This keeps test coverage moving forward.\r\n3. **Fixing the bug and re-enabling the original test is a separate task** - do not block the current phase on it.\r\n\r\nTweaking a test to avoid a real bug - changing types, adding casts, restructuring loops - hides regressions and defeats the purpose of the test suite.\r\n\r\n## Tests that check for a raised exception\r\n\r\nWhen a test verifies that something raises an exception, guard that part with `{$IFDEF ISTESTTOOLPROJ}` so it runs only under ISTestTool, not the DEBUG self-test. The self-test runs in the unit's `initialization` block inside the real application, where an intentionally raised exception would break in the debugger on every run. ISTestTool defines `ISTESTTOOLPROJ` and runs these checks normally.\r\n\r\nUse this pattern:\r\n\r\n```pascal\r\n{$IFDEF ISTESTTOOLPROJ}\r\n{ <what must raise and why> }\r\nvar Caught := False;\r\ntry\r\n  SomethingThatMustRaise;\r\nexcept\r\n  Caught := True;\r\nend;\r\nAssert(Caught);\r\n{$ENDIF}\r\n```\r\n\r\nKeep assertions that must always run, such as the contrasting success case, outside the `{$IFDEF ISTESTTOOLPROJ}` block.\r\n",".claude/rules/unips.md":"---\r\npaths: [\"Components/UniPs/**\"]\r\n---\r\n# Instructions for UniPs (Pascal Script) components\r\n\r\n## Upstream origin\r\n\r\nThese files are copies of the RemObjects Pascal Script `stable` branch (see `rev.txt` for the commit hash).\r\n\r\nYou may still edit them, but:\r\n- Do not refactor the code style to match Inno Setup conventions.\r\n- Keep changes minimal and focused. Even though Inno Setup is a Delphi Windows codebase, the Pascal Script code is cross-platform: it compiles under multiple compilers (Delphi and FPC), operating systems (Windows and others), and CPU bitnesses (32- and 64-bit). A change must either be correct on every combination, or be guarded so it only affects the ones you have verified. Useful guards: `{$IFDEF DELPHI}` / `{$IFDEF FPC}` (compiler), `{$IFDEF MSWINDOWS}` (OS), and `{$IFDEF CPU64}` (bitness).\r\n  Inno Setup always builds with Delphi on Windows, in both 32- and 64-bit, so your change must be correct there. Improving support for the platforms Inno Setup does not use (FPC, non-Windows) is a bonus, but extend a change to them only when it is easy and correctness is easy to confirm; otherwise guard the change.\r\n- Don't edit or inspect `rev.txt` as it is an auto-generated bookkeeping file.\r\n\r\n## Registration: compile-time (uPSC_) vs runtime (uPSR_)\r\n\r\nPascal Script has two registration layers that must stay in sync:\r\n- **Compile-time** (`uPSC_*.pas`): declares what the script compiler accepts.\r\n- **Runtime** (`uPSR_*.pas`): provides actual method pointers and property helpers.\r\n\r\nWhen a compile-time registration is guarded by `{$IFDEF}` or `{$IFNDEF}`, the matching runtime registration must use the same guard. A mismatch causes scripts to compile successfully but crash at runtime.\r\n\r\nA compile-time `RegisterProperty` for a **published** property does not require a matching runtime `RegisterPropertyHelper`. RTTI handles published properties automatically. Only non-published properties need explicit runtime read/write helpers.\r\n\r\nUse the actual Pascal type name in `RegisterProperty`, not a shortcut like `'Byte'` for enums or sets. For example, use `'TComponentState'` for a set type and `'TFontPitch'` for an enum, not `'Byte'`.","AGENTS.md":"# Inno Setup AI Agent Guide\r\n\r\n## Introduction\r\n- Source code of Inno Setup, an open-source installation builder for Windows applications by Jordan Russell and Martijn Laan, first released in 1997.\r\n- Comes in 64-bit and 32-bit editions; both can build 32-bit or 64-bit installers.\r\n- Copyrighted software; see `LICENSE.TXT` for distribution restrictions. Commercial users are requested to purchase a commercial license.\r\n\r\n## Project Architecture\r\nDelphi projects under `Projects/`:\r\n\r\n| Project | Output | Role |\r\n|---------|--------|------|\r\n| `ISIDE` | EXE | GUI compiler front-end (IDE), thin shell around ISCmplr.dll |\r\n| `ISCC` | EXE | CLI compiler front-end, thin shell around ISCmplr.dll |\r\n| `ISCmplr` | DLL | Actual compiler engine; entry point: `Compiler.SetupCompiler.pas` |\r\n| `ISPP` | DLL | Preprocessor |\r\n| `Setup` | EXE | Installer runtime; entry point: `Setup.MainFunc.pas` |\r\n| `SetupCustomStyle` | EXE | Installer runtime with VCL Styles support |\r\n| `SetupLdr` | EXE | Self-extracting loader that decompresses and launches Setup |\r\n| `ISSigTool` | EXE | Signs and verifies files using custom signatures |\r\n| `ISTestTool` | EXE | Internal utility that runs unit tests; invoked by build.bat and build-ce.bat |\r\n\r\nUnder `ISHelp/ISHelpGen/`:\r\n\r\n| Project | Output | Role |\r\n|---------|--------|------|\r\n| `ISHelpGen` | EXE | Generates XML files for help and Pascal Script autocomplete |\r\n\r\n## Core System\r\n- Delphi codebase targeting Windows 7 and later via the Windows API. All projects build for x64 and x86.\r\n- Primary project-specific source lives in `Projects/Src/` using namespace prefixes: `Compiler.*`, `Compression.*`, `IDE.*`, `ISPP.*`, `Setup.*`, `SetupLdrAndSetup.*`, `Shared.*`. Projects also compile shared units from `Components/`, and `ISIDE` additionally consumes the generated `ISHelp\\isxclasses_wordlists_generated.pas`. New project-specific source files must follow the namespace convention and be placed in `Projects/Src/`.\r\n- `Shared.Struct.pas` defines cross-project record layouts, and `Shared.CompilerInt.Struct.pas` defines the compiler/front-end interface layout. Changing either requires reviewing every consumer and recompiling the relevant projects.\r\n- Other shared units live under `Components` and `Projects\\Src\\Shared.*.pas`.\r\n- `SetupLdrAndSetup.*` units are shared by SetupLdr, Setup, and SetupCustomStyle; changes must account for all three.\r\n- `SetupCustomStyle` uses the same sources as `Setup` plus `Vcl.Themes`/`Vcl.Styles` and `Setup.TaskDialogForm`.\r\n- Many UI units in `Projects/Src/` are paired with checked-in `.dfm` files; form changes often require coordinated `.pas` and `.dfm` edits.\r\n- Compression engines pull native code from `Projects\\Src\\Compression.*`.\r\n- Pascal Script integration sits in `Compiler.Script*.pas` and `Setup.Script*.pas`; changes must be mirrored on both compiler and setup sides.\r\n- Setup path redirection: `ApplyPathRedirRules` rewrites System32/SysWOW64/Sysnative and converts to super paths. Unless documented otherwise, functions should receive current-process-bit paths. Use `ApplyRedirToRunEntryPaths` for run entries and `ApplyRedirForRegistrationOperation` for registration/shared-count operations. Old-style FS redirection disabling is still used when running 64-bit system executables from a 32-bit Setup process.\r\n- Extended-length (super) paths (`\\\\?\\`) are used by Setup to avoid MAX_PATH issues and are produced by `ApplyPathRedirRules` unless `rfNormalPath` is used. Only pass super paths to APIs known to accept them; when in doubt (especially for shell APIs or user-facing strings), convert back to a normal path.\r\n\r\n## Build\r\n- Run `compile.bat x64` or `compile.bat x86`. Both output release binaries to `Files`.\r\n- Append a project name, such as `compile.bat x64 ISCC`, to compile only that project.\r\n- Compiler path is configured in `compilesettings.bat`.\r\n- `build.bat` orchestrates full release builds.\r\n- In a fresh worktree, run `issig.bat embed` before the first compile. This updates the tracked files `Components\\TrustFunc.AllowedPublicKeys.inc` and `def02.ispublickey`. Leave them in place.\r\n- If a release build binary under `Files\\` reports \"Signature file is not valid\", run `issig.bat embed`, then rerun the relevant compile command, usually `compile.bat x64`, and retry the failed command.\r\n\r\n## Code Conventions\r\n- `**/*.iss`: see `.claude/rules/iss.md`.\r\n- `**/*.pas`, `**/*.dpr`, `**/*.inc`: see `.claude/rules/pascal.md`.\r\n- `**/*Test.pas`, `**/*Test.iss`: see `.claude/rules/test.md`.\r\n- `Files/Languages/*.isl`, `Files/Languages/Unofficial/*.isl`: see `.claude/rules/isl.md`.\r\n- `Components/UniPs/**`: see `.claude/rules/unips.md`.\r\n- `Projects/Src/Compression.LZMACompressor/islzma/**`, `Projects/Src/Compression.LZMADecompressor/Lzma2Decode/**`: see `.claude/rules/islzma.md`.\r\n- Indentation: see `.claude/rules/indentation.md`.\r\n\r\n## Documentation Conventions\r\n- `whatsnew.htm`, `ISHelp/isetup.xml`, `ISHelp/ispp.xml`, `ISHelp/isx.xml`, `ISHelp/isxfunc.xml`, `ISHelp/isxclasses.header*`, `ISHelp/isxclasses.footer`: see `.claude/rules/docs.general.md`.\r\n- `ISHelp/isetup.xml`, `ISHelp/isx.xml`, `ISHelp/isxfunc.xml`, `ISHelp/isxclasses.header*`, `ISHelp/isxclasses.footer`, `ISHelp/ispp.xml`: see `.claude/rules/docs.ishelp.md`.\r\n- `ISHelp/isetup.xml`: see `.claude/rules/docs.ishelp.isetup.md`.\r\n- `ISHelp/isxfunc.xml`: see `.claude/rules/docs.ishelp.isxfunc.md`.\r\n- `ISHelp/ispp.xml`: see `.claude/rules/docs.ishelp.ispp.md`.\r\n- `whatsnew.htm`: see `.claude/rules/docs.whatsnew.md`.\r\n\r\n## Docs\r\n- `whatsnew.htm` contains the Revision History.\r\n- Help content lives under `ISHelp`:\r\n  - When editing `ISHelp\\*`, regenerate CHM/Web help: run `compile.bat x64 ISHelpGen` then `ISHelp\\compile.bat` and verify 0 errors. Don't skip; this regenerates `isxclasses_wordlists_generated.pas`, which is in Git.\r\n  - `isxfunc.xml` documents Pascal Script functions.\r\n  - `isxclasses.pas` documents Pascal Script classes, with `isxclasses.header`, `isxclasses.header2`, and `isxclasses.footer` as helpers. When a `uPSC_*.pas` registration changes for Inno Setup (`PS_MINIVCL` is defined, `FPC` and `CLX` are not), update `isxclasses.pas` to match and regenerate as above.\r\n  - `isx.xml` contains all other Pascal Script documentation.\r\n  - `ispp.xml` documents the ISPP preprocessor.\r\n  - `isetup.xml` contains the remaining documentation.\r\n  - `isetup.dtd`, `ispp.dtd`, `isxfunc.dtd`, `isxfunc.xsl`, and `ispp.xsl` are schema and XSL files consumed by `ISHelpGen`.\r\n  - Don't edit files generated by `ISHelpGen`: `ispp_generated.xml`, `isxclasses_generated.xml`, `isxclasses_wordlists_generated.pas`, `isxfunc_generated.xml`.\r\n- Don't use em dashes or en dashes; use periods or commas instead.\r\n- Don't use \"e.g.\"; use \"for example\" or \"such as\" instead.\r\n\r\n## Precompiled Binaries\r\n- `Files/` contains precompiled C/C++ DLLs (7-Zip, zlib, bzip2, LZMA, Scintilla) and `.issig` signature files.\r\n- Rebuild with `build-precomp.bat` (requires separate repository checkouts); refresh signatures separately with ISSigTool afterward.\r\n\r\n## Testing & Verification\r\n- After editing any `.pas`, `.dpr`, `.dproj`, or `.inc` file: run `compile.bat x64` and verify 0 errors.\r\n- Unit tests live in `*.Test.pas` files. No testing framework is used; tests raise an exception on failure.\r\n- To run tests, run `test.bat [x86|x64]` and verify 0 exit code. Omit the architecture to test both. This also compiles `ISTestTool` first.\r\n\r\n## Other information\r\n- When creating a new file: immediately `git add` it, but only if still untracked.\r\n- Otherwise treat Git as read-only.\r\n- A task is not complete until the relevant compilation succeeds with 0 errors.\r\n"},"files":{".claude/rules/docs.general.md":"---\r\npaths: [\"whatsnew.htm\", \"ISHelp/isetup.xml\", \"ISHelp/ispp.xml\", \"ISHelp/isx.xml\", \"ISHelp/isxfunc.xml\", \"ISHelp/isxclasses.header*\", \"ISHelp/isxclasses.footer\"]\r\n---\r\n# General documentation conventions for Inno Setup\r\n\r\n## Voice and Tone\r\n\r\n- **Direct and technical.** State facts plainly. Do not hedge or pad with filler.\r\n- **Second person** (\"you\") when addressing the user who writes scripts or configures Setup.\r\n- **Impersonal** when describing system behavior: \"Setup will...\", \"the compiler will...\", \"an exception will be raised if...\".\r\n- **Not chatty.** No rhetorical questions, no \"Note that you might wonder...\". Just state the information.\r\n- **Contractions are used.** Write \"don't\", \"isn't\", \"can't\", \"won't\", \"doesn't\", \"aren't\", \"hasn't\", \"didn't\", \"wouldn't\", \"couldn't\", \"shouldn't\". These are natural and make the text less stiff for non-native readers.\r\n\r\n## Sentence Structure\r\n\r\n- Prefer **short, clear sentences**. One idea per sentence when possible.\r\n- Avoid deeply nested clauses. If a sentence grows complex, split it.\r\n- **Active voice** when possible: \"Setup creates the directory\" rather than \"the directory is created by Setup\". Passive voice is acceptable when the actor is irrelevant or when it reads more naturally: \"An exception will be raised if...\".\r\n- Parenthetical notes are common and acceptable: \"(which can include constants)\", \"(the default setting)\".\r\n\r\n## Vocabulary and Terminology\r\n\r\nUse the established Inno Setup terms consistently. Never substitute synonyms:\r\n\r\n| Correct term | Do not use |\r\n|---|---|\r\n| Setup, the Setup program, the installer | the installation program (note: \"installer\" is also standard for the compiled artifact, such as \"64-bit installers\") |\r\n| Uninstall, the uninstaller | the uninstall program |\r\n| the compiler | the build system, the compilation engine |\r\n| the end user | the customer, the consumer |\r\n| the user | the developer, the script author (when addressing the person writing .iss scripts) |\r\n| support function | helper function, utility function |\r\n| support class | helper class |\r\n| directive | setting, option (for [Setup] section items) |\r\n| parameter | field, property (for section entry items) |\r\n| flag | option, switch (for Flags parameter values) |\r\n| entry | line, row (for a line in a section) |\r\n| section | block, group (for [Setup], [Files], etc.) |\r\n| the Compiler IDE | the editor (\"the IDE\" is acceptable after \"the Compiler IDE\" has been established in the same context, in both ISHelp and whatsnew) |\r\n| Pascal Scripting | the scripting engine (for the feature/topic name; \"Pascal Script\" is acceptable when referring to the RemObjects Pascal Script engine itself) |\r\n| extended-length paths | long paths (use \"also known as super paths\" parenthetically on first mention within a topic; don't use \"super paths\" as a standalone term) |\r\n| menu item | menu option |\r\n| Start menu (but \"Start Menu\" in titles, such as the *Select Start Menu Folder* wizard page) | Start Menu |\r\n| checkbox | check box |\r\n| without a BOM | BOM-less, BOMless |\r\n| the help file | the help |\r\n\r\nAdditional vocabulary rules:\r\n- \"Setup or Uninstall\" or \"the Setup program and uninstaller\" when a feature applies to both. Not \"the installer or uninstaller\".\r\n- \"the user's system\" for the target environment. Not \"the target machine\". \"computer\" is acceptable for restarts (\"restart the computer\") and computer names (\"the name of the computer\").\r\n- \"specified\" is the standard word for parameters and directives: \"the specified file\", \"the specified parameter\". Not \"provided\".\r\n- \"given\" is the standard word for function argument descriptions: \"the given string\", \"the given file name\".\r\n- \"Returns True if...\" is the standard pattern for boolean function descriptions.\r\n- \"cannot\" as one word. Not \"can not\".\r\n- Use \"use\" not \"utilize\".\r\n- Use \"non-zero\" not \"non-zero value\".\r\n- Do not shorten established descriptive terms. Write \"support function\", not \"func\".\r\n- Repeat the same term for the same concept. Do not rotate between synonyms for variety.\r\n\r\n## Punctuation\r\n\r\n- **Oxford (serial) comma:** Use it. \"A, B, and C\", not \"A, B and C\".\r\n- **Periods** at the end of complete sentences, including list items that are complete sentences.\r\n- **No em dashes or en dashes.** Use periods, commas, or parentheses instead.\r\n- **No \"e.g.\"** Use \"for example\" or \"such as\".\r\n- **No \"i.e.\"** Use \"that is\" or rephrase.\r\n- **\"etc.\" is acceptable** but use sparingly.\r\n- **Colons** before examples and lists.\r\n\r\n## Formatting\r\n\r\n- Code identifiers should render as monospace: section names, directive names, parameter names, flag names, constant names, type names, function names, file names, directory names, path values, registry key and value type names, environment variable names, command-line switches, and values like `yes`/`no`/`True`/`False`. In prose, use `<tt>` for this. Inside already-monospace contexts, such as `<pre>`, `<precode>`, or ISPP `<line>` elements, no extra `<tt>` is needed.\r\n- When a code identifier is in a prose link's display text, still make it monospace with `<tt>`:\r\n  - For an internal `<link>`: outside the link if the identifier is the whole display text, inside otherwise.\r\n  - For an `<extlink>`: always inside, because external links get an icon added that must not appear inside the `<tt>` pill.\r\n- `<i>` for emphasis, wizard page names (such as *Select Destination Location*), UI element names, and font names.\r\n- `<b>` sparingly, for important warnings or the word \"NOTE:\".\r\n\r\n## Syntax Highlighting\r\n\r\nThe IDE styler (`Projects/Src/IDE.ScintStylerInnoSetup.pas`) is the source of truth for which token gets which\r\ncategory. Five non-obvious rules:\r\n\r\n- Use `<sec>`, `<evt>`, `<key>`, `<com>`, `<con>`, `<str>`, `<num>`, and `<ispp>` for syntax-highlighted script examples.\r\n- Use `<str>` and `<num>` only in Pascal Script and ISPP contexts. Section directive and parameter string\r\n  values stay plain, with only their inner constants using `<con>`. Number literals include ISPP array indices.\r\n- Use of `<con>` depends on context. Use it for a regular constant (`{app}`) inside a section directive or parameter\r\n  value, including inside a parameter value such as `ExpandConstant('<con>{app}</con>\\...')`,\r\n  but not inside a Pascal string literal, where the whole literal stays `<str>`. An ISPP inline constant\r\n  (`{#...}`) is the exception: it always uses `<ispp>` on the `{#...}` delimiters and directive name (the inner\r\n  expression keeps its own styling), even inside a string literal, because ISPP pre-styles it.\r\n- `<evt>` applies only to the fixed `BasicEventFunctions` set; functions named via event attributes are not bolded.\r\n- `[Messages]`/`[CustomMessages]`/`[LangOptions]`: only the message name is `<key>`; a language prefix is not.\r\n\r\n## Review Guidelines\r\n\r\nWhen reviewing documentation, check for:\r\n\r\n1. **Terminology consistency.** Are the correct Inno Setup terms used? (See the vocabulary table above.)\r\n2. **Factual accuracy.** Does the documentation match the actual code behavior?\r\n3. **Completeness.** Are all parameters, flags, return values, and error conditions documented?\r\n4. **Cross-references.** Are related topics linked?\r\n5. **Code formatting.** Are code identifiers in prose wrapped in `<tt>`? Are examples provided?\r\n6. **Style violations.** Check for: em/en dashes, \"e.g.\", \"i.e.\", synonym rotation, missing Oxford commas, \"can not\" instead of \"cannot\", \"utilize\" instead of \"use\".\r\n7. **Clarity for non-native speakers.** Avoid idioms, complex subordinate clauses, and uncommon vocabulary.\r\n8. **Do not nitpick** about subjective style matters in existing text that is not being changed. Only flag style issues in new or modified text.\r\n",".claude/rules/docs.ishelp.isetup.md":"---\npaths: [\"ISHelp/isetup.xml\"]\n---\n# isetup.xml documentation conventions\n\nThese are specific to `isetup.xml`, which documents the entry sections and [Setup] directives; the general ISHelp conventions in `docs.ishelp.md` apply too.\n\n## Section topic structure\n\nEach entry section topic (such as [Files], [Registry], [Run]) follows this structure:\n1. Opening paragraph: \"This optional section defines...\" or \"This section contains...\".\n2. Introductory notes about default behavior.\n3. Example section with `<precode>`.\n4. \"The following is a list of the supported parameters:\" introducing the parameter list.\n5. Parameters documented with `<paramlist>` / `<param>`.\n6. Links to Common Parameters and Components/Tasks Parameters at the bottom.\n\n## Directive-topic structure\n\nEach [Setup] directive topic uses `<setuptopic>`:\n1. `<setuptopic directive=\"DirectiveName\">`: topic wrapper.\n2. `<setupvalid>`: valid values (optional, omitted when free-form text).\n3. `<setupdefault>`: default value (optional).\n4. `<body>`: opening paragraph, followed by detail paragraphs, notes, examples, and optional \"See also\" links. Common opening patterns: \"This directive specifies...\", \"This tells the compiler...\", \"Controls whether...\", \"If set to [value]...\".\n\n## Parameter documentation\n\nEach parameter follows this pattern:\n1. Description paragraph: what it controls.\n2. Additional detail paragraphs as needed.\n3. Example with `<example><pre>`.\n4. For Flags parameters: \"This parameter is a set of extra options. Multiple options may be used by separating them by spaces. The following options are supported:\" followed by `<flaglist>`.\n\n## Conditional behavior\n\nUse the pattern: \"If [value] is specified, Setup will [action].\" Repeat for each value. Example:\n> If <tt>string</tt> is specified, Setup will create a string (<tt>REG_SZ</tt>) value.\n> If <tt>dword</tt> is specified, Setup will create a 32-bit integer (<tt>REG_DWORD</tt>) value.\n\n## Default values\n\nState defaults explicitly: \"Defaults to [value].\" or \"The default value is [value].\" or \"(the default setting)\".\n",".claude/rules/docs.ishelp.ispp.md":"---\r\npaths: [\"ISHelp/ispp.xml\"]\r\n---\r\n# ispp.xml documentation conventions\r\n\r\nThese are specific to `ispp.xml`; the general ISHelp conventions in `docs.ishelp.md` apply too.\r\n\r\n## Directive documentation\r\n\r\nPreprocessor directives use `<topic>` with `<syntax>`/`<define>`, `<description>`, and `<section>`.\r\n\r\n## Function documentation\r\n\r\nFunctions put the signature in `<section title=\"Prototype\">` (inside `<pre><line>`) and related links in `<section title=\"See also\">`.\r\n\r\nBoolean-like functions are documented as \"Returns non-zero if [condition].\" rather than \"Returns True if [condition], False otherwise.\"\r\n\r\n## Differences from the general conventions\r\n\r\n- **Cross-reference links:** use `<link href=\"topicname\">Display Text</link>`. `ispp.dtd` has no `anchor` attribute; the `href` carries the target.\r\n- **Examples:** examples sit in a bare `<pre>` inside `<section title=\"Examples\">`.\r\n- **Function shorthand:** `<isxfunc>` not available; link ISPP functions with `<link href=\"...\">`.\r\n- **Indentation:** `ispp.xml` is tab-indented, unlike the other ISHelp sources. Keep using tabs; the rules in `indentation.md` do not apply.\r\n",".claude/rules/docs.ishelp.isxfunc.md":"---\r\npaths: [\"ISHelp/isxfunc.xml\"]\r\n---\r\n# isxfunc.xml documentation conventions\r\n\r\nThese are specific to `isxfunc.xml`; the general ISHelp conventions in `docs.ishelp.md` apply too.\r\n\r\n`<link topic=\"...\">` (with optional `anchor`), `<extlink>`, `<sd>`, `<sn>`, and `<isxfunc>` all work as in the general conventions.\r\n\r\n## Function documentation\r\n\r\nEach function follows this pattern:\r\n- `<name>`: Function name.\r\n- `<prototype>`: Full function signature.\r\n- `<description>`: One or more `<p>` elements. First sentence is the key description.\r\n  - For functions returning a value: \"Returns [description of return value].\"\r\n  - For procedures: \"Does [action].\" or imperative form.\r\n  - For boolean functions: \"Returns True if [condition], False otherwise.\"\r\n- `<remarks>` (optional): Additional notes, edge cases, caveats.\r\n- `<seealso>` (optional): Links to related functions.\r\n- `<example>` (optional): Code example.\r\n\r\nStandard description patterns:\r\n- \"Returns the [noun] of [context].\"\r\n- \"Returns True if [condition].\"\r\n- \"Returns a [type] containing [description].\"\r\n- \"Gets/Sets the value of [thing].\"\r\n- \"Creates/Deletes/Removes [thing].\"\r\n- \"An exception will be raised if [error condition].\"\r\n- \"If [condition], [function name] returns [value].\"\r\n\r\n## Differences from the general conventions\r\n\r\n- **Examples:** use `<example>`, which may contain `<pre>`. `isxfunc.dtd` has no `<precode>`.\r\n",".claude/rules/docs.ishelp.md":"---\r\npaths: [\"ISHelp/isetup.xml\", \"ISHelp/isx.xml\", \"ISHelp/isxfunc.xml\", \"ISHelp/isxclasses.header*\", \"ISHelp/isxclasses.footer\", \"ISHelp/ispp.xml\"]\r\n---\r\n# ISHelp documentation conventions\r\n\r\nThese are the general documentation conventions shared by all ISHelp sources. `isetup.xml`, `isx.xml`, and the `isxclasses.*` helpers use `isetup.dtd`; `isxfunc.xml` (`isxfunc.dtd`) and `ispp.xml` (`ispp.dtd`) use their own DTD. They all follow the conventions below, except where a file's own rule file notes a difference or adds file-specific structure: see `docs.ishelp.isetup.md`, `docs.ishelp.isxfunc.md`, and `docs.ishelp.ispp.md`. Prose conventions for all of these files live in `docs.general.md`, not here.\r\n\r\n## Additional formatting\r\n\r\n- `<precode>` for syntax-highlighted section-level and topic-level script examples (such as showing a full [Run] section).\r\n- `<example><pre>` for syntax-highlighted parameter and function examples, which can also be multi-line.\r\n\r\n## Cross-references\r\n\r\n- Use `<link topic=\"topicname\">Display Text</link>`.\r\n- Always link to related topics when mentioning directives, sections, or functions. Do not leave them as plain text if a help topic exists.\r\n- Use the `<sd>Directive</sd>`, `<sn>[Section]</sn>`, and `<isxfunc>FunctionName</isxfunc>` shorthands instead of a `<link>` to a [Setup] directive, section, or support function.\r\n- To specific anchors: `<link topic=\"topicname\" anchor=\"anchorname\">Display Text</link>`.\r\n- External links: `<extlink href=\"url\">Display Text</extlink>`.\r\n",".claude/rules/docs.whatsnew.md":"---\r\npaths: [\"whatsnew.htm\"]\r\n---\r\n# Inno Setup Revision History documentation conventions\r\n\r\n## Additional formatting\r\n\r\n- `<i>Fix:</i>` prefix for bug fix entries.\r\n- `<pre><code class=\"innosetup\">` for syntax-highlighted script examples.\r\n\r\n## Example script references\r\n\r\n- \"See updated <tt><a href=\"...\">ScriptName.iss</a></tt> example script.\"\r\n- \"See updated <tt><a href=\"...\">ScriptName.iss</a></tt> example script for an example.\"\r\n- \"See new <tt><a href=\"...\">ScriptName.iss</a></tt> example script.\"\r\n\r\n## Entry structure\r\n\r\nChangelog entries appear as `<li>` items in `<ul>` lists.\r\n\r\n**New features:**\r\n- \"Added new [type] <tt>Name</tt>.\" or \"Added new [type] <tt>Name</tt> to [context].\"\r\n- \"Added new support functions <tt>Name1</tt>, <tt>Name2</tt>, and <tt>Name3</tt>.\"\r\n- \"Added new support classes <tt>Name1</tt>, <tt>Name2</tt>, and <tt>Name3</tt>.\"\r\n- \"Added new properties <tt>Name1</tt>, <tt>Name2</tt>, and <tt>Name3</tt> to class <tt>ClassName</tt>.\"\r\n- \"Added support for [feature].\"\r\n\r\n**Changes:**\r\n- \"Directive <tt>Name</tt> now defaults to <tt>value</tt>.\"\r\n- \"<tt>Feature</tt> is now [new behavior].\"\r\n- \"Enhanced/Improved/Updated [thing] [description of change].\"\r\n- \"Renamed <tt>OldName</tt> to <tt>NewName</tt>. The old name still works.\"\r\n\r\n**Bug fixes:**\r\n- Always prefixed: \"<i>Fix:</i> Description of what was wrong and what is now correct.\"\r\n- For documentation-only fixes: \"<i>Documentation fix:</i> Description.\"\r\n- Describe the symptom, not just the fix. Include \"broken since X.Y.Z\" or \"broken in X.Y.Z\" when known.\r\n\r\n**Removals:**\r\n- \"Removed support for [feature].\" or \"Support for [feature] has been dropped.\"\r\n- \"Removed [thing]. Use [replacement] instead.\"\r\n\r\n**Deprecations:**\r\n- \"This function is deprecated.\" followed by what to use instead.\r\n- \"The compiler still accepts <tt>OldName</tt> as an alias for <tt>NewName</tt>, but will emit a deprecation warning when used.\"\r\n\r\n## Subcategories\r\n\r\nGroup related changes under subcategory headers using nested lists:\r\n```html\r\n<li>Pascal Scripting:\r\n<ul>\r\n  <li>Added new support function <tt>Foo</tt>.</li>\r\n  <li><i>Fix:</i> <tt>Bar</tt> now works correctly.</li>\r\n</ul>\r\n</li>\r\n```\r\n\r\nStandard subcategory names: \"Compiler IDE:\", \"Pascal Scripting:\", \"ISPP:\", \"Setup:\", \"Compiler:\", \"Command-Line Compiler (ISCC):\", \"Examples:\", \"Security improvement:\", \"Updated documentation:\", and product-specific names such as \"Inno Setup Signature Tool:\". Other one-off names are acceptable when a group of entries warrants its own heading.\r\n\r\n## Catch-all entries\r\n\r\nEnd a version's changes with one of:\r\n- \"Other minor improvements.\"\r\n- \"Minor tweaks.\"\r\n- \"Minor tweaks and fixes.\"\r\n- \"Other minor improvements and fixes.\"\r\n- \"Documentation improvements.\"\r\n\r\n## Security section intro\r\n\r\nWhen there is a security improvements section:\r\n> Updating is recommended, even if you don't plan to use the other enhancements right away. We continually add extra checks to make your installers safer and more reliable. In this version:\r\n",".claude/rules/indentation.md":"---\r\npaths: [\"**/*.pas\", \"**/*.dpr\", \"**/*.dpk\", \"**/*.inc\", \"**/*.iss\", \"**/*.htm\", \"**/*.bat\", \"**/*.c\", \"**/*.h\", \"**/*.dfm\", \"**/*.xml\", \"**/*.dtd\", \"**/*.xsl\", \"**/*.md\", \"**/*.yml\"]\r\n---\r\n# Indentation conventions for all text files\r\n- Use spaces for indentation, not tabs.\r\n- Unless the format requires otherwise (for example, `.md` lists), use two spaces per indentation level.\r\n",".claude/rules/isl.md":"---\r\npaths: [\"Files/Languages/*.isl\", \"Files/Languages/Unofficial/*.isl\"]\r\n---\r\n# Conventions for Inno Setup translation files\r\n\r\nThese files translate `Files/Default.isl` into another language. `Default.isl` is the English baseline and the source of truth for the message set; it changes between Inno Setup versions, so always work from the most recent `Default.isl`, read it fresh, and treat its `[Messages]` and `[CustomMessages]` IDs as authoritative. A translation must stay faithful to its English counterpart: the English is the fixed reference and the ceiling, not something to clarify, complete, or improve.\r\n\r\n## Quality rules\r\n\r\n### File format and structure\r\n- **Encoding.** UTF-8 without a BOM.\r\n- **Newlines.** Windows CRLF throughout.\r\n- **Extension.** `.isl`. The `.islu` extension is obsolete.\r\n- **Compiles cleanly.** The file must compile with no errors and no warnings.\r\n\r\n### Comment header (top-of-file comments)\r\n- The first line is the version line, usually `; *** Inno Setup version X+ ... messages ***`. Keep it consistent with the `Default.isl` header version. It must never be higher than the `Default.isl` version.\r\n- The top of the file must also carry, as comments, the language's English name and the maintainer's name and e-mail address.\r\n\r\n### `[LangOptions]` settings\r\n- **LanguageName.** The language's native name (the name as written in the language itself), not its English name. For example Dutch is `Nederlands`, not `Dutch`. It is shown in the *Select Language* dialog. The obsolete `<HHHH>` escape syntax still works but is no longer needed; write the literal characters directly.\r\n- **LanguageID.** A valid hexadecimal language identifier beginning with `$`, matching the language and its region (for example `$0413` for Dutch (Netherlands), `$0813` for Belgian Dutch). It must not be left at `$0409`, which is the English ID of `Default.isl`. Verify against Microsoft's language-identifier list (https://learn.microsoft.com/en-us/windows/win32/intl/language-identifier-constants-and-strings). If no identifier exists for the language, set it to `0`. Together with `LanguageCodePage` it is used to auto-detect the most appropriate default language, so set it correctly.\r\n- **LanguageCodePage.** The Windows ANSI code page the compiler uses to convert any non-Unicode text in the language's files to Unicode (for example 1252 Western European, 1250 Central European, 1251 Cyrillic, 1253 Greek, 1254 Turkish, 1255 Hebrew, 1256 Arabic, 1257 Baltic, 1258 Vietnamese, 874 Thai, 932 Japanese, 936 Chinese Simplified, 949 Korean, 950 Chinese Traditional). Set it to `0` only when no code page exists for the language (a Unicode-only script such as Hindi, Tamil, Bengali, Armenian, Georgian) or the language uses only ASCII characters. It still matters even though the `.isl` is UTF-8, because it converts non-Unicode files such as a README supplied by the script author. (Text in the `.iss` file itself, such as a `[CustomMessages]` entry, is never converted and must already be Unicode.)\r\n- **RightToLeft.** `RightToLeft=yes` must be set for a right-to-left script (Arabic, Hebrew, Persian (Farsi), Urdu, Uyghur) and must not be set (or `RightToLeft=no`) for a left-to-right language.\r\n- **Fonts** (`DialogFontName`, `DialogFontSize`, `WelcomeFontName`, and so on). `Default.isl` keeps them all commented out. Uncomment only the entries the language genuinely needs to differ; an entry equal to the default stays commented out, so it inherits future default changes. Drop obsolete entries no longer in `Default.isl` (such as `CopyrightFontName`/`CopyrightFontSize`).\r\n\r\n### Sections and message set (compared to `Default.isl`)\r\n- **Translate the existing entries only.** Provide every `[Messages]` and `[CustomMessages]` ID that `Default.isl` defines, translated. Do not add your own custom messages to `[CustomMessages]`, and do not invent new IDs.\r\n- **No missing IDs.** Every ID defined in `Default.isl` must be present.\r\n- **No obsolete IDs.** Do not keep IDs that no longer exist in `Default.isl`.\r\n- **Empty values.** A message that is empty in `Default.isl` must stay empty in the translation, except for the `TranslatorNote` message.\r\n\r\n### Per-message rules (each message compared to its English counterpart)\r\n- **Placeholder integrity.** The same set and count of `%1`..`%9` must be present (the order may differ to suit the target grammar, and an argument may legitimately be duplicated, such as `%1 ... %1 %2`). Keep `%n` line breaks and `%%` literal-percent escapes intact. Preserve the same bracketed runtime placeholders, currently `[name]`, `[name/ver]`, `[mb]`, and `[gb]`. Never drop, add, or malform a placeholder or format specifier.\r\n- **Placeholder grammar.** A placeholder is filled at runtime with a value the translator cannot see or inflect, and which is not always the expected token (a wizard-name `%1`, for example, can be a custom name). Phrase the surrounding text so it reads correctly for any value: keep the placeholder in a slot that needs no inflection of, or grammatical agreement with, the inserted value, and never assume the value's gender, number, or case. If the English drops the value into a slot your language would inflect or agree with, rebuild the clause rather than guessing one form.\r\n- **Accelerator keys.** Keep an `&` accelerator wherever the English has one, and do not add one where the English has none. Drop an accelerator only when it cannot be placed on any letter of the translated text; resolve a collision by moving it to another letter rather than dropping it. Within each accelerator scope every accelerator letter must be unique, compared case-insensitively.\r\n- **No added periods.** Do not add a period to the end of a message that did not have one already. Exception: for languages with their own period character, such as Japanese and Chinese, it was added to the end of messages as needed. Keep a trailing period where the English has one. Exception: Thai and Lao remove trailing periods and question marks. If the English ends with `...`, keep the trailing ellipsis, written either as three dots `...` or as a single ellipsis character `…`. Spacing before the ellipsis follows the target language's typography (for example German puts a space before it, while English does not).\r\n- **Faithful meaning.** Stay as close to the original English as possible. Do not add to or change the meaning of a message to suit personal taste (for example do not append \"Try again one more time.\" to an error message that did not say that).\r\n\r\n### Translation quality (linguistic)\r\n- No spelling or grammar errors.\r\n- No untranslated messages that should have been translated. Some values are legitimately identical to English (`Setup`, `OK`, brand names, placeholder-only messages); only genuine omissions are wrong.\r\n- Consistent terminology: the same concept uses the same term across every message, with consistent button-label style and capitalization.\r\n- Use the language's native standard terminology, taking installer terms from the matching official Setup translation and everything else from Microsoft Terminology plus the language's Style Guide (for example the standard local words for Setup, folder, uninstall, administrator).\r\n- Consistent, language-appropriate tone, formality, casing, punctuation, and quote style (for example German capitalizes nouns and addresses the user formally; Japanese uses full-width punctuation where the platform does).\r\n- Translate naturally. As loose guidance stay near the English length (roughly within about 150 percent), but naturalness wins.\r\n\r\n## Faithfulness check before changing a message\r\n\r\nBefore changing a translated message because it looks wrong, confirm all of these; if any fails, leave it alone:\r\n1. Quote the exact English string. If you can't, you haven't compared against it.\r\n2. The current translation differs from what the English *means*, not from a clearer or more explicit version you imagined. If the English is itself ambiguous, general, or underspecified, an equally ambiguous translation is correct, not a problem.\r\n3. Your change preserves the English meaning. It must not add precision, disambiguation, or detail the English does not have.\r\n4. It is substantive. Awkward-but-acceptable phrasing, debatable terminology, and pure style preferences are nitpicks; leave them.\r\n5. Back-translate both the current text and your replacement into English. Change it only if the current text back-translates to a different meaning than the English *and* your replacement back-translates to the same meaning. If the replacement back-translates to something the English does not say, it adds meaning; drop it.\r\n",".claude/rules/islzma.md":"---\r\npaths: [\"Projects/Src/Compression.LZMACompressor/islzma/**\", \"Projects/Src/Compression.LZMADecompressor/Lzma2Decode/**\"]\r\n---\r\n# Instructions for the native LZMA C code (islzma and Lzma2Decode)\r\n\r\n## Indentation\r\n\r\nThese files keep their existing indentation style; the rules in `indentation.md` do not apply:\r\n- `islzma.c`, `islzma.h`, `islzma_dll.c`, `islzma_exe.c`, `ISLzmaDec.c`, and `test/test.bat` are tab-indented.\r\n- `test/roundtrip.c` is four-space indented.\r\n\r\nDo not reformat these files. When editing, match the surrounding indentation of the file you are in.\r\n",".claude/rules/iss.md":"---\r\npaths: [\"**/*.iss\"]\r\n---\r\n# Coding conventions for Inno Setup script files\r\nInno Setup `.iss` scripts use the `[Code]` section for Pascal Script code. This is RemObjects Pascal Script (ROPS), not modern Delphi. The following rules apply to code in `[Code]` sections.\r\n## Language differences compared to Delphi\r\nMost of these are hard constraints of the ROPS compiler. Violating them causes compile errors.\r\n- No inline `var` or inline `const`. All local variables must be declared in a `var` block before `begin`.\r\n- No local `const` or `type` declarations. Only `var` and `label` blocks are allowed before `begin`.\r\n- No `Exit(Value)` syntax. Assign to `Result` first, then call `Exit` separately.\r\n- No typed constants (`const X: Integer = 1`). Only untyped constants (`const X = 1`).\r\n- No default parameter values.\r\n- No function or procedure overloading.\r\n- No `raise` keyword. Use `RaiseException(Msg)` or `RaiseLastException` instead.\r\n- No `on E: ExceptionType do` in `except` blocks. Use `GetExceptionMessage` to inspect the current exception.\r\n- No script-defined classes. Classes can be used, but only those defined by Inno Setup.\r\n- No variant records.\r\n- `const` parameters are passed by value (copied), and not by reference as in modern Delphi.\r\n- As in Delphi, assigning a dynamic array, or passing it as a value or `const` parameter, shares its elements. A change to an element through one variable is visible through the other. `SetArrayLength` and `SetLength` copy a shared array only when the length changes. Delphi's `SetLength` always copies it. `Copy` doesn't support arrays. To get an array that isn't shared, change its length and change it back, or copy the elements to a new array.\r\n- The `/` operator always returns `Extended`, even when both operands are integers. Use `div` for integer division.\r\n- `Break` and `Continue` are not reserved words. They are ordinary identifiers recognized specially inside loop bodies. A local declaration named `Break` or `Continue` will shadow the loop-control behavior.\r\n- `Low`, `High`, and `SizeOf` must be used with a variable, not a type.\r\n## Conventions (same spirit as the Pascal rules, adapted for ROPS)\r\n- Pre-declare all local variables in the `var` block before `begin`.\r\n- Do not use `with` statements.\r\n- `if` and `begin` should be on the same line.\r\n- `else` and `begin` should be on the same line.\r\n- Do not use `begin..end` for single one-line statement blocks, but always use it when the block spans multiple lines. This includes when the block's single statement spans multiple lines (such as a multi-line `for`), and when a comment on its own line accompanies the statement (a trailing comment on the statement's line does not count).\r\n  Count lines per indentation level: a child statement never adds to its parent's count, so a chain of one-line statements takes no `begin..end` at any level.\r\n  A statement wrapped over continuation lines still counts as one line. But a statement that is genuinely multi-line at its own level (a `begin..end` block, or a control statement with a body, of its own) makes each level above it multi-line too.\r\n- Do not use `Longint` or `LongWord`; use `Integer` or `Cardinal` instead.\r\n- Mark read-only parameters as `const`.\r\n- Do not shorten descriptive names. Write `Expression`, not `Expr`; `MultiFileHandler`, not `MFH`. Conventional short names (`I`, `J`, `S`, `Res`) and established identifiers (`HiWord`) are fine.\r\n## Code editing guidelines\r\n- Do not modify existing comments unless the code they describe is also being changed.\r\n- Keep new comments short and match the style of existing comments in the file.\r\n",".claude/rules/pascal.md":"---\r\npaths: [\"**/*.pas\", \"**/*.dpr\", \"**/*.inc\"]\r\n---\r\n# Coding conventions for Pascal source files\r\n- Always use inline variables instead of pre-declaring them at the start of the function.\r\n  Exception: Delphi 10.4 does not support anonymous array types in inline variable or constant declarations, so pre-declare them.\r\n- Prefer inline constants over inline variables, even for run-time values and not just for compile-time constants.\r\n  Exception: inline constants cannot be passed as `var` parameters, so use an inline variable in that case.\r\n  Inline constants which are an object can still have their properties modified.\r\n  Inline constants use `=` as the assignment operator instead of `:=`. Examples:\r\n  `const MaxCount = MinCount * 2;`\r\n  `const ExpandedFilename = PathExpand(Filenames[I]);`\r\n- Prefer factoring shared code into a routine, or binding the expression to an inline const.\r\n- A routine whose callers all sit inside one routine belongs nested in it, not as a method or a unit-level routine. Keep such helpers siblings at a single level: never nest a helper inside another helper. No exceptions, except a routine assigned to an event stays a method.\r\n- Do not use `with` statements.\r\n- `if` and `begin` should be on the same line.\r\n- `else` and `begin` should be on the same line.\r\n- A `Result` assignment followed by an `Exit` statement should be combined into a single statement. For example: `Exit(ResultValue);`\r\n- Do not use `begin..end` for single one-line statement blocks, but always use it when the block spans multiple lines. This includes when the block's single statement spans multiple lines (such as a multi-line `for`), and when a comment on its own line accompanies the statement (a trailing comment on the statement's line does not count).\r\n  Count lines per indentation level: a child statement never adds to its parent's count, so a chain of one-line statements takes no `begin..end` at any level:\r\n  `for var X in Y do`\r\n  `  if Z(X) then`\r\n  `    Exit(True);`\r\n  A statement wrapped over continuation lines still counts as one line. But a statement that is genuinely multi-line at its own level (a `begin..end` block, or a control statement with a body, of its own) makes each level above it multi-line too.\r\n- Do not use `Longint` or `LongWord`, use `Integer` or `Cardinal` instead.\r\n- Mark read-only parameters as `const`.\r\n- Use Windows units first, then RTL/VCL units, then Components units, then Shared units, then project specific units.\r\n- Class methods should be static when possible.\r\n- Do not shorten descriptive names. Write `Expression`, not `Expr`; `MultiFileHandler`, not `MFH`. Conventional short names (`I`, `J`, `S`, `Res`) and established identifiers (`HiWord`) are fine.\r\n- Comments should be short and match the style of existing comments in the file. Prefer using `{` and `}`, and do not end one-sentence comments with a period.\r\n# Code editing guidelines\r\n- Do not modify existing comments unless the code they describe is also being changed.\r\n- When modifying code that calls Windows APIs, read the actual documentation before writing code. Do not assume parameter semantics based on similar APIs.\r\n- Update Inno Setup copyright header of any file you edit, if the current year is not already included.\r\n- Add tests for new code to the unit's `*.Test.pas` if it exists; otherwise consider creating one if the code is complex enough to warrant testing.\r\n  ISPP and ROPS code is tested by `Script.ISPP.Test.iss` and `Script.ROPS.Test.iss`, not a `*.Test.pas` unit.\r\n# Code review guidelines\r\n- All errors must be checked. Installers should be reliable above all.\r\n- Be alert for `out` parameters: an `out` parameter, like a `var` parameter, is passed by reference. However, with an `out` parameter, the initial value of the referenced variable for managed types, such as strings or arrays, is discarded by the caller before it is passed to the routine. Meanwhile, the initial value for unmanaged types, such as integers or pointers, is ignored. Therefore, for unmanaged types, it is not guaranteed that the initial value of the referenced variable will be overwritten in the routine to which it is passed.\r\n- Be alert for functions not assigning a value to Result: if a function exits without assigning a value to Result or the function name, then the function's return value is undefined, even for managed types.\r\n- Be alert for dynamic-array aliasing: assigning one dynamic array (e.g. `TBytes`) to another makes both reference the same buffer. Unlike strings and static arrays, copy-on-write is not employed, so writes through one alias (including `FillChar`) are visible through the other. Use `Copy(Source)` when an independent buffer is needed.\r\n- Code must be compatible with Delphi 10.4 and later.\r\n- Code must be compatible with 32-bit and 64-bit builds.\r\n- Code must be compatible with Windows 7 and later.\r\n- Do not suggest applying coding conventions to unchanged code.\r\n- Do not suggest changing an inline constant to an inline variable.\r\n- Do not nitpick, especially not about readability or subjective matters. This includes:\r\n  - Comment style or presence of comments.",".claude/rules/test.md":"---\r\npaths: [\"**/*Test.pas\", \"**/*Test.iss\"]\r\n---\r\n# Instructions for adding tests\r\n\r\n## When a correct test fails: allow investigation instead of pure tweaking\r\n\r\nIf a test that looks correct fails at compile time or at runtime, **do not silently adjust it until it passes**. A test that matches spec behavior but fails is evidence of a bug, not a bad test. The right response is:\r\n\r\n1. **Keep the original test** in the test source file, commented out, with a short explanation of the bug it exposed (e.g. `{ bug: 'for I: Byte := 0 to 255' infinite-loops because the loop variable wraps from 255 to 0 }`).\r\n2. **Write an alternate working test** that covers the same functionality without hitting the bug, if one exists. For example, use a narrower range or a different loop structure. This keeps test coverage moving forward.\r\n3. **Fixing the bug and re-enabling the original test is a separate task** - do not block the current phase on it.\r\n\r\nTweaking a test to avoid a real bug - changing types, adding casts, restructuring loops - hides regressions and defeats the purpose of the test suite.\r\n\r\n## Tests that check for a raised exception\r\n\r\nWhen a test verifies that something raises an exception, guard that part with `{$IFDEF ISTESTTOOLPROJ}` so it runs only under ISTestTool, not the DEBUG self-test. The self-test runs in the unit's `initialization` block inside the real application, where an intentionally raised exception would break in the debugger on every run. ISTestTool defines `ISTESTTOOLPROJ` and runs these checks normally.\r\n\r\nUse this pattern:\r\n\r\n```pascal\r\n{$IFDEF ISTESTTOOLPROJ}\r\n{ <what must raise and why> }\r\nvar Caught := False;\r\ntry\r\n  SomethingThatMustRaise;\r\nexcept\r\n  Caught := True;\r\nend;\r\nAssert(Caught);\r\n{$ENDIF}\r\n```\r\n\r\nKeep assertions that must always run, such as the contrasting success case, outside the `{$IFDEF ISTESTTOOLPROJ}` block.\r\n",".claude/rules/unips.md":"---\r\npaths: [\"Components/UniPs/**\"]\r\n---\r\n# Instructions for UniPs (Pascal Script) components\r\n\r\n## Upstream origin\r\n\r\nThese files are copies of the RemObjects Pascal Script `stable` branch (see `rev.txt` for the commit hash).\r\n\r\nYou may still edit them, but:\r\n- Do not refactor the code style to match Inno Setup conventions.\r\n- Keep changes minimal and focused. Even though Inno Setup is a Delphi Windows codebase, the Pascal Script code is cross-platform: it compiles under multiple compilers (Delphi and FPC), operating systems (Windows and others), and CPU bitnesses (32- and 64-bit). A change must either be correct on every combination, or be guarded so it only affects the ones you have verified. Useful guards: `{$IFDEF DELPHI}` / `{$IFDEF FPC}` (compiler), `{$IFDEF MSWINDOWS}` (OS), and `{$IFDEF CPU64}` (bitness).\r\n  Inno Setup always builds with Delphi on Windows, in both 32- and 64-bit, so your change must be correct there. Improving support for the platforms Inno Setup does not use (FPC, non-Windows) is a bonus, but extend a change to them only when it is easy and correctness is easy to confirm; otherwise guard the change.\r\n- Don't edit or inspect `rev.txt` as it is an auto-generated bookkeeping file.\r\n\r\n## Registration: compile-time (uPSC_) vs runtime (uPSR_)\r\n\r\nPascal Script has two registration layers that must stay in sync:\r\n- **Compile-time** (`uPSC_*.pas`): declares what the script compiler accepts.\r\n- **Runtime** (`uPSR_*.pas`): provides actual method pointers and property helpers.\r\n\r\nWhen a compile-time registration is guarded by `{$IFDEF}` or `{$IFNDEF}`, the matching runtime registration must use the same guard. A mismatch causes scripts to compile successfully but crash at runtime.\r\n\r\nA compile-time `RegisterProperty` for a **published** property does not require a matching runtime `RegisterPropertyHelper`. RTTI handles published properties automatically. Only non-published properties need explicit runtime read/write helpers.\r\n\r\nUse the actual Pascal type name in `RegisterProperty`, not a shortcut like `'Byte'` for enums or sets. For example, use `'TComponentState'` for a set type and `'TFontPitch'` for an enum, not `'Byte'`.","AGENTS.md":"# Inno Setup AI Agent Guide\r\n\r\n## Introduction\r\n- Source code of Inno Setup, an open-source installation builder for Windows applications by Jordan Russell and Martijn Laan, first released in 1997.\r\n- Comes in 64-bit and 32-bit editions; both can build 32-bit or 64-bit installers.\r\n- Copyrighted software; see `LICENSE.TXT` for distribution restrictions. Commercial users are requested to purchase a commercial license.\r\n\r\n## Project Architecture\r\nDelphi projects under `Projects/`:\r\n\r\n| Project | Output | Role |\r\n|---------|--------|------|\r\n| `ISIDE` | EXE | GUI compiler front-end (IDE), thin shell around ISCmplr.dll |\r\n| `ISCC` | EXE | CLI compiler front-end, thin shell around ISCmplr.dll |\r\n| `ISCmplr` | DLL | Actual compiler engine; entry point: `Compiler.SetupCompiler.pas` |\r\n| `ISPP` | DLL | Preprocessor |\r\n| `Setup` | EXE | Installer runtime; entry point: `Setup.MainFunc.pas` |\r\n| `SetupCustomStyle` | EXE | Installer runtime with VCL Styles support |\r\n| `SetupLdr` | EXE | Self-extracting loader that decompresses and launches Setup |\r\n| `ISSigTool` | EXE | Signs and verifies files using custom signatures |\r\n| `ISTestTool` | EXE | Internal utility that runs unit tests; invoked by build.bat and build-ce.bat |\r\n\r\nUnder `ISHelp/ISHelpGen/`:\r\n\r\n| Project | Output | Role |\r\n|---------|--------|------|\r\n| `ISHelpGen` | EXE | Generates XML files for help and Pascal Script autocomplete |\r\n\r\n## Core System\r\n- Delphi codebase targeting Windows 7 and later via the Windows API. All projects build for x64 and x86.\r\n- Primary project-specific source lives in `Projects/Src/` using namespace prefixes: `Compiler.*`, `Compression.*`, `IDE.*`, `ISPP.*`, `Setup.*`, `SetupLdrAndSetup.*`, `Shared.*`. Projects also compile shared units from `Components/`, and `ISIDE` additionally consumes the generated `ISHelp\\isxclasses_wordlists_generated.pas`. New project-specific source files must follow the namespace convention and be placed in `Projects/Src/`.\r\n- `Shared.Struct.pas` defines cross-project record layouts, and `Shared.CompilerInt.Struct.pas` defines the compiler/front-end interface layout. Changing either requires reviewing every consumer and recompiling the relevant projects.\r\n- Other shared units live under `Components` and `Projects\\Src\\Shared.*.pas`.\r\n- `SetupLdrAndSetup.*` units are shared by SetupLdr, Setup, and SetupCustomStyle; changes must account for all three.\r\n- `SetupCustomStyle` uses the same sources as `Setup` plus `Vcl.Themes`/`Vcl.Styles` and `Setup.TaskDialogForm`.\r\n- Many UI units in `Projects/Src/` are paired with checked-in `.dfm` files; form changes often require coordinated `.pas` and `.dfm` edits.\r\n- Compression engines pull native code from `Projects\\Src\\Compression.*`.\r\n- Pascal Script integration sits in `Compiler.Script*.pas` and `Setup.Script*.pas`; changes must be mirrored on both compiler and setup sides.\r\n- Setup path redirection: `ApplyPathRedirRules` rewrites System32/SysWOW64/Sysnative and converts to super paths. Unless documented otherwise, functions should receive current-process-bit paths. Use `ApplyRedirToRunEntryPaths` for run entries and `ApplyRedirForRegistrationOperation` for registration/shared-count operations. Old-style FS redirection disabling is still used when running 64-bit system executables from a 32-bit Setup process.\r\n- Extended-length (super) paths (`\\\\?\\`) are used by Setup to avoid MAX_PATH issues and are produced by `ApplyPathRedirRules` unless `rfNormalPath` is used. Only pass super paths to APIs known to accept them; when in doubt (especially for shell APIs or user-facing strings), convert back to a normal path.\r\n\r\n## Build\r\n- Run `compile.bat x64` or `compile.bat x86`. Both output release binaries to `Files`.\r\n- Append a project name, such as `compile.bat x64 ISCC`, to compile only that project.\r\n- Compiler path is configured in `compilesettings.bat`.\r\n- `build.bat` orchestrates full release builds.\r\n- In a fresh worktree, run `issig.bat embed` before the first compile. This updates the tracked files `Components\\TrustFunc.AllowedPublicKeys.inc` and `def02.ispublickey`. Leave them in place.\r\n- If a release build binary under `Files\\` reports \"Signature file is not valid\", run `issig.bat embed`, then rerun the relevant compile command, usually `compile.bat x64`, and retry the failed command.\r\n\r\n## Code Conventions\r\n- `**/*.iss`: see `.claude/rules/iss.md`.\r\n- `**/*.pas`, `**/*.dpr`, `**/*.inc`: see `.claude/rules/pascal.md`.\r\n- `**/*Test.pas`, `**/*Test.iss`: see `.claude/rules/test.md`.\r\n- `Files/Languages/*.isl`, `Files/Languages/Unofficial/*.isl`: see `.claude/rules/isl.md`.\r\n- `Components/UniPs/**`: see `.claude/rules/unips.md`.\r\n- `Projects/Src/Compression.LZMACompressor/islzma/**`, `Projects/Src/Compression.LZMADecompressor/Lzma2Decode/**`: see `.claude/rules/islzma.md`.\r\n- Indentation: see `.claude/rules/indentation.md`.\r\n\r\n## Documentation Conventions\r\n- `whatsnew.htm`, `ISHelp/isetup.xml`, `ISHelp/ispp.xml`, `ISHelp/isx.xml`, `ISHelp/isxfunc.xml`, `ISHelp/isxclasses.header*`, `ISHelp/isxclasses.footer`: see `.claude/rules/docs.general.md`.\r\n- `ISHelp/isetup.xml`, `ISHelp/isx.xml`, `ISHelp/isxfunc.xml`, `ISHelp/isxclasses.header*`, `ISHelp/isxclasses.footer`, `ISHelp/ispp.xml`: see `.claude/rules/docs.ishelp.md`.\r\n- `ISHelp/isetup.xml`: see `.claude/rules/docs.ishelp.isetup.md`.\r\n- `ISHelp/isxfunc.xml`: see `.claude/rules/docs.ishelp.isxfunc.md`.\r\n- `ISHelp/ispp.xml`: see `.claude/rules/docs.ishelp.ispp.md`.\r\n- `whatsnew.htm`: see `.claude/rules/docs.whatsnew.md`.\r\n\r\n## Docs\r\n- `whatsnew.htm` contains the Revision History.\r\n- Help content lives under `ISHelp`:\r\n  - When editing `ISHelp\\*`, regenerate CHM/Web help: run `compile.bat x64 ISHelpGen` then `ISHelp\\compile.bat` and verify 0 errors. Don't skip; this regenerates `isxclasses_wordlists_generated.pas`, which is in Git.\r\n  - `isxfunc.xml` documents Pascal Script functions.\r\n  - `isxclasses.pas` documents Pascal Script classes, with `isxclasses.header`, `isxclasses.header2`, and `isxclasses.footer` as helpers. When a `uPSC_*.pas` registration changes for Inno Setup (`PS_MINIVCL` is defined, `FPC` and `CLX` are not), update `isxclasses.pas` to match and regenerate as above.\r\n  - `isx.xml` contains all other Pascal Script documentation.\r\n  - `ispp.xml` documents the ISPP preprocessor.\r\n  - `isetup.xml` contains the remaining documentation.\r\n  - `isetup.dtd`, `ispp.dtd`, `isxfunc.dtd`, `isxfunc.xsl`, and `ispp.xsl` are schema and XSL files consumed by `ISHelpGen`.\r\n  - Don't edit files generated by `ISHelpGen`: `ispp_generated.xml`, `isxclasses_generated.xml`, `isxclasses_wordlists_generated.pas`, `isxfunc_generated.xml`.\r\n- Don't use em dashes or en dashes; use periods or commas instead.\r\n- Don't use \"e.g.\"; use \"for example\" or \"such as\" instead.\r\n\r\n## Precompiled Binaries\r\n- `Files/` contains precompiled C/C++ DLLs (7-Zip, zlib, bzip2, LZMA, Scintilla) and `.issig` signature files.\r\n- Rebuild with `build-precomp.bat` (requires separate repository checkouts); refresh signatures separately with ISSigTool afterward.\r\n\r\n## Testing & Verification\r\n- After editing any `.pas`, `.dpr`, `.dproj`, or `.inc` file: run `compile.bat x64` and verify 0 errors.\r\n- Unit tests live in `*.Test.pas` files. No testing framework is used; tests raise an exception on failure.\r\n- To run tests, run `test.bat [x86|x64]` and verify 0 exit code. Omit the architecture to test both. This also compiles `ISTestTool` first.\r\n\r\n## Other information\r\n- When creating a new file: immediately `git add` it, but only if still untracked.\r\n- Otherwise treat Git as read-only.\r\n- A task is not complete until the relevant compilation succeeds with 0 errors.\r\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","rawUrl":"https://raw.githubusercontent.com/jrsoftware/issrc/HEAD/AGENTS.md","title":"AI Agent Protocol & Instructions","category":"root-instruction","format":"markdown","content":"# Inno Setup AI Agent Guide\r\n\r\n## Introduction\r\n- Source code of Inno Setup, an open-source installation builder for Windows applications by Jordan Russell and Martijn Laan, first released in 1997.\r\n- Comes in 64-bit and 32-bit editions; both can build 32-bit or 64-bit installers.\r\n- Copyrighted software; see `LICENSE.TXT` for distribution restrictions. Commercial users are requested to purchase a commercial license.\r\n\r\n## Project Architecture\r\nDelphi projects under `Projects/`:\r\n\r\n| Project | Output | Role |\r\n|---------|--------|------|\r\n| `ISIDE` | EXE | GUI compiler front-end (IDE), thin shell around ISCmplr.dll |\r\n| `ISCC` | EXE | CLI compiler front-end, thin shell around ISCmplr.dll |\r\n| `ISCmplr` | DLL | Actual compiler engine; entry point: `Compiler.SetupCompiler.pas` |\r\n| `ISPP` | DLL | Preprocessor |\r\n| `Setup` | EXE | Installer runtime; entry point: `Setup.MainFunc.pas` |\r\n| `SetupCustomStyle` | EXE | Installer runtime with VCL Styles support |\r\n| `SetupLdr` | EXE | Self-extracting loader that decompresses and launches Setup |\r\n| `ISSigTool` | EXE | Signs and verifies files using custom signatures |\r\n| `ISTestTool` | EXE | Internal utility that runs unit tests; invoked by build.bat and build-ce.bat |\r\n\r\nUnder `ISHelp/ISHelpGen/`:\r\n\r\n| Project | Output | Role |\r\n|---------|--------|------|\r\n| `ISHelpGen` | EXE | Generates XML files for help and Pascal Script autocomplete |\r\n\r\n## Core System\r\n- Delphi codebase targeting Windows 7 and later via the Windows API. All projects build for x64 and x86.\r\n- Primary project-specific source lives in `Projects/Src/` using namespace prefixes: `Compiler.*`, `Compression.*`, `IDE.*`, `ISPP.*`, `Setup.*`, `SetupLdrAndSetup.*`, `Shared.*`. Projects also compile shared units from `Components/`, and `ISIDE` additionally consumes the generated `ISHelp\\isxclasses_wordlists_generated.pas`. New project-specific source files must follow the namespace convention and be placed in `Projects/Src/`.\r\n- `Shared.Struct.pas` defines cross-project record layouts, and `Shared.CompilerInt.Struct.pas` defines the compiler/front-end interface layout. Changing either requires reviewing every consumer and recompiling the relevant projects.\r\n- Other shared units live under `Components` and `Projects\\Src\\Shared.*.pas`.\r\n- `SetupLdrAndSetup.*` units are shared by SetupLdr, Setup, and SetupCustomStyle; changes must account for all three.\r\n- `SetupCustomStyle` uses the same sources as `Setup` plus `Vcl.Themes`/`Vcl.Styles` and `Setup.TaskDialogForm`.\r\n- Many UI units in `Projects/Src/` are paired with checked-in `.dfm` files; form changes often require coordinated `.pas` and `.dfm` edits.\r\n- Compression engines pull native code from `Projects\\Src\\Compression.*`.\r\n- Pascal Script integration sits in `Compiler.Script*.pas` and `Setup.Script*.pas`; changes must be mirrored on both compiler and setup sides.\r\n- Setup path redirection: `ApplyPathRedirRules` rewrites System32/SysWOW64/Sysnative and converts to super paths. Unless documented otherwise, functions should receive current-process-bit paths. Use `ApplyRedirToRunEntryPaths` for run entries and `ApplyRedirForRegistrationOperation` for registration/shared-count operations. Old-style FS redirection disabling is still used when running 64-bit system executables from a 32-bit Setup process.\r\n- Extended-length (super) paths (`\\\\?\\`) are used by Setup to avoid MAX_PATH issues and are produced by `ApplyPathRedirRules` unless `rfNormalPath` is used. Only pass super paths to APIs known to accept them; when in doubt (especially for shell APIs or user-facing strings), convert back to a normal path.\r\n\r\n## Build\r\n- Run `compile.bat x64` or `compile.bat x86`. Both output release binaries to `Files`.\r\n- Append a project name, such as `compile.bat x64 ISCC`, to compile only that project.\r\n- Compiler path is configured in `compilesettings.bat`.\r\n- `build.bat` orchestrates full release builds.\r\n- In a fresh worktree, run `issig.bat embed` before the first compile. This updates the tracked files `Components\\TrustFunc.AllowedPublicKeys.inc` and `def02.ispublickey`. Leave them in place.\r\n- If a release build binary under `Files\\` reports \"Signature file is not valid\", run `issig.bat embed`, then rerun the relevant compile command, usually `compile.bat x64`, and retry the failed command.\r\n\r\n## Code Conventions\r\n- `**/*.iss`: see `.claude/rules/iss.md`.\r\n- `**/*.pas`, `**/*.dpr`, `**/*.inc`: see `.claude/rules/pascal.md`.\r\n- `**/*Test.pas`, `**/*Test.iss`: see `.claude/rules/test.md`.\r\n- `Files/Languages/*.isl`, `Files/Languages/Unofficial/*.isl`: see `.claude/rules/isl.md`.\r\n- `Components/UniPs/**`: see `.claude/rules/unips.md`.\r\n- `Projects/Src/Compression.LZMACompressor/islzma/**`, `Projects/Src/Compression.LZMADecompressor/Lzma2Decode/**`: see `.claude/rules/islzma.md`.\r\n- Indentation: see `.claude/rules/indentation.md`.\r\n\r\n## Documentation Conventions\r\n- `whatsnew.htm`, `ISHelp/isetup.xml`, `ISHelp/ispp.xml`, `ISHelp/isx.xml`, `ISHelp/isxfunc.xml`, `ISHelp/isxclasses.header*`, `ISHelp/isxclasses.footer`: see `.claude/rules/docs.general.md`.\r\n- `ISHelp/isetup.xml`, `ISHelp/isx.xml`, `ISHelp/isxfunc.xml`, `ISHelp/isxclasses.header*`, `ISHelp/isxclasses.footer`, `ISHelp/ispp.xml`: see `.claude/rules/docs.ishelp.md`.\r\n- `ISHelp/isetup.xml`: see `.claude/rules/docs.ishelp.isetup.md`.\r\n- `ISHelp/isxfunc.xml`: see `.claude/rules/docs.ishelp.isxfunc.md`.\r\n- `ISHelp/ispp.xml`: see `.claude/rules/docs.ishelp.ispp.md`.\r\n- `whatsnew.htm`: see `.claude/rules/docs.whatsnew.md`.\r\n\r\n## Docs\r\n- `whatsnew.htm` contains the Revision History.\r\n- Help content lives under `ISHelp`:\r\n  - When editing `ISHelp\\*`, regenerate CHM/Web help: run `compile.bat x64 ISHelpGen` then `ISHelp\\compile.bat` and verify 0 errors. Don't skip; this regenerates `isxclasses_wordlists_generated.pas`, which is in Git.\r\n  - `isxfunc.xml` documents Pascal Script functions.\r\n  - `isxclasses.pas` documents Pascal Script classes, with `isxclasses.header`, `isxclasses.header2`, and `isxclasses.footer` as helpers. When a `uPSC_*.pas` registration changes for Inno Setup (`PS_MINIVCL` is defined, `FPC` and `CLX` are not), update `isxclasses.pas` to match and regenerate as above.\r\n  - `isx.xml` contains all other Pascal Script documentation.\r\n  - `ispp.xml` documents the ISPP preprocessor.\r\n  - `isetup.xml` contains the remaining documentation.\r\n  - `isetup.dtd`, `ispp.dtd`, `isxfunc.dtd`, `isxfunc.xsl`, and `ispp.xsl` are schema and XSL files consumed by `ISHelpGen`.\r\n  - Don't edit files generated by `ISHelpGen`: `ispp_generated.xml`, `isxclasses_generated.xml`, `isxclasses_wordlists_generated.pas`, `isxfunc_generated.xml`.\r\n- Don't use em dashes or en dashes; use periods or commas instead.\r\n- Don't use \"e.g.\"; use \"for example\" or \"such as\" instead.\r\n\r\n## Precompiled Binaries\r\n- `Files/` contains precompiled C/C++ DLLs (7-Zip, zlib, bzip2, LZMA, Scintilla) and `.issig` signature files.\r\n- Rebuild with `build-precomp.bat` (requires separate repository checkouts); refresh signatures separately with ISSigTool afterward.\r\n\r\n## Testing & Verification\r\n- After editing any `.pas`, `.dpr`, `.dproj`, or `.inc` file: run `compile.bat x64` and verify 0 errors.\r\n- Unit tests live in `*.Test.pas` files. No testing framework is used; tests raise an exception on failure.\r\n- To run tests, run `test.bat [x86|x64]` and verify 0 exit code. Omit the architecture to test both. This also compiles `ISTestTool` first.\r\n\r\n## Other information\r\n- When creating a new file: immediately `git add` it, but only if still untracked.\r\n- Otherwise treat Git as read-only.\r\n- A task is not complete until the relevant compilation succeeds with 0 errors.\r\n","isInternal":false,"tokens":2019,"sizeBytes":7661},{"name":"docs.general.md","path":".claude/rules/docs.general.md","rawUrl":"https://raw.githubusercontent.com/jrsoftware/issrc/HEAD/.claude/rules/docs.general.md","title":"Rules Skill","category":"anthropic-skill","format":"markdown","content":"---\r\npaths: [\"whatsnew.htm\", \"ISHelp/isetup.xml\", \"ISHelp/ispp.xml\", \"ISHelp/isx.xml\", \"ISHelp/isxfunc.xml\", \"ISHelp/isxclasses.header*\", \"ISHelp/isxclasses.footer\"]\r\n---\r\n# General documentation conventions for Inno Setup\r\n\r\n## Voice and Tone\r\n\r\n- **Direct and technical.** State facts plainly. Do not hedge or pad with filler.\r\n- **Second person** (\"you\") when addressing the user who writes scripts or configures Setup.\r\n- **Impersonal** when describing system behavior: \"Setup will...\", \"the compiler will...\", \"an exception will be raised if...\".\r\n- **Not chatty.** No rhetorical questions, no \"Note that you might wonder...\". Just state the information.\r\n- **Contractions are used.** Write \"don't\", \"isn't\", \"can't\", \"won't\", \"doesn't\", \"aren't\", \"hasn't\", \"didn't\", \"wouldn't\", \"couldn't\", \"shouldn't\". These are natural and make the text less stiff for non-native readers.\r\n\r\n## Sentence Structure\r\n\r\n- Prefer **short, clear sentences**. One idea per sentence when possible.\r\n- Avoid deeply nested clauses. If a sentence grows complex, split it.\r\n- **Active voice** when possible: \"Setup creates the directory\" rather than \"the directory is created by Setup\". Passive voice is acceptable when the actor is irrelevant or when it reads more naturally: \"An exception will be raised if...\".\r\n- Parenthetical notes are common and acceptable: \"(which can include constants)\", \"(the default setting)\".\r\n\r\n## Vocabulary and Terminology\r\n\r\nUse the established Inno Setup terms consistently. Never substitute synonyms:\r\n\r\n| Correct term | Do not use |\r\n|---|---|\r\n| Setup, the Setup program, the installer | the installation program (note: \"installer\" is also standard for the compiled artifact, such as \"64-bit installers\") |\r\n| Uninstall, the uninstaller | the uninstall program |\r\n| the compiler | the build system, the compilation engine |\r\n| the end user | the customer, the consumer |\r\n| the user | the developer, the script author (when addressing the person writing .iss scripts) |\r\n| support function | helper function, utility function |\r\n| support class | helper class |\r\n| directive | setting, option (for [Setup] section items) |\r\n| parameter | field, property (for section entry items) |\r\n| flag | option, switch (for Flags parameter values) |\r\n| entry | line, row (for a line in a section) |\r\n| section | block, group (for [Setup], [Files], etc.) |\r\n| the Compiler IDE | the editor (\"the IDE\" is acceptable after \"the Compiler IDE\" has been established in the same context, in both ISHelp and whatsnew) |\r\n| Pascal Scripting | the scripting engine (for the feature/topic name; \"Pascal Script\" is acceptable when referring to the RemObjects Pascal Script engine itself) |\r\n| extended-length paths | long paths (use \"also known as super paths\" parenthetically on first mention within a topic; don't use \"super paths\" as a standalone term) |\r\n| menu item | menu option |\r\n| Start menu (but \"Start Menu\" in titles, such as the *Select Start Menu Folder* wizard page) | Start Menu |\r\n| checkbox | check box |\r\n| without a BOM | BOM-less, BOMless |\r\n| the help file | the help |\r\n\r\nAdditional vocabulary rules:\r\n- \"Setup or Uninstall\" or \"the Setup program and uninstaller\" when a feature applies to both. Not \"the installer or uninstaller\".\r\n- \"the user's system\" for the target environment. Not \"the target machine\". \"computer\" is acceptable for restarts (\"restart the computer\") and computer names (\"the name of the computer\").\r\n- \"specified\" is the standard word for parameters and directives: \"the specified file\", \"the specified parameter\". Not \"provided\".\r\n- \"given\" is the standard word for function argument descriptions: \"the given string\", \"the given file name\".\r\n- \"Returns True if...\" is the standard pattern for boolean function descriptions.\r\n- \"cannot\" as one word. Not \"can not\".\r\n- Use \"use\" not \"utilize\".\r\n- Use \"non-zero\" not \"non-zero value\".\r\n- Do not shorten established descriptive terms. Write \"support function\", not \"func\".\r\n- Repeat the same term for the same concept. Do not rotate between synonyms for variety.\r\n\r\n## Punctuation\r\n\r\n- **Oxford (serial) comma:** Use it. \"A, B, and C\", not \"A, B and C\".\r\n- **Periods** at the end of complete sentences, including list items that are complete sentences.\r\n- **No em dashes or en dashes.** Use periods, commas, or parentheses instead.\r\n- **No \"e.g.\"** Use \"for example\" or \"such as\".\r\n- **No \"i.e.\"** Use \"that is\" or rephrase.\r\n- **\"etc.\" is acceptable** but use sparingly.\r\n- **Colons** before examples and lists.\r\n\r\n## Formatting\r\n\r\n- Code identifiers should render as monospace: section names, directive names, parameter names, flag names, constant names, type names, function names, file names, directory names, path values, registry key and value type names, environment variable names, command-line switches, and values like `yes`/`no`/`True`/`False`. In prose, use `<tt>` for this. Inside already-monospace contexts, such as `<pre>`, `<precode>`, or ISPP `<line>` elements, no extra `<tt>` is needed.\r\n- When a code identifier is in a prose link's display text, still make it monospace with `<tt>`:\r\n  - For an internal `<link>`: outside the link if the identifier is the whole display text, inside otherwise.\r\n  - For an `<extlink>`: always inside, because external links get an icon added that must not appear inside the `<tt>` pill.\r\n- `<i>` for emphasis, wizard page names (such as *Select Destination Location*), UI element names, and font names.\r\n- `<b>` sparingly, for important warnings or the word \"NOTE:\".\r\n\r\n## Syntax Highlighting\r\n\r\nThe IDE styler (`Projects/Src/IDE.ScintStylerInnoSetup.pas`) is the source of truth for which token gets which\r\ncategory. Five non-obvious rules:\r\n\r\n- Use `<sec>`, `<evt>`, `<key>`, `<com>`, `<con>`, `<str>`, `<num>`, and `<ispp>` for syntax-highlighted script examples.\r\n- Use `<str>` and `<num>` only in Pascal Script and ISPP contexts. Section directive and parameter string\r\n  values stay plain, with only their inner constants using `<con>`. Number literals include ISPP array indices.\r\n- Use of `<con>` depends on context. Use it for a regular constant (`{app}`) inside a section directive or parameter\r\n  value, including inside a parameter value such as `ExpandConstant('<con>{app}</con>\\...')`,\r\n  but not inside a Pascal string literal, where the whole literal stays `<str>`. An ISPP inline constant\r\n  (`{#...}`) is the exception: it always uses `<ispp>` on the `{#...}` delimiters and directive name (the inner\r\n  expression keeps its own styling), even inside a string literal, because ISPP pre-styles it.\r\n- `<evt>` applies only to the fixed `BasicEventFunctions` set; functions named via event attributes are not bolded.\r\n- `[Messages]`/`[CustomMessages]`/`[LangOptions]`: only the message name is `<key>`; a language prefix is not.\r\n\r\n## Review Guidelines\r\n\r\nWhen reviewing documentation, check for:\r\n\r\n1. **Terminology consistency.** Are the correct Inno Setup terms used? (See the vocabulary table above.)\r\n2. **Factual accuracy.** Does the documentation match the actual code behavior?\r\n3. **Completeness.** Are all parameters, flags, return values, and error conditions documented?\r\n4. **Cross-references.** Are related topics linked?\r\n5. **Code formatting.** Are code identifiers in prose wrapped in `<tt>`? Are examples provided?\r\n6. **Style violations.** Check for: em/en dashes, \"e.g.\", \"i.e.\", synonym rotation, missing Oxford commas, \"can not\" instead of \"cannot\", \"utilize\" instead of \"use\".\r\n7. **Clarity for non-native speakers.** Avoid idioms, complex subordinate clauses, and uncommon vocabulary.\r\n8. **Do not nitpick** about subjective style matters in existing text that is not being changed. Only flag style issues in new or modified text.\r\n","frontmatter":{"paths":["whatsnew.htm","ISHelp/isetup.xml","ISHelp/ispp.xml","ISHelp/isx.xml","ISHelp/isxfunc.xml","ISHelp/isxclasses.header*","ISHelp/isxclasses.footer"]},"isInternal":false,"tokens":1854,"sizeBytes":7711},{"name":"docs.ishelp.isetup.md","path":".claude/rules/docs.ishelp.isetup.md","rawUrl":"https://raw.githubusercontent.com/jrsoftware/issrc/HEAD/.claude/rules/docs.ishelp.isetup.md","title":"Rules Skill","category":"anthropic-skill","format":"markdown","content":"---\npaths: [\"ISHelp/isetup.xml\"]\n---\n# isetup.xml documentation conventions\n\nThese are specific to `isetup.xml`, which documents the entry sections and [Setup] directives; the general ISHelp conventions in `docs.ishelp.md` apply too.\n\n## Section topic structure\n\nEach entry section topic (such as [Files], [Registry], [Run]) follows this structure:\n1. Opening paragraph: \"This optional section defines...\" or \"This section contains...\".\n2. Introductory notes about default behavior.\n3. Example section with `<precode>`.\n4. \"The following is a list of the supported parameters:\" introducing the parameter list.\n5. Parameters documented with `<paramlist>` / `<param>`.\n6. Links to Common Parameters and Components/Tasks Parameters at the bottom.\n\n## Directive-topic structure\n\nEach [Setup] directive topic uses `<setuptopic>`:\n1. `<setuptopic directive=\"DirectiveName\">`: topic wrapper.\n2. `<setupvalid>`: valid values (optional, omitted when free-form text).\n3. `<setupdefault>`: default value (optional).\n4. `<body>`: opening paragraph, followed by detail paragraphs, notes, examples, and optional \"See also\" links. Common opening patterns: \"This directive specifies...\", \"This tells the compiler...\", \"Controls whether...\", \"If set to [value]...\".\n\n## Parameter documentation\n\nEach parameter follows this pattern:\n1. Description paragraph: what it controls.\n2. Additional detail paragraphs as needed.\n3. Example with `<example><pre>`.\n4. For Flags parameters: \"This parameter is a set of extra options. Multiple options may be used by separating them by spaces. The following options are supported:\" followed by `<flaglist>`.\n\n## Conditional behavior\n\nUse the pattern: \"If [value] is specified, Setup will [action].\" Repeat for each value. Example:\n> If <tt>string</tt> is specified, Setup will create a string (<tt>REG_SZ</tt>) value.\n> If <tt>dword</tt> is specified, Setup will create a 32-bit integer (<tt>REG_DWORD</tt>) value.\n\n## Default values\n\nState defaults explicitly: \"Defaults to [value].\" or \"The default value is [value].\" or \"(the default setting)\".\n","frontmatter":{"paths":["ISHelp/isetup.xml"]},"isInternal":false,"tokens":475,"sizeBytes":2067},{"name":"docs.ishelp.ispp.md","path":".claude/rules/docs.ishelp.ispp.md","rawUrl":"https://raw.githubusercontent.com/jrsoftware/issrc/HEAD/.claude/rules/docs.ishelp.ispp.md","title":"Rules Skill","category":"anthropic-skill","format":"markdown","content":"---\r\npaths: [\"ISHelp/ispp.xml\"]\r\n---\r\n# ispp.xml documentation conventions\r\n\r\nThese are specific to `ispp.xml`; the general ISHelp conventions in `docs.ishelp.md` apply too.\r\n\r\n## Directive documentation\r\n\r\nPreprocessor directives use `<topic>` with `<syntax>`/`<define>`, `<description>`, and `<section>`.\r\n\r\n## Function documentation\r\n\r\nFunctions put the signature in `<section title=\"Prototype\">` (inside `<pre><line>`) and related links in `<section title=\"See also\">`.\r\n\r\nBoolean-like functions are documented as \"Returns non-zero if [condition].\" rather than \"Returns True if [condition], False otherwise.\"\r\n\r\n## Differences from the general conventions\r\n\r\n- **Cross-reference links:** use `<link href=\"topicname\">Display Text</link>`. `ispp.dtd` has no `anchor` attribute; the `href` carries the target.\r\n- **Examples:** examples sit in a bare `<pre>` inside `<section title=\"Examples\">`.\r\n- **Function shorthand:** `<isxfunc>` not available; link ISPP functions with `<link href=\"...\">`.\r\n- **Indentation:** `ispp.xml` is tab-indented, unlike the other ISHelp sources. Keep using tabs; the rules in `indentation.md` do not apply.\r\n","frontmatter":{"paths":["ISHelp/ispp.xml"]},"isInternal":false,"tokens":269,"sizeBytes":1139},{"name":"docs.ishelp.isxfunc.md","path":".claude/rules/docs.ishelp.isxfunc.md","rawUrl":"https://raw.githubusercontent.com/jrsoftware/issrc/HEAD/.claude/rules/docs.ishelp.isxfunc.md","title":"Rules Skill","category":"anthropic-skill","format":"markdown","content":"---\r\npaths: [\"ISHelp/isxfunc.xml\"]\r\n---\r\n# isxfunc.xml documentation conventions\r\n\r\nThese are specific to `isxfunc.xml`; the general ISHelp conventions in `docs.ishelp.md` apply too.\r\n\r\n`<link topic=\"...\">` (with optional `anchor`), `<extlink>`, `<sd>`, `<sn>`, and `<isxfunc>` all work as in the general conventions.\r\n\r\n## Function documentation\r\n\r\nEach function follows this pattern:\r\n- `<name>`: Function name.\r\n- `<prototype>`: Full function signature.\r\n- `<description>`: One or more `<p>` elements. First sentence is the key description.\r\n  - For functions returning a value: \"Returns [description of return value].\"\r\n  - For procedures: \"Does [action].\" or imperative form.\r\n  - For boolean functions: \"Returns True if [condition], False otherwise.\"\r\n- `<remarks>` (optional): Additional notes, edge cases, caveats.\r\n- `<seealso>` (optional): Links to related functions.\r\n- `<example>` (optional): Code example.\r\n\r\nStandard description patterns:\r\n- \"Returns the [noun] of [context].\"\r\n- \"Returns True if [condition].\"\r\n- \"Returns a [type] containing [description].\"\r\n- \"Gets/Sets the value of [thing].\"\r\n- \"Creates/Deletes/Removes [thing].\"\r\n- \"An exception will be raised if [error condition].\"\r\n- \"If [condition], [function name] returns [value].\"\r\n\r\n## Differences from the general conventions\r\n\r\n- **Examples:** use `<example>`, which may contain `<pre>`. `isxfunc.dtd` has no `<precode>`.\r\n","frontmatter":{"paths":["ISHelp/isxfunc.xml"]},"isInternal":false,"tokens":345,"sizeBytes":1402},{"name":"docs.ishelp.md","path":".claude/rules/docs.ishelp.md","rawUrl":"https://raw.githubusercontent.com/jrsoftware/issrc/HEAD/.claude/rules/docs.ishelp.md","title":"Rules Skill","category":"anthropic-skill","format":"markdown","content":"---\r\npaths: [\"ISHelp/isetup.xml\", \"ISHelp/isx.xml\", \"ISHelp/isxfunc.xml\", \"ISHelp/isxclasses.header*\", \"ISHelp/isxclasses.footer\", \"ISHelp/ispp.xml\"]\r\n---\r\n# ISHelp documentation conventions\r\n\r\nThese are the general documentation conventions shared by all ISHelp sources. `isetup.xml`, `isx.xml`, and the `isxclasses.*` helpers use `isetup.dtd`; `isxfunc.xml` (`isxfunc.dtd`) and `ispp.xml` (`ispp.dtd`) use their own DTD. They all follow the conventions below, except where a file's own rule file notes a difference or adds file-specific structure: see `docs.ishelp.isetup.md`, `docs.ishelp.isxfunc.md`, and `docs.ishelp.ispp.md`. Prose conventions for all of these files live in `docs.general.md`, not here.\r\n\r\n## Additional formatting\r\n\r\n- `<precode>` for syntax-highlighted section-level and topic-level script examples (such as showing a full [Run] section).\r\n- `<example><pre>` for syntax-highlighted parameter and function examples, which can also be multi-line.\r\n\r\n## Cross-references\r\n\r\n- Use `<link topic=\"topicname\">Display Text</link>`.\r\n- Always link to related topics when mentioning directives, sections, or functions. Do not leave them as plain text if a help topic exists.\r\n- Use the `<sd>Directive</sd>`, `<sn>[Section]</sn>`, and `<isxfunc>FunctionName</isxfunc>` shorthands instead of a `<link>` to a [Setup] directive, section, or support function.\r\n- To specific anchors: `<link topic=\"topicname\" anchor=\"anchorname\">Display Text</link>`.\r\n- External links: `<extlink href=\"url\">Display Text</extlink>`.\r\n","frontmatter":{"paths":["ISHelp/isetup.xml","ISHelp/isx.xml","ISHelp/isxfunc.xml","ISHelp/isxclasses.header*","ISHelp/isxclasses.footer","ISHelp/ispp.xml"]},"isInternal":false,"tokens":392,"sizeBytes":1527},{"name":"docs.whatsnew.md","path":".claude/rules/docs.whatsnew.md","rawUrl":"https://raw.githubusercontent.com/jrsoftware/issrc/HEAD/.claude/rules/docs.whatsnew.md","title":"Rules Skill","category":"anthropic-skill","format":"markdown","content":"---\r\npaths: [\"whatsnew.htm\"]\r\n---\r\n# Inno Setup Revision History documentation conventions\r\n\r\n## Additional formatting\r\n\r\n- `<i>Fix:</i>` prefix for bug fix entries.\r\n- `<pre><code class=\"innosetup\">` for syntax-highlighted script examples.\r\n\r\n## Example script references\r\n\r\n- \"See updated <tt><a href=\"...\">ScriptName.iss</a></tt> example script.\"\r\n- \"See updated <tt><a href=\"...\">ScriptName.iss</a></tt> example script for an example.\"\r\n- \"See new <tt><a href=\"...\">ScriptName.iss</a></tt> example script.\"\r\n\r\n## Entry structure\r\n\r\nChangelog entries appear as `<li>` items in `<ul>` lists.\r\n\r\n**New features:**\r\n- \"Added new [type] <tt>Name</tt>.\" or \"Added new [type] <tt>Name</tt> to [context].\"\r\n- \"Added new support functions <tt>Name1</tt>, <tt>Name2</tt>, and <tt>Name3</tt>.\"\r\n- \"Added new support classes <tt>Name1</tt>, <tt>Name2</tt>, and <tt>Name3</tt>.\"\r\n- \"Added new properties <tt>Name1</tt>, <tt>Name2</tt>, and <tt>Name3</tt> to class <tt>ClassName</tt>.\"\r\n- \"Added support for [feature].\"\r\n\r\n**Changes:**\r\n- \"Directive <tt>Name</tt> now defaults to <tt>value</tt>.\"\r\n- \"<tt>Feature</tt> is now [new behavior].\"\r\n- \"Enhanced/Improved/Updated [thing] [description of change].\"\r\n- \"Renamed <tt>OldName</tt> to <tt>NewName</tt>. The old name still works.\"\r\n\r\n**Bug fixes:**\r\n- Always prefixed: \"<i>Fix:</i> Description of what was wrong and what is now correct.\"\r\n- For documentation-only fixes: \"<i>Documentation fix:</i> Description.\"\r\n- Describe the symptom, not just the fix. Include \"broken since X.Y.Z\" or \"broken in X.Y.Z\" when known.\r\n\r\n**Removals:**\r\n- \"Removed support for [feature].\" or \"Support for [feature] has been dropped.\"\r\n- \"Removed [thing]. Use [replacement] instead.\"\r\n\r\n**Deprecations:**\r\n- \"This function is deprecated.\" followed by what to use instead.\r\n- \"The compiler still accepts <tt>OldName</tt> as an alias for <tt>NewName</tt>, but will emit a deprecation warning when used.\"\r\n\r\n## Subcategories\r\n\r\nGroup related changes under subcategory headers using nested lists:\r\n```html\r\n<li>Pascal Scripting:\r\n<ul>\r\n  <li>Added new support function <tt>Foo</tt>.</li>\r\n  <li><i>Fix:</i> <tt>Bar</tt> now works correctly.</li>\r\n</ul>\r\n</li>\r\n```\r\n\r\nStandard subcategory names: \"Compiler IDE:\", \"Pascal Scripting:\", \"ISPP:\", \"Setup:\", \"Compiler:\", \"Command-Line Compiler (ISCC):\", \"Examples:\", \"Security improvement:\", \"Updated documentation:\", and product-specific names such as \"Inno Setup Signature Tool:\". Other one-off names are acceptable when a group of entries warrants its own heading.\r\n\r\n## Catch-all entries\r\n\r\nEnd a version's changes with one of:\r\n- \"Other minor improvements.\"\r\n- \"Minor tweaks.\"\r\n- \"Minor tweaks and fixes.\"\r\n- \"Other minor improvements and fixes.\"\r\n- \"Documentation improvements.\"\r\n\r\n## Security section intro\r\n\r\nWhen there is a security improvements section:\r\n> Updating is recommended, even if you don't plan to use the other enhancements right away. We continually add extra checks to make your installers safer and more reliable. In this version:\r\n","frontmatter":{"paths":["whatsnew.htm"]},"isInternal":false,"tokens":792,"sizeBytes":3019},{"name":"indentation.md","path":".claude/rules/indentation.md","rawUrl":"https://raw.githubusercontent.com/jrsoftware/issrc/HEAD/.claude/rules/indentation.md","title":"Rules Skill","category":"anthropic-skill","format":"markdown","content":"---\r\npaths: [\"**/*.pas\", \"**/*.dpr\", \"**/*.dpk\", \"**/*.inc\", \"**/*.iss\", \"**/*.htm\", \"**/*.bat\", \"**/*.c\", \"**/*.h\", \"**/*.dfm\", \"**/*.xml\", \"**/*.dtd\", \"**/*.xsl\", \"**/*.md\", \"**/*.yml\"]\r\n---\r\n# Indentation conventions for all text files\r\n- Use spaces for indentation, not tabs.\r\n- Unless the format requires otherwise (for example, `.md` lists), use two spaces per indentation level.\r\n","frontmatter":{"paths":["**/*.pas","**/*.dpr","**/*.dpk","**/*.inc","**/*.iss","**/*.htm","**/*.bat","**/*.c","**/*.h","**/*.dfm","**/*.xml","**/*.dtd","**/*.xsl","**/*.md","**/*.yml"]},"isInternal":false,"tokens":112,"sizeBytes":387},{"name":"isl.md","path":".claude/rules/isl.md","rawUrl":"https://raw.githubusercontent.com/jrsoftware/issrc/HEAD/.claude/rules/isl.md","title":"Rules Skill","category":"anthropic-skill","format":"markdown","content":"---\r\npaths: [\"Files/Languages/*.isl\", \"Files/Languages/Unofficial/*.isl\"]\r\n---\r\n# Conventions for Inno Setup translation files\r\n\r\nThese files translate `Files/Default.isl` into another language. `Default.isl` is the English baseline and the source of truth for the message set; it changes between Inno Setup versions, so always work from the most recent `Default.isl`, read it fresh, and treat its `[Messages]` and `[CustomMessages]` IDs as authoritative. A translation must stay faithful to its English counterpart: the English is the fixed reference and the ceiling, not something to clarify, complete, or improve.\r\n\r\n## Quality rules\r\n\r\n### File format and structure\r\n- **Encoding.** UTF-8 without a BOM.\r\n- **Newlines.** Windows CRLF throughout.\r\n- **Extension.** `.isl`. The `.islu` extension is obsolete.\r\n- **Compiles cleanly.** The file must compile with no errors and no warnings.\r\n\r\n### Comment header (top-of-file comments)\r\n- The first line is the version line, usually `; *** Inno Setup version X+ ... messages ***`. Keep it consistent with the `Default.isl` header version. It must never be higher than the `Default.isl` version.\r\n- The top of the file must also carry, as comments, the language's English name and the maintainer's name and e-mail address.\r\n\r\n### `[LangOptions]` settings\r\n- **LanguageName.** The language's native name (the name as written in the language itself), not its English name. For example Dutch is `Nederlands`, not `Dutch`. It is shown in the *Select Language* dialog. The obsolete `<HHHH>` escape syntax still works but is no longer needed; write the literal characters directly.\r\n- **LanguageID.** A valid hexadecimal language identifier beginning with `$`, matching the language and its region (for example `$0413` for Dutch (Netherlands), `$0813` for Belgian Dutch). It must not be left at `$0409`, which is the English ID of `Default.isl`. Verify against Microsoft's language-identifier list (https://learn.microsoft.com/en-us/windows/win32/intl/language-identifier-constants-and-strings). If no identifier exists for the language, set it to `0`. Together with `LanguageCodePage` it is used to auto-detect the most appropriate default language, so set it correctly.\r\n- **LanguageCodePage.** The Windows ANSI code page the compiler uses to convert any non-Unicode text in the language's files to Unicode (for example 1252 Western European, 1250 Central European, 1251 Cyrillic, 1253 Greek, 1254 Turkish, 1255 Hebrew, 1256 Arabic, 1257 Baltic, 1258 Vietnamese, 874 Thai, 932 Japanese, 936 Chinese Simplified, 949 Korean, 950 Chinese Traditional). Set it to `0` only when no code page exists for the language (a Unicode-only script such as Hindi, Tamil, Bengali, Armenian, Georgian) or the language uses only ASCII characters. It still matters even though the `.isl` is UTF-8, because it converts non-Unicode files such as a README supplied by the script author. (Text in the `.iss` file itself, such as a `[CustomMessages]` entry, is never converted and must already be Unicode.)\r\n- **RightToLeft.** `RightToLeft=yes` must be set for a right-to-left script (Arabic, Hebrew, Persian (Farsi), Urdu, Uyghur) and must not be set (or `RightToLeft=no`) for a left-to-right language.\r\n- **Fonts** (`DialogFontName`, `DialogFontSize`, `WelcomeFontName`, and so on). `Default.isl` keeps them all commented out. Uncomment only the entries the language genuinely needs to differ; an entry equal to the default stays commented out, so it inherits future default changes. Drop obsolete entries no longer in `Default.isl` (such as `CopyrightFontName`/`CopyrightFontSize`).\r\n\r\n### Sections and message set (compared to `Default.isl`)\r\n- **Translate the existing entries only.** Provide every `[Messages]` and `[CustomMessages]` ID that `Default.isl` defines, translated. Do not add your own custom messages to `[CustomMessages]`, and do not invent new IDs.\r\n- **No missing IDs.** Every ID defined in `Default.isl` must be present.\r\n- **No obsolete IDs.** Do not keep IDs that no longer exist in `Default.isl`.\r\n- **Empty values.** A message that is empty in `Default.isl` must stay empty in the translation, except for the `TranslatorNote` message.\r\n\r\n### Per-message rules (each message compared to its English counterpart)\r\n- **Placeholder integrity.** The same set and count of `%1`..`%9` must be present (the order may differ to suit the target grammar, and an argument may legitimately be duplicated, such as `%1 ... %1 %2`). Keep `%n` line breaks and `%%` literal-percent escapes intact. Preserve the same bracketed runtime placeholders, currently `[name]`, `[name/ver]`, `[mb]`, and `[gb]`. Never drop, add, or malform a placeholder or format specifier.\r\n- **Placeholder grammar.** A placeholder is filled at runtime with a value the translator cannot see or inflect, and which is not always the expected token (a wizard-name `%1`, for example, can be a custom name). Phrase the surrounding text so it reads correctly for any value: keep the placeholder in a slot that needs no inflection of, or grammatical agreement with, the inserted value, and never assume the value's gender, number, or case. If the English drops the value into a slot your language would inflect or agree with, rebuild the clause rather than guessing one form.\r\n- **Accelerator keys.** Keep an `&` accelerator wherever the English has one, and do not add one where the English has none. Drop an accelerator only when it cannot be placed on any letter of the translated text; resolve a collision by moving it to another letter rather than dropping it. Within each accelerator scope every accelerator letter must be unique, compared case-insensitively.\r\n- **No added periods.** Do not add a period to the end of a message that did not have one already. Exception: for languages with their own period character, such as Japanese and Chinese, it was added to the end of messages as needed. Keep a trailing period where the English has one. Exception: Thai and Lao remove trailing periods and question marks. If the English ends with `...`, keep the trailing ellipsis, written either as three dots `...` or as a single ellipsis character `…`. Spacing before the ellipsis follows the target language's typography (for example German puts a space before it, while English does not).\r\n- **Faithful meaning.** Stay as close to the original English as possible. Do not add to or change the meaning of a message to suit personal taste (for example do not append \"Try again one more time.\" to an error message that did not say that).\r\n\r\n### Translation quality (linguistic)\r\n- No spelling or grammar errors.\r\n- No untranslated messages that should have been translated. Some values are legitimately identical to English (`Setup`, `OK`, brand names, placeholder-only messages); only genuine omissions are wrong.\r\n- Consistent terminology: the same concept uses the same term across every message, with consistent button-label style and capitalization.\r\n- Use the language's native standard terminology, taking installer terms from the matching official Setup translation and everything else from Microsoft Terminology plus the language's Style Guide (for example the standard local words for Setup, folder, uninstall, administrator).\r\n- Consistent, language-appropriate tone, formality, casing, punctuation, and quote style (for example German capitalizes nouns and addresses the user formally; Japanese uses full-width punctuation where the platform does).\r\n- Translate naturally. As loose guidance stay near the English length (roughly within about 150 percent), but naturalness wins.\r\n\r\n## Faithfulness check before changing a message\r\n\r\nBefore changing a translated message because it looks wrong, confirm all of these; if any fails, leave it alone:\r\n1. Quote the exact English string. If you can't, you haven't compared against it.\r\n2. The current translation differs from what the English *means*, not from a clearer or more explicit version you imagined. If the English is itself ambiguous, general, or underspecified, an equally ambiguous translation is correct, not a problem.\r\n3. Your change preserves the English meaning. It must not add precision, disambiguation, or detail the English does not have.\r\n4. It is substantive. Awkward-but-acceptable phrasing, debatable terminology, and pure style preferences are nitpicks; leave them.\r\n5. Back-translate both the current text and your replacement into English. Change it only if the current text back-translates to a different meaning than the English *and* your replacement back-translates to the same meaning. If the replacement back-translates to something the English does not say, it adds meaning; drop it.\r\n","frontmatter":{"paths":["Files/Languages/*.isl","Files/Languages/Unofficial/*.isl"]},"isInternal":false,"tokens":1925,"sizeBytes":8673},{"name":"islzma.md","path":".claude/rules/islzma.md","rawUrl":"https://raw.githubusercontent.com/jrsoftware/issrc/HEAD/.claude/rules/islzma.md","title":"Rules Skill","category":"anthropic-skill","format":"markdown","content":"---\r\npaths: [\"Projects/Src/Compression.LZMACompressor/islzma/**\", \"Projects/Src/Compression.LZMADecompressor/Lzma2Decode/**\"]\r\n---\r\n# Instructions for the native LZMA C code (islzma and Lzma2Decode)\r\n\r\n## Indentation\r\n\r\nThese files keep their existing indentation style; the rules in `indentation.md` do not apply:\r\n- `islzma.c`, `islzma.h`, `islzma_dll.c`, `islzma_exe.c`, `ISLzmaDec.c`, and `test/test.bat` are tab-indented.\r\n- `test/roundtrip.c` is four-space indented.\r\n\r\nDo not reformat these files. When editing, match the surrounding indentation of the file you are in.\r\n","frontmatter":{"paths":["Projects/Src/Compression.LZMACompressor/islzma/**","Projects/Src/Compression.LZMADecompressor/Lzma2Decode/**"]},"isInternal":false,"tokens":166,"sizeBytes":578},{"name":"iss.md","path":".claude/rules/iss.md","rawUrl":"https://raw.githubusercontent.com/jrsoftware/issrc/HEAD/.claude/rules/iss.md","title":"Rules Skill","category":"anthropic-skill","format":"markdown","content":"---\r\npaths: [\"**/*.iss\"]\r\n---\r\n# Coding conventions for Inno Setup script files\r\nInno Setup `.iss` scripts use the `[Code]` section for Pascal Script code. This is RemObjects Pascal Script (ROPS), not modern Delphi. The following rules apply to code in `[Code]` sections.\r\n## Language differences compared to Delphi\r\nMost of these are hard constraints of the ROPS compiler. Violating them causes compile errors.\r\n- No inline `var` or inline `const`. All local variables must be declared in a `var` block before `begin`.\r\n- No local `const` or `type` declarations. Only `var` and `label` blocks are allowed before `begin`.\r\n- No `Exit(Value)` syntax. Assign to `Result` first, then call `Exit` separately.\r\n- No typed constants (`const X: Integer = 1`). Only untyped constants (`const X = 1`).\r\n- No default parameter values.\r\n- No function or procedure overloading.\r\n- No `raise` keyword. Use `RaiseException(Msg)` or `RaiseLastException` instead.\r\n- No `on E: ExceptionType do` in `except` blocks. Use `GetExceptionMessage` to inspect the current exception.\r\n- No script-defined classes. Classes can be used, but only those defined by Inno Setup.\r\n- No variant records.\r\n- `const` parameters are passed by value (copied), and not by reference as in modern Delphi.\r\n- As in Delphi, assigning a dynamic array, or passing it as a value or `const` parameter, shares its elements. A change to an element through one variable is visible through the other. `SetArrayLength` and `SetLength` copy a shared array only when the length changes. Delphi's `SetLength` always copies it. `Copy` doesn't support arrays. To get an array that isn't shared, change its length and change it back, or copy the elements to a new array.\r\n- The `/` operator always returns `Extended`, even when both operands are integers. Use `div` for integer division.\r\n- `Break` and `Continue` are not reserved words. They are ordinary identifiers recognized specially inside loop bodies. A local declaration named `Break` or `Continue` will shadow the loop-control behavior.\r\n- `Low`, `High`, and `SizeOf` must be used with a variable, not a type.\r\n## Conventions (same spirit as the Pascal rules, adapted for ROPS)\r\n- Pre-declare all local variables in the `var` block before `begin`.\r\n- Do not use `with` statements.\r\n- `if` and `begin` should be on the same line.\r\n- `else` and `begin` should be on the same line.\r\n- Do not use `begin..end` for single one-line statement blocks, but always use it when the block spans multiple lines. This includes when the block's single statement spans multiple lines (such as a multi-line `for`), and when a comment on its own line accompanies the statement (a trailing comment on the statement's line does not count).\r\n  Count lines per indentation level: a child statement never adds to its parent's count, so a chain of one-line statements takes no `begin..end` at any level.\r\n  A statement wrapped over continuation lines still counts as one line. But a statement that is genuinely multi-line at its own level (a `begin..end` block, or a control statement with a body, of its own) makes each level above it multi-line too.\r\n- Do not use `Longint` or `LongWord`; use `Integer` or `Cardinal` instead.\r\n- Mark read-only parameters as `const`.\r\n- Do not shorten descriptive names. Write `Expression`, not `Expr`; `MultiFileHandler`, not `MFH`. Conventional short names (`I`, `J`, `S`, `Res`) and established identifiers (`HiWord`) are fine.\r\n## Code editing guidelines\r\n- Do not modify existing comments unless the code they describe is also being changed.\r\n- Keep new comments short and match the style of existing comments in the file.\r\n","frontmatter":{"paths":["**/*.iss"]},"isInternal":false,"tokens":860,"sizeBytes":3642},{"name":"pascal.md","path":".claude/rules/pascal.md","rawUrl":"https://raw.githubusercontent.com/jrsoftware/issrc/HEAD/.claude/rules/pascal.md","title":"Rules Skill","category":"anthropic-skill","format":"markdown","content":"---\r\npaths: [\"**/*.pas\", \"**/*.dpr\", \"**/*.inc\"]\r\n---\r\n# Coding conventions for Pascal source files\r\n- Always use inline variables instead of pre-declaring them at the start of the function.\r\n  Exception: Delphi 10.4 does not support anonymous array types in inline variable or constant declarations, so pre-declare them.\r\n- Prefer inline constants over inline variables, even for run-time values and not just for compile-time constants.\r\n  Exception: inline constants cannot be passed as `var` parameters, so use an inline variable in that case.\r\n  Inline constants which are an object can still have their properties modified.\r\n  Inline constants use `=` as the assignment operator instead of `:=`. Examples:\r\n  `const MaxCount = MinCount * 2;`\r\n  `const ExpandedFilename = PathExpand(Filenames[I]);`\r\n- Prefer factoring shared code into a routine, or binding the expression to an inline const.\r\n- A routine whose callers all sit inside one routine belongs nested in it, not as a method or a unit-level routine. Keep such helpers siblings at a single level: never nest a helper inside another helper. No exceptions, except a routine assigned to an event stays a method.\r\n- Do not use `with` statements.\r\n- `if` and `begin` should be on the same line.\r\n- `else` and `begin` should be on the same line.\r\n- A `Result` assignment followed by an `Exit` statement should be combined into a single statement. For example: `Exit(ResultValue);`\r\n- Do not use `begin..end` for single one-line statement blocks, but always use it when the block spans multiple lines. This includes when the block's single statement spans multiple lines (such as a multi-line `for`), and when a comment on its own line accompanies the statement (a trailing comment on the statement's line does not count).\r\n  Count lines per indentation level: a child statement never adds to its parent's count, so a chain of one-line statements takes no `begin..end` at any level:\r\n  `for var X in Y do`\r\n  `  if Z(X) then`\r\n  `    Exit(True);`\r\n  A statement wrapped over continuation lines still counts as one line. But a statement that is genuinely multi-line at its own level (a `begin..end` block, or a control statement with a body, of its own) makes each level above it multi-line too.\r\n- Do not use `Longint` or `LongWord`, use `Integer` or `Cardinal` instead.\r\n- Mark read-only parameters as `const`.\r\n- Use Windows units first, then RTL/VCL units, then Components units, then Shared units, then project specific units.\r\n- Class methods should be static when possible.\r\n- Do not shorten descriptive names. Write `Expression`, not `Expr`; `MultiFileHandler`, not `MFH`. Conventional short names (`I`, `J`, `S`, `Res`) and established identifiers (`HiWord`) are fine.\r\n- Comments should be short and match the style of existing comments in the file. Prefer using `{` and `}`, and do not end one-sentence comments with a period.\r\n# Code editing guidelines\r\n- Do not modify existing comments unless the code they describe is also being changed.\r\n- When modifying code that calls Windows APIs, read the actual documentation before writing code. Do not assume parameter semantics based on similar APIs.\r\n- Update Inno Setup copyright header of any file you edit, if the current year is not already included.\r\n- Add tests for new code to the unit's `*.Test.pas` if it exists; otherwise consider creating one if the code is complex enough to warrant testing.\r\n  ISPP and ROPS code is tested by `Script.ISPP.Test.iss` and `Script.ROPS.Test.iss`, not a `*.Test.pas` unit.\r\n# Code review guidelines\r\n- All errors must be checked. Installers should be reliable above all.\r\n- Be alert for `out` parameters: an `out` parameter, like a `var` parameter, is passed by reference. However, with an `out` parameter, the initial value of the referenced variable for managed types, such as strings or arrays, is discarded by the caller before it is passed to the routine. Meanwhile, the initial value for unmanaged types, such as integers or pointers, is ignored. Therefore, for unmanaged types, it is not guaranteed that the initial value of the referenced variable will be overwritten in the routine to which it is passed.\r\n- Be alert for functions not assigning a value to Result: if a function exits without assigning a value to Result or the function name, then the function's return value is undefined, even for managed types.\r\n- Be alert for dynamic-array aliasing: assigning one dynamic array (e.g. `TBytes`) to another makes both reference the same buffer. Unlike strings and static arrays, copy-on-write is not employed, so writes through one alias (including `FillChar`) are visible through the other. Use `Copy(Source)` when an independent buffer is needed.\r\n- Code must be compatible with Delphi 10.4 and later.\r\n- Code must be compatible with 32-bit and 64-bit builds.\r\n- Code must be compatible with Windows 7 and later.\r\n- Do not suggest applying coding conventions to unchanged code.\r\n- Do not suggest changing an inline constant to an inline variable.\r\n- Do not nitpick, especially not about readability or subjective matters. This includes:\r\n  - Comment style or presence of comments.","frontmatter":{"paths":["**/*.pas","**/*.dpr","**/*.inc"]},"isInternal":false,"tokens":1143,"sizeBytes":5148},{"name":"test.md","path":".claude/rules/test.md","rawUrl":"https://raw.githubusercontent.com/jrsoftware/issrc/HEAD/.claude/rules/test.md","title":"Rules Skill","category":"anthropic-skill","format":"markdown","content":"---\r\npaths: [\"**/*Test.pas\", \"**/*Test.iss\"]\r\n---\r\n# Instructions for adding tests\r\n\r\n## When a correct test fails: allow investigation instead of pure tweaking\r\n\r\nIf a test that looks correct fails at compile time or at runtime, **do not silently adjust it until it passes**. A test that matches spec behavior but fails is evidence of a bug, not a bad test. The right response is:\r\n\r\n1. **Keep the original test** in the test source file, commented out, with a short explanation of the bug it exposed (e.g. `{ bug: 'for I: Byte := 0 to 255' infinite-loops because the loop variable wraps from 255 to 0 }`).\r\n2. **Write an alternate working test** that covers the same functionality without hitting the bug, if one exists. For example, use a narrower range or a different loop structure. This keeps test coverage moving forward.\r\n3. **Fixing the bug and re-enabling the original test is a separate task** - do not block the current phase on it.\r\n\r\nTweaking a test to avoid a real bug - changing types, adding casts, restructuring loops - hides regressions and defeats the purpose of the test suite.\r\n\r\n## Tests that check for a raised exception\r\n\r\nWhen a test verifies that something raises an exception, guard that part with `{$IFDEF ISTESTTOOLPROJ}` so it runs only under ISTestTool, not the DEBUG self-test. The self-test runs in the unit's `initialization` block inside the real application, where an intentionally raised exception would break in the debugger on every run. ISTestTool defines `ISTESTTOOLPROJ` and runs these checks normally.\r\n\r\nUse this pattern:\r\n\r\n```pascal\r\n{$IFDEF ISTESTTOOLPROJ}\r\n{ <what must raise and why> }\r\nvar Caught := False;\r\ntry\r\n  SomethingThatMustRaise;\r\nexcept\r\n  Caught := True;\r\nend;\r\nAssert(Caught);\r\n{$ENDIF}\r\n```\r\n\r\nKeep assertions that must always run, such as the contrasting success case, outside the `{$IFDEF ISTESTTOOLPROJ}` block.\r\n","frontmatter":{"paths":["**/*Test.pas","**/*Test.iss"]},"isInternal":false,"tokens":436,"sizeBytes":1880},{"name":"unips.md","path":".claude/rules/unips.md","rawUrl":"https://raw.githubusercontent.com/jrsoftware/issrc/HEAD/.claude/rules/unips.md","title":"Rules Skill","category":"anthropic-skill","format":"markdown","content":"---\r\npaths: [\"Components/UniPs/**\"]\r\n---\r\n# Instructions for UniPs (Pascal Script) components\r\n\r\n## Upstream origin\r\n\r\nThese files are copies of the RemObjects Pascal Script `stable` branch (see `rev.txt` for the commit hash).\r\n\r\nYou may still edit them, but:\r\n- Do not refactor the code style to match Inno Setup conventions.\r\n- Keep changes minimal and focused. Even though Inno Setup is a Delphi Windows codebase, the Pascal Script code is cross-platform: it compiles under multiple compilers (Delphi and FPC), operating systems (Windows and others), and CPU bitnesses (32- and 64-bit). A change must either be correct on every combination, or be guarded so it only affects the ones you have verified. Useful guards: `{$IFDEF DELPHI}` / `{$IFDEF FPC}` (compiler), `{$IFDEF MSWINDOWS}` (OS), and `{$IFDEF CPU64}` (bitness).\r\n  Inno Setup always builds with Delphi on Windows, in both 32- and 64-bit, so your change must be correct there. Improving support for the platforms Inno Setup does not use (FPC, non-Windows) is a bonus, but extend a change to them only when it is easy and correctness is easy to confirm; otherwise guard the change.\r\n- Don't edit or inspect `rev.txt` as it is an auto-generated bookkeeping file.\r\n\r\n## Registration: compile-time (uPSC_) vs runtime (uPSR_)\r\n\r\nPascal Script has two registration layers that must stay in sync:\r\n- **Compile-time** (`uPSC_*.pas`): declares what the script compiler accepts.\r\n- **Runtime** (`uPSR_*.pas`): provides actual method pointers and property helpers.\r\n\r\nWhen a compile-time registration is guarded by `{$IFDEF}` or `{$IFNDEF}`, the matching runtime registration must use the same guard. A mismatch causes scripts to compile successfully but crash at runtime.\r\n\r\nA compile-time `RegisterProperty` for a **published** property does not require a matching runtime `RegisterPropertyHelper`. RTTI handles published properties automatically. Only non-published properties need explicit runtime read/write helpers.\r\n\r\nUse the actual Pascal type name in `RegisterProperty`, not a shortcut like `'Byte'` for enums or sets. For example, use `'TComponentState'` for a set type and `'TFontPitch'` for an enum, not `'Byte'`.","frontmatter":{"paths":["Components/UniPs/**"]},"isInternal":false,"tokens":508,"sizeBytes":2177}],"systemPromptSnippet":"<yakaai_skills repo=\"jrsoftware/issrc\">\n<!-- File: AGENTS.md (Tokens: ~2019 | Category: root-instruction) -->\n# Inno Setup AI Agent Guide\r\n\r\n## Introduction\r\n- Source code of Inno Setup, an open-source installation builder for Windows applications by Jordan Russell and Martijn Laan, first released in 1997.\r\n- Comes in 64-bit and 32-bit editions; both can build 32-bit or 64-bit installers.\r\n- Copyrighted software; see `LICENSE.TXT` for distribution restrictions. Commercial users are requested to purchase a commercial license.\r\n\r\n## Project Architecture\r\nDelphi projects under `Projects/`:\r\n\r\n| Project | Output | Role |\r\n|---------|--------|------|\r\n| `ISIDE` | EXE | GUI compiler front-end (IDE), thin shell around ISCmplr.dll |\r\n| `ISCC` | EXE | CLI compiler front-end, thin shell around ISCmplr.dll |\r\n| `ISCmplr` | DLL | Actual compiler engine; entry point: `Compiler.SetupCompiler.pas` |\r\n| `ISPP` | DLL | Preprocessor |\r\n| `Setup` | EXE | Installer runtime; entry point: `Setup.MainFunc.pas` |\r\n| `SetupCustomStyle` | EXE | Installer runtime with VCL Styles support |\r\n| `SetupLdr` | EXE | Self-extracting loader that decompresses and launches Setup |\r\n| `ISSigTool` | EXE | Signs and verifies files using custom signatures |\r\n| `ISTestTool` | EXE | Internal utility that runs unit tests; invoked by build.bat and build-ce.bat |\r\n\r\nUnder `ISHelp/ISHelpGen/`:\r\n\r\n| Project | Output | Role |\r\n|---------|--------|------|\r\n| `ISHelpGen` | EXE | Generates XML files for help and Pascal Script autocomplete |\r\n\r\n## Core System\r\n- Delphi codebase targeting Windows 7 and later via the Windows API. All projects build for x64 and x86.\r\n- Primary project-specific source lives in `Projects/Src/` using namespace prefixes: `Compiler.*`, `Compression.*`, `IDE.*`, `ISPP.*`, `Setup.*`, `SetupLdrAndSetup.*`, `Shared.*`. Projects also compile shared units from `Components/`, and `ISIDE` additionally consumes the generated `ISHelp\\isxclasses_wordlists_generated.pas`. New project-specific source files must follow the namespace convention and be placed in `Projects/Src/`.\r\n- `Shared.Struct.pas` defines cross-project record layouts, and `Shared.CompilerInt.Struct.pas` defines the compiler/front-end interface layout. Changing either requires reviewing every consumer and recompiling the relevant projects.\r\n- Other shared units live under `Components` and `Projects\\Src\\Shared.*.pas`.\r\n- `SetupLdrAndSetup.*` units are shared by SetupLdr, Setup, and SetupCustomStyle; changes must account for all three.\r\n- `SetupCustomStyle` uses the same sources as `Setup` plus `Vcl.Themes`/`Vcl.Styles` and `Setup.TaskDialogForm`.\r\n- Many UI units in `Projects/Src/` are paired with checked-in `.dfm` files; form changes often require coordinated `.pas` and `.dfm` edits.\r\n- Compression engines pull native code from `Projects\\Src\\Compression.*`.\r\n- Pascal Script integration sits in `Compiler.Script*.pas` and `Setup.Script*.pas`; changes must be mirrored on both compiler and setup sides.\r\n- Setup path redirection: `ApplyPathRedirRules` rewrites System32/SysWOW64/Sysnative and converts to super paths. Unless documented otherwise, functions should receive current-process-bit paths. Use `ApplyRedirToRunEntryPaths` for run entries and `ApplyRedirForRegistrationOperation` for registration/shared-count operations. Old-style FS redirection disabling is still used when running 64-bit system executables from a 32-bit Setup process.\r\n- Extended-length (super) paths (`\\\\?\\`) are used by Setup to avoid MAX_PATH issues and are produced by `ApplyPathRedirRules` unless `rfNormalPath` is used. Only pass super paths to APIs known to accept them; when in doubt (especially for shell APIs or user-facing strings), convert back to a normal path.\r\n\r\n## Build\r\n- Run `compile.bat x64` or `compile.bat x86`. Both output release binaries to `Files`.\r\n- Append a project name, such as `compile.bat x64 ISCC`, to compile only that project.\r\n- Compiler path is configured in `compilesettings.bat`.\r\n- `build.bat` orchestrates full release builds.\r\n- In a fresh worktree, run `issig.bat embed` before the first compile. This updates the tracked files `Components\\TrustFunc.AllowedPublicKeys.inc` and `def02.ispublickey`. Leave them in place.\r\n- If a release build binary under `Files\\` reports \"Signature file is not valid\", run `issig.bat embed`, then rerun the relevant compile command, usually `compile.bat x64`, and retry the failed command.\r\n\r\n## Code Conventions\r\n- `**/*.iss`: see `.claude/rules/iss.md`.\r\n- `**/*.pas`, `**/*.dpr`, `**/*.inc`: see `.claude/rules/pascal.md`.\r\n- `**/*Test.pas`, `**/*Test.iss`: see `.claude/rules/test.md`.\r\n- `Files/Languages/*.isl`, `Files/Languages/Unofficial/*.isl`: see `.claude/rules/isl.md`.\r\n- `Components/UniPs/**`: see `.claude/rules/unips.md`.\r\n- `Projects/Src/Compression.LZMACompressor/islzma/**`, `Projects/Src/Compression.LZMADecompressor/Lzma2Decode/**`: see `.claude/rules/islzma.md`.\r\n- Indentation: see `.claude/rules/indentation.md`.\r\n\r\n## Documentation Conventions\r\n- `whatsnew.htm`, `ISHelp/isetup.xml`, `ISHelp/ispp.xml`, `ISHelp/isx.xml`, `ISHelp/isxfunc.xml`, `ISHelp/isxclasses.header*`, `ISHelp/isxclasses.footer`: see `.claude/rules/docs.general.md`.\r\n- `ISHelp/isetup.xml`, `ISHelp/isx.xml`, `ISHelp/isxfunc.xml`, `ISHelp/isxclasses.header*`, `ISHelp/isxclasses.footer`, `ISHelp/ispp.xml`: see `.claude/rules/docs.ishelp.md`.\r\n- `ISHelp/isetup.xml`: see `.claude/rules/docs.ishelp.isetup.md`.\r\n- `ISHelp/isxfunc.xml`: see `.claude/rules/docs.ishelp.isxfunc.md`.\r\n- `ISHelp/ispp.xml`: see `.claude/rules/docs.ishelp.ispp.md`.\r\n- `whatsnew.htm`: see `.claude/rules/docs.whatsnew.md`.\r\n\r\n## Docs\r\n- `whatsnew.htm` contains the Revision History.\r\n- Help content lives under `ISHelp`:\r\n  - When editing `ISHelp\\*`, regenerate CHM/Web help: run `compile.bat x64 ISHelpGen` then `ISHelp\\compile.bat` and verify 0 errors. Don't skip; this regenerates `isxclasses_wordlists_generated.pas`, which is in Git.\r\n  - `isxfunc.xml` documents Pascal Script functions.\r\n  - `isxclasses.pas` documents Pascal Script classes, with `isxclasses.header`, `isxclasses.header2`, and `isxclasses.footer` as helpers. When a `uPSC_*.pas` registration changes for Inno Setup (`PS_MINIVCL` is defined, `FPC` and `CLX` are not), update `isxclasses.pas` to match and regenerate as above.\r\n  - `isx.xml` contains all other Pascal Script documentation.\r\n  - `ispp.xml` documents the ISPP preprocessor.\r\n  - `isetup.xml` contains the remaining documentation.\r\n  - `isetup.dtd`, `ispp.dtd`, `isxfunc.dtd`, `isxfunc.xsl`, and `ispp.xsl` are schema and XSL files consumed by `ISHelpGen`.\r\n  - Don't edit files generated by `ISHelpGen`: `ispp_generated.xml`, `isxclasses_generated.xml`, `isxclasses_wordlists_generated.pas`, `isxfunc_generated.xml`.\r\n- Don't use em dashes or en dashes; use periods or commas instead.\r\n- Don't use \"e.g.\"; use \"for example\" or \"such as\" instead.\r\n\r\n## Precompiled Binaries\r\n- `Files/` contains precompiled C/C++ DLLs (7-Zip, zlib, bzip2, LZMA, Scintilla) and `.issig` signature files.\r\n- Rebuild with `build-precomp.bat` (requires separate repository checkouts); refresh signatures separately with ISSigTool afterward.\r\n\r\n## Testing & Verification\r\n- After editing any `.pas`, `.dpr`, `.dproj`, or `.inc` file: run `compile.bat x64` and verify 0 errors.\r\n- Unit tests live in `*.Test.pas` files. No testing framework is used; tests raise an exception on failure.\r\n- To run tests, run `test.bat [x86|x64]` and verify 0 exit code. Omit the architecture to test both. This also compiles `ISTestTool` first.\r\n\r\n## Other information\r\n- When creating a new file: immediately `git add` it, but only if still untracked.\r\n- Otherwise treat Git as read-only.\r\n- A task is not complete until the relevant compilation succeeds with 0 errors.\n\n<!-- File: .claude/rules/docs.general.md (Tokens: ~1854 | Category: anthropic-skill) -->\n---\r\npaths: [\"whatsnew.htm\", \"ISHelp/isetup.xml\", \"ISHelp/ispp.xml\", \"ISHelp/isx.xml\", \"ISHelp/isxfunc.xml\", \"ISHelp/isxclasses.header*\", \"ISHelp/isxclasses.footer\"]\r\n---\r\n# General documentation conventions for Inno Setup\r\n\r\n## Voice and Tone\r\n\r\n- **Direct and technical.** State facts plainly. Do not hedge or pad with filler.\r\n- **Second person** (\"you\") when addressing the user who writes scripts or configures Setup.\r\n- **Impersonal** when describing system behavior: \"Setup will...\", \"the compiler will...\", \"an exception will be raised if...\".\r\n- **Not chatty.** No rhetorical questions, no \"Note that you might wonder...\". Just state the information.\r\n- **Contractions are used.** Write \"don't\", \"isn't\", \"can't\", \"won't\", \"doesn't\", \"aren't\", \"hasn't\", \"didn't\", \"wouldn't\", \"couldn't\", \"shouldn't\". These are natural and make the text less stiff for non-native readers.\r\n\r\n## Sentence Structure\r\n\r\n- Prefer **short, clear sentences**. One idea per sentence when possible.\r\n- Avoid deeply nested clauses. If a sentence grows complex, split it.\r\n- **Active voice** when possible: \"Setup creates the directory\" rather than \"the directory is created by Setup\". Passive voice is acceptable when the actor is irrelevant or when it reads more naturally: \"An exception will be raised if...\".\r\n- Parenthetical notes are common and acceptable: \"(which can include constants)\", \"(the default setting)\".\r\n\r\n## Vocabulary and Terminology\r\n\r\nUse the established Inno Setup terms consistently. Never substitute synonyms:\r\n\r\n| Correct term | Do not use |\r\n|---|---|\r\n| Setup, the Setup program, the installer | the installation program (note: \"installer\" is also standard for the compiled artifact, such as \"64-bit installers\") |\r\n| Uninstall, the uninstaller | the uninstall program |\r\n| the compiler | the build system, the compilation engine |\r\n| the end user | the customer, the consumer |\r\n| the user | the developer, the script author (when addressing the person writing .iss scripts) |\r\n| support function | helper function, utility function |\r\n| support class | helper class |\r\n| directive | setting, option (for [Setup] section items) |\r\n| parameter | field, property (for section entry items) |\r\n| flag | option, switch (for Flags parameter values) |\r\n| entry | line, row (for a line in a section) |\r\n| section | block, group (for [Setup], [Files], etc.) |\r\n| the Compiler IDE | the editor (\"the IDE\" is acceptable after \"the Compiler IDE\" has been established in the same context, in both ISHelp and whatsnew) |\r\n| Pascal Scripting | the scripting engine (for the feature/topic name; \"Pascal Script\" is acceptable when referring to the RemObjects Pascal Script engine itself) |\r\n| extended-length paths | long paths (use \"also known as super paths\" parenthetically on first mention within a topic; don't use \"super paths\" as a standalone term) |\r\n| menu item | menu option |\r\n| Start menu (but \"Start Menu\" in titles, such as the *Select Start Menu Folder* wizard page) | Start Menu |\r\n| checkbox | check box |\r\n| without a BOM | BOM-less, BOMless |\r\n| the help file | the help |\r\n\r\nAdditional vocabulary rules:\r\n- \"Setup or Uninstall\" or \"the Setup program and uninstaller\" when a feature applies to both. Not \"the installer or uninstaller\".\r\n- \"the user's system\" for the target environment. Not \"the target machine\". \"computer\" is acceptable for restarts (\"restart the computer\") and computer names (\"the name of the computer\").\r\n- \"specified\" is the standard word for parameters and directives: \"the specified file\", \"the specified parameter\". Not \"provided\".\r\n- \"given\" is the standard word for function argument descriptions: \"the given string\", \"the given file name\".\r\n- \"Returns True if...\" is the standard pattern for boolean function descriptions.\r\n- \"cannot\" as one word. Not \"can not\".\r\n- Use \"use\" not \"utilize\".\r\n- Use \"non-zero\" not \"non-zero value\".\r\n- Do not shorten established descriptive terms. Write \"support function\", not \"func\".\r\n- Repeat the same term for the same concept. Do not rotate between synonyms for variety.\r\n\r\n## Punctuation\r\n\r\n- **Oxford (serial) comma:** Use it. \"A, B, and C\", not \"A, B and C\".\r\n- **Periods** at the end of complete sentences, including list items that are complete sentences.\r\n- **No em dashes or en dashes.** Use periods, commas, or parentheses instead.\r\n- **No \"e.g.\"** Use \"for example\" or \"such as\".\r\n- **No \"i.e.\"** Use \"that is\" or rephrase.\r\n- **\"etc.\" is acceptable** but use sparingly.\r\n- **Colons** before examples and lists.\r\n\r\n## Formatting\r\n\r\n- Code identifiers should render as monospace: section names, directive names, parameter names, flag names, constant names, type names, function names, file names, directory names, path values, registry key and value type names, environment variable names, command-line switches, and values like `yes`/`no`/`True`/`False`. In prose, use `<tt>` for this. Inside already-monospace contexts, such as `<pre>`, `<precode>`, or ISPP `<line>` elements, no extra `<tt>` is needed.\r\n- When a code identifier is in a prose link's display text, still make it monospace with `<tt>`:\r\n  - For an internal `<link>`: outside the link if the identifier is the whole display text, inside otherwise.\r\n  - For an `<extlink>`: always inside, because external links get an icon added that must not appear inside the `<tt>` pill.\r\n- `<i>` for emphasis, wizard page names (such as *Select Destination Location*), UI element names, and font names.\r\n- `<b>` sparingly, for important warnings or the word \"NOTE:\".\r\n\r\n## Syntax Highlighting\r\n\r\nThe IDE styler (`Projects/Src/IDE.ScintStylerInnoSetup.pas`) is the source of truth for which token gets which\r\ncategory. Five non-obvious rules:\r\n\r\n- Use `<sec>`, `<evt>`, `<key>`, `<com>`, `<con>`, `<str>`, `<num>`, and `<ispp>` for syntax-highlighted script examples.\r\n- Use `<str>` and `<num>` only in Pascal Script and ISPP contexts. Section directive and parameter string\r\n  values stay plain, with only their inner constants using `<con>`. Number literals include ISPP array indices.\r\n- Use of `<con>` depends on context. Use it for a regular constant (`{app}`) inside a section directive or parameter\r\n  value, including inside a parameter value such as `ExpandConstant('<con>{app}</con>\\...')`,\r\n  but not inside a Pascal string literal, where the whole literal stays `<str>`. An ISPP inline constant\r\n  (`{#...}`) is the exception: it always uses `<ispp>` on the `{#...}` delimiters and directive name (the inner\r\n  expression keeps its own styling), even inside a string literal, because ISPP pre-styles it.\r\n- `<evt>` applies only to the fixed `BasicEventFunctions` set; functions named via event attributes are not bolded.\r\n- `[Messages]`/`[CustomMessages]`/`[LangOptions]`: only the message name is `<key>`; a language prefix is not.\r\n\r\n## Review Guidelines\r\n\r\nWhen reviewing documentation, check for:\r\n\r\n1. **Terminology consistency.** Are the correct Inno Setup terms used? (See the vocabulary table above.)\r\n2. **Factual accuracy.** Does the documentation match the actual code behavior?\r\n3. **Completeness.** Are all parameters, flags, return values, and error conditions documented?\r\n4. **Cross-references.** Are related topics linked?\r\n5. **Code formatting.** Are code identifiers in prose wrapped in `<tt>`? Are examples provided?\r\n6. **Style violations.** Check for: em/en dashes, \"e.g.\", \"i.e.\", synonym rotation, missing Oxford commas, \"can not\" instead of \"cannot\", \"utilize\" instead of \"use\".\r\n7. **Clarity for non-native speakers.** Avoid idioms, complex subordinate clauses, and uncommon vocabulary.\r\n8. **Do not nitpick** about subjective style matters in existing text that is not being changed. Only flag style issues in new or modified text.\n\n<!-- File: .claude/rules/docs.ishelp.isetup.md (Tokens: ~475 | Category: anthropic-skill) -->\n---\npaths: [\"ISHelp/isetup.xml\"]\n---\n# isetup.xml documentation conventions\n\nThese are specific to `isetup.xml`, which documents the entry sections and [Setup] directives; the general ISHelp conventions in `docs.ishelp.md` apply too.\n\n## Section topic structure\n\nEach entry section topic (such as [Files], [Registry], [Run]) follows this structure:\n1. Opening paragraph: \"This optional section defines...\" or \"This section contains...\".\n2. Introductory notes about default behavior.\n3. Example section with `<precode>`.\n4. \"The following is a list of the supported parameters:\" introducing the parameter list.\n5. Parameters documented with `<paramlist>` / `<param>`.\n6. Links to Common Parameters and Components/Tasks Parameters at the bottom.\n\n## Directive-topic structure\n\nEach [Setup] directive topic uses `<setuptopic>`:\n1. `<setuptopic directive=\"DirectiveName\">`: topic wrapper.\n2. `<setupvalid>`: valid values (optional, omitted when free-form text).\n3. `<setupdefault>`: default value (optional).\n4. `<body>`: opening paragraph, followed by detail paragraphs, notes, examples, and optional \"See also\" links. Common opening patterns: \"This directive specifies...\", \"This tells the compiler...\", \"Controls whether...\", \"If set to [value]...\".\n\n## Parameter documentation\n\nEach parameter follows this pattern:\n1. Description paragraph: what it controls.\n2. Additional detail paragraphs as needed.\n3. Example with `<example><pre>`.\n4. For Flags parameters: \"This parameter is a set of extra options. Multiple options may be used by separating them by spaces. The following options are supported:\" followed by `<flaglist>`.\n\n## Conditional behavior\n\nUse the pattern: \"If [value] is specified, Setup will [action].\" Repeat for each value. Example:\n> If <tt>string</tt> is specified, Setup will create a string (<tt>REG_SZ</tt>) value.\n> If <tt>dword</tt> is specified, Setup will create a 32-bit integer (<tt>REG_DWORD</tt>) value.\n\n## Default values\n\nState defaults explicitly: \"Defaults to [value].\" or \"The default value is [value].\" or \"(the default setting)\".\n\n<!-- File: .claude/rules/docs.ishelp.ispp.md (Tokens: ~269 | Category: anthropic-skill) -->\n---\r\npaths: [\"ISHelp/ispp.xml\"]\r\n---\r\n# ispp.xml documentation conventions\r\n\r\nThese are specific to `ispp.xml`; the general ISHelp conventions in `docs.ishelp.md` apply too.\r\n\r\n## Directive documentation\r\n\r\nPreprocessor directives use `<topic>` with `<syntax>`/`<define>`, `<description>`, and `<section>`.\r\n\r\n## Function documentation\r\n\r\nFunctions put the signature in `<section title=\"Prototype\">` (inside `<pre><line>`) and related links in `<section title=\"See also\">`.\r\n\r\nBoolean-like functions are documented as \"Returns non-zero if [condition].\" rather than \"Returns True if [condition], False otherwise.\"\r\n\r\n## Differences from the general conventions\r\n\r\n- **Cross-reference links:** use `<link href=\"topicname\">Display Text</link>`. `ispp.dtd` has no `anchor` attribute; the `href` carries the target.\r\n- **Examples:** examples sit in a bare `<pre>` inside `<section title=\"Examples\">`.\r\n- **Function shorthand:** `<isxfunc>` not available; link ISPP functions with `<link href=\"...\">`.\r\n- **Indentation:** `ispp.xml` is tab-indented, unlike the other ISHelp sources. Keep using tabs; the rules in `indentation.md` do not apply.\n\n<!-- File: .claude/rules/docs.ishelp.isxfunc.md (Tokens: ~345 | Category: anthropic-skill) -->\n---\r\npaths: [\"ISHelp/isxfunc.xml\"]\r\n---\r\n# isxfunc.xml documentation conventions\r\n\r\nThese are specific to `isxfunc.xml`; the general ISHelp conventions in `docs.ishelp.md` apply too.\r\n\r\n`<link topic=\"...\">` (with optional `anchor`), `<extlink>`, `<sd>`, `<sn>`, and `<isxfunc>` all work as in the general conventions.\r\n\r\n## Function documentation\r\n\r\nEach function follows this pattern:\r\n- `<name>`: Function name.\r\n- `<prototype>`: Full function signature.\r\n- `<description>`: One or more `<p>` elements. First sentence is the key description.\r\n  - For functions returning a value: \"Returns [description of return value].\"\r\n  - For procedures: \"Does [action].\" or imperative form.\r\n  - For boolean functions: \"Returns True if [condition], False otherwise.\"\r\n- `<remarks>` (optional): Additional notes, edge cases, caveats.\r\n- `<seealso>` (optional): Links to related functions.\r\n- `<example>` (optional): Code example.\r\n\r\nStandard description patterns:\r\n- \"Returns the [noun] of [context].\"\r\n- \"Returns True if [condition].\"\r\n- \"Returns a [type] containing [description].\"\r\n- \"Gets/Sets the value of [thing].\"\r\n- \"Creates/Deletes/Removes [thing].\"\r\n- \"An exception will be raised if [error condition].\"\r\n- \"If [condition], [function name] returns [value].\"\r\n\r\n## Differences from the general conventions\r\n\r\n- **Examples:** use `<example>`, which may contain `<pre>`. `isxfunc.dtd` has no `<precode>`.\n\n<!-- File: .claude/rules/docs.ishelp.md (Tokens: ~392 | Category: anthropic-skill) -->\n---\r\npaths: [\"ISHelp/isetup.xml\", \"ISHelp/isx.xml\", \"ISHelp/isxfunc.xml\", \"ISHelp/isxclasses.header*\", \"ISHelp/isxclasses.footer\", \"ISHelp/ispp.xml\"]\r\n---\r\n# ISHelp documentation conventions\r\n\r\nThese are the general documentation conventions shared by all ISHelp sources. `isetup.xml`, `isx.xml`, and the `isxclasses.*` helpers use `isetup.dtd`; `isxfunc.xml` (`isxfunc.dtd`) and `ispp.xml` (`ispp.dtd`) use their own DTD. They all follow the conventions below, except where a file's own rule file notes a difference or adds file-specific structure: see `docs.ishelp.isetup.md`, `docs.ishelp.isxfunc.md`, and `docs.ishelp.ispp.md`. Prose conventions for all of these files live in `docs.general.md`, not here.\r\n\r\n## Additional formatting\r\n\r\n- `<precode>` for syntax-highlighted section-level and topic-level script examples (such as showing a full [Run] section).\r\n- `<example><pre>` for syntax-highlighted parameter and function examples, which can also be multi-line.\r\n\r\n## Cross-references\r\n\r\n- Use `<link topic=\"topicname\">Display Text</link>`.\r\n- Always link to related topics when mentioning directives, sections, or functions. Do not leave them as plain text if a help topic exists.\r\n- Use the `<sd>Directive</sd>`, `<sn>[Section]</sn>`, and `<isxfunc>FunctionName</isxfunc>` shorthands instead of a `<link>` to a [Setup] directive, section, or support function.\r\n- To specific anchors: `<link topic=\"topicname\" anchor=\"anchorname\">Display Text</link>`.\r\n- External links: `<extlink href=\"url\">Display Text</extlink>`.\n\n<!-- File: .claude/rules/docs.whatsnew.md (Tokens: ~792 | Category: anthropic-skill) -->\n---\r\npaths: [\"whatsnew.htm\"]\r\n---\r\n# Inno Setup Revision History documentation conventions\r\n\r\n## Additional formatting\r\n\r\n- `<i>Fix:</i>` prefix for bug fix entries.\r\n- `<pre><code class=\"innosetup\">` for syntax-highlighted script examples.\r\n\r\n## Example script references\r\n\r\n- \"See updated <tt><a href=\"...\">ScriptName.iss</a></tt> example script.\"\r\n- \"See updated <tt><a href=\"...\">ScriptName.iss</a></tt> example script for an example.\"\r\n- \"See new <tt><a href=\"...\">ScriptName.iss</a></tt> example script.\"\r\n\r\n## Entry structure\r\n\r\nChangelog entries appear as `<li>` items in `<ul>` lists.\r\n\r\n**New features:**\r\n- \"Added new [type] <tt>Name</tt>.\" or \"Added new [type] <tt>Name</tt> to [context].\"\r\n- \"Added new support functions <tt>Name1</tt>, <tt>Name2</tt>, and <tt>Name3</tt>.\"\r\n- \"Added new support classes <tt>Name1</tt>, <tt>Name2</tt>, and <tt>Name3</tt>.\"\r\n- \"Added new properties <tt>Name1</tt>, <tt>Name2</tt>, and <tt>Name3</tt> to class <tt>ClassName</tt>.\"\r\n- \"Added support for [feature].\"\r\n\r\n**Changes:**\r\n- \"Directive <tt>Name</tt> now defaults to <tt>value</tt>.\"\r\n- \"<tt>Feature</tt> is now [new behavior].\"\r\n- \"Enhanced/Improved/Updated [thing] [description of change].\"\r\n- \"Renamed <tt>OldName</tt> to <tt>NewName</tt>. The old name still works.\"\r\n\r\n**Bug fixes:**\r\n- Always prefixed: \"<i>Fix:</i> Description of what was wrong and what is now correct.\"\r\n- For documentation-only fixes: \"<i>Documentation fix:</i> Description.\"\r\n- Describe the symptom, not just the fix. Include \"broken since X.Y.Z\" or \"broken in X.Y.Z\" when known.\r\n\r\n**Removals:**\r\n- \"Removed support for [feature].\" or \"Support for [feature] has been dropped.\"\r\n- \"Removed [thing]. Use [replacement] instead.\"\r\n\r\n**Deprecations:**\r\n- \"This function is deprecated.\" followed by what to use instead.\r\n- \"The compiler still accepts <tt>OldName</tt> as an alias for <tt>NewName</tt>, but will emit a deprecation warning when used.\"\r\n\r\n## Subcategories\r\n\r\nGroup related changes under subcategory headers using nested lists:\r\n```html\r\n<li>Pascal Scripting:\r\n<ul>\r\n  <li>Added new support function <tt>Foo</tt>.</li>\r\n  <li><i>Fix:</i> <tt>Bar</tt> now works correctly.</li>\r\n</ul>\r\n</li>\r\n```\r\n\r\nStandard subcategory names: \"Compiler IDE:\", \"Pascal Scripting:\", \"ISPP:\", \"Setup:\", \"Compiler:\", \"Command-Line Compiler (ISCC):\", \"Examples:\", \"Security improvement:\", \"Updated documentation:\", and product-specific names such as \"Inno Setup Signature Tool:\". Other one-off names are acceptable when a group of entries warrants its own heading.\r\n\r\n## Catch-all entries\r\n\r\nEnd a version's changes with one of:\r\n- \"Other minor improvements.\"\r\n- \"Minor tweaks.\"\r\n- \"Minor tweaks and fixes.\"\r\n- \"Other minor improvements and fixes.\"\r\n- \"Documentation improvements.\"\r\n\r\n## Security section intro\r\n\r\nWhen there is a security improvements section:\r\n> Updating is recommended, even if you don't plan to use the other enhancements right away. We continually add extra checks to make your installers safer and more reliable. In this version:\n\n<!-- File: .claude/rules/indentation.md (Tokens: ~112 | Category: anthropic-skill) -->\n---\r\npaths: [\"**/*.pas\", \"**/*.dpr\", \"**/*.dpk\", \"**/*.inc\", \"**/*.iss\", \"**/*.htm\", \"**/*.bat\", \"**/*.c\", \"**/*.h\", \"**/*.dfm\", \"**/*.xml\", \"**/*.dtd\", \"**/*.xsl\", \"**/*.md\", \"**/*.yml\"]\r\n---\r\n# Indentation conventions for all text files\r\n- Use spaces for indentation, not tabs.\r\n- Unless the format requires otherwise (for example, `.md` lists), use two spaces per indentation level.\n\n<!-- File: .claude/rules/isl.md (Tokens: ~1925 | Category: anthropic-skill) -->\n---\r\npaths: [\"Files/Languages/*.isl\", \"Files/Languages/Unofficial/*.isl\"]\r\n---\r\n# Conventions for Inno Setup translation files\r\n\r\nThese files translate `Files/Default.isl` into another language. `Default.isl` is the English baseline and the source of truth for the message set; it changes between Inno Setup versions, so always work from the most recent `Default.isl`, read it fresh, and treat its `[Messages]` and `[CustomMessages]` IDs as authoritative. A translation must stay faithful to its English counterpart: the English is the fixed reference and the ceiling, not something to clarify, complete, or improve.\r\n\r\n## Quality rules\r\n\r\n### File format and structure\r\n- **Encoding.** UTF-8 without a BOM.\r\n- **Newlines.** Windows CRLF throughout.\r\n- **Extension.** `.isl`. The `.islu` extension is obsolete.\r\n- **Compiles cleanly.** The file must compile with no errors and no warnings.\r\n\r\n### Comment header (top-of-file comments)\r\n- The first line is the version line, usually `; *** Inno Setup version X+ ... messages ***`. Keep it consistent with the `Default.isl` header version. It must never be higher than the `Default.isl` version.\r\n- The top of the file must also carry, as comments, the language's English name and the maintainer's name and e-mail address.\r\n\r\n### `[LangOptions]` settings\r\n- **LanguageName.** The language's native name (the name as written in the language itself), not its English name. For example Dutch is `Nederlands`, not `Dutch`. It is shown in the *Select Language* dialog. The obsolete `<HHHH>` escape syntax still works but is no longer needed; write the literal characters directly.\r\n- **LanguageID.** A valid hexadecimal language identifier beginning with `$`, matching the language and its region (for example `$0413` for Dutch (Netherlands), `$0813` for Belgian Dutch). It must not be left at `$0409`, which is the English ID of `Default.isl`. Verify against Microsoft's language-identifier list (https://learn.microsoft.com/en-us/windows/win32/intl/language-identifier-constants-and-strings). If no identifier exists for the language, set it to `0`. Together with `LanguageCodePage` it is used to auto-detect the most appropriate default language, so set it correctly.\r\n- **LanguageCodePage.** The Windows ANSI code page the compiler uses to convert any non-Unicode text in the language's files to Unicode (for example 1252 Western European, 1250 Central European, 1251 Cyrillic, 1253 Greek, 1254 Turkish, 1255 Hebrew, 1256 Arabic, 1257 Baltic, 1258 Vietnamese, 874 Thai, 932 Japanese, 936 Chinese Simplified, 949 Korean, 950 Chinese Traditional). Set it to `0` only when no code page exists for the language (a Unicode-only script such as Hindi, Tamil, Bengali, Armenian, Georgian) or the language uses only ASCII characters. It still matters even though the `.isl` is UTF-8, because it converts non-Unicode files such as a README supplied by the script author. (Text in the `.iss` file itself, such as a `[CustomMessages]` entry, is never converted and must already be Unicode.)\r\n- **RightToLeft.** `RightToLeft=yes` must be set for a right-to-left script (Arabic, Hebrew, Persian (Farsi), Urdu, Uyghur) and must not be set (or `RightToLeft=no`) for a left-to-right language.\r\n- **Fonts** (`DialogFontName`, `DialogFontSize`, `WelcomeFontName`, and so on). `Default.isl` keeps them all commented out. Uncomment only the entries the language genuinely needs to differ; an entry equal to the default stays commented out, so it inherits future default changes. Drop obsolete entries no longer in `Default.isl` (such as `CopyrightFontName`/`CopyrightFontSize`).\r\n\r\n### Sections and message set (compared to `Default.isl`)\r\n- **Translate the existing entries only.** Provide every `[Messages]` and `[CustomMessages]` ID that `Default.isl` defines, translated. Do not add your own custom messages to `[CustomMessages]`, and do not invent new IDs.\r\n- **No missing IDs.** Every ID defined in `Default.isl` must be present.\r\n- **No obsolete IDs.** Do not keep IDs that no longer exist in `Default.isl`.\r\n- **Empty values.** A message that is empty in `Default.isl` must stay empty in the translation, except for the `TranslatorNote` message.\r\n\r\n### Per-message rules (each message compared to its English counterpart)\r\n- **Placeholder integrity.** The same set and count of `%1`..`%9` must be present (the order may differ to suit the target grammar, and an argument may legitimately be duplicated, such as `%1 ... %1 %2`). Keep `%n` line breaks and `%%` literal-percent escapes intact. Preserve the same bracketed runtime placeholders, currently `[name]`, `[name/ver]`, `[mb]`, and `[gb]`. Never drop, add, or malform a placeholder or format specifier.\r\n- **Placeholder grammar.** A placeholder is filled at runtime with a value the translator cannot see or inflect, and which is not always the expected token (a wizard-name `%1`, for example, can be a custom name). Phrase the surrounding text so it reads correctly for any value: keep the placeholder in a slot that needs no inflection of, or grammatical agreement with, the inserted value, and never assume the value's gender, number, or case. If the English drops the value into a slot your language would inflect or agree with, rebuild the clause rather than guessing one form.\r\n- **Accelerator keys.** Keep an `&` accelerator wherever the English has one, and do not add one where the English has none. Drop an accelerator only when it cannot be placed on any letter of the translated text; resolve a collision by moving it to another letter rather than dropping it. Within each accelerator scope every accelerator letter must be unique, compared case-insensitively.\r\n- **No added periods.** Do not add a period to the end of a message that did not have one already. Exception: for languages with their own period character, such as Japanese and Chinese, it was added to the end of messages as needed. Keep a trailing period where the English has one. Exception: Thai and Lao remove trailing periods and question marks. If the English ends with `...`, keep the trailing ellipsis, written either as three dots `...` or as a single ellipsis character `…`. Spacing before the ellipsis follows the target language's typography (for example German puts a space before it, while English does not).\r\n- **Faithful meaning.** Stay as close to the original English as possible. Do not add to or change the meaning of a message to suit personal taste (for example do not append \"Try again one more time.\" to an error message that did not say that).\r\n\r\n### Translation quality (linguistic)\r\n- No spelling or grammar errors.\r\n- No untranslated messages that should have been translated. Some values are legitimately identical to English (`Setup`, `OK`, brand names, placeholder-only messages); only genuine omissions are wrong.\r\n- Consistent terminology: the same concept uses the same term across every message, with consistent button-label style and capitalization.\r\n- Use the language's native standard terminology, taking installer terms from the matching official Setup translation and everything else from Microsoft Terminology plus the language's Style Guide (for example the standard local words for Setup, folder, uninstall, administrator).\r\n- Consistent, language-appropriate tone, formality, casing, punctuation, and quote style (for example German capitalizes nouns and addresses the user formally; Japanese uses full-width punctuation where the platform does).\r\n- Translate naturally. As loose guidance stay near the English length (roughly within about 150 percent), but naturalness wins.\r\n\r\n## Faithfulness check before changing a message\r\n\r\nBefore changing a translated message because it looks wrong, confirm all of these; if any fails, leave it alone:\r\n1. Quote the exact English string. If you can't, you haven't compared against it.\r\n2. The current translation differs from what the English *means*, not from a clearer or more explicit version you imagined. If the English is itself ambiguous, general, or underspecified, an equally ambiguous translation is correct, not a problem.\r\n3. Your change preserves the English meaning. It must not add precision, disambiguation, or detail the English does not have.\r\n4. It is substantive. Awkward-but-acceptable phrasing, debatable terminology, and pure style preferences are nitpicks; leave them.\r\n5. Back-translate both the current text and your replacement into English. Change it only if the current text back-translates to a different meaning than the English *and* your replacement back-translates to the same meaning. If the replacement back-translates to something the English does not say, it adds meaning; drop it.\n\n<!-- File: .claude/rules/islzma.md (Tokens: ~166 | Category: anthropic-skill) -->\n---\r\npaths: [\"Projects/Src/Compression.LZMACompressor/islzma/**\", \"Projects/Src/Compression.LZMADecompressor/Lzma2Decode/**\"]\r\n---\r\n# Instructions for the native LZMA C code (islzma and Lzma2Decode)\r\n\r\n## Indentation\r\n\r\nThese files keep their existing indentation style; the rules in `indentation.md` do not apply:\r\n- `islzma.c`, `islzma.h`, `islzma_dll.c`, `islzma_exe.c`, `ISLzmaDec.c`, and `test/test.bat` are tab-indented.\r\n- `test/roundtrip.c` is four-space indented.\r\n\r\nDo not reformat these files. When editing, match the surrounding indentation of the file you are in.\n\n<!-- File: .claude/rules/iss.md (Tokens: ~860 | Category: anthropic-skill) -->\n---\r\npaths: [\"**/*.iss\"]\r\n---\r\n# Coding conventions for Inno Setup script files\r\nInno Setup `.iss` scripts use the `[Code]` section for Pascal Script code. This is RemObjects Pascal Script (ROPS), not modern Delphi. The following rules apply to code in `[Code]` sections.\r\n## Language differences compared to Delphi\r\nMost of these are hard constraints of the ROPS compiler. Violating them causes compile errors.\r\n- No inline `var` or inline `const`. All local variables must be declared in a `var` block before `begin`.\r\n- No local `const` or `type` declarations. Only `var` and `label` blocks are allowed before `begin`.\r\n- No `Exit(Value)` syntax. Assign to `Result` first, then call `Exit` separately.\r\n- No typed constants (`const X: Integer = 1`). Only untyped constants (`const X = 1`).\r\n- No default parameter values.\r\n- No function or procedure overloading.\r\n- No `raise` keyword. Use `RaiseException(Msg)` or `RaiseLastException` instead.\r\n- No `on E: ExceptionType do` in `except` blocks. Use `GetExceptionMessage` to inspect the current exception.\r\n- No script-defined classes. Classes can be used, but only those defined by Inno Setup.\r\n- No variant records.\r\n- `const` parameters are passed by value (copied), and not by reference as in modern Delphi.\r\n- As in Delphi, assigning a dynamic array, or passing it as a value or `const` parameter, shares its elements. A change to an element through one variable is visible through the other. `SetArrayLength` and `SetLength` copy a shared array only when the length changes. Delphi's `SetLength` always copies it. `Copy` doesn't support arrays. To get an array that isn't shared, change its length and change it back, or copy the elements to a new array.\r\n- The `/` operator always returns `Extended`, even when both operands are integers. Use `div` for integer division.\r\n- `Break` and `Continue` are not reserved words. They are ordinary identifiers recognized specially inside loop bodies. A local declaration named `Break` or `Continue` will shadow the loop-control behavior.\r\n- `Low`, `High`, and `SizeOf` must be used with a variable, not a type.\r\n## Conventions (same spirit as the Pascal rules, adapted for ROPS)\r\n- Pre-declare all local variables in the `var` block before `begin`.\r\n- Do not use `with` statements.\r\n- `if` and `begin` should be on the same line.\r\n- `else` and `begin` should be on the same line.\r\n- Do not use `begin..end` for single one-line statement blocks, but always use it when the block spans multiple lines. This includes when the block's single statement spans multiple lines (such as a multi-line `for`), and when a comment on its own line accompanies the statement (a trailing comment on the statement's line does not count).\r\n  Count lines per indentation level: a child statement never adds to its parent's count, so a chain of one-line statements takes no `begin..end` at any level.\r\n  A statement wrapped over continuation lines still counts as one line. But a statement that is genuinely multi-line at its own level (a `begin..end` block, or a control statement with a body, of its own) makes each level above it multi-line too.\r\n- Do not use `Longint` or `LongWord`; use `Integer` or `Cardinal` instead.\r\n- Mark read-only parameters as `const`.\r\n- Do not shorten descriptive names. Write `Expression`, not `Expr`; `MultiFileHandler`, not `MFH`. Conventional short names (`I`, `J`, `S`, `Res`) and established identifiers (`HiWord`) are fine.\r\n## Code editing guidelines\r\n- Do not modify existing comments unless the code they describe is also being changed.\r\n- Keep new comments short and match the style of existing comments in the file.\n\n<!-- File: .claude/rules/pascal.md (Tokens: ~1143 | Category: anthropic-skill) -->\n---\r\npaths: [\"**/*.pas\", \"**/*.dpr\", \"**/*.inc\"]\r\n---\r\n# Coding conventions for Pascal source files\r\n- Always use inline variables instead of pre-declaring them at the start of the function.\r\n  Exception: Delphi 10.4 does not support anonymous array types in inline variable or constant declarations, so pre-declare them.\r\n- Prefer inline constants over inline variables, even for run-time values and not just for compile-time constants.\r\n  Exception: inline constants cannot be passed as `var` parameters, so use an inline variable in that case.\r\n  Inline constants which are an object can still have their properties modified.\r\n  Inline constants use `=` as the assignment operator instead of `:=`. Examples:\r\n  `const MaxCount = MinCount * 2;`\r\n  `const ExpandedFilename = PathExpand(Filenames[I]);`\r\n- Prefer factoring shared code into a routine, or binding the expression to an inline const.\r\n- A routine whose callers all sit inside one routine belongs nested in it, not as a method or a unit-level routine. Keep such helpers siblings at a single level: never nest a helper inside another helper. No exceptions, except a routine assigned to an event stays a method.\r\n- Do not use `with` statements.\r\n- `if` and `begin` should be on the same line.\r\n- `else` and `begin` should be on the same line.\r\n- A `Result` assignment followed by an `Exit` statement should be combined into a single statement. For example: `Exit(ResultValue);`\r\n- Do not use `begin..end` for single one-line statement blocks, but always use it when the block spans multiple lines. This includes when the block's single statement spans multiple lines (such as a multi-line `for`), and when a comment on its own line accompanies the statement (a trailing comment on the statement's line does not count).\r\n  Count lines per indentation level: a child statement never adds to its parent's count, so a chain of one-line statements takes no `begin..end` at any level:\r\n  `for var X in Y do`\r\n  `  if Z(X) then`\r\n  `    Exit(True);`\r\n  A statement wrapped over continuation lines still counts as one line. But a statement that is genuinely multi-line at its own level (a `begin..end` block, or a control statement with a body, of its own) makes each level above it multi-line too.\r\n- Do not use `Longint` or `LongWord`, use `Integer` or `Cardinal` instead.\r\n- Mark read-only parameters as `const`.\r\n- Use Windows units first, then RTL/VCL units, then Components units, then Shared units, then project specific units.\r\n- Class methods should be static when possible.\r\n- Do not shorten descriptive names. Write `Expression`, not `Expr`; `MultiFileHandler`, not `MFH`. Conventional short names (`I`, `J`, `S`, `Res`) and established identifiers (`HiWord`) are fine.\r\n- Comments should be short and match the style of existing comments in the file. Prefer using `{` and `}`, and do not end one-sentence comments with a period.\r\n# Code editing guidelines\r\n- Do not modify existing comments unless the code they describe is also being changed.\r\n- When modifying code that calls Windows APIs, read the actual documentation before writing code. Do not assume parameter semantics based on similar APIs.\r\n- Update Inno Setup copyright header of any file you edit, if the current year is not already included.\r\n- Add tests for new code to the unit's `*.Test.pas` if it exists; otherwise consider creating one if the code is complex enough to warrant testing.\r\n  ISPP and ROPS code is tested by `Script.ISPP.Test.iss` and `Script.ROPS.Test.iss`, not a `*.Test.pas` unit.\r\n# Code review guidelines\r\n- All errors must be checked. Installers should be reliable above all.\r\n- Be alert for `out` parameters: an `out` parameter, like a `var` parameter, is passed by reference. However, with an `out` parameter, the initial value of the referenced variable for managed types, such as strings or arrays, is discarded by the caller before it is passed to the routine. Meanwhile, the initial value for unmanaged types, such as integers or pointers, is ignored. Therefore, for unmanaged types, it is not guaranteed that the initial value of the referenced variable will be overwritten in the routine to which it is passed.\r\n- Be alert for functions not assigning a value to Result: if a function exits without assigning a value to Result or the function name, then the function's return value is undefined, even for managed types.\r\n- Be alert for dynamic-array aliasing: assigning one dynamic array (e.g. `TBytes`) to another makes both reference the same buffer. Unlike strings and static arrays, copy-on-write is not employed, so writes through one alias (including `FillChar`) are visible through the other. Use `Copy(Source)` when an independent buffer is needed.\r\n- Code must be compatible with Delphi 10.4 and later.\r\n- Code must be compatible with 32-bit and 64-bit builds.\r\n- Code must be compatible with Windows 7 and later.\r\n- Do not suggest applying coding conventions to unchanged code.\r\n- Do not suggest changing an inline constant to an inline variable.\r\n- Do not nitpick, especially not about readability or subjective matters. This includes:\r\n  - Comment style or presence of comments.\n\n<!-- File: .claude/rules/test.md (Tokens: ~436 | Category: anthropic-skill) -->\n---\r\npaths: [\"**/*Test.pas\", \"**/*Test.iss\"]\r\n---\r\n# Instructions for adding tests\r\n\r\n## When a correct test fails: allow investigation instead of pure tweaking\r\n\r\nIf a test that looks correct fails at compile time or at runtime, **do not silently adjust it until it passes**. A test that matches spec behavior but fails is evidence of a bug, not a bad test. The right response is:\r\n\r\n1. **Keep the original test** in the test source file, commented out, with a short explanation of the bug it exposed (e.g. `{ bug: 'for I: Byte := 0 to 255' infinite-loops because the loop variable wraps from 255 to 0 }`).\r\n2. **Write an alternate working test** that covers the same functionality without hitting the bug, if one exists. For example, use a narrower range or a different loop structure. This keeps test coverage moving forward.\r\n3. **Fixing the bug and re-enabling the original test is a separate task** - do not block the current phase on it.\r\n\r\nTweaking a test to avoid a real bug - changing types, adding casts, restructuring loops - hides regressions and defeats the purpose of the test suite.\r\n\r\n## Tests that check for a raised exception\r\n\r\nWhen a test verifies that something raises an exception, guard that part with `{$IFDEF ISTESTTOOLPROJ}` so it runs only under ISTestTool, not the DEBUG self-test. The self-test runs in the unit's `initialization` block inside the real application, where an intentionally raised exception would break in the debugger on every run. ISTestTool defines `ISTESTTOOLPROJ` and runs these checks normally.\r\n\r\nUse this pattern:\r\n\r\n```pascal\r\n{$IFDEF ISTESTTOOLPROJ}\r\n{ <what must raise and why> }\r\nvar Caught := False;\r\ntry\r\n  SomethingThatMustRaise;\r\nexcept\r\n  Caught := True;\r\nend;\r\nAssert(Caught);\r\n{$ENDIF}\r\n```\r\n\r\nKeep assertions that must always run, such as the contrasting success case, outside the `{$IFDEF ISTESTTOOLPROJ}` block.\n\n<!-- File: .claude/rules/unips.md (Tokens: ~508 | Category: anthropic-skill) -->\n---\r\npaths: [\"Components/UniPs/**\"]\r\n---\r\n# Instructions for UniPs (Pascal Script) components\r\n\r\n## Upstream origin\r\n\r\nThese files are copies of the RemObjects Pascal Script `stable` branch (see `rev.txt` for the commit hash).\r\n\r\nYou may still edit them, but:\r\n- Do not refactor the code style to match Inno Setup conventions.\r\n- Keep changes minimal and focused. Even though Inno Setup is a Delphi Windows codebase, the Pascal Script code is cross-platform: it compiles under multiple compilers (Delphi and FPC), operating systems (Windows and others), and CPU bitnesses (32- and 64-bit). A change must either be correct on every combination, or be guarded so it only affects the ones you have verified. Useful guards: `{$IFDEF DELPHI}` / `{$IFDEF FPC}` (compiler), `{$IFDEF MSWINDOWS}` (OS), and `{$IFDEF CPU64}` (bitness).\r\n  Inno Setup always builds with Delphi on Windows, in both 32- and 64-bit, so your change must be correct there. Improving support for the platforms Inno Setup does not use (FPC, non-Windows) is a bonus, but extend a change to them only when it is easy and correctness is easy to confirm; otherwise guard the change.\r\n- Don't edit or inspect `rev.txt` as it is an auto-generated bookkeeping file.\r\n\r\n## Registration: compile-time (uPSC_) vs runtime (uPSR_)\r\n\r\nPascal Script has two registration layers that must stay in sync:\r\n- **Compile-time** (`uPSC_*.pas`): declares what the script compiler accepts.\r\n- **Runtime** (`uPSR_*.pas`): provides actual method pointers and property helpers.\r\n\r\nWhen a compile-time registration is guarded by `{$IFDEF}` or `{$IFNDEF}`, the matching runtime registration must use the same guard. A mismatch causes scripts to compile successfully but crash at runtime.\r\n\r\nA compile-time `RegisterProperty` for a **published** property does not require a matching runtime `RegisterPropertyHelper`. RTTI handles published properties automatically. Only non-published properties need explicit runtime read/write helpers.\r\n\r\nUse the actual Pascal type name in `RegisterProperty`, not a shortcut like `'Byte'` for enums or sets. For example, use `'TComponentState'` for a set type and `'TFontPitch'` for an enum, not `'Byte'`.\n</yakaai_skills>"}