@condorcet.vote/cef-writer 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +419 -0
  3. package/dist/Cef.d.ts +188 -0
  4. package/dist/Cef.d.ts.map +1 -0
  5. package/dist/Cef.js +291 -0
  6. package/dist/CefFormat.d.ts +57 -0
  7. package/dist/CefFormat.d.ts.map +1 -0
  8. package/dist/CefFormat.js +133 -0
  9. package/dist/CommentLine.d.ts +18 -0
  10. package/dist/CommentLine.d.ts.map +1 -0
  11. package/dist/CommentLine.js +27 -0
  12. package/dist/Exception/CefFormatException.d.ts +16 -0
  13. package/dist/Exception/CefFormatException.d.ts.map +1 -0
  14. package/dist/Exception/CefFormatException.js +19 -0
  15. package/dist/Exception/CefWriteException.d.ts +12 -0
  16. package/dist/Exception/CefWriteException.d.ts.map +1 -0
  17. package/dist/Exception/CefWriteException.js +13 -0
  18. package/dist/Exception/DuplicateCandidateException.d.ts +9 -0
  19. package/dist/Exception/DuplicateCandidateException.d.ts.map +1 -0
  20. package/dist/Exception/DuplicateCandidateException.js +8 -0
  21. package/dist/Exception/InvalidUtf8Exception.d.ts +13 -0
  22. package/dist/Exception/InvalidUtf8Exception.d.ts.map +1 -0
  23. package/dist/Exception/InvalidUtf8Exception.js +12 -0
  24. package/dist/Exception/InvalidValueException.d.ts +15 -0
  25. package/dist/Exception/InvalidValueException.d.ts.map +1 -0
  26. package/dist/Exception/InvalidValueException.js +14 -0
  27. package/dist/Exception/InvalidWriterStateException.d.ts +14 -0
  28. package/dist/Exception/InvalidWriterStateException.d.ts.map +1 -0
  29. package/dist/Exception/InvalidWriterStateException.js +13 -0
  30. package/dist/Exception/ReservedCharacterException.d.ts +12 -0
  31. package/dist/Exception/ReservedCharacterException.d.ts.map +1 -0
  32. package/dist/Exception/ReservedCharacterException.js +11 -0
  33. package/dist/Exception/index.d.ts +8 -0
  34. package/dist/Exception/index.d.ts.map +1 -0
  35. package/dist/Exception/index.js +7 -0
  36. package/dist/FileWriteTarget.d.ts +27 -0
  37. package/dist/FileWriteTarget.d.ts.map +1 -0
  38. package/dist/FileWriteTarget.js +35 -0
  39. package/dist/Parameter/CandidatesParameter.d.ts +20 -0
  40. package/dist/Parameter/CandidatesParameter.d.ts.map +1 -0
  41. package/dist/Parameter/CandidatesParameter.js +39 -0
  42. package/dist/Parameter/CustomParameter.d.ts +19 -0
  43. package/dist/Parameter/CustomParameter.d.ts.map +1 -0
  44. package/dist/Parameter/CustomParameter.js +35 -0
  45. package/dist/Parameter/ImplicitRankingParameter.d.ts +11 -0
  46. package/dist/Parameter/ImplicitRankingParameter.d.ts.map +1 -0
  47. package/dist/Parameter/ImplicitRankingParameter.js +16 -0
  48. package/dist/Parameter/NumberOfSeatsParameter.d.ts +14 -0
  49. package/dist/Parameter/NumberOfSeatsParameter.d.ts.map +1 -0
  50. package/dist/Parameter/NumberOfSeatsParameter.js +23 -0
  51. package/dist/Parameter/ParameterInterface.d.ts +20 -0
  52. package/dist/Parameter/ParameterInterface.d.ts.map +1 -0
  53. package/dist/Parameter/ParameterInterface.js +1 -0
  54. package/dist/Parameter/StandardParameter.d.ts +14 -0
  55. package/dist/Parameter/StandardParameter.d.ts.map +1 -0
  56. package/dist/Parameter/StandardParameter.js +14 -0
  57. package/dist/Parameter/VotingMethodsParameter.d.ts +16 -0
  58. package/dist/Parameter/VotingMethodsParameter.d.ts.map +1 -0
  59. package/dist/Parameter/VotingMethodsParameter.js +29 -0
  60. package/dist/Parameter/WeightAllowedParameter.d.ts +11 -0
  61. package/dist/Parameter/WeightAllowedParameter.d.ts.map +1 -0
  62. package/dist/Parameter/WeightAllowedParameter.js +16 -0
  63. package/dist/Parameter/index.d.ts +9 -0
  64. package/dist/Parameter/index.d.ts.map +1 -0
  65. package/dist/Parameter/index.js +7 -0
  66. package/dist/Ranking.d.ts +91 -0
  67. package/dist/Ranking.d.ts.map +1 -0
  68. package/dist/Ranking.js +162 -0
  69. package/dist/VoteLine.d.ts +156 -0
  70. package/dist/VoteLine.d.ts.map +1 -0
  71. package/dist/VoteLine.js +289 -0
  72. package/dist/index.browser.d.ts +17 -0
  73. package/dist/index.browser.d.ts.map +1 -0
  74. package/dist/index.browser.js +16 -0
  75. package/dist/index.d.ts +8 -0
  76. package/dist/index.d.ts.map +1 -0
  77. package/dist/index.js +7 -0
  78. package/dist/index.node.d.ts +19 -0
  79. package/dist/index.node.d.ts.map +1 -0
  80. package/dist/index.node.js +25 -0
  81. package/package.json +79 -0
  82. package/src/Cef.ts +405 -0
  83. package/src/CefFormat.ts +152 -0
  84. package/src/CommentLine.ts +32 -0
  85. package/src/Exception/CefFormatException.ts +19 -0
  86. package/src/Exception/CefWriteException.ts +13 -0
  87. package/src/Exception/DuplicateCandidateException.ts +8 -0
  88. package/src/Exception/InvalidUtf8Exception.ts +12 -0
  89. package/src/Exception/InvalidValueException.ts +14 -0
  90. package/src/Exception/InvalidWriterStateException.ts +13 -0
  91. package/src/Exception/ReservedCharacterException.ts +11 -0
  92. package/src/Exception/index.ts +7 -0
  93. package/src/FileWriteTarget.ts +42 -0
  94. package/src/Parameter/CandidatesParameter.ts +49 -0
  95. package/src/Parameter/CustomParameter.ts +45 -0
  96. package/src/Parameter/ImplicitRankingParameter.ts +17 -0
  97. package/src/Parameter/NumberOfSeatsParameter.ts +25 -0
  98. package/src/Parameter/ParameterInterface.ts +20 -0
  99. package/src/Parameter/StandardParameter.ts +13 -0
  100. package/src/Parameter/VotingMethodsParameter.ts +36 -0
  101. package/src/Parameter/WeightAllowedParameter.ts +17 -0
  102. package/src/Parameter/index.ts +8 -0
  103. package/src/Ranking.ts +197 -0
  104. package/src/VoteLine.ts +398 -0
  105. package/src/index.browser.ts +36 -0
  106. package/src/index.node.ts +47 -0
  107. package/src/index.ts +8 -0
