{
  "$schema": "../cases.schema.json",
  "format": 1,
  "domain": "voterId",
  "title": {
    "en": "Voter ID",
    "pt-BR": "Título de eleitor"
  },
  "functions": [
    {
      "id": "voterId.format",
      "level": "core",
      "summary": "Formats a Brazilian voter ID for display.",
      "description": "Formats a voter ID with the grouping `0000 0000 00 00`.\n\n- A voter ID has at most 12 digits (Resolução TSE nº 23.659/2021, art. 36), so the function drops the digits after the 12th and has no 13-digit grouping. 2.4.0 grouped a 13-digit SP/MG value as `0000 0000 0 00 00`.\n- The TSE drops the leading zeros of the sequential number when it issues the ID. By default a shorter value is formatted from the left, as a partial value. `options.pad` first left-pads it with zeros to 12 digits: `123450159` gives `0001 2345 01 59`.\n- `options.obfuscate` (default `false`) hides the first 3 digits and the 2 check digits with `*`: `***4 5678 01 **`. The UF code stays visible.\n- No authority publishes a masking rule for the voter ID. The rule is an analogy with the one the Leis de Diretrizes Orçamentárias set for publishing a CPF (\"ocultar os três primeiros dígitos e os dois dígitos verificadores\", Lei nº 12.309/2010, art. 87, § 5º, repeated up to the LDO 2026, Lei nº 15.321/2025, art. 163), not a published norm.\n- The mask hides by position. A voter ID given as a number has lost its leading zeros, so pass `pad` together with `obfuscate` for it.\n- A number is read only when it is a safe non-negative integer. A negative, fractional, non-finite or unsafe number gives an empty string (2.4.0 read the digits of any number).\n- Pending decision (findings §2 #2, #3): the reference (JS) formats only the characters an incomplete value has and returns an empty string for empty or invalid input. Other libraries return `null`.\n- A value with no digits (empty, or only letters and symbols) returns an empty string, even with `pad`.\n- `options.obfuscate` is applied after `pad`, and is read for truthiness like `pad`: a non-boolean such as `1` hides the digits too, and `0` does not. The two can be combined (`123450159` gives `***1 2345 01 **`).",
      "params": [
        {
          "name": "value",
          "type": "string | number"
        },
        {
          "name": "options",
          "type": "FormatVoterIdOptions",
          "optional": true
        }
      ],
      "returns": "string",
      "cases": [
        {
          "id": "voterId.format#[\"652688902801\"]",
          "args": [
            "652688902801"
          ],
          "expect": {
            "returns": "6526 8890 28 01"
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "voterId.format#[\"051401322801\"]",
          "args": [
            "051401322801"
          ],
          "expect": {
            "returns": "0514 0132 28 01"
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "voterId.format#[\"859962902836\"]",
          "args": [
            "859962902836"
          ],
          "expect": {
            "returns": "8599 6290 28 36"
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "voterId.format#[\"\"]",
          "args": [
            ""
          ],
          "expect": {
            "returns": ""
          },
          "note": "JavaScript's own test: should format voter ids"
        },
        {
          "id": "voterId.format#[\"1\"]",
          "args": [
            "1"
          ],
          "expect": {
            "returns": "1"
          },
          "note": "JavaScript's own test: should format voter ids"
        },
        {
          "id": "voterId.format#[\"12\"]",
          "args": [
            "12"
          ],
          "expect": {
            "returns": "12"
          },
          "note": "JavaScript's own test: should format voter ids"
        },
        {
          "id": "voterId.format#[\"123\"]",
          "args": [
            "123"
          ],
          "expect": {
            "returns": "123"
          },
          "note": "JavaScript's own test: should format voter ids"
        },
        {
          "id": "voterId.format#[\"1234\"]",
          "args": [
            "1234"
          ],
          "expect": {
            "returns": "1234"
          },
          "note": "JavaScript's own test: should format voter ids"
        },
        {
          "id": "voterId.format#[\"12345\"]",
          "args": [
            "12345"
          ],
          "expect": {
            "returns": "1234 5"
          },
          "note": "JavaScript's own test: should format voter ids"
        },
        {
          "id": "voterId.format#[\"123456\"]",
          "args": [
            "123456"
          ],
          "expect": {
            "returns": "1234 56"
          },
          "note": "JavaScript's own test: should format voter ids"
        },
        {
          "id": "voterId.format#[\"1234567\"]",
          "args": [
            "1234567"
          ],
          "expect": {
            "returns": "1234 567"
          },
          "note": "JavaScript's own test: should format voter ids"
        },
        {
          "id": "voterId.format#[\"12345678\"]",
          "args": [
            "12345678"
          ],
          "expect": {
            "returns": "1234 5678"
          },
          "note": "JavaScript's own test: should format voter ids"
        },
        {
          "id": "voterId.format#[\"123456780\"]",
          "args": [
            "123456780"
          ],
          "expect": {
            "returns": "1234 5678 0"
          },
          "note": "JavaScript's own test: should format voter ids"
        },
        {
          "id": "voterId.format#[\"1234567801\"]",
          "args": [
            "1234567801"
          ],
          "expect": {
            "returns": "1234 5678 01"
          },
          "note": "JavaScript's own test: should format voter ids"
        },
        {
          "id": "voterId.format#[\"12345678012\"]",
          "args": [
            "12345678012"
          ],
          "expect": {
            "returns": "1234 5678 01 2"
          },
          "note": "JavaScript's own test: should format voter ids"
        },
        {
          "id": "voterId.format#[\"123456780124\"]",
          "args": [
            "123456780124"
          ],
          "expect": {
            "returns": "1234 5678 01 24"
          },
          "note": "JavaScript's own test: should format voter ids"
        },
        {
          "id": "voterId.format#[\"1234567880191\"]",
          "args": [
            "1234567880191"
          ],
          "expect": {
            "returns": "1234 5678 80 19"
          },
          "note": "changed in 2.5.0 (#593): a voter ID has at most 12 digits (Resolução TSE nº 23.659/2021, art. 36), so the 13-digit SP/MG grouping is gone and the digits after the 12th are dropped. 2.4.0 returned \"1234 5678 8 01 91\""
        },
        {
          "id": "voterId.format#[\"1234567880299\"]",
          "args": [
            "1234567880299"
          ],
          "expect": {
            "returns": "1234 5678 80 29"
          },
          "note": "changed in 2.5.0 (#593): a voter ID has at most 12 digits (Resolução TSE nº 23.659/2021, art. 36), so the 13-digit SP/MG grouping is gone and the digits after the 12th are dropped. 2.4.0 returned \"1234 5678 8 02 99\""
        },
        {
          "id": "voterId.format#[\"12345678801912\"]",
          "args": [
            "12345678801912"
          ],
          "expect": {
            "returns": "1234 5678 80 19"
          },
          "note": "changed in 2.5.0 (#593): a voter ID has at most 12 digits (Resolução TSE nº 23.659/2021, art. 36), so the 13-digit SP/MG grouping is gone and the digits after the 12th are dropped. 2.4.0 returned \"1234 5678 8 01 91\""
        },
        {
          "id": "voterId.format#[\"123456788019123\"]",
          "args": [
            "123456788019123"
          ],
          "expect": {
            "returns": "1234 5678 80 19"
          },
          "note": "changed in 2.5.0 (#593): a voter ID has at most 12 digits (Resolução TSE nº 23.659/2021, art. 36), so the 13-digit SP/MG grouping is gone and the digits after the 12th are dropped. 2.4.0 returned \"1234 5678 8 01 91\""
        },
        {
          "id": "voterId.format#[\"12345678803991\"]",
          "args": [
            "12345678803991"
          ],
          "expect": {
            "returns": "1234 5678 80 39"
          },
          "note": "JavaScript's own test: should drop the digits past the 12th"
        },
        {
          "id": "voterId.format#[\"1234567880399\"]",
          "args": [
            "1234567880399"
          ],
          "expect": {
            "returns": "1234 5678 80 39"
          },
          "note": "JavaScript's own test: should drop the digits past the 12th"
        },
        {
          "id": "voterId.format#[\"123456788\"]",
          "args": [
            "123456788"
          ],
          "expect": {
            "returns": "1234 5678 8"
          },
          "note": "JavaScript's own test: should format voter ids"
        },
        {
          "id": "voterId.format#[\"123456788019\"]",
          "args": [
            "123456788019"
          ],
          "expect": {
            "returns": "1234 5678 80 19"
          },
          "note": "JavaScript's own test: should format voter ids"
        },
        {
          "id": "voterId.format#[\"123456780175\",{\"obfuscate\":true}]",
          "args": [
            "123456780175",
            {
              "obfuscate": true
            }
          ],
          "expect": {
            "returns": "***4 5678 01 **"
          },
          "note": "from the maintainer briefing, #567"
        },
        {
          "id": "voterId.format#[\"123456780124\",{\"obfuscate\":true}]",
          "args": [
            "123456780124",
            {
              "obfuscate": true
            }
          ],
          "expect": {
            "returns": "***4 5678 01 **"
          },
          "note": "JavaScript's own test: should hide the first 3 digits and the 2 check digits when obfuscate is truthy"
        },
        {
          "id": "voterId.format#[123456780124,{\"obfuscate\":true}]",
          "args": [
            123456780124,
            {
              "obfuscate": true
            }
          ],
          "expect": {
            "returns": "***4 5678 01 **"
          },
          "note": "JavaScript's own test: should hide the first 3 digits and the 2 check digits when obfuscate is truthy"
        },
        {
          "id": "voterId.format#[\"1234567880191\",{\"obfuscate\":true}]",
          "args": [
            "1234567880191",
            {
              "obfuscate": true
            }
          ],
          "expect": {
            "returns": "***4 5678 80 **"
          },
          "note": "JavaScript's own test: should hide the first 3 digits and the 2 check digits when obfuscate is truthy"
        },
        {
          "id": "voterId.format#[\"12345\",{\"obfuscate\":true}]",
          "args": [
            "12345",
            {
              "obfuscate": true
            }
          ],
          "expect": {
            "returns": "***4 5"
          },
          "note": "JavaScript's own test: should hide the first 3 digits and the 2 check digits when obfuscate is truthy"
        },
        {
          "id": "voterId.format#[\"123456780124\",{\"obfuscate\":false}]",
          "args": [
            "123456780124",
            {
              "obfuscate": false
            }
          ],
          "expect": {
            "returns": "1234 5678 01 24"
          },
          "note": "JavaScript's own test: should behave exactly as without the option when obfuscate is falsy"
        },
        {
          "id": "voterId.format#[\"123456780124\",{}]",
          "args": [
            "123456780124",
            {}
          ],
          "expect": {
            "returns": "1234 5678 01 24"
          },
          "note": "JavaScript's own test: should behave exactly as without the option when obfuscate is falsy"
        },
        {
          "id": "voterId.format#[\"123450159\",{\"pad\":true}]",
          "args": [
            "123450159",
            {
              "pad": true
            }
          ],
          "expect": {
            "returns": "0001 2345 01 59"
          },
          "note": "JavaScript's own test: should restore the leading zeros of a voter id issued without them when pad is true"
        },
        {
          "id": "voterId.format#[123450159,{\"pad\":true}]",
          "args": [
            123450159,
            {
              "pad": true
            }
          ],
          "expect": {
            "returns": "0001 2345 01 59"
          },
          "note": "JavaScript's own test: should restore the leading zeros of a voter id issued without them when pad is true"
        },
        {
          "id": "voterId.format#[\"10191\",{\"pad\":true}]",
          "args": [
            "10191",
            {
              "pad": true
            }
          ],
          "expect": {
            "returns": "0000 0001 01 91"
          },
          "note": "JavaScript's own test: should restore the leading zeros of a voter id issued without them when pad is true"
        },
        {
          "id": "voterId.format#[\"123456780124\",{\"pad\":true}]",
          "args": [
            "123456780124",
            {
              "pad": true
            }
          ],
          "expect": {
            "returns": "1234 5678 01 24"
          },
          "note": "JavaScript's own test: should restore the leading zeros of a voter id issued without them when pad is true"
        },
        {
          "id": "voterId.format#[\"123450159\",{\"pad\":true,\"obfuscate\":true}]",
          "args": [
            "123450159",
            {
              "pad": true,
              "obfuscate": true
            }
          ],
          "expect": {
            "returns": "***1 2345 01 **"
          },
          "note": "JavaScript's own test: should restore the leading zeros of a voter id issued without them when pad is true"
        },
        {
          "id": "voterId.format#[\"123450159\",{\"pad\":false}]",
          "args": [
            "123450159",
            {
              "pad": false
            }
          ],
          "expect": {
            "returns": "1234 5015 9"
          },
          "note": "JavaScript's own test: should restore the leading zeros of a voter id issued without them when pad is true"
        },
        {
          "id": "voterId.format#[\"123450159\"]",
          "args": [
            "123450159"
          ],
          "expect": {
            "returns": "1234 5015 9"
          },
          "note": "JavaScript docs example"
        },
        {
          "id": "voterId.format#[123450159,{\"obfuscate\":true}]",
          "args": [
            123450159,
            {
              "obfuscate": true
            }
          ],
          "expect": {
            "returns": "***4 5015 9"
          },
          "note": "the mask hides by position: without pad a number that lost its leading zeros shows the wrong digits"
        },
        {
          "id": "voterId.format#[-123456780124]",
          "args": [
            -123456780124
          ],
          "expect": {
            "returns": ""
          },
          "note": "changed in 2.5.0 (#593): a negative number is not a safe non-negative integer. 2.4.0 returned \"1234 5678 01 24\". JavaScript's own test: when it is a negative, fractional or unsafe number"
        },
        {
          "id": "voterId.format#[1.5]",
          "args": [
            1.5
          ],
          "expect": {
            "returns": ""
          },
          "note": "JavaScript's own test: when it is a negative, fractional or unsafe number"
        },
        {
          "id": "voterId.format#[9007199254740992]",
          "args": [
            9007199254740992
          ],
          "expect": {
            "returns": ""
          },
          "note": "JavaScript's own test: when it is a negative, fractional or unsafe number (2^53)"
        },
        {
          "id": "voterId.format#[\"\",{\"pad\":true}]",
          "args": [
            "",
            {
              "pad": true
            }
          ],
          "expect": {
            "returns": ""
          },
          "note": "JavaScript's own test: should return an empty string for a value without digits even when padding"
        },
        {
          "id": "voterId.format#[\"abc\",{\"pad\":true}]",
          "args": [
            "abc",
            {
              "pad": true
            }
          ],
          "expect": {
            "returns": ""
          },
          "note": "JavaScript's own test: should return an empty string for a value without digits even when padding"
        },
        {
          "id": "voterId.format#[\"123456780175\"]",
          "args": [
            "123456780175"
          ],
          "expect": {
            "returns": "1234 5678 01 75"
          },
          "note": "JavaScript docs example"
        }
      ]
    },
    {
      "id": "voterId.generate",
      "level": "core",
      "summary": "Generates a valid random Brazilian voter ID.",
      "description": "Generates a valid random voter ID: 12 digits, unformatted, with the leading zeros of the sequential number kept.\n\n- `state` (a state code, or `ZZ` for a voter ID issued abroad) sets the UF code. Letter case and surrounding whitespace are ignored (`\" sp \"` is `SP`); 2.4.0 read a lowercase code as unknown. An unknown value falls back to `ZZ` (UF `28`).\n- The result always has 12 digits. The same ID without the leading zeros of its sequential number is valid too (`voterId.isValid` reads it).\n- A value that is not a string also falls back to `ZZ`; the function never throws for `state`.",
      "params": [
        {
          "name": "state",
          "type": "string",
          "optional": true
        }
      ],
      "returns": "string",
      "cases": [
        {
          "id": "voterId.generate#generated-is-valid",
          "args": [],
          "expect": {
            "satisfies": "voterId.isValid"
          },
          "repeat": 5,
          "note": "every generated value must pass the lib's own validator"
        }
      ]
    },
    {
      "id": "voterId.getInfo",
      "level": "extended",
      "summary": "Reads the fields of a voter ID (título de eleitor).",
      "description": "Reads the fields of a voter ID: the sequential number, the federative union of the registration and the check digits.\n\n- Returns `null` exactly when `voterId.isValid` returns `false`; the input rules are the same.\n- The result has `sequentialNumber` (8 digits), `federativeUnion` (the code `01` to `28`), `stateCode` (the state code, or `null` for `28`, the voters abroad) and `checkDigits` (2 digits). Codes are strings that keep their leading zeros.\n- A voter ID issued without the leading zeros of its sequential number is read as `voterId.isValid` reads it, left-padded with zeros to 12 digits: `123450159` gives the `sequentialNumber` `00012345`.\n- `stateCode` is the federative union of the registration, not necessarily where the voter lives today.\n- Each call returns a new object.",
      "params": [
        {
          "name": "value",
          "type": "string"
        }
      ],
      "returns": "VoterIdInfo?",
      "cases": [
        {
          "id": "voterId.getInfo#docs-example",
          "args": [
            "1023 8501 06 71"
          ],
          "expect": {
            "returns": {
              "sequentialNumber": "10238501",
              "federativeUnion": "06",
              "stateCode": "PR",
              "checkDigits": "71"
            }
          },
          "note": "JavaScript docs example"
        },
        {
          "id": "voterId.getInfo#abroad",
          "args": [
            "000000002801"
          ],
          "expect": {
            "returns": {
              "sequentialNumber": "00000000",
              "federativeUnion": "28",
              "stateCode": null,
              "checkDigits": "01"
            }
          },
          "note": "JavaScript docs example: 28 is the voters abroad (ZZ), with no state"
        },
        {
          "id": "voterId.getInfo#invalid-check-digits",
          "args": [
            "123456780124"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript docs example: invalid check digits"
        },
        {
          "id": "voterId.getInfo#empty",
          "args": [
            ""
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test: when it is an empty string"
        },
        {
          "id": "voterId.getInfo#[\"102385010671\"]",
          "args": [
            "102385010671"
          ],
          "expect": {
            "returns": {
              "sequentialNumber": "10238501",
              "federativeUnion": "06",
              "stateCode": "PR",
              "checkDigits": "71"
            }
          },
          "note": "JavaScript's own test (getVoterIdInfo)"
        },
        {
          "id": "voterId.getInfo#[\"10238501\"]",
          "args": [
            "10238501"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test (getVoterIdInfo)"
        },
        {
          "id": "voterId.getInfo#[\"123456780191\"]",
          "args": [
            "123456780191"
          ],
          "expect": {
            "returns": {
              "sequentialNumber": "12345678",
              "federativeUnion": "01",
              "stateCode": "SP",
              "checkDigits": "91"
            }
          },
          "note": "JavaScript's own test (getVoterIdInfo)"
        },
        {
          "id": "voterId.getInfo#[\" 1234 5678 01 91\\\\n\"]",
          "args": [
            " 1234 5678 01 91\\n"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test (getVoterIdInfo)"
        },
        {
          "id": "voterId.getInfo#[\"1234.5678-01/91\"]",
          "args": [
            "1234.5678-01/91"
          ],
          "expect": {
            "returns": {
              "sequentialNumber": "12345678",
              "federativeUnion": "01",
              "stateCode": "SP",
              "checkDigits": "91"
            }
          },
          "note": "JavaScript's own test (getVoterIdInfo)"
        },
        {
          "id": "voterId.getInfo#[\"12345678\"]",
          "args": [
            "12345678"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test (getVoterIdInfo)"
        },
        {
          "id": "voterId.getInfo#[\"00012345\"]",
          "args": [
            "00012345"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test (getVoterIdInfo)"
        },
        {
          "id": "voterId.getInfo#[\"000123450159\"]",
          "args": [
            "000123450159"
          ],
          "expect": {
            "returns": {
              "sequentialNumber": "00012345",
              "federativeUnion": "01",
              "stateCode": "SP",
              "checkDigits": "59"
            }
          },
          "note": "JavaScript's own test (getVoterIdInfo)"
        },
        {
          "id": "voterId.getInfo#[\"123450159\"]",
          "args": [
            "123450159"
          ],
          "expect": {
            "returns": {
              "sequentialNumber": "00012345",
              "federativeUnion": "01",
              "stateCode": "SP",
              "checkDigits": "59"
            }
          },
          "note": "JavaScript's own test (getVoterIdInfo)"
        },
        {
          "id": "voterId.getInfo#[\"12345 01 59\"]",
          "args": [
            "12345 01 59"
          ],
          "expect": {
            "returns": {
              "sequentialNumber": "00012345",
              "federativeUnion": "01",
              "stateCode": "SP",
              "checkDigits": "59"
            }
          },
          "note": "JavaScript's own test (getVoterIdInfo)"
        },
        {
          "id": "voterId.getInfo#[\"12340639\"]",
          "args": [
            "12340639"
          ],
          "expect": {
            "returns": {
              "sequentialNumber": "00001234",
              "federativeUnion": "06",
              "stateCode": "PR",
              "checkDigits": "39"
            }
          },
          "note": "JavaScript's own test (getVoterIdInfo)"
        },
        {
          "id": "voterId.getInfo#[\"00001234\"]",
          "args": [
            "00001234"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test (getVoterIdInfo)"
        },
        {
          "id": "voterId.getInfo#[\"000000000116\"]",
          "args": [
            "000000000116"
          ],
          "expect": {
            "returns": {
              "sequentialNumber": "00000000",
              "federativeUnion": "01",
              "stateCode": "SP",
              "checkDigits": "16"
            }
          },
          "note": "JavaScript's own test (getVoterIdInfo)"
        },
        {
          "id": "voterId.getInfo#[\"00000000\"]",
          "args": [
            "00000000"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test (getVoterIdInfo)"
        },
        {
          "id": "voterId.getInfo#[\"122844\"]",
          "args": [
            "122844"
          ],
          "expect": {
            "returns": {
              "sequentialNumber": "00000012",
              "federativeUnion": "28",
              "stateCode": null,
              "checkDigits": "44"
            }
          },
          "note": "JavaScript's own test (getVoterIdInfo)"
        },
        {
          "id": "voterId.getInfo#[\"00000012\"]",
          "args": [
            "00000012"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test (getVoterIdInfo)"
        },
        {
          "id": "voterId.getInfo#[\"123456780013\"]",
          "args": [
            "123456780013"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test (getVoterIdInfo)"
        },
        {
          "id": "voterId.getInfo#[\"123456782913\"]",
          "args": [
            "123456782913"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test (getVoterIdInfo)"
        },
        {
          "id": "voterId.getInfo#[\"1234567880191\"]",
          "args": [
            "1234567880191"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test (getVoterIdInfo)"
        },
        {
          "id": "voterId.getInfo#[\"0191\"]",
          "args": [
            "0191"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test (getVoterIdInfo)"
        },
        {
          "id": "voterId.getInfo#[\"ab102385010671\"]",
          "args": [
            "ab102385010671"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test (getVoterIdInfo)"
        },
        {
          "id": "voterId.getInfo#[\"1023_8501_06_71\"]",
          "args": [
            "1023_8501_06_71"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test (getVoterIdInfo)"
        }
      ]
    },
    {
      "id": "voterId.isValid",
      "level": "core",
      "summary": "Checks whether a Brazilian voter ID is valid.",
      "description": "Validates a voter ID: an 8-digit sequential number, a 2-digit UF code (`01` to `28`) and 2 modulus 11 check digits, at most 12 digits (Resolução TSE nº 23.659/2021, art. 36).\n\n- A 13-digit value is rejected. 2.4.0 accepted a 13-digit SP/MG form with a 9-digit sequential number.\n- The TSE drops the leading zeros of the sequential number when it issues the ID. A shorter value is left-padded with zeros to 12 digits before the check: `123450159` is checked as `000123450159`. At least one sequential digit is required, so the shortest accepted value has 5 digits. 2.4.0 rejected these shorter values.\n- No official source gives the weights of the check digits or the SP/MG rule that turns a remainder of 0 into 1. They follow community references.\n- Pending decision (findings §2 #1): the reference (JS) accepts whitespace, dots, hyphens and slashes around and between the groups, with a shortened sequential number grouped from the right (`123 4567 01 91`). Until 2.4.0 it accepted whitespace and dots only. Other libraries accept digits only.\n- Mask characters: whitespace, `.`, `-` and `/`, alone or in a run, around and between the `0000 0000 00 00` groups (the same ones `cpf.isValid` reads). Any other character, a letter in particular, makes the value invalid. A separator inside a group is rejected, except between the digits of a sequential number written without its leading zeros, grouped from the right (`123 4567 01 91`).\n- Only a string is read. Any other type returns `false`.",
      "params": [
        {
          "name": "value",
          "type": "string"
        }
      ],
      "returns": "boolean",
      "cases": [
        {
          "id": "voterId.isValid#[\"652688902801\"]",
          "args": [
            "652688902801"
          ],
          "expect": {
            "returns": true
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "voterId.isValid#[\"652688902802\"]",
          "args": [
            "652688902802"
          ],
          "expect": {
            "returns": false
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "voterId.isValid#[\"000000000000\"]",
          "args": [
            "000000000000"
          ],
          "expect": {
            "returns": false
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "voterId.isValid#[\"051401322801\"]",
          "args": [
            "051401322801"
          ],
          "expect": {
            "returns": true
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "voterId.isValid#[\"051401322802\"]",
          "args": [
            "051401322802"
          ],
          "expect": {
            "returns": false
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "voterId.isValid#[\"859962902836\"]",
          "args": [
            "859962902836"
          ],
          "expect": {
            "returns": true
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "voterId.isValid#[\"859962902837\"]",
          "args": [
            "859962902837"
          ],
          "expect": {
            "returns": false
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "voterId.isValid#[\"\"]",
          "args": [
            ""
          ],
          "expect": {
            "returns": false
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "voterId.isValid#[\"   \"]",
          "args": [
            "   "
          ],
          "expect": {
            "returns": false
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "voterId.isValid#[\"abc\"]",
          "args": [
            "abc"
          ],
          "expect": {
            "returns": false
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "voterId.isValid#[\"102385010671\"]",
          "args": [
            "102385010671"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should validate a real 12-digit voter id"
        },
        {
          "id": "voterId.isValid#[\"1234567880191\"]",
          "args": [
            "1234567880191"
          ],
          "expect": {
            "returns": false
          },
          "note": "changed in 2.5.0 (#593): a voter ID has at most 12 digits (Resolução TSE nº 23.659/2021, art. 36), so a 13-digit value is rejected. 2.4.0 returned true. JavaScript's own test: should reject a 13-digit value, since a voter id has at most 12 digits"
        },
        {
          "id": "voterId.isValid#[\"1234567880192\"]",
          "args": [
            "1234567880192"
          ],
          "expect": {
            "returns": false
          },
          "note": "a 13-digit value: still false in 2.5.0, now because a voter ID has at most 12 digits (Resolução TSE nº 23.659/2021, art. 36)"
        },
        {
          "id": "voterId.isValid#[\"1234567890396\"]",
          "args": [
            "1234567890396"
          ],
          "expect": {
            "returns": false
          },
          "note": "a 13-digit value: still false in 2.5.0, now because a voter ID has at most 12 digits (Resolução TSE nº 23.659/2021, art. 36)"
        },
        {
          "id": "voterId.isValid#[\"123456780396\"]",
          "args": [
            "123456780396"
          ],
          "expect": {
            "returns": true
          },
          "note": "a 12-digit value whose check digits match (UF 03)"
        },
        {
          "id": "voterId.isValid#[\"12345678980191\"]",
          "args": [
            "12345678980191"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should reject a value longer than 12 digits"
        },
        {
          "id": "voterId.isValid#[\"123456789900\"]",
          "args": [
            "123456789900"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when the UF code is outside 01-28"
        },
        {
          "id": "voterId.isValid#[\"1234567890345\"]",
          "args": [
            "1234567890345"
          ],
          "expect": {
            "returns": false
          },
          "note": "a 13-digit value: still false in 2.5.0, now because a voter ID has at most 12 digits (Resolução TSE nº 23.659/2021, art. 36)"
        },
        {
          "id": "voterId.isValid#[\"ab102385010671\"]",
          "args": [
            "ab102385010671"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should reject a value with a letter attached to the digits"
        },
        {
          "id": "voterId.isValid#[\"102385010671ab\"]",
          "args": [
            "102385010671ab"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should reject a value with a letter attached to the digits"
        },
        {
          "id": "voterId.isValid#[\"1023-8501-06-71\"]",
          "args": [
            "1023-8501-06-71"
          ],
          "expect": {
            "returns": true
          },
          "note": "changed in 2.5.0 (#615): hyphens and slashes are mask characters, like in cpf.isValid. 2.4.0 returned false. JavaScript's own test: should reject a mask character outside whitespace, `.`, `-` and `/`"
        },
        {
          "id": "voterId.isValid#[\"1023 8501 06 71\"]",
          "args": [
            "1023 8501 06 71"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should accept the documented whitespace and dot masks"
        },
        {
          "id": "voterId.isValid#[\"1023.8501.06.71\"]",
          "args": [
            "1023.8501.06.71"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should accept the documented whitespace and dot masks"
        },
        {
          "id": "voterId.isValid#[\"1234 5678 8 01 91\"]",
          "args": [
            "1234 5678 8 01 91"
          ],
          "expect": {
            "returns": false
          },
          "note": "changed in 2.5.0 (#593): a voter ID has at most 12 digits (Resolução TSE nº 23.659/2021, art. 36), so a 13-digit value is rejected. 2.4.0 returned true. JavaScript's own test: should reject a 13-digit value, since a voter id has at most 12 digits"
        },
        {
          "id": "voterId.isValid#[\"000010191\"]",
          "args": [
            "000010191"
          ],
          "expect": {
            "returns": true
          },
          "note": "changed in 2.5.0 (#593): a value shorter than 12 digits is the ID without the leading zeros of its sequential number (Resolução TSE nº 23.659/2021, art. 36), so it is checked as 000000010191, which is valid. 2.4.0 required 12 or 13 digits and returned false. JavaScript's own test: should read a 9-digit value as the id without its leading zeros"
        },
        {
          "id": "voterId.isValid#[\"1234567890370\"]",
          "args": [
            "1234567890370"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should reject a value longer than 12 digits, even when its checksum would otherwise match"
        },
        {
          "id": "voterId.isValid#[\"000000002909\"]",
          "args": [
            "000000002909"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should reject the UF code boundaries 0 and 29, even when the checksum would otherwise match"
        },
        {
          "id": "voterId.isValid#[\"000000010191\"]",
          "args": [
            "000000010191"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should accept the UF code boundaries 1 and 28"
        },
        {
          "id": "voterId.isValid#[\"000000002801\"]",
          "args": [
            "000000002801"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should accept the UF code boundaries 1 and 28"
        },
        {
          "id": "voterId.isValid#[\"123450159\"]",
          "args": [
            "123450159"
          ],
          "expect": {
            "returns": true
          },
          "note": "changed in 2.5.0 (#593): checked as 000123450159. 2.4.0 returned false. JavaScript's own test: should accept a voter id issued without the leading zeros of its sequential number"
        },
        {
          "id": "voterId.isValid#[\"000123450159\"]",
          "args": [
            "000123450159"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should accept a voter id issued without the leading zeros of its sequential number"
        },
        {
          "id": "voterId.isValid#[\"00123450159\"]",
          "args": [
            "00123450159"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should accept a voter id issued without the leading zeros of its sequential number"
        },
        {
          "id": "voterId.isValid#[\"1 2345 01 59\"]",
          "args": [
            "1 2345 01 59"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should accept a voter id issued without the leading zeros of its sequential number"
        },
        {
          "id": "voterId.isValid#[\"12345 01 59\"]",
          "args": [
            "12345 01 59"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should accept a voter id issued without the leading zeros of its sequential number"
        },
        {
          "id": "voterId.isValid#[\"123450158\"]",
          "args": [
            "123450158"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should accept a voter id issued without the leading zeros of its sequential number (wrong check digit)"
        },
        {
          "id": "voterId.isValid#[\"122844\"]",
          "args": [
            "122844"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should accept a sequential number of every length from 1 to 8 digits once its zeros are dropped"
        },
        {
          "id": "voterId.isValid#[\"12340639\"]",
          "args": [
            "12340639"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should accept a sequential number of every length from 1 to 8 digits once its zeros are dropped"
        },
        {
          "id": "voterId.isValid#[\"1234 06 39\"]",
          "args": [
            "1234 06 39"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should accept a sequential number of every length from 1 to 8 digits once its zeros are dropped"
        },
        {
          "id": "voterId.isValid#[\"10191\"]",
          "args": [
            "10191"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should accept the shortest form, a single sequential digit, and nothing shorter"
        },
        {
          "id": "voterId.isValid#[\"000000000116\"]",
          "args": [
            "000000000116"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should accept the shortest form, a single sequential digit, and nothing shorter"
        },
        {
          "id": "voterId.isValid#[\"0116\"]",
          "args": [
            "0116"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should accept the shortest form, a single sequential digit, and nothing shorter"
        },
        {
          "id": "voterId.isValid#[\"0123456780191\"]",
          "args": [
            "0123456780191"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should reject a 13-digit value, since a voter id has at most 12 digits"
        },
        {
          "id": "voterId.isValid#[\"123456780191\"]",
          "args": [
            "123456780191"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should reject a 13-digit value, since a voter id has at most 12 digits"
        },
        {
          "id": "voterId.isValid#[\"0000000000191\"]",
          "args": [
            "0000000000191"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should reject a value longer than 12 digits, even when its checksum would otherwise match"
        },
        {
          "id": "voterId.isValid#[\"0001.2345.01.59\"]",
          "args": [
            "0001.2345.01.59"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should accept the documented whitespace and dot masks"
        },
        {
          "id": "voterId.isValid#[\"123 4567 01 91\"]",
          "args": [
            "123 4567 01 91"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should only accept separators between the groups of a sequential number grouped from the right"
        },
        {
          "id": "voterId.isValid#[\"1234 567 01 91\"]",
          "args": [
            "1234 567 01 91"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should only accept separators between the groups of a sequential number grouped from the right"
        },
        {
          "id": "voterId.isValid#[\"1234 5678 0 1 91\"]",
          "args": [
            "1234 5678 0 1 91"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should only accept separators between the groups of a sequential number grouped from the right"
        },
        {
          "id": "voterId.isValid#[\"1023-8501/06-71\"]",
          "args": [
            "1023-8501/06-71"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should accept the documented whitespace and dot masks"
        },
        {
          "id": "voterId.isValid#[\" 1023  8501 06 71 \"]",
          "args": [
            " 1023  8501 06 71 "
          ],
          "expect": {
            "returns": true
          },
          "note": "a run of whitespace around and between the groups is accepted"
        },
        {
          "id": "voterId.isValid#[\"1023_8501_06_71\"]",
          "args": [
            "1023_8501_06_71"
          ],
          "expect": {
            "returns": false
          },
          "note": "an underscore is not a mask character"
        },
        {
          "id": "voterId.isValid#[\"1023(8501)0671\"]",
          "args": [
            "1023(8501)0671"
          ],
          "expect": {
            "returns": false
          },
          "note": "parentheses are not mask characters"
        }
      ]
    },
    {
      "id": "voterId.parse",
      "level": "extended",
      "summary": "Removes the formatting characters of a voter ID and returns only the digits.",
      "description": "Removes voter ID formatting and keeps only digits, capped at 12 digits for every UF.\n\n- A voter ID has at most 12 digits (Resolução TSE nº 23.659/2021, art. 36). 2.4.0 kept 13 digits when the UF digits were SP or MG.\n- A shorter value is returned as it is, not padded. `voterId.isValid` accepts that form, and `voterId.format` with `pad` restores the zeros.\n- A number is read only when it is a safe non-negative integer. A negative, fractional, non-finite or unsafe number gives an empty string (2.4.0 read the digits of any number).",
      "params": [
        {
          "name": "value",
          "type": "string | number"
        }
      ],
      "returns": "string",
      "cases": [
        {
          "id": "voterId.parse#masked",
          "args": [
            "1234 5678 01 24"
          ],
          "expect": {
            "returns": "123456780124"
          }
        },
        {
          "id": "voterId.parse#unmasked",
          "args": [
            "123456780124"
          ],
          "expect": {
            "returns": "123456780124"
          }
        },
        {
          "id": "voterId.parse#empty",
          "args": [
            ""
          ],
          "expect": {
            "returns": ""
          }
        },
        {
          "id": "voterId.parse#13-digit-sp-mg",
          "args": [
            "1234 5678 8 01 91"
          ],
          "expect": {
            "returns": "123456788019"
          },
          "note": "changed in 2.5.0 (#593): 12 digits at most for every UF (Resolução TSE nº 23.659/2021, art. 36). 2.4.0 returned \"1234567880191\". JavaScript's own test: should keep 12 digits at most, São Paulo (01) and Minas Gerais (02) included"
        },
        {
          "id": "voterId.parse#[\"12345678032499\"]",
          "args": [
            "12345678032499"
          ],
          "expect": {
            "returns": "123456780324"
          },
          "note": "JavaScript's own test: should ignore digits after the voter id length (non SP/MG)"
        },
        {
          "id": "voterId.parse#[\"1234567880299\"]",
          "args": [
            "1234567880299"
          ],
          "expect": {
            "returns": "123456788029"
          },
          "note": "changed in 2.5.0 (#593): 12 digits at most for every UF (Resolução TSE nº 23.659/2021, art. 36). 2.4.0 returned \"1234567880299\". JavaScript's own test: should keep 12 digits at most, São Paulo (01) and Minas Gerais (02) included"
        },
        {
          "id": "voterId.parse#[\"123456788019199\"]",
          "args": [
            "123456788019199"
          ],
          "expect": {
            "returns": "123456788019"
          },
          "note": "changed in 2.5.0 (#593): 12 digits at most for every UF (Resolução TSE nº 23.659/2021, art. 36). 2.4.0 returned \"1234567880191\". JavaScript's own test: should keep 12 digits at most, São Paulo (01) and Minas Gerais (02) included"
        },
        {
          "id": "voterId.parse#[\"12345678905999\"]",
          "args": [
            "12345678905999"
          ],
          "expect": {
            "returns": "123456789059"
          },
          "note": "JavaScript's own test: should ignore digits after the 12-digit length when the 9th/10th digits are not SP/MG, even with extra digits"
        },
        {
          "id": "voterId.parse#[\"12345 01 59\"]",
          "args": [
            "12345 01 59"
          ],
          "expect": {
            "returns": "123450159"
          },
          "note": "JavaScript's own test: should keep a voter id issued without its leading zeros as it is"
        },
        {
          "id": "voterId.parse#[\"0001 2345 01 59\"]",
          "args": [
            "0001 2345 01 59"
          ],
          "expect": {
            "returns": "000123450159"
          },
          "note": "JavaScript's own test: should keep a voter id issued without its leading zeros as it is"
        },
        {
          "id": "voterId.parse#[-123456780124]",
          "args": [
            -123456780124
          ],
          "expect": {
            "returns": ""
          },
          "note": "changed in 2.5.0 (#593): a negative number gives an empty string. 2.4.0 returned \"123456780124\". JavaScript's own test: when it is a negative, fractional or unsafe number"
        },
        {
          "id": "voterId.parse#[1.5]",
          "args": [
            1.5
          ],
          "expect": {
            "returns": ""
          },
          "note": "JavaScript's own test: when it is a negative, fractional or unsafe number"
        },
        {
          "id": "voterId.parse#[123456780124]",
          "args": [
            123456780124
          ],
          "expect": {
            "returns": "123456780124"
          },
          "note": "a safe non-negative integer is read as before"
        }
      ]
    }
  ]
}