@@ -0,0 +1,91 @@
1
+ /**
2
+ * An ordered ranking of candidates.
3
+ *
4
+ * The ranking is expressed as an ordered list of ranks; each rank is itself a
5
+ * list of candidate names tied at that position. An empty top-level ranking
6
+ * (`[]`) renders as the `/EMPTY_RANKING/` blank-ballot sentinel.
7
+ *
8
+ * A `Ranking` is immutable and self-validating: any specification violation
9
+ * (reserved character, empty rank, duplicate candidate) throws a
10
+ * {@link CefFormatException} at construction time. Render it to a CEF string
11
+ * with {@link format} (or by casting to `string` via {@link toString}).
12
+ */
13
+ export declare class Ranking {
14
+ readonly ranks: readonly (readonly string[])[];
15
+ /**
16
+ * @param ranks Ordered ranks; each inner list is non-empty. Pass `[]` for
17
+ * the `/EMPTY_RANKING/` blank ballot.
18
+ *
19
+ * @throws {CefFormatException} on any specification violation
20
+ */
21
+ constructor(ranks: readonly (readonly string[])[]);
22
+ /**
23
+ * Build a {@link Ranking} from a ranking-only string.
24
+ *
25
+ * The string may contain candidate names joined by the `>` (rank) and `=`
26
+ * (tie) operators, or the `/EMPTY_RANKING/` sentinel. Any reserved character
27
+ * (`^`, `*`, `#`, `;`, `,`, `/`), the `||` tag separator, or a line break is
28
+ * rejected — there is no way to smuggle a weight, quantifier, tag or inline
29
+ * comment through the string.
30
+ *
31
+ * @param ranking Ranking only, e.g. `"A > B = C"` or `"/EMPTY_RANKING/"`.
32
+ *
33
+ * @throws {CefFormatException}
34
+ */
35
+ static fromString(ranking: string): Ranking;
36
+ /**
37
+ * Validate a ranking-only string without allocating a {@link Ranking}.
38
+ *
39
+ * Runs the exact same checks as {@link fromString} (empty input, `||` tag
40
+ * separator, reserved characters, line breaks, duplicate candidates) but
41
+ * never materialises the parsed structure nor a `Ranking` instance — useful
42
+ * for hot paths that write the ranking string verbatim after a strict format
43
+ * check.
44
+ *
45
+ * @param ranking Ranking only, e.g. `"A > B = C"` or `"/EMPTY_RANKING/"`.
46
+ *
47
+ * @throws {CefFormatException}
48
+ */
49
+ static assertValidString(ranking: string): void;
50
+ /**
51
+ * Trim a ranking-only string and reject the two patterns that the
52
+ * per-candidate validation cannot catch on its own: an empty input and the
53
+ * `||` tag separator. Returns the trimmed work string.
54
+ *
55
+ * @throws {CefFormatException}
56
+ */
57
+ private static normalizeString;
58
+ /**
59
+ * Render the ranking — *without* trailing newline, tags, weight, quantifier
60
+ * or inline comment — using the spacing flavor selected by `autoFormat`.
61
+ *
62
+ * When `autoFormat` is `true` (default), ranks are separated by `" > "` and
63
+ * tied candidates by `" = "`; when `false`, the most compact `>` / `=` form
64
+ * is emitted. An empty ranking yields the `/EMPTY_RANKING/` sentinel.
65
+ */
66
+ format(autoFormat?: boolean): string;
67
+ /**
68
+ * Render the ranking in its relaxed (auto-formatted) flavor.
69
+ */
70
+ toString(): string;
71
+ /**
72
+ * Split a cleaned ranking string into its raw, *un-validated* rank/tie
73
+ * structure. The `/EMPTY_RANKING/` sentinel maps to an empty list. Ranks are
74
+ * separated by `>`, tied candidates within a rank by `=`; every token is
75
+ * trimmed but not otherwise checked here.
76
+ */
77
+ private static split;
78
+ /**
79
+ * @throws {CefFormatException}
80
+ */
81
+ private static validate;
82
+ /**
83
+ * Trim and validate a single candidate name, rejecting reserved characters,
84
+ * line breaks, invalid UTF-8 and duplicates. The `seen` set is updated to
85
+ * detect repeats across the whole ranking.
86
+ *
87
+ * @throws {CefFormatException}
88
+ */
89
+ private static assertCandidate;
90
+ }
91
+ //# sourceMappingURL=Ranking.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Ranking.d.ts","sourceRoot":"","sources":["../src/Ranking.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;GAWG;AACH,qBAAa,OAAO;IAClB,SAAgB,KAAK,EAAE,SAAS,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,CAAC;IAEtD;;;;;OAKG;gBACgB,KAAK,EAAE,SAAS,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE;IAIxD;;;;;;;;;;;;OAYG;WACW,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAIlD;;;;;;;;;;;;OAYG;WACW,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAgBtD;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,eAAe;IAkB9B;;;;;;;OAOG;IACI,MAAM,CAAC,UAAU,UAAO,GAAG,MAAM;IAWxC;;OAEG;IACI,QAAQ,IAAI,MAAM;IAIzB;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,KAAK;IAoBpB;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ;IAqBvB;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,eAAe;CAc/B"}
@@ -0,0 +1,162 @@
1
+ import { CefFormat } from './CefFormat';
2
+ import { DuplicateCandidateException, InvalidValueException } from './Exception';
3
+ /**
4
+ * An ordered ranking of candidates.
5
+ *
6
+ * The ranking is expressed as an ordered list of ranks; each rank is itself a
7
+ * list of candidate names tied at that position. An empty top-level ranking
8
+ * (`[]`) renders as the `/EMPTY_RANKING/` blank-ballot sentinel.
9
+ *
10
+ * A `Ranking` is immutable and self-validating: any specification violation
11
+ * (reserved character, empty rank, duplicate candidate) throws a
12
+ * {@link CefFormatException} at construction time. Render it to a CEF string
13
+ * with {@link format} (or by casting to `string` via {@link toString}).
14
+ */
15
+ export class Ranking {
16
+ ranks;
17
+ /**
18
+ * @param ranks Ordered ranks; each inner list is non-empty. Pass `[]` for
19
+ * the `/EMPTY_RANKING/` blank ballot.
20
+ *
21
+ * @throws {CefFormatException} on any specification violation
22
+ */
23
+ constructor(ranks) {
24
+ this.ranks = Ranking.validate(ranks);
25
+ }
26
+ /**
27
+ * Build a {@link Ranking} from a ranking-only string.
28
+ *
29
+ * The string may contain candidate names joined by the `>` (rank) and `=`
30
+ * (tie) operators, or the `/EMPTY_RANKING/` sentinel. Any reserved character
31
+ * (`^`, `*`, `#`, `;`, `,`, `/`), the `||` tag separator, or a line break is
32
+ * rejected — there is no way to smuggle a weight, quantifier, tag or inline
33
+ * comment through the string.
34
+ *
35
+ * @param ranking Ranking only, e.g. `"A > B = C"` or `"/EMPTY_RANKING/"`.
36
+ *
37
+ * @throws {CefFormatException}
38
+ */
39
+ static fromString(ranking) {
40
+ return new Ranking(Ranking.split(Ranking.normalizeString(ranking)));
41
+ }
42
+ /**
43
+ * Validate a ranking-only string without allocating a {@link Ranking}.
44
+ *
45
+ * Runs the exact same checks as {@link fromString} (empty input, `||` tag
46
+ * separator, reserved characters, line breaks, duplicate candidates) but
47
+ * never materialises the parsed structure nor a `Ranking` instance — useful
48
+ * for hot paths that write the ranking string verbatim after a strict format
49
+ * check.
50
+ *
51
+ * @param ranking Ranking only, e.g. `"A > B = C"` or `"/EMPTY_RANKING/"`.
52
+ *
53
+ * @throws {CefFormatException}
54
+ */
55
+ static assertValidString(ranking) {
56
+ const work = Ranking.normalizeString(ranking);
57
+ if (work === CefFormat.EMPTY_RANKING) {
58
+ return;
59
+ }
60
+ const seen = new Set();
61
+ for (const rankString of work.split('>')) {
62
+ for (const candidate of rankString.split('=')) {
63
+ Ranking.assertCandidate(candidate, seen);
64
+ }
65
+ }
66
+ }
67
+ /**
68
+ * Trim a ranking-only string and reject the two patterns that the
69
+ * per-candidate validation cannot catch on its own: an empty input and the
70
+ * `||` tag separator. Returns the trimmed work string.
71
+ *
72
+ * @throws {CefFormatException}
73
+ */
74
+ static normalizeString(ranking) {
75
+ const work = ranking.trim();
76
+ if (work === '') {
77
+ throw new InvalidValueException('Ranking string cannot be empty; use "/EMPTY_RANKING/" for a blank ballot.');
78
+ }
79
+ // The "||" tag separator is the only forbidden pattern that per-candidate
80
+ // validation would not catch on its own ("|" is not a reserved character),
81
+ // so reject it explicitly here. Every reserved character and line break is
82
+ // rejected later, candidate by candidate.
83
+ CefFormat.assertNoTagSeparator(work, 'Ranking');
84
+ return work;
85
+ }
86
+ /**
87
+ * Render the ranking — *without* trailing newline, tags, weight, quantifier
88
+ * or inline comment — using the spacing flavor selected by `autoFormat`.
89
+ *
90
+ * When `autoFormat` is `true` (default), ranks are separated by `" > "` and
91
+ * tied candidates by `" = "`; when `false`, the most compact `>` / `=` form
92
+ * is emitted. An empty ranking yields the `/EMPTY_RANKING/` sentinel.
93
+ */
94
+ format(autoFormat = true) {
95
+ if (this.ranks.length === 0) {
96
+ return CefFormat.EMPTY_RANKING;
97
+ }
98
+ const rankSep = autoFormat ? ' > ' : '>';
99
+ const tieSep = autoFormat ? ' = ' : '=';
100
+ return this.ranks.map((rank) => rank.join(tieSep)).join(rankSep);
101
+ }
102
+ /**
103
+ * Render the ranking in its relaxed (auto-formatted) flavor.
104
+ */
105
+ toString() {
106
+ return this.format();
107
+ }
108
+ /**
109
+ * Split a cleaned ranking string into its raw, *un-validated* rank/tie
110
+ * structure. The `/EMPTY_RANKING/` sentinel maps to an empty list. Ranks are
111
+ * separated by `>`, tied candidates within a rank by `=`; every token is
112
+ * trimmed but not otherwise checked here.
113
+ */
114
+ static split(work) {
115
+ if (work === CefFormat.EMPTY_RANKING) {
116
+ return [];
117
+ }
118
+ const rawRanking = [];
119
+ for (const rankString of work.split('>')) {
120
+ const rank = [];
121
+ for (const candidate of rankString.split('=')) {
122
+ rank.push(candidate.trim());
123
+ }
124
+ rawRanking.push(rank);
125
+ }
126
+ return rawRanking;
127
+ }
128
+ /**
129
+ * @throws {CefFormatException}
130
+ */
131
+ static validate(ranks) {
132
+ const cleaned = [];
133
+ const seen = new Set();
134
+ ranks.forEach((rank, rankIndex) => {
135
+ if (rank.length === 0) {
136
+ throw new InvalidValueException(`Rank #${String(rankIndex + 1)} is empty.`);
137
+ }
138
+ const cleanedRank = [];
139
+ for (const candidate of rank) {
140
+ cleanedRank.push(Ranking.assertCandidate(candidate, seen));
141
+ }
142
+ cleaned.push(cleanedRank);
143
+ });
144
+ return cleaned;
145
+ }
146
+ /**
147
+ * Trim and validate a single candidate name, rejecting reserved characters,
148
+ * line breaks, invalid UTF-8 and duplicates. The `seen` set is updated to
149
+ * detect repeats across the whole ranking.
150
+ *
151
+ * @throws {CefFormatException}
152
+ */
153
+ static assertCandidate(candidate, seen) {
154
+ const trimmed = candidate.trim();
155
+ CefFormat.assertValueIsClean(trimmed, 'Ranked candidate');
156
+ if (seen.has(trimmed)) {
157
+ throw new DuplicateCandidateException(`Candidate "${trimmed}" appears more than once in the ranking.`);
158
+ }
159
+ seen.add(trimmed);
160
+ return trimmed;
161
+ }
162
+ }
@@ -0,0 +1,156 @@
1
+ import { Ranking } from './Ranking';
2
+ /**
3
+ * A single ballot.
4
+ *
5
+ * Instances are never built with `new`: use one of the static named
6
+ * constructors — {@link fromRanking} (typed ranks or a {@link Ranking}),
7
+ * {@link fromString} (a full CEF vote-line string), or
8
+ * {@link fromRawRankingString} (a pre-validated *verbatim* ranking string).
9
+ *
10
+ * The ranking is held as a {@link Ranking} value object on {@link ranking}. An
11
+ * empty ranking renders as the `/EMPTY_RANKING/` blank-ballot sentinel. In the
12
+ * verbatim mode the ranking string is written untouched and is *not* parsed,
13
+ * so {@link ranking} is `null`.
14
+ *
15
+ * Optional companions:
16
+ * - `tags` — labels separated by `,`, appended before `||`;
17
+ * - `weight` — strictly positive integer; only meaningful when the
18
+ * `Weight Allowed` parameter is enabled in the document;
19
+ * - `quantifier` — strictly positive integer that collapses identical
20
+ * votes onto a single line;
21
+ * - `inlineComment` — free-form trailing comment introduced by `#`.
22
+ */
23
+ export declare class VoteLine {
24
+ /**
25
+ * The parsed ranking, or `null` when the ballot was built from a verbatim
26
+ * ranking string via {@link fromRawRankingString} — in that mode the ranking
27
+ * is deliberately *not* parsed into a {@link Ranking} structure.
28
+ */
29
+ readonly ranking: Ranking | null;
30
+ /**
31
+ * Verbatim, pre-validated ranking string written to the output untouched.
32
+ * Set only in the {@link fromRawRankingString} mode; `null` otherwise (when
33
+ * {@link ranking} carries the parsed structure instead).
34
+ */
35
+ private readonly rawRanking;
36
+ readonly tags: readonly string[];
37
+ readonly weight: number | null;
38
+ readonly quantifier: number | null;
39
+ readonly inlineComment: string | null;
40
+ /**
41
+ * @internal Use a static named constructor instead: {@link fromRanking},
42
+ * {@link fromString} or {@link fromRawRankingString}.
43
+ *
44
+ * @throws {CefFormatException} on any specification violation
45
+ */
46
+ private constructor();
47
+ /**
48
+ * Build a {@link VoteLine} from typed ranks or a ready-made {@link Ranking}.
49
+ *
50
+ * This is the primary, typed constructor. The `ranking` argument is either an
51
+ * ordered list of ranks (each inner list a non-empty group of tied
52
+ * candidates; pass `[]` for the `/EMPTY_RANKING/` blank ballot) or a
53
+ * {@link Ranking} value object.
54
+ *
55
+ * @throws {CefFormatException} on any specification violation
56
+ */
57
+ static fromRanking(ranking: readonly (readonly string[])[] | Ranking, options?: {
58
+ tags?: readonly string[];
59
+ weight?: number | null;
60
+ quantifier?: number | null;
61
+ inlineComment?: string | null;
62
+ }): VoteLine;
63
+ /**
64
+ * Build a {@link VoteLine} from a raw CEF vote-line string.
65
+ *
66
+ * Accepted shape — every component except the ranking is optional:
67
+ *
68
+ * [tag1, tag2 || ] ranking [ ^weight] [ *quantifier] [# comment]
69
+ *
70
+ * Both the relaxed and the compact spacing flavors are accepted, e.g.
71
+ * `"A>B^7*2"` and `"A > B ^7 * 2"` parse identically. The `/EMPTY_RANKING/`
72
+ * sentinel is recognised as a blank ballot.
73
+ *
74
+ * The string is parsed into its components; the resulting `VoteLine` is then
75
+ * constructed through the normal constructor, so every validation rule
76
+ * (reserved characters, empty rank, duplicate candidate, positive weight /
77
+ * quantifier) applies.
78
+ *
79
+ * @throws {CefFormatException}
80
+ */
81
+ static fromString(line: string): VoteLine;
82
+ /**
83
+ * Validate that `line` is a syntactically valid CEF vote line, without
84
+ * allocating a `VoteLine` instance.
85
+ *
86
+ * The exact same parsing and validation pipeline that {@link fromString} uses
87
+ * is applied — only the final object construction is skipped. Useful for hot
88
+ * paths that want to write a pre-built line straight to the output after a
89
+ * strict format check.
90
+ *
91
+ * @throws {CefFormatException}
92
+ */
93
+ static assertValidString(line: string): void;
94
+ /**
95
+ * Build a {@link VoteLine} from a ranking-only string, kept *verbatim*.
96
+ *
97
+ * The special, allocation-light sibling of {@link fromRanking}: the ranking
98
+ * string is validated as a ranking and *nothing else* — any reserved
99
+ * character (`^`, `*`, `#`, `;`, `,`, `/`), the `||` tag separator, or a line
100
+ * break is rejected, so it cannot smuggle a weight, quantifier, tag or inline
101
+ * comment — but it is **not** parsed into a {@link Ranking}. The string is
102
+ * stored as-is and written untouched by {@link format} (only the
103
+ * library-built companions — the `||` separator, `^weight`, `*quantifier` —
104
+ * follow `autoFormat`). The resulting instance therefore has a `null`
105
+ * {@link ranking}. Used by `Cef.addRawVote()`.
106
+ *
107
+ * @throws {CefFormatException}
108
+ */
109
+ static fromRawRankingString(ranking: string, options?: {
110
+ tags?: readonly string[];
111
+ weight?: number | null;
112
+ quantifier?: number | null;
113
+ }): VoteLine;
114
+ /**
115
+ * Shared parser+validator used by {@link fromString} and
116
+ * {@link assertValidString}.
117
+ *
118
+ * Trims the input, extracts every component, and runs the same per-field
119
+ * validation (reserved characters, empty rank, duplicate candidate, positive
120
+ * weight / quantifier, single-line comment) that the constructor performs.
121
+ * Returns the components.
122
+ *
123
+ * @throws {CefFormatException}
124
+ */
125
+ private static parseStringComponents;
126
+ /**
127
+ * Render the ballot — *without* trailing newline or inline comment — using
128
+ * the spacing flavor selected by `autoFormat`.
129
+ */
130
+ format(autoFormat?: boolean): string;
131
+ /**
132
+ * Return the ranking part of the line: the verbatim string in raw mode, or
133
+ * the parsed ranking rendered with `autoFormat` otherwise.
134
+ */
135
+ private renderRanking;
136
+ /**
137
+ * Reject a non-null, non-positive weight or quantifier.
138
+ *
139
+ * @throws {CefFormatException}
140
+ */
141
+ private static assertCompanions;
142
+ /**
143
+ * Wrap a ranking string with the tag prefix and the weight / quantifier
144
+ * suffix, using the spacing flavor selected by `autoFormat`.
145
+ */
146
+ private assembleLine;
147
+ /**
148
+ * @throws {CefFormatException}
149
+ */
150
+ private static validateTags;
151
+ /**
152
+ * Strip trailing whitespace, mirroring PHP's `rtrim()`.
153
+ */
154
+ private static rtrim;
155
+ }
156
+ //# sourceMappingURL=VoteLine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VoteLine.d.ts","sourceRoot":"","sources":["../src/VoteLine.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAapC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,QAAQ;IACnB;;;;OAIG;IACH,SAAgB,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IAExC;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgB;IAE3C,SAAgB,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IAExC,SAAgB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAEtC,SAAgB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAE1C,SAAgB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAE7C;;;;;OAKG;IACH,OAAO;IAwCP;;;;;;;;;OASG;WACW,WAAW,CACvB,OAAO,EAAE,SAAS,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,GAAG,OAAO,EACjD,OAAO,GAAE;QACP,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QACzB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC1B,GACL,QAAQ;IAWX;;;;;;;;;;;;;;;;;OAiBG;WACW,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ;IAahD;;;;;;;;;;OAUG;WACW,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAInD;;;;;;;;;;;;;;OAcG;WACW,oBAAoB,CAChC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;QACP,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QACzB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KACvB,GACL,QAAQ;IAUX;;;;;;;;;;OAUG;IACH,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAgFpC;;;OAGG;IACI,MAAM,CAAC,UAAU,UAAO,GAAG,MAAM;IAIxC;;;OAGG;IACH,OAAO,CAAC,aAAa;IAcrB;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAU/B;;;OAGG;IACH,OAAO,CAAC,YAAY;IAsBpB;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,YAAY;IAkB3B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,KAAK;CAGrB"}