@jjlmoya/utils-civic 1.1.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.
- package/.github/workflows/npm-publish.yml +40 -0
- package/.gitignore +6 -0
- package/.stylelintrc.json +98 -0
- package/astro.config.mjs +19 -0
- package/eslint.config.js +201 -0
- package/package.json +79 -0
- package/prompts/create_tool.md +98 -0
- package/prompts/i18n/de.md +16 -0
- package/prompts/i18n/en.md +16 -0
- package/prompts/i18n/es.md +16 -0
- package/prompts/i18n/fr.md +16 -0
- package/prompts/i18n/id.md +16 -0
- package/prompts/i18n/it.md +16 -0
- package/prompts/i18n/ja.md +16 -0
- package/prompts/i18n/ko.md +16 -0
- package/prompts/i18n/nl.md +16 -0
- package/prompts/i18n/pl.md +16 -0
- package/prompts/i18n/pt.md +16 -0
- package/prompts/i18n/ru.md +16 -0
- package/prompts/i18n/sv.md +16 -0
- package/prompts/i18n/tr.md +16 -0
- package/prompts/i18n/zh.md +16 -0
- package/prompts/seo.md +58 -0
- package/prompts/translations/french.md +33 -0
- package/scripts/postinstall.mjs +27 -0
- package/src/category/CivicCategorySEO.astro +9 -0
- package/src/category/i18n/de.ts +21 -0
- package/src/category/i18n/en.ts +25 -0
- package/src/category/i18n/es.ts +21 -0
- package/src/category/i18n/fr.ts +21 -0
- package/src/category/i18n/id.ts +21 -0
- package/src/category/i18n/it.ts +21 -0
- package/src/category/i18n/ja.ts +21 -0
- package/src/category/i18n/ko.ts +21 -0
- package/src/category/i18n/nl.ts +21 -0
- package/src/category/i18n/pl.ts +21 -0
- package/src/category/i18n/pt.ts +21 -0
- package/src/category/i18n/ru.ts +21 -0
- package/src/category/i18n/sv.ts +21 -0
- package/src/category/i18n/tr.ts +21 -0
- package/src/category/i18n/zh.ts +21 -0
- package/src/category/index.ts +24 -0
- package/src/components/PreviewNavSidebar.astro +116 -0
- package/src/components/PreviewToolbar.astro +143 -0
- package/src/data.ts +10 -0
- package/src/entries.ts +9 -0
- package/src/env.d.ts +5 -0
- package/src/index.ts +20 -0
- package/src/layouts/PreviewLayout.astro +117 -0
- package/src/pages/[locale]/[slug].astro +163 -0
- package/src/pages/[locale].astro +253 -0
- package/src/pages/index.astro +4 -0
- package/src/tests/bibliography_wellformed_export.test.ts +46 -0
- package/src/tests/category_seo_quality.test.ts +79 -0
- package/src/tests/diacritics_density.test.ts +118 -0
- package/src/tests/faq_count.test.ts +18 -0
- package/src/tests/i18n_coverage.test.ts +34 -0
- package/src/tests/inverted_punctuation.test.ts +84 -0
- package/src/tests/locale_completeness.test.ts +23 -0
- package/src/tests/mocks/astro_mock.js +2 -0
- package/src/tests/no_em_dash.test.ts +47 -0
- package/src/tests/no_en_dash.test.ts +70 -0
- package/src/tests/no_h1_in_components.test.ts +48 -0
- package/src/tests/pagespeed_best_practices.test.ts +198 -0
- package/src/tests/qa-test-helpers.ts +31 -0
- package/src/tests/qa_bibliography_links.test.ts +53 -0
- package/src/tests/qa_claim_evidence.test.ts +68 -0
- package/src/tests/qa_logic_reference_coverage.test.ts +45 -0
- package/src/tests/qa_runtime_i18n.test.ts +100 -0
- package/src/tests/registry_contract.test.ts +67 -0
- package/src/tests/schemas_fulfillment.test.ts +23 -0
- package/src/tests/script_density.test.ts +94 -0
- package/src/tests/seo_length.test.ts +23 -0
- package/src/tests/seo_parity.test.ts +60 -0
- package/src/tests/seo_translation_completeness.test.ts +75 -0
- package/src/tests/seo_wellformed_export.test.ts +65 -0
- package/src/tests/shared-test-helpers.ts +56 -0
- package/src/tests/slug_language_code_format.test.ts +23 -0
- package/src/tests/slug_uniqueness.test.ts +81 -0
- package/src/tests/spanish_leakage.test.ts +175 -0
- package/src/tests/title_quality.test.ts +55 -0
- package/src/tests/tool_exports.test.ts +34 -0
- package/src/tests/tool_validation.test.ts +16 -0
- package/src/tests/translation_copy.test.ts +123 -0
- package/src/tool/election-seat-apportionment-calculator/bibliography.astro +6 -0
- package/src/tool/election-seat-apportionment-calculator/bibliography.ts +16 -0
- package/src/tool/election-seat-apportionment-calculator/component.astro +69 -0
- package/src/tool/election-seat-apportionment-calculator/controller.ts +181 -0
- package/src/tool/election-seat-apportionment-calculator/dom-views.ts +75 -0
- package/src/tool/election-seat-apportionment-calculator/election-seat-apportionment-calculator.css +585 -0
- package/src/tool/election-seat-apportionment-calculator/entry.ts +28 -0
- package/src/tool/election-seat-apportionment-calculator/evaluator.ts +20 -0
- package/src/tool/election-seat-apportionment-calculator/i18n/de.ts +55 -0
- package/src/tool/election-seat-apportionment-calculator/i18n/en.ts +108 -0
- package/src/tool/election-seat-apportionment-calculator/i18n/es.ts +50 -0
- package/src/tool/election-seat-apportionment-calculator/i18n/fr.ts +48 -0
- package/src/tool/election-seat-apportionment-calculator/i18n/id.ts +48 -0
- package/src/tool/election-seat-apportionment-calculator/i18n/it.ts +48 -0
- package/src/tool/election-seat-apportionment-calculator/i18n/ja.ts +48 -0
- package/src/tool/election-seat-apportionment-calculator/i18n/ko.ts +48 -0
- package/src/tool/election-seat-apportionment-calculator/i18n/nl.ts +48 -0
- package/src/tool/election-seat-apportionment-calculator/i18n/pl.ts +48 -0
- package/src/tool/election-seat-apportionment-calculator/i18n/pt.ts +48 -0
- package/src/tool/election-seat-apportionment-calculator/i18n/ru.ts +48 -0
- package/src/tool/election-seat-apportionment-calculator/i18n/sv.ts +48 -0
- package/src/tool/election-seat-apportionment-calculator/i18n/tr.ts +48 -0
- package/src/tool/election-seat-apportionment-calculator/i18n/zh.ts +48 -0
- package/src/tool/election-seat-apportionment-calculator/index.ts +11 -0
- package/src/tool/election-seat-apportionment-calculator/logic.test.ts +90 -0
- package/src/tool/election-seat-apportionment-calculator/logic.ts +268 -0
- package/src/tool/election-seat-apportionment-calculator/seo.astro +14 -0
- package/src/tool/election-seat-apportionment-calculator/sharing.test.ts +34 -0
- package/src/tool/election-seat-apportionment-calculator/sharing.ts +88 -0
- package/src/tool/election-seat-apportionment-calculator/storage.ts +28 -0
- package/src/tool/election-seat-apportionment-calculator/ui.ts +92 -0
- package/src/tools.ts +7 -0
- package/src/types.ts +69 -0
- package/tsconfig.json +15 -0
- package/vitest.config.ts +20 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import { bibliography } from '../bibliography';
|
|
4
|
+
import type { ElectionSeatLocaleContent } from '../entry';
|
|
5
|
+
import type { ElectionSeatUI } from '../ui';
|
|
6
|
+
|
|
7
|
+
const ui: ElectionSeatUI = {
|
|
8
|
+
allocationTitle: 'Sitzverteilung',
|
|
9
|
+
eventsTitle: 'Die nächsten Sitze werden hier entschieden',
|
|
10
|
+
sensitivityTitle: 'Was sich an der Schwelle ändert',
|
|
11
|
+
methodLabel: 'Verteilungsmethode', dhondtLabel: 'D\'Hondt mit Höchstzahlen', sainteLagueLabel: 'Sainte-Laguë mit Höchstzahlen', hareLabel: 'Hare-Quote und größte Reste',
|
|
12
|
+
partiesLabel: 'Stimmen nach Partei oder Liste', partyNameLabel: 'Name der Partei oder Liste', votesLabel: 'Stimmen', addParty: 'Partei hinzufügen', removeParty: 'Partei entfernen',
|
|
13
|
+
shareResult: 'Link zum Teilen kopieren', shareCopied: 'Link zum Teilen kopiert.', shareCopyFallback: 'Link zum Teilen aus dem Dialog kopieren.', invalidSharedResult: 'Dieser geteilte Ergebnislink ist ungültig. Das Beispiel wird angezeigt.',
|
|
14
|
+
totalSeatsLabel: 'Zu verteilende Sitze', thresholdLabel: 'Sperrklausel', districtsLabel: 'Optionale Wahlkreisgruppen', districtsHelp: 'Sitzanzahlen durch Kommas trennen. Das Modell verwendet in jedem Wahlkreis dasselbe Stimmenprofil.', districtsPlaceholder: 'Beispiel: 10, 8, 7', reset: 'Beispiel zurücksetzen',
|
|
15
|
+
allocatedSeatsLabel: 'Verteilte Sitze', voteShareLabel: 'Stimmenanteil', seatShareLabel: 'Sitzanteil', excludedLabel: 'Wegen Schwelle ausgeschlossen', chamberLabel: 'Sitzverteilung', quotientLabel: 'Quotient', remainderLabel: 'Rest', eventLabel: 'Reihenfolge der Sitzvergabe', eligibleVotesLabel: 'Berücksichtigte Stimmen', excludedVotesLabel: 'Ausgeschlossene Stimmen', effectiveThresholdLabel: 'Beobachtete Sitzschwelle', sensitivityLabel: 'Schwellenempfindlichkeit', lowerThresholdLabel: 'Bei Schwelle minus 1 Punkt', higherThresholdLabel: 'Bei Schwelle plus 1 Punkt', changedLabel: 'Geänderte Sitze', noChangesLabel: 'Keine Sitzänderung in diesem Test', districtAssumption: 'Der Wahlkreismodus ist ein Szenario: Das eingegebene nationale Stimmenprofil wird in jedem Wahlkreis wiederholt und ersetzt keine amtlichen Wahlkreisergebnisse.', modelNotice: 'Nur ein Bildungsmodell. Kein amtliches Wahlergebnis, keine Rechtsberatung und keine Prognose.', emptyState: 'Stimmen eingeben, um die Sitzverteilung zu sehen.', invalidNumber: 'Eine gültige nichtnegative Zahl verwenden.', seatUnit: 'Sitze',
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const faq = [
|
|
19
|
+
{ question: 'Ist dies ein offizieller Wahlrechner?', answer: 'Nein. Es ist ein Offline Bildungsmodell und berücksichtigt nicht alle Schwellen, Wahlkreisregeln, reservierten Sitze, Rundungen und Stichentscheidungen eines konkreten Wahlrechts.' },
|
|
20
|
+
{ question: 'Was unterscheidet D\'Hondt, Sainte-Laguë und Hare?', answer: 'D\'Hondt und Sainte-Laguë ordnen fortlaufende Quotienten. D\'Hondt nutzt 1, 2, 3 und weiter, Sainte-Laguë ungerade Teiler. Hare verteilt ganze Quoten und anschließend die größten Reste.' },
|
|
21
|
+
{ question: 'Was nimmt die Wahlkreisoption an?', answer: 'Sie wiederholt das eingegebene Stimmenprofil in jedem aufgeführten Wahlkreis und verteilt dessen Sitze separat. Das untersucht die Wahlkreisgröße, rekonstruiert aber keine örtlichen Ergebnisse.' },
|
|
22
|
+
{ question: 'Kann ich ein festes Szenario teilen?', answer: 'Ja. Nach der Eingabe das Teilen des Links kopieren. Der Ergebnisparameter speichert Parteien, Stimmen, Sitze, Methode, Schwelle und Wahlkreise für andere Leser.' },
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
const howTo = [
|
|
26
|
+
{ name: 'Stimmen eingeben', text: 'Parteien oder Listen hinzufügen und ihre Stimmen eintragen.' },
|
|
27
|
+
{ name: 'Verteilungsregel wählen', text: 'D\'Hondt, Sainte-Laguë oder Hare mit größtem Rest auswählen.' },
|
|
28
|
+
{ name: 'Sitze und Schwelle setzen', text: 'Verfügbare Sitze und gegebenenfalls eine Sperrklausel eingeben.' },
|
|
29
|
+
{ name: 'Verteilung lesen', text: 'Kammer, Anteile, Vergabereihenfolge, Ausschlüsse und Schwellenempfindlichkeit prüfen.' },
|
|
30
|
+
{ name: 'Szenario teilen', text: 'Den Teilen-Link kopieren, damit andere genau dieselben Eingaben öffnen können.' },
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
const softwareApplication: SoftwareApplication = { '@type': 'SoftwareApplication', name: 'Rechner für die Sitzverteilung bei Wahlen', applicationCategory: 'EducationalApplication', operatingSystem: 'Any', description: 'Modelliert die proportionale Sitzverteilung mit D\'Hondt, Sainte-Laguë und Hare.', url: 'https://gamebob.dev/de/wahl-sitzverteilung-rechner', offers: { '@type': 'Offer', price: '0', priceCurrency: 'USD' } };
|
|
34
|
+
const faqSchema: FAQPage = { '@type': 'FAQPage', mainEntity: faq.map((item) => ({ '@type': 'Question', name: item.question, acceptedAnswer: { '@type': 'Answer', text: item.answer } })) };
|
|
35
|
+
const howToSchema: HowTo = { '@type': 'HowTo', name: 'Eine proportionale Sitzverteilung modellieren', step: howTo.map((step) => ({ '@type': 'HowToStep', name: step.name, text: step.text })) };
|
|
36
|
+
|
|
37
|
+
export const content: ToolLocaleContent<ElectionSeatLocaleContent['ui']> = {
|
|
38
|
+
slug: 'wahl-sitzverteilung-rechner', title: 'Rechner für die Sitzverteilung bei Wahlen', description: 'Stimmen mit D\'Hondt, Sainte-Laguë oder Hare in Sitze umrechnen. Schwellen, Wahlkreisgrößen und Vergabeschritte transparent als Offline-Szenario prüfen.', ui,
|
|
39
|
+
seo: [
|
|
40
|
+
{ type: 'title', text: 'Stimmen in Sitze übersetzen', level: 2 },
|
|
41
|
+
{ type: 'paragraph', html: 'Die Sitzverteilung ist der Schritt zwischen einem Wahlergebnis und der Zusammensetzung eines Parlaments. Gib Parteien oder Listen, Stimmen und die Zahl der Sitze ein. Der Rechner zeigt die Sitze als Kammer, Anteile und nachvollziehbare Vergabereihenfolge. Das Ergebnis ist ein Lern- und Erklärmodell, keine Feststellung darüber, wer gewählt wurde.' },
|
|
42
|
+
{ type: 'title', text: 'Drei Regeln mit derselben Datengrundlage vergleichen', level: 2 },
|
|
43
|
+
{ type: 'paragraph', html: 'D\'Hondt und Sainte-Laguë arbeiten mit aufeinanderfolgenden Quotienten: Der nächste Sitz geht an den höchsten verfügbaren Quotienten. D\'Hondt teilt durch 1, 2, 3 und so weiter, Sainte-Laguë durch 1, 3, 5 und so weiter. Unterschiedliche Teiler können bei identischen Stimmen zu einer anderen Vertretung führen.' },
|
|
44
|
+
{ type: 'paragraph', html: 'Die Hare-Quote teilt die berücksichtigten Stimmen durch die Sitzzahl. Zuerst erhält jede Liste die ganzen Quoten, danach werden übrige Sitze nach den größten Resten vergeben. Bei echten Wahlen zählen zusätzlich gesetzliche Schwellen, Sonderregeln und die genaue Behandlung von Gleichständen.' },
|
|
45
|
+
{ type: 'table', headers: ['Methode', 'Verteilungsschritt', 'Leitfrage'], rows: [['D\'Hondt', 'Stimmen durch 1, 2, 3 und weiter teilen.', 'Wie stark hilft die Methode größeren Listen?'], ['Sainte-Laguë', 'Stimmen durch ungerade Teiler teilen.', 'Wie verändert eine gleichmäßigere Folge die Kammer?'], ['Hare mit größtem Rest', 'Ganze Quoten vergeben, dann Reste ordnen.', 'Wer profitiert, wenn Reststimmen den letzten Sitz entscheiden?']] },
|
|
46
|
+
{ type: 'title', text: 'Schwellen und Wahlkreise als Annahmen prüfen', level: 2 },
|
|
47
|
+
{ type: 'paragraph', html: 'Eine Sperrklausel schließt Parteien aus, deren Anteil unter dem eingetragenen Wert liegt. Der Rechner macht die ausgeschlossenen Stimmen sichtbar, statt sie still in den Rest einzurechnen. Die beobachtete Sitzschwelle ist nur das niedrigste Stimmenprozent einer Liste mit Sitz in diesem Modell und keine Aussage über geltendes Recht.' },
|
|
48
|
+
{ type: 'list', items: ['Beginne mit der amtlichen Sitzzahl der untersuchten Kammer.', 'Verwende eine Schwelle nur, wenn das untersuchte Regelwerk sie vorsieht.', 'Vergleiche Methoden zunächst bei identischen Stimmen und Sitzen.', 'Nutze die Empfindlichkeitskarten, um Listen nahe an der Schwelle zu erkennen.'] },
|
|
49
|
+
{ type: 'tip', title: 'Wahlkreisannahme richtig einordnen', html: 'Der Wahlkreismodus wiederholt dasselbe nationale Stimmenprofil in jedem eingegebenen Wahlkreis. Er isoliert den Einfluss der Wahlkreisgröße, kann aber keine lokalen Verschiebungen, Regionalparteien, reservierten Sitze, Überhangmandate oder Koalitionsregeln abbilden.' },
|
|
50
|
+
{ type: 'title', text: 'Was das Modell nicht entscheiden kann', level: 2 },
|
|
51
|
+
{ type: 'paragraph', html: 'Wahlrecht ist von Land zu Land verschieden. Eine echte Auszählung kann eine andere Schwellenbasis, einen veränderten Sainte-Laguë-Teiler, eine zweistufige Verteilung, Ausgleichssitze oder eine gesetzliche Gleichstandsregel verwenden. Vor einer realen Erklärung immer die zuständige Wahlbehörde und das geltende Gesetz prüfen.' },
|
|
52
|
+
{ type: 'tip', title: 'Von der Überraschung zur Prüfung', html: 'Die Quotienten- und Resttabellen bilden eine Prüfspur. Wenn ein Sitz unerwartet wirkt, sieh dir den nächsten verlorenen Quotienten oder Rest an und vergleiche ihn mit der konkreten Regel des Landes.' },
|
|
53
|
+
],
|
|
54
|
+
faq, bibliography, howTo, schemas: [softwareApplication, faqSchema, howToSchema] as unknown as Record<string, unknown>[],
|
|
55
|
+
};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import type { FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import { bibliography } from '../bibliography';
|
|
4
|
+
import type { ElectionSeatLocaleContent } from '../entry';
|
|
5
|
+
import { ui } from '../ui';
|
|
6
|
+
|
|
7
|
+
const softwareApplication: SoftwareApplication = {
|
|
8
|
+
'@type': 'SoftwareApplication',
|
|
9
|
+
name: 'Election Seat Apportionment Calculator',
|
|
10
|
+
applicationCategory: 'EducationalApplication',
|
|
11
|
+
operatingSystem: 'Any',
|
|
12
|
+
description: 'Model proportional seat allocation with D\'Hondt, Sainte-Lague, and Hare largest remainder methods.',
|
|
13
|
+
url: 'https://gamebob.dev/en/election-seat-apportionment-calculator',
|
|
14
|
+
offers: { '@type': 'Offer', price: '0', priceCurrency: 'USD' },
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const faqPage: FAQPage = {
|
|
18
|
+
'@type': 'FAQPage',
|
|
19
|
+
mainEntity: [
|
|
20
|
+
{
|
|
21
|
+
'@type': 'Question',
|
|
22
|
+
name: 'Is this an official election calculator?',
|
|
23
|
+
acceptedAnswer: {
|
|
24
|
+
'@type': 'Answer',
|
|
25
|
+
text: 'No. It is an offline educational model. Official results can include legal thresholds, district rules, reserved seats, rounding instructions, alliances, and tie procedures that this general model does not know.',
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
'@type': 'Question',
|
|
30
|
+
name: 'What is the difference between D\'Hondt, Sainte-Lague, and Hare?',
|
|
31
|
+
acceptedAnswer: {
|
|
32
|
+
'@type': 'Answer',
|
|
33
|
+
text: 'D\'Hondt and Sainte-Lague allocate seats from successive quotients. D\'Hondt divides by 1, 2, 3 and so on, while Sainte-Lague uses 1, 3, 5 and so on. Hare gives each eligible party its full vote quota first, then assigns remaining seats by the largest remainders.',
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
'@type': 'Question',
|
|
38
|
+
name: 'What does the district option assume?',
|
|
39
|
+
acceptedAnswer: {
|
|
40
|
+
'@type': 'Answer',
|
|
41
|
+
text: 'It repeats the entered vote profile in each listed district and allocates that district\'s seats separately. Use it to explore the effect of district magnitude, not to reproduce an election with different local vote totals.',
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
'@type': 'Question',
|
|
46
|
+
name: 'Can I share a fixed scenario?',
|
|
47
|
+
acceptedAnswer: {
|
|
48
|
+
'@type': 'Answer',
|
|
49
|
+
text: 'Yes. Copy the share link after entering the scenario. The result query parameter stores the parties, votes, seats, method, threshold, and districts so the same model opens for another reader.',
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const howTo: HowTo = {
|
|
56
|
+
'@type': 'HowTo',
|
|
57
|
+
name: 'Model a proportional seat allocation',
|
|
58
|
+
step: [
|
|
59
|
+
{ '@type': 'HowToStep', name: 'Enter the vote totals', text: 'Add each party or list and enter its vote total.' },
|
|
60
|
+
{ '@type': 'HowToStep', name: 'Choose the allocation rule', text: 'Select D\'Hondt, Sainte-Lague, or Hare quota and largest remainder.' },
|
|
61
|
+
{ '@type': 'HowToStep', name: 'Set seats and threshold', text: 'Enter the available seats and an eligibility threshold if the scenario uses one.' },
|
|
62
|
+
{ '@type': 'HowToStep', name: 'Read the allocation', text: 'Review the chamber, vote and seat shares, award order, exclusions, and threshold sensitivity.' },
|
|
63
|
+
{ '@type': 'HowToStep', name: 'Share the scenario', text: 'Copy the share link to preserve the exact inputs for another reader.' },
|
|
64
|
+
],
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export const content: ToolLocaleContent<ElectionSeatLocaleContent['ui']> = {
|
|
68
|
+
slug: 'election-seat-apportionment-calculator',
|
|
69
|
+
title: 'Election Seat Apportionment Calculator',
|
|
70
|
+
description: 'Model how votes become seats with D\'Hondt, Sainte-Lague, and Hare largest remainder methods. Compare thresholds and district magnitudes in a transparent offline scenario.',
|
|
71
|
+
ui,
|
|
72
|
+
seo: [
|
|
73
|
+
{ type: 'title', text: 'Turn Votes into Seats with a Transparent Model', level: 2 },
|
|
74
|
+
{ type: 'paragraph', html: 'Seat apportionment is the conversion step between a vote count and a representative chamber. This calculator lets you name the parties, enter votes, choose a method, and see the allocation as a seat chamber plus an auditable award order. The result is a model for learning and scenario planning, not a declaration of who was elected.' },
|
|
75
|
+
{ type: 'title', text: 'How the Three Allocation Methods Differ', level: 2 },
|
|
76
|
+
{ type: 'paragraph', html: 'D\'Hondt and Sainte-Lague are highest average methods. Each possible next seat has a quotient, and the available seats go to the highest quotients in order. D\'Hondt uses divisors 1, 2, 3 and onward; Sainte-Lague uses odd divisors 1, 3, 5 and onward. Because the quotient series differ, the same vote totals can produce different representation.' },
|
|
77
|
+
{ type: 'paragraph', html: 'Hare quota with largest remainder starts with a quota equal to eligible votes divided by seats. Each party receives the whole number of quotas it contains, then unfilled seats go to the largest fractional remainders. The method can give smaller lists a stronger chance than a highest average rule, but every threshold and tie rule in a real jurisdiction still matters.' },
|
|
78
|
+
{ type: 'table', headers: ['Method', 'Allocation step', 'Useful question'], rows: [
|
|
79
|
+
['D\'Hondt', 'Rank votes divided by 1, 2, 3 and onward.', 'How does a highest average rule reward larger lists?'],
|
|
80
|
+
['Sainte-Lague', 'Rank votes divided by 1, 3, 5 and onward.', 'How does a more even divisor series change the chamber?'],
|
|
81
|
+
['Hare largest remainder', 'Give full quotas, then rank the remaining fractions.', 'Who benefits when leftover votes decide the final seats?'],
|
|
82
|
+
] },
|
|
83
|
+
{ type: 'title', text: 'Use Thresholds and Districts as Explicit Scenarios', level: 2 },
|
|
84
|
+
{ type: 'paragraph', html: 'The eligibility threshold removes parties whose share is below the number you enter before seats are distributed. That makes the excluded vote total visible instead of silently folding it into a result. The observed seat threshold is the lowest vote share among parties that receive a seat in this particular model; it is an outcome of the inputs, not a legal claim.' },
|
|
85
|
+
{ type: 'list', items: ['Start with the official number of seats for the chamber you are studying.', 'Enter a threshold only when the rule you are modelling actually has one.', 'Compare methods with the same votes and seats before changing several assumptions at once.', 'Use the one point sensitivity cards to spot parties close to the eligibility boundary.'] },
|
|
86
|
+
{ type: 'tip', title: 'Interpret the district option carefully', html: 'District mode applies the same national vote profile to every district and allocates each district separately. This isolates the effect of district magnitude. It cannot reproduce local swings, regional parties, reserved seats, overhang seats, coalition rules, or legal tie breakers.' },
|
|
87
|
+
{ type: 'title', text: 'What This Model Cannot Decide', level: 2 },
|
|
88
|
+
{ type: 'paragraph', html: 'Election law is jurisdiction specific. A real count may use a different threshold base, a modified Sainte-Lague divisor, a two stage allocation, district corrections, candidate level rules, invalid ballot decisions, or a random tie breaker. Check the applicable electoral authority and legislation before using a scenario to explain a real result.' },
|
|
89
|
+
{ type: 'tip', title: 'Evidence before conclusion', html: 'Treat the quotient and remainder tables as an audit trail. If a seat surprises you, inspect the next highest losing quotient or remainder, then verify the jurisdiction\'s exact rule instead of assuming the generic method is controlling.' },
|
|
90
|
+
],
|
|
91
|
+
faq: [
|
|
92
|
+
{ question: 'Is this an official election calculator?', answer: 'No. It is an offline educational model, not an official result, legal advice, or a prediction. Real election rules can add district, candidate, threshold, rounding, alliance, and tie procedures.' },
|
|
93
|
+
{ question: 'What is the difference between D\'Hondt, Sainte-Lague, and Hare?', answer: 'D\'Hondt and Sainte-Lague rank successive quotients. D\'Hondt uses 1, 2, 3 and onward, while Sainte-Lague uses odd divisors. Hare gives full quotas first and assigns remaining seats by largest remainder.' },
|
|
94
|
+
{ question: 'What does the district option assume?', answer: 'It repeats the entered vote profile in every listed district and allocates each district separately. It is a district magnitude scenario, not a reconstruction of local election returns.' },
|
|
95
|
+
{ question: 'Can I share a fixed scenario?', answer: 'Yes. Copy the share link after entering the scenario. The result query parameter stores the exact parties, votes, seats, method, threshold, and districts for another reader.' },
|
|
96
|
+
],
|
|
97
|
+
bibliography,
|
|
98
|
+
howTo: [
|
|
99
|
+
{ name: 'Enter the vote totals', text: 'Add each party or list and enter its vote total.' },
|
|
100
|
+
{ name: 'Choose the allocation rule', text: 'Select D\'Hondt, Sainte-Lague, or Hare quota and largest remainder.' },
|
|
101
|
+
{ name: 'Set seats and threshold', text: 'Enter available seats and any eligibility threshold used by your scenario.' },
|
|
102
|
+
{ name: 'Read the allocation', text: 'Review the chamber, shares, award order, exclusions, and sensitivity cards.' },
|
|
103
|
+
{ name: 'Share the scenario', text: 'Copy the share link to preserve the exact inputs for another reader.' },
|
|
104
|
+
],
|
|
105
|
+
schemas: [softwareApplication, faqPage, howTo] as unknown as Record<string, unknown>[],
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
export const englishContent: ElectionSeatLocaleContent = content;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import { bibliography } from '../bibliography';
|
|
4
|
+
import type { ElectionSeatLocaleContent } from '../entry';
|
|
5
|
+
import type { ElectionSeatUI } from '../ui';
|
|
6
|
+
|
|
7
|
+
const ui: ElectionSeatUI = {
|
|
8
|
+
allocationTitle: 'Reparto de escaños',
|
|
9
|
+
eventsTitle: 'Aquí se deciden los siguientes escaños',
|
|
10
|
+
sensitivityTitle: 'Qué cambia alrededor del umbral',
|
|
11
|
+
methodLabel: 'Método de reparto', dhondtLabel: 'Promedios mayores de D\'Hondt', sainteLagueLabel: 'Promedios mayores de Sainte-Laguë', hareLabel: 'Cuota Hare y resto mayor', partiesLabel: 'Votos por partido o lista', partyNameLabel: 'Nombre del partido o lista', votesLabel: 'Votos', addParty: 'Añadir partido', removeParty: 'Eliminar partido',
|
|
12
|
+
shareResult: 'Copiar enlace para compartir', shareCopied: 'Enlace copiado.', shareCopyFallback: 'Copia el enlace desde el diálogo.', invalidSharedResult: 'Este enlace compartido no es válido. Se muestra el ejemplo.', totalSeatsLabel: 'Escaños a repartir', thresholdLabel: 'Umbral de elegibilidad', districtsLabel: 'Agrupación opcional por distritos', districtsHelp: 'Escribe el número de escaños separado por comas. El modelo aplica el mismo perfil de votos en cada distrito.', districtsPlaceholder: 'Ejemplo: 10, 8, 7', reset: 'Restablecer ejemplo',
|
|
13
|
+
allocatedSeatsLabel: 'Escaños repartidos', voteShareLabel: 'Porcentaje de votos', seatShareLabel: 'Porcentaje de escaños', excludedLabel: 'Excluido por el umbral', chamberLabel: 'Cámara de escaños', quotientLabel: 'Cociente', remainderLabel: 'Resto', eventLabel: 'Orden de asignación', eligibleVotesLabel: 'Votos elegibles', excludedVotesLabel: 'Votos excluidos', effectiveThresholdLabel: 'Umbral observado para obtener escaño', sensitivityLabel: 'Sensibilidad al umbral', lowerThresholdLabel: 'Con el umbral un punto menor', higherThresholdLabel: 'Con el umbral un punto mayor', changedLabel: 'Escaños que cambian', noChangesLabel: 'No cambia ningún escaño en esta prueba', districtAssumption: 'El modo por distritos es un escenario: repite el perfil nacional de votos en cada distrito y no sustituye los resultados oficiales de cada circunscripción.', modelNotice: 'Solo es un modelo educativo. No es un resultado electoral oficial, asesoramiento jurídico ni una predicción.', emptyState: 'Introduce votos para mostrar la cámara de escaños.', invalidNumber: 'Usa un número válido no negativo.', seatUnit: 'escaños',
|
|
14
|
+
};
|
|
15
|
+
const faq = [
|
|
16
|
+
{ question: '¿Es una calculadora electoral oficial?', answer: 'No. Es un modelo educativo offline. Un escrutinio real puede incluir umbrales legales, reglas territoriales, escaños reservados, redondeos y procedimientos de desempate que este modelo general no conoce.' },
|
|
17
|
+
{ question: '¿Qué diferencia hay entre D\'Hondt, Sainte-Laguë y Hare?', answer: 'D\'Hondt y Sainte-Laguë ordenan cocientes sucesivos. D\'Hondt divide por 1, 2, 3 y siguientes, mientras Sainte-Laguë usa divisores impares. Hare asigna primero las cuotas enteras y después los escaños restantes por los restos mayores.' },
|
|
18
|
+
{ question: '¿Qué supone la opción de distritos?', answer: 'Repite el perfil de votos introducido en cada distrito y reparte por separado sus escaños. Sirve para estudiar la magnitud del distrito, no para reconstruir resultados locales.' },
|
|
19
|
+
{ question: '¿Puedo compartir un escenario fijo?', answer: 'Sí. Pulsa el botón para copiar el enlace después de introducir el escenario. El parámetro result guarda partidos, votos, escaños, método, umbral y distritos para que otra persona abra el mismo modelo.' },
|
|
20
|
+
];
|
|
21
|
+
const howTo = [
|
|
22
|
+
{ name: 'Introduce los votos', text: 'Añade cada partido o lista y escribe su número de votos.' },
|
|
23
|
+
{ name: 'Elige la regla de reparto', text: 'Selecciona D\'Hondt, Sainte-Laguë o cuota Hare y resto mayor.' },
|
|
24
|
+
{ name: 'Configura escaños y umbral', text: 'Indica los escaños disponibles y el umbral si el escenario lo utiliza.' },
|
|
25
|
+
{ name: 'Lee el reparto', text: 'Revisa la cámara, los porcentajes, el orden de asignación, las exclusiones y la sensibilidad.' },
|
|
26
|
+
{ name: 'Comparte el escenario', text: 'Copia el enlace para conservar exactamente las mismas entradas para otra persona.' },
|
|
27
|
+
];
|
|
28
|
+
const softwareApplication: SoftwareApplication = { '@type': 'SoftwareApplication', name: 'Calculadora de reparto de escaños electorales', applicationCategory: 'EducationalApplication', operatingSystem: 'Any', description: 'Calcula un reparto proporcional de escaños con D\'Hondt, Sainte-Laguë y resto mayor de Hare.', url: 'https://gamebob.dev/es/calculadora-reparto-escanos-elecciones', offers: { '@type': 'Offer', price: '0', priceCurrency: 'USD' } };
|
|
29
|
+
const faqSchema: FAQPage = { '@type': 'FAQPage', mainEntity: faq.map((item) => ({ '@type': 'Question', name: item.question, acceptedAnswer: { '@type': 'Answer', text: item.answer } })) };
|
|
30
|
+
const howToSchema: HowTo = { '@type': 'HowTo', name: 'Modelar un reparto proporcional de escaños', step: howTo.map((step) => ({ '@type': 'HowToStep', name: step.name, text: step.text })) };
|
|
31
|
+
|
|
32
|
+
export const content: ToolLocaleContent<ElectionSeatLocaleContent['ui']> = {
|
|
33
|
+
slug: 'calculadora-reparto-escanos-elecciones', title: 'Calculadora de reparto de escaños electorales', description: 'Convierte votos en escaños con D\'Hondt, Sainte-Laguë o resto mayor de Hare. Compara umbrales y distritos en un escenario offline transparente.', ui,
|
|
34
|
+
seo: [
|
|
35
|
+
{ type: 'title', text: 'De los votos a la representación', level: 2 },
|
|
36
|
+
{ type: 'paragraph', html: 'El reparto de escaños conecta el recuento de votos con la composición de una cámara. Introduce partidos o listas, sus votos y el número de escaños disponibles. La calculadora muestra la cámara resultante, los porcentajes y el orden auditable en el que se asigna cada escaño. Sirve para aprender y explicar escenarios, no para declarar quién ha sido elegido.' },
|
|
37
|
+
{ type: 'title', text: 'Compara tres métodos con los mismos datos', level: 2 },
|
|
38
|
+
{ type: 'paragraph', html: 'D\'Hondt y Sainte-Laguë son métodos de promedios mayores: cada escaño posible genera un cociente y se eligen los más altos. D\'Hondt divide por 1, 2, 3 y siguientes; Sainte-Laguë utiliza 1, 3, 5 y siguientes. Por eso unos mismos votos pueden producir una composición diferente.' },
|
|
39
|
+
{ type: 'paragraph', html: 'El resto mayor de Hare empieza con una cuota igual a los votos elegibles divididos entre los escaños. Cada partido recibe primero sus cuotas enteras y los escaños restantes se asignan por los restos más grandes. En una elección real también importan la ley, los umbrales y las reglas para empates.' },
|
|
40
|
+
{ type: 'table', headers: ['Método', 'Paso de reparto', 'Pregunta útil'], rows: [['D\'Hondt', 'Ordena los votos divididos por 1, 2, 3 y siguientes.', '¿Cómo favorece el promedio mayor a las listas grandes?'], ['Sainte-Laguë', 'Ordena los votos divididos por divisores impares.', '¿Qué cambia con una serie de divisores más equilibrada?'], ['Resto mayor de Hare', 'Asigna cuotas enteras y ordena los restos.', '¿Quién se beneficia cuando un resto decide el último escaño?']] },
|
|
41
|
+
{ type: 'title', text: 'Usa umbrales y distritos como supuestos explícitos', level: 2 },
|
|
42
|
+
{ type: 'paragraph', html: 'El umbral elimina antes del reparto a los partidos cuyo porcentaje queda por debajo de la cifra introducida. Así se ve cuántos votos quedan excluidos. El umbral observado para obtener escaño es el porcentaje más bajo entre las listas que reciben un escaño en este cálculo concreto; no es una afirmación legal.' },
|
|
43
|
+
{ type: 'list', items: ['Empieza con el número oficial de escaños de la cámara que estudias.', 'Introduce un umbral solo si existe en la regla electoral que quieres modelar.', 'Compara los métodos manteniendo iguales los votos y los escaños.', 'Mira las tarjetas de sensibilidad para detectar listas cercanas al umbral.'] },
|
|
44
|
+
{ type: 'tip', title: 'Interpreta bien la opción de distritos', html: 'El modo por distritos repite el mismo perfil nacional de votos en cada distrito. Aísla el efecto de la magnitud del distrito, pero no puede representar cambios locales, partidos regionales, escaños reservados, restos de compensación ni reglas de coalición.' },
|
|
45
|
+
{ type: 'title', text: 'Lo que este modelo no puede decidir', level: 2 },
|
|
46
|
+
{ type: 'paragraph', html: 'La legislación electoral depende de cada jurisdicción. Un recuento real puede usar otra base para el umbral, una variante de Sainte-Laguë, dos fases de reparto, correcciones territoriales, reglas para candidatos o un desempate aleatorio. Consulta siempre la autoridad electoral y la norma aplicable antes de explicar un resultado real.' },
|
|
47
|
+
{ type: 'tip', title: 'Convierte una sorpresa en una comprobación', html: 'Las tablas de cocientes y restos forman una pista de auditoría. Si un escaño te sorprende, revisa el siguiente cociente o resto perdedor y compáralo con la regla exacta de la jurisdicción.' },
|
|
48
|
+
],
|
|
49
|
+
faq, bibliography, howTo, schemas: [softwareApplication, faqSchema, howToSchema] as unknown as Record<string, unknown>[],
|
|
50
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import { bibliography } from '../bibliography';
|
|
4
|
+
import type { ElectionSeatLocaleContent } from '../entry';
|
|
5
|
+
import type { ElectionSeatUI } from '../ui';
|
|
6
|
+
|
|
7
|
+
const ui: ElectionSeatUI = {
|
|
8
|
+
allocationTitle: 'Répartition des sièges',
|
|
9
|
+
eventsTitle: 'Les prochains sièges se décident ici',
|
|
10
|
+
sensitivityTitle: 'Ce qui change autour du seuil',
|
|
11
|
+
methodLabel: 'Méthode de répartition', dhondtLabel: 'Plus fortes moyennes de D\'Hondt', sainteLagueLabel: 'Plus fortes moyennes de Sainte-Laguë', hareLabel: 'Quota de Hare et plus grands restes', partiesLabel: 'Voix par parti ou liste', partyNameLabel: 'Nom du parti ou de la liste', votesLabel: 'Voix', addParty: 'Ajouter un parti', removeParty: 'Supprimer le parti', shareResult: 'Copier le lien à partager', shareCopied: 'Lien à partager copié.', shareCopyFallback: 'Copiez le lien depuis la boîte de dialogue.', invalidSharedResult: 'Ce lien de résultat partagé est invalide. L\'exemple est affiché.', totalSeatsLabel: 'Sièges à répartir', thresholdLabel: 'Seuil d\'éligibilité', districtsLabel: 'Regroupement facultatif des circonscriptions', districtsHelp: 'Saisissez les nombres de sièges séparés par des virgules. Le modèle applique le même profil de voix dans chaque circonscription.', districtsPlaceholder: 'Exemple: 10, 8, 7', reset: 'Réinitialiser l\'exemple', allocatedSeatsLabel: 'Sièges répartis', voteShareLabel: 'Part des voix', seatShareLabel: 'Part des sièges', excludedLabel: 'Exclu par le seuil', chamberLabel: 'Répartition des sièges', quotientLabel: 'Quotient', remainderLabel: 'Reste', eventLabel: 'Ordre d\'attribution des sièges', eligibleVotesLabel: 'Voix éligibles', excludedVotesLabel: 'Voix exclues', effectiveThresholdLabel: 'Seuil observé pour obtenir un siège', sensitivityLabel: 'Sensibilité au seuil', lowerThresholdLabel: 'Avec un seuil inférieur d\'un point', higherThresholdLabel: 'Avec un seuil supérieur d\'un point', changedLabel: 'Sièges modifiés', noChangesLabel: 'Aucun siège ne change dans ce test', districtAssumption: 'Le mode par circonscriptions est un scénario: il répète le profil national saisi dans chaque circonscription et ne remplace pas les résultats officiels locaux.', modelNotice: 'Modèle éducatif uniquement. Ce n\'est ni un résultat officiel, ni un conseil juridique, ni une prédiction.', emptyState: 'Saisissez des voix pour afficher la répartition.', invalidNumber: 'Utilisez un nombre valide et non négatif.', seatUnit: 'sièges',
|
|
12
|
+
};
|
|
13
|
+
const faq = [
|
|
14
|
+
{ question: 'Est-ce un calculateur électoral officiel ?', answer: 'Non. C\'est un modèle éducatif hors ligne. Un scrutin réel peut appliquer des seuils légaux, des règles territoriales, des sièges réservés, des arrondis et des procédures de départage qui ne sont pas intégrés ici.' },
|
|
15
|
+
{ question: 'Quelle différence entre D\'Hondt, Sainte-Laguë et Hare ?', answer: 'D\'Hondt et Sainte-Laguë classent des quotients successifs. D\'Hondt divise par 1, 2, 3 et ainsi de suite, tandis que Sainte-Laguë utilise les diviseurs impairs. Hare attribue d\'abord les quotas entiers, puis les sièges restants aux plus grands restes.' },
|
|
16
|
+
{ question: 'Que suppose l\'option des circonscriptions ?', answer: 'Elle répète le profil de voix saisi dans chaque circonscription et répartit séparément ses sièges. Elle sert à étudier la magnitude d\'une circonscription, pas à reconstituer des résultats locaux.' },
|
|
17
|
+
{ question: 'Puis-je partager un scénario fixe ?', answer: 'Oui. Copiez le lien après avoir saisi le scénario. Le paramètre result conserve les partis, les voix, les sièges, la méthode, le seuil et les circonscriptions pour ouvrir le même modèle ailleurs.' },
|
|
18
|
+
];
|
|
19
|
+
const howTo = [
|
|
20
|
+
{ name: 'Saisir les voix', text: 'Ajoutez chaque parti ou liste et saisissez son nombre de voix.' },
|
|
21
|
+
{ name: 'Choisir la règle', text: 'Sélectionnez D\'Hondt, Sainte-Laguë ou le quota de Hare et les plus grands restes.' },
|
|
22
|
+
{ name: 'Définir sièges et seuil', text: 'Indiquez les sièges disponibles et le seuil si le scénario en utilise un.' },
|
|
23
|
+
{ name: 'Lire la répartition', text: 'Examinez la chambre, les parts, l\'ordre d\'attribution, les exclusions et la sensibilité.' },
|
|
24
|
+
{ name: 'Partager le scénario', text: 'Copiez le lien pour conserver exactement les mêmes données pour un autre lecteur.' },
|
|
25
|
+
];
|
|
26
|
+
const softwareApplication: SoftwareApplication = { '@type': 'SoftwareApplication', name: 'Calculateur de répartition des sièges électoraux', applicationCategory: 'EducationalApplication', operatingSystem: 'Any', description: 'Modélise une répartition proportionnelle avec D\'Hondt, Sainte-Laguë et le plus grand reste de Hare.', url: 'https://gamebob.dev/fr/calculateur-repartition-sieges-electoraux', offers: { '@type': 'Offer', price: '0', priceCurrency: 'USD' } };
|
|
27
|
+
const faqSchema: FAQPage = { '@type': 'FAQPage', mainEntity: faq.map((item) => ({ '@type': 'Question', name: item.question, acceptedAnswer: { '@type': 'Answer', text: item.answer } })) };
|
|
28
|
+
const howToSchema: HowTo = { '@type': 'HowTo', name: 'Modéliser une répartition proportionnelle', step: howTo.map((step) => ({ '@type': 'HowToStep', name: step.name, text: step.text })) };
|
|
29
|
+
|
|
30
|
+
export const content: ToolLocaleContent<ElectionSeatLocaleContent['ui']> = {
|
|
31
|
+
slug: 'calculateur-repartition-sieges-electoraux', title: 'Calculateur de répartition des sièges électoraux', description: 'Transformez des voix en sièges avec D\'Hondt, Sainte-Laguë ou Hare. Comparez seuils et circonscriptions dans un scénario hors ligne transparent.', ui,
|
|
32
|
+
seo: [
|
|
33
|
+
{ type: 'title', text: 'Passer des voix à la représentation', level: 2 },
|
|
34
|
+
{ type: 'paragraph', html: 'La répartition des sièges relie le décompte des voix à la composition d\'une assemblée. Saisissez les partis ou listes, leurs voix et le nombre de sièges disponibles. Le calculateur montre la chambre, les pourcentages et l\'ordre vérifiable d\'attribution de chaque siège. Il sert à apprendre et à expliquer des scénarios, pas à déclarer les élus.' },
|
|
35
|
+
{ type: 'title', text: 'Comparer trois méthodes sur les mêmes données', level: 2 },
|
|
36
|
+
{ type: 'paragraph', html: 'D\'Hondt et Sainte-Laguë sont des méthodes de plus fortes moyennes: chaque siège possible produit un quotient et les plus élevés sont retenus. D\'Hondt divise par 1, 2, 3 et les suivants ; Sainte-Laguë utilise 1, 3, 5 et les suivants. Les mêmes voix peuvent donc produire une représentation différente.' },
|
|
37
|
+
{ type: 'paragraph', html: 'Le plus grand reste de Hare commence par un quota égal aux voix éligibles divisées par le nombre de sièges. Chaque liste reçoit ses quotas entiers, puis les sièges restants vont aux restes les plus grands. Pour une élection réelle, il faut aussi vérifier le droit applicable et les règles d\'égalité.' },
|
|
38
|
+
{ type: 'table', headers: ['Méthode', 'Étape de répartition', 'Question utile'], rows: [['D\'Hondt', 'Classer les voix divisées par 1, 2, 3 et les suivants.', 'Les grandes listes sont-elles favorisées ?'], ['Sainte-Laguë', 'Classer les voix divisées par des diviseurs impairs.', 'Que change une suite plus équilibrée ?'], ['Plus grand reste de Hare', 'Attribuer les quotas entiers puis classer les restes.', 'Qui profite du reste qui décide le dernier siège ?']] },
|
|
39
|
+
{ type: 'title', text: 'Tester clairement seuils et circonscriptions', level: 2 },
|
|
40
|
+
{ type: 'paragraph', html: 'Le seuil retire avant la répartition les partis dont le pourcentage est inférieur à la valeur saisie. Les voix exclues restent visibles. Le seuil observé pour obtenir un siège est le plus petit pourcentage d\'une liste qui reçoit un siège dans ce calcul précis ; ce n\'est pas une règle de droit.' },
|
|
41
|
+
{ type: 'list', items: ['Commencez par le nombre officiel de sièges de l\'assemblée étudiée.', 'N\'utilisez un seuil que s\'il figure dans la règle électorale étudiée.', 'Comparez les méthodes avec les mêmes voix et le même nombre de sièges.', 'Consultez la sensibilité pour repérer les listes proches de la limite.'] },
|
|
42
|
+
{ type: 'tip', title: 'Bien interpréter les circonscriptions', html: 'Le mode par circonscriptions répète le profil national dans chaque circonscription. Il isole l\'effet de leur magnitude, mais ne représente ni les variations locales, ni les partis régionaux, ni les sièges réservés, ni les règles de coalition.' },
|
|
43
|
+
{ type: 'title', text: 'Ce que le modèle ne peut pas décider', level: 2 },
|
|
44
|
+
{ type: 'paragraph', html: 'Le droit électoral dépend de chaque juridiction. Un scrutin réel peut utiliser une autre base de seuil, une variante de Sainte-Laguë, plusieurs étapes de répartition, des corrections territoriales ou une règle de départage. Vérifiez toujours l\'autorité électorale et le texte applicable avant d\'expliquer un résultat réel.' },
|
|
45
|
+
{ type: 'tip', title: 'Transformer une surprise en vérification', html: 'Les tableaux de quotients et de restes constituent une piste d\'audit. Si un siège étonne, examinez le quotient ou le reste suivant qui n\'a pas obtenu de siège et comparez-le à la règle exacte de la juridiction.' },
|
|
46
|
+
],
|
|
47
|
+
faq, bibliography, howTo, schemas: [softwareApplication, faqSchema, howToSchema] as unknown as Record<string, unknown>[],
|
|
48
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import { bibliography } from '../bibliography';
|
|
4
|
+
import type { ElectionSeatLocaleContent } from '../entry';
|
|
5
|
+
import type { ElectionSeatUI } from '../ui';
|
|
6
|
+
|
|
7
|
+
const ui: ElectionSeatUI = {
|
|
8
|
+
allocationTitle: 'Pembagian kursi',
|
|
9
|
+
eventsTitle: 'Kursi berikutnya ditentukan di sini',
|
|
10
|
+
sensitivityTitle: 'Perubahan di sekitar ambang',
|
|
11
|
+
methodLabel: 'Metode pembagian', dhondtLabel: 'Rata-rata tertinggi D\'Hondt', sainteLagueLabel: 'Rata-rata tertinggi Sainte-Laguë', hareLabel: 'Kuota Hare dan sisa terbesar', partiesLabel: 'Suara menurut partai atau daftar', partyNameLabel: 'Nama partai atau daftar', votesLabel: 'Suara', addParty: 'Tambah partai', removeParty: 'Hapus partai', shareResult: 'Salin tautan berbagi', shareCopied: 'Tautan berbagi disalin.', shareCopyFallback: 'Salin tautan berbagi dari dialog.', invalidSharedResult: 'Tautan hasil yang dibagikan tidak valid. Contoh ditampilkan.', totalSeatsLabel: 'Kursi yang dibagikan', thresholdLabel: 'Ambang kelayakan', districtsLabel: 'Pengelompokan distrik opsional', districtsHelp: 'Masukkan jumlah kursi yang dipisahkan koma. Model menerapkan profil suara yang sama di setiap distrik.', districtsPlaceholder: 'Contoh: 10, 8, 7', reset: 'Atur ulang contoh', allocatedSeatsLabel: 'Kursi yang dibagikan', voteShareLabel: 'Proporsi suara', seatShareLabel: 'Proporsi kursi', excludedLabel: 'Dikecualikan oleh ambang', chamberLabel: 'Pembagian kursi', quotientLabel: 'Hasil bagi', remainderLabel: 'Sisa', eventLabel: 'Urutan pemberian kursi', eligibleVotesLabel: 'Suara yang memenuhi syarat', excludedVotesLabel: 'Suara yang dikecualikan', effectiveThresholdLabel: 'Ambang kursi yang teramati', sensitivityLabel: 'Sensitivitas ambang', lowerThresholdLabel: 'Pada ambang satu poin lebih rendah', higherThresholdLabel: 'Pada ambang satu poin lebih tinggi', changedLabel: 'Kursi yang berubah', noChangesLabel: 'Tidak ada perubahan kursi dalam pengujian ini', districtAssumption: 'Mode distrik adalah skenario: profil suara nasional yang dimasukkan diulang di setiap distrik dan tidak menggantikan hasil distrik resmi.', modelNotice: 'Hanya model edukasi. Bukan hasil pemilu resmi, nasihat hukum, atau prediksi.', emptyState: 'Masukkan suara untuk melihat pembagian kursi.', invalidNumber: 'Gunakan angka valid yang tidak negatif.', seatUnit: 'kursi',
|
|
12
|
+
};
|
|
13
|
+
const faq = [
|
|
14
|
+
{ question: 'Apakah ini kalkulator pemilu resmi?', answer: 'Bukan. Ini model edukasi offline. Penghitungan nyata dapat memakai ambang hukum, aturan wilayah, kursi khusus, pembulatan, dan prosedur penentuan seri yang tidak diketahui model umum ini.' },
|
|
15
|
+
{ question: 'Apa perbedaan D\'Hondt, Sainte-Laguë, dan Hare?', answer: 'D\'Hondt dan Sainte-Laguë mengurutkan hasil bagi berturut-turut. D\'Hondt membagi dengan 1, 2, 3 dan seterusnya, sedangkan Sainte-Laguë memakai pembagi ganjil. Hare memberi kuota penuh lebih dulu, lalu kursi tersisa berdasarkan sisa terbesar.' },
|
|
16
|
+
{ question: 'Apa asumsi pilihan distrik?', answer: 'Pilihan ini mengulang profil suara yang dimasukkan di setiap distrik dan membagikan kursi tiap distrik secara terpisah. Gunanya untuk mempelajari ukuran distrik, bukan merekonstruksi hasil lokal.' },
|
|
17
|
+
{ question: 'Bisakah saya membagikan skenario tetap?', answer: 'Bisa. Salin tautan setelah memasukkan skenario. Parameter result menyimpan partai, suara, kursi, metode, ambang, dan distrik agar pembaca lain membuka model yang sama.' },
|
|
18
|
+
];
|
|
19
|
+
const howTo = [
|
|
20
|
+
{ name: 'Masukkan jumlah suara', text: 'Tambahkan setiap partai atau daftar dan masukkan jumlah suaranya.' },
|
|
21
|
+
{ name: 'Pilih aturan pembagian', text: 'Pilih D\'Hondt, Sainte-Laguë, atau kuota Hare dengan sisa terbesar.' },
|
|
22
|
+
{ name: 'Atur kursi dan ambang', text: 'Masukkan kursi yang tersedia serta ambang jika skenario memakainya.' },
|
|
23
|
+
{ name: 'Baca pembagiannya', text: 'Tinjau kamar, proporsi, urutan pemberian, pengecualian, dan sensitivitas.' },
|
|
24
|
+
{ name: 'Bagikan skenario', text: 'Salin tautan agar masukan yang sama dapat dibuka oleh pembaca lain.' },
|
|
25
|
+
];
|
|
26
|
+
const softwareApplication: SoftwareApplication = { '@type': 'SoftwareApplication', name: 'Kalkulator pembagian kursi pemilu', applicationCategory: 'EducationalApplication', operatingSystem: 'Any', description: 'Memodelkan pembagian kursi proporsional dengan D\'Hondt, Sainte-Laguë, dan sisa terbesar Hare.', url: 'https://gamebob.dev/id/kalkulator-pembagian-kursi-pemilu', offers: { '@type': 'Offer', price: '0', priceCurrency: 'USD' } };
|
|
27
|
+
const faqSchema: FAQPage = { '@type': 'FAQPage', mainEntity: faq.map((item) => ({ '@type': 'Question', name: item.question, acceptedAnswer: { '@type': 'Answer', text: item.answer } })) };
|
|
28
|
+
const howToSchema: HowTo = { '@type': 'HowTo', name: 'Memodelkan pembagian kursi proporsional', step: howTo.map((step) => ({ '@type': 'HowToStep', name: step.name, text: step.text })) };
|
|
29
|
+
|
|
30
|
+
export const content: ToolLocaleContent<ElectionSeatLocaleContent['ui']> = {
|
|
31
|
+
slug: 'kalkulator-pembagian-kursi-pemilu', title: 'Kalkulator pembagian kursi pemilu', description: 'Ubah suara menjadi kursi dengan D\'Hondt, Sainte-Laguë, atau sisa terbesar Hare. Bandingkan ambang dan distrik dalam skenario offline yang transparan.', ui,
|
|
32
|
+
seo: [
|
|
33
|
+
{ type: 'title', text: 'Mengubah suara menjadi keterwakilan', level: 2 },
|
|
34
|
+
{ type: 'paragraph', html: 'Pembagian kursi menghubungkan jumlah suara dengan susunan sebuah lembaga perwakilan. Masukkan partai atau daftar, jumlah suara, dan jumlah kursi yang tersedia. Kalkulator menampilkan kamar, proporsi, serta urutan pemberian kursi yang dapat ditelusuri. Hasilnya untuk belajar dan menjelaskan skenario, bukan untuk menetapkan siapa yang terpilih.' },
|
|
35
|
+
{ type: 'title', text: 'Bandingkan tiga metode dengan data yang sama', level: 2 },
|
|
36
|
+
{ type: 'paragraph', html: 'D\'Hondt dan Sainte-Laguë adalah metode rata-rata tertinggi. Setiap kursi yang mungkin menghasilkan hasil bagi, lalu hasil bagi tertinggi dipilih. D\'Hondt memakai pembagi 1, 2, 3 dan seterusnya, sedangkan Sainte-Laguë memakai 1, 3, 5 dan seterusnya. Karena itu, suara yang sama dapat menghasilkan keterwakilan yang berbeda.' },
|
|
37
|
+
{ type: 'paragraph', html: 'Sisa terbesar Hare dimulai dengan kuota yang sama dengan suara yang memenuhi syarat dibagi jumlah kursi. Setiap daftar menerima kuota utuh terlebih dahulu, lalu kursi yang tersisa diberikan kepada sisa terbesar. Dalam pemilu nyata, periksa juga ambang hukum, aturan daerah, dan ketentuan saat hasil sama.' },
|
|
38
|
+
{ type: 'table', headers: ['Metode', 'Langkah pembagian', 'Pertanyaan berguna'], rows: [['D\'Hondt', 'Urutkan suara yang dibagi dengan 1, 2, 3 dan seterusnya.', 'Seberapa besar metode ini membantu daftar besar?'], ['Sainte-Laguë', 'Urutkan suara yang dibagi dengan pembagi ganjil.', 'Apa yang berubah dengan deret pembagi yang lebih seimbang?'], ['Sisa terbesar Hare', 'Berikan kuota utuh, lalu urutkan sisa.', 'Siapa yang diuntungkan saat sisa menentukan kursi terakhir?']] },
|
|
39
|
+
{ type: 'title', text: 'Uji ambang dan distrik sebagai asumsi yang jelas', level: 2 },
|
|
40
|
+
{ type: 'paragraph', html: 'Ambang mengeluarkan partai yang persentasenya berada di bawah angka yang dimasukkan sebelum kursi dibagikan. Jumlah suara yang dikecualikan tetap terlihat. Ambang kursi yang teramati adalah persentase suara terendah dari daftar yang memperoleh kursi pada perhitungan ini, bukan klaim tentang aturan hukum.' },
|
|
41
|
+
{ type: 'list', items: ['Mulai dari jumlah kursi resmi untuk lembaga yang sedang dipelajari.', 'Gunakan ambang hanya jika aturan pemilu yang dimodelkan memang memilikinya.', 'Bandingkan metode dengan suara dan kursi yang sama.', 'Gunakan kartu sensitivitas untuk menemukan daftar yang dekat dengan ambang.'] },
|
|
42
|
+
{ type: 'tip', title: 'Pahami asumsi distrik', html: 'Mode distrik mengulang profil suara nasional yang sama di setiap distrik. Ini mengisolasi pengaruh ukuran distrik, tetapi tidak menggambarkan perubahan lokal, partai regional, kursi khusus, kursi kompensasi, atau aturan koalisi.' },
|
|
43
|
+
{ type: 'title', text: 'Hal yang tidak dapat diputuskan model ini', level: 2 },
|
|
44
|
+
{ type: 'paragraph', html: 'Hukum pemilu berbeda menurut yurisdiksi. Penghitungan nyata dapat memakai dasar ambang lain, varian Sainte-Laguë, beberapa tahap pembagian, koreksi wilayah, aturan kandidat, atau pemecah seri acak. Selalu periksa otoritas pemilu dan hukum yang berlaku sebelum menjelaskan hasil nyata.' },
|
|
45
|
+
{ type: 'tip', title: 'Ubah kejutan menjadi pemeriksaan', html: 'Tabel hasil bagi dan sisa merupakan jejak audit. Jika sebuah kursi terasa mengejutkan, periksa hasil bagi atau sisa tertinggi berikutnya yang kalah dan bandingkan dengan aturan yurisdiksi yang tepat.' },
|
|
46
|
+
],
|
|
47
|
+
faq, bibliography, howTo, schemas: [softwareApplication, faqSchema, howToSchema] as unknown as Record<string, unknown>[],
|
|
48
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import { bibliography } from '../bibliography';
|
|
4
|
+
import type { ElectionSeatLocaleContent } from '../entry';
|
|
5
|
+
import type { ElectionSeatUI } from '../ui';
|
|
6
|
+
|
|
7
|
+
const ui: ElectionSeatUI = {
|
|
8
|
+
allocationTitle: 'Ripartizione dei seggi',
|
|
9
|
+
eventsTitle: 'Qui si decidono i seggi successivi',
|
|
10
|
+
sensitivityTitle: 'Cosa cambia attorno alla soglia',
|
|
11
|
+
methodLabel: 'Metodo di ripartizione', dhondtLabel: 'Medie più alte di D\'Hondt', sainteLagueLabel: 'Medie più alte di Sainte-Laguë', hareLabel: 'Quota Hare e più grandi resti', partiesLabel: 'Voti per partito o lista', partyNameLabel: 'Nome del partito o della lista', votesLabel: 'Voti', addParty: 'Aggiungi partito', removeParty: 'Rimuovi partito', shareResult: 'Copia il link da condividere', shareCopied: 'Link da condividere copiato.', shareCopyFallback: 'Copia il link dalla finestra di dialogo.', invalidSharedResult: 'Questo link condiviso non è valido. Viene mostrato l\'esempio.', totalSeatsLabel: 'Seggi da distribuire', thresholdLabel: 'Soglia di eleggibilità', districtsLabel: 'Raggruppamento facoltativo dei collegi', districtsHelp: 'Inserisci i numeri di seggi separati da virgole. Il modello applica lo stesso profilo di voti in ogni collegio.', districtsPlaceholder: 'Esempio: 10, 8, 7', reset: 'Ripristina esempio', allocatedSeatsLabel: 'Seggi distribuiti', voteShareLabel: 'Quota di voti', seatShareLabel: 'Quota di seggi', excludedLabel: 'Escluso dalla soglia', chamberLabel: 'Ripartizione dei seggi', quotientLabel: 'Quoziente', remainderLabel: 'Resto', eventLabel: 'Ordine di assegnazione dei seggi', eligibleVotesLabel: 'Voti ammissibili', excludedVotesLabel: 'Voti esclusi', effectiveThresholdLabel: 'Soglia osservata per ottenere un seggio', sensitivityLabel: 'Sensibilità alla soglia', lowerThresholdLabel: 'Con soglia inferiore di un punto', higherThresholdLabel: 'Con soglia superiore di un punto', changedLabel: 'Seggi modificati', noChangesLabel: 'Nessun seggio cambia in questo test', districtAssumption: 'La modalità per collegi è uno scenario: ripete il profilo nazionale inserito in ogni collegio e non sostituisce i risultati ufficiali locali.', modelNotice: 'Solo un modello didattico. Non è un risultato elettorale ufficiale, un parere legale o una previsione.', emptyState: 'Inserisci i voti per mostrare la ripartizione.', invalidNumber: 'Usa un numero valido non negativo.', seatUnit: 'seggi',
|
|
12
|
+
};
|
|
13
|
+
const faq = [
|
|
14
|
+
{ question: 'È un calcolatore elettorale ufficiale?', answer: 'No. È un modello didattico offline. Uno scrutinio reale può includere soglie legali, regole territoriali, seggi riservati, arrotondamenti e procedure di spareggio che questo modello generale non conosce.' },
|
|
15
|
+
{ question: 'Qual è la differenza tra D\'Hondt, Sainte-Laguë e Hare?', answer: 'D\'Hondt e Sainte-Laguë ordinano quozienti successivi. D\'Hondt divide per 1, 2, 3 e così via, mentre Sainte-Laguë usa divisori dispari. Hare assegna prima le quote intere, poi i seggi rimanenti ai resti maggiori.' },
|
|
16
|
+
{ question: 'Che cosa presuppone l\'opzione dei collegi?', answer: 'Ripete il profilo di voti inserito in ogni collegio e distribuisce separatamente i suoi seggi. Serve a studiare l\'ampiezza del collegio, non a ricostruire risultati locali.' },
|
|
17
|
+
{ question: 'Posso condividere uno scenario fisso?', answer: 'Sì. Copia il link dopo aver inserito lo scenario. Il parametro result conserva partiti, voti, seggi, metodo, soglia e collegi per aprire lo stesso modello altrove.' },
|
|
18
|
+
];
|
|
19
|
+
const howTo = [
|
|
20
|
+
{ name: 'Inserisci i voti', text: 'Aggiungi ogni partito o lista e inserisci il suo numero di voti.' },
|
|
21
|
+
{ name: 'Scegli la regola', text: 'Seleziona D\'Hondt, Sainte-Laguë oppure quota Hare e più grandi resti.' },
|
|
22
|
+
{ name: 'Imposta seggi e soglia', text: 'Indica i seggi disponibili e una soglia se lo scenario la prevede.' },
|
|
23
|
+
{ name: 'Leggi la ripartizione', text: 'Controlla camera, quote, ordine di assegnazione, esclusioni e sensibilità.' },
|
|
24
|
+
{ name: 'Condividi lo scenario', text: 'Copia il link per conservare esattamente gli stessi dati per un altro lettore.' },
|
|
25
|
+
];
|
|
26
|
+
const softwareApplication: SoftwareApplication = { '@type': 'SoftwareApplication', name: 'Calcolatore della ripartizione dei seggi elettorali', applicationCategory: 'EducationalApplication', operatingSystem: 'Any', description: 'Modella la ripartizione proporzionale con D\'Hondt, Sainte-Laguë e il più grande resto di Hare.', url: 'https://gamebob.dev/it/calcolatore-ripartizione-seggi-elettorali', offers: { '@type': 'Offer', price: '0', priceCurrency: 'USD' } };
|
|
27
|
+
const faqSchema: FAQPage = { '@type': 'FAQPage', mainEntity: faq.map((item) => ({ '@type': 'Question', name: item.question, acceptedAnswer: { '@type': 'Answer', text: item.answer } })) };
|
|
28
|
+
const howToSchema: HowTo = { '@type': 'HowTo', name: 'Modellare una ripartizione proporzionale', step: howTo.map((step) => ({ '@type': 'HowToStep', name: step.name, text: step.text })) };
|
|
29
|
+
|
|
30
|
+
export const content: ToolLocaleContent<ElectionSeatLocaleContent['ui']> = {
|
|
31
|
+
slug: 'calcolatore-ripartizione-seggi-elettorali', title: 'Calcolatore della ripartizione dei seggi elettorali', description: 'Trasforma i voti in seggi con D\'Hondt, Sainte-Laguë o più grande resto di Hare. Confronta soglie e collegi in uno scenario offline trasparente.', ui,
|
|
32
|
+
seo: [
|
|
33
|
+
{ type: 'title', text: 'Dai voti alla rappresentanza', level: 2 },
|
|
34
|
+
{ type: 'paragraph', html: 'La ripartizione dei seggi collega il conteggio dei voti alla composizione di un\'assemblea. Inserisci partiti o liste, voti e seggi disponibili. Il calcolatore mostra camera, percentuali e ordine verificabile con cui viene assegnato ogni seggio. È uno strumento per imparare e spiegare scenari, non una dichiarazione degli eletti.' },
|
|
35
|
+
{ type: 'title', text: 'Confronta tre metodi con gli stessi dati', level: 2 },
|
|
36
|
+
{ type: 'paragraph', html: 'D\'Hondt e Sainte-Laguë sono metodi delle medie più alte: ogni possibile seggio produce un quoziente e vengono scelti quelli maggiori. D\'Hondt divide per 1, 2, 3 e successivi; Sainte-Laguë usa 1, 3, 5 e successivi. Gli stessi voti possono quindi produrre una rappresentanza diversa.' },
|
|
37
|
+
{ type: 'paragraph', html: 'Il più grande resto di Hare parte da una quota pari ai voti ammissibili divisi per i seggi. Ogni lista riceve prima le quote intere, poi i seggi rimanenti vanno ai resti più grandi. In un\'elezione reale contano anche la soglia prevista dalla legge e le regole per i pari merito.' },
|
|
38
|
+
{ type: 'table', headers: ['Metodo', 'Passaggio', 'Domanda utile'], rows: [['D\'Hondt', 'Ordina i voti divisi per 1, 2, 3 e successivi.', 'Quanto favorisce le liste più grandi?'], ['Sainte-Laguë', 'Ordina i voti divisi per divisori dispari.', 'Che cosa cambia con una serie più equilibrata?'], ['Più grande resto di Hare', 'Assegna quote intere e poi ordina i resti.', 'Chi beneficia del resto che decide l\'ultimo seggio?']] },
|
|
39
|
+
{ type: 'title', text: 'Prova soglie e collegi come ipotesi esplicite', level: 2 },
|
|
40
|
+
{ type: 'paragraph', html: 'La soglia esclude prima della distribuzione i partiti la cui percentuale è inferiore al valore inserito. I voti esclusi restano visibili. La soglia osservata è la percentuale più bassa tra le liste che ricevono un seggio in questo calcolo, non una regola giuridica.' },
|
|
41
|
+
{ type: 'list', items: ['Parti dal numero ufficiale di seggi dell\'assemblea studiata.', 'Inserisci una soglia solo se la regola elettorale esaminata la prevede.', 'Confronta i metodi mantenendo uguali voti e seggi.', 'Usa la sensibilità per trovare le liste vicine al limite.'] },
|
|
42
|
+
{ type: 'tip', title: 'Interpreta correttamente i collegi', html: 'La modalità per collegi ripete lo stesso profilo nazionale in ogni collegio inserito. Isola l\'effetto della sua ampiezza, ma non può rappresentare variazioni locali, partiti regionali, seggi riservati, seggi compensativi o regole di coalizione.' },
|
|
43
|
+
{ type: 'title', text: 'Che cosa il modello non può decidere', level: 2 },
|
|
44
|
+
{ type: 'paragraph', html: 'La legge elettorale varia secondo la giurisdizione. Uno scrutinio reale può usare un\'altra base per la soglia, una variante di Sainte-Laguë, più fasi di distribuzione, correzioni territoriali o una regola specifica di spareggio. Verifica sempre l\'autorità elettorale e la norma applicabile prima di spiegare un risultato reale.' },
|
|
45
|
+
{ type: 'tip', title: 'Trasforma una sorpresa in una verifica', html: 'Le tabelle di quozienti e resti sono una traccia di controllo. Se un seggio sorprende, guarda il quoziente o il resto successivo che non ha vinto e confrontalo con la regola esatta della giurisdizione.' },
|
|
46
|
+
],
|
|
47
|
+
faq, bibliography, howTo, schemas: [softwareApplication, faqSchema, howToSchema] as unknown as Record<string, unknown>[],
|
|
48
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import { bibliography } from '../bibliography';
|
|
4
|
+
import type { ElectionSeatLocaleContent } from '../entry';
|
|
5
|
+
import type { ElectionSeatUI } from '../ui';
|
|
6
|
+
|
|
7
|
+
const ui: ElectionSeatUI = {
|
|
8
|
+
allocationTitle: '議席配分',
|
|
9
|
+
eventsTitle: '次の議席がここで決まります',
|
|
10
|
+
sensitivityTitle: 'しきい値付近で変わること',
|
|
11
|
+
methodLabel: '配分方式', dhondtLabel: 'ドント式', sainteLagueLabel: 'サン=ラグ式', hareLabel: 'ヘア式最大剰余法', partiesLabel: '政党または名簿の得票数', partyNameLabel: '政党または名簿名', votesLabel: '得票数', addParty: '政党を追加', removeParty: '政党を削除', shareResult: '共有リンクをコピー', shareCopied: '共有リンクをコピーしました。', shareCopyFallback: 'ダイアログから共有リンクをコピーしてください。', invalidSharedResult: '共有された結果リンクが無効です。例を表示します。', totalSeatsLabel: '配分する議席数', thresholdLabel: '資格しきい値', districtsLabel: '選挙区別の配分(任意)', districtsHelp: '議席数をコンマで区切って入力します。各選挙区で同じ得票プロフィールを使います。', districtsPlaceholder: '例:10, 8, 7', reset: '例をリセット', allocatedSeatsLabel: '配分された議席', voteShareLabel: '得票率', seatShareLabel: '議席率', excludedLabel: 'しきい値未満', chamberLabel: '議席構成', quotientLabel: '商', remainderLabel: '剰余', eventLabel: '議席配分の順序', eligibleVotesLabel: '対象得票', excludedVotesLabel: '除外された得票', effectiveThresholdLabel: '議席を得た最低得票率', sensitivityLabel: 'しきい値の感度', lowerThresholdLabel: 'しきい値を1ポイント下げた場合', higherThresholdLabel: 'しきい値を1ポイント上げた場合', changedLabel: '変化した議席', noChangesLabel: 'このテストでは議席は変わりません', districtAssumption: '選挙区モードはシナリオです。入力した全国の得票プロフィールを各選挙区で繰り返し、公式の選挙区結果に置き換えるものではありません。', modelNotice: '教育用モデルです。公式の選挙結果、法的助言、予測ではありません。', emptyState: '得票数を入力すると議席構成が表示されます。', invalidNumber: '0以上の有効な数値を入力してください。', seatUnit: '議席',
|
|
12
|
+
};
|
|
13
|
+
const faq = [
|
|
14
|
+
{ question: '公式の選挙計算機ですか?', answer: 'いいえ。オフラインの教育用モデルです。実際の集計では、法定しきい値、地域規則、特別議席、丸め方、同数時の手続きなど、この一般モデルに含まれない条件が使われることがあります。' },
|
|
15
|
+
{ question: 'ドント式、サン=ラグ式、ヘア式の違いは何ですか?', answer: 'ドント式とサン=ラグ式は連続する商を順位付けします。ドント式は1、2、3の順に割り、サン=ラグ式は奇数で割ります。ヘア式は整数 quota を先に配分し、残りを最大剰余で決めます。' },
|
|
16
|
+
{ question: '選挙区の設定は何を仮定しますか?', answer: '入力した得票プロフィールを各選挙区で繰り返し、選挙区ごとに議席を配分します。選挙区の議席規模を調べるための設定で、地域ごとの実際の得票を再現するものではありません。' },
|
|
17
|
+
{ question: '固定したシナリオを共有できますか?', answer: 'できます。シナリオを入力した後に共有リンクをコピーしてください。result パラメーターに政党、得票、議席数、方式、しきい値、選挙区が保存され、同じモデルを開けます。' },
|
|
18
|
+
];
|
|
19
|
+
const howTo = [
|
|
20
|
+
{ name: '得票数を入力する', text: '政党または名簿を追加し、それぞれの得票数を入力します。' },
|
|
21
|
+
{ name: '配分規則を選ぶ', text: 'ドント式、サン=ラグ式、またはヘア式最大剰余法を選択します。' },
|
|
22
|
+
{ name: '議席数としきい値を設定する', text: '利用できる議席数と、シナリオに必要な資格しきい値を入力します。' },
|
|
23
|
+
{ name: '配分結果を読む', text: '議席構成、割合、配分順序、除外票、しきい値の感度を確認します。' },
|
|
24
|
+
{ name: 'シナリオを共有する', text: '共有リンクをコピーして、同じ入力を別の読者に渡します。' },
|
|
25
|
+
];
|
|
26
|
+
const softwareApplication: SoftwareApplication = { '@type': 'SoftwareApplication', name: '選挙議席配分計算機', applicationCategory: 'EducationalApplication', operatingSystem: 'Any', description: 'ドント式、サン=ラグ式、ヘア式最大剰余法で比例的な議席配分をモデル化します。', url: 'https://gamebob.dev/ja/election-seat-apportionment-calculator', offers: { '@type': 'Offer', price: '0', priceCurrency: 'USD' } };
|
|
27
|
+
const faqSchema: FAQPage = { '@type': 'FAQPage', mainEntity: faq.map((item) => ({ '@type': 'Question', name: item.question, acceptedAnswer: { '@type': 'Answer', text: item.answer } })) };
|
|
28
|
+
const howToSchema: HowTo = { '@type': 'HowTo', name: '比例的な議席配分をモデル化する', step: howTo.map((step) => ({ '@type': 'HowToStep', name: step.name, text: step.text })) };
|
|
29
|
+
|
|
30
|
+
export const content: ToolLocaleContent<ElectionSeatLocaleContent['ui']> = {
|
|
31
|
+
slug: 'election-seat-apportionment-calculator', title: '選挙議席配分計算機', description: '得票数をドント式、サン=ラグ式、ヘア式で議席に変換します。しきい値と選挙区規模を透明なオフラインシナリオで比較できます。', ui,
|
|
32
|
+
seo: [
|
|
33
|
+
{ type: 'title', text: '得票数から代表構成へ', level: 2 },
|
|
34
|
+
{ type: 'paragraph', html: '議席配分は、得票数と議会の構成をつなぐ計算です。政党や名簿、得票数、利用できる議席数を入力すると、議席構成、割合、各議席が決まる順序を確認できます。学習や説明のためのモデルであり、当選者を確定するものではありません。' },
|
|
35
|
+
{ type: 'title', text: '同じデータで三つの方式を比べる', level: 2 },
|
|
36
|
+
{ type: 'paragraph', html: 'ドント式とサン=ラグ式は最高平均方式です。配分可能な各議席について商を作り、大きい順に選びます。ドント式は1、2、3と続く除数を使い、サン=ラグ式は1、3、5と続く奇数を使うため、同じ得票でも構成が変わることがあります。' },
|
|
37
|
+
{ type: 'paragraph', html: 'ヘア式最大剰余法では、対象得票を議席数で割って quota を求めます。各名簿に整数部分を配分し、残った議席を剰余の大きい順に配分します。実際の選挙では、法定しきい値や同数時の規則も確認する必要があります。' },
|
|
38
|
+
{ type: 'table', headers: ['方式', '配分の流れ', '考える問い'], rows: [['ドント式', '得票数を1、2、3と続く数で割って順位付けします。', '大きな名簿にどの程度有利ですか?'], ['サン=ラグ式', '得票数を奇数の除数で割って順位付けします。', 'より均等な除数列で構成はどう変わりますか?'], ['ヘア式最大剰余法', '整数 quota を配分し、その後に剰余を順位付けします。', '最後の議席を剰余が決めると誰が有利ですか?']] },
|
|
39
|
+
{ type: 'title', text: 'しきい値と選挙区を明示的な前提として試す', level: 2 },
|
|
40
|
+
{ type: 'paragraph', html: 'しきい値を下回る政党は、議席配分の前に除外されます。除外された得票数も表示されるため、結果に影響した前提を確認できます。議席を得た最低得票率は、この入力で議席を得た名簿の最小値であり、法律上の基準ではありません。' },
|
|
41
|
+
{ type: 'list', items: ['まず調べる議会の公式な議席数を入力します。', 'しきい値は、対象の選挙制度に存在する場合だけ使います。', '方式を比べるときは得票数と議席数をそろえます。', '感度カードで、しきい値の近くにある名簿を確認します。'] },
|
|
42
|
+
{ type: 'tip', title: '選挙区モードの意味', html: '選挙区モードは、同じ全国得票プロフィールを各選挙区で繰り返します。選挙区の規模による差を調べるためのもので、地域差、地域政党、特別議席、調整議席、連立規則は再現しません。' },
|
|
43
|
+
{ type: 'title', text: 'このモデルで決められないこと', level: 2 },
|
|
44
|
+
{ type: 'paragraph', html: '選挙法は地域によって異なります。実際の集計では、別のしきい値の基準、サン=ラグ式の変形、複数段階の配分、地域補正、候補者規則、同数時の抽選などが使われる場合があります。現実の結果を説明する前に、選挙管理機関と適用法令を確認してください。' },
|
|
45
|
+
{ type: 'tip', title: '疑問を検算に変える', html: '商と剰余の表は検算の手がかりです。議席が意外に見えるときは、次に敗れた商または剰余を調べ、対象地域の正確な規則と比較してください。' },
|
|
46
|
+
],
|
|
47
|
+
faq, bibliography, howTo, schemas: [softwareApplication, faqSchema, howToSchema] as unknown as Record<string, unknown>[],
|
|
48
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import { bibliography } from '../bibliography';
|
|
4
|
+
import type { ElectionSeatLocaleContent } from '../entry';
|
|
5
|
+
import type { ElectionSeatUI } from '../ui';
|
|
6
|
+
|
|
7
|
+
const ui: ElectionSeatUI = {
|
|
8
|
+
allocationTitle: '의석 배분',
|
|
9
|
+
eventsTitle: '다음 의석은 여기서 결정됩니다',
|
|
10
|
+
sensitivityTitle: '기준선 주변의 변화',
|
|
11
|
+
methodLabel: '배분 방식', dhondtLabel: '동트식 최고 평균', sainteLagueLabel: '생트라고식 최고 평균', hareLabel: '헤어 쿼터와 최대 나머지', partiesLabel: '정당 또는 명부별 득표수', partyNameLabel: '정당 또는 명부 이름', votesLabel: '득표수', addParty: '정당 추가', removeParty: '정당 삭제', shareResult: '공유 링크 복사', shareCopied: '공유 링크를 복사했습니다.', shareCopyFallback: '대화 상자에서 공유 링크를 복사하세요.', invalidSharedResult: '공유 결과 링크가 올바르지 않습니다. 예시를 표시합니다.', totalSeatsLabel: '배분할 의석 수', thresholdLabel: '자격 기준선', districtsLabel: '선택 사항인 선거구 묶음', districtsHelp: '의석 수를 쉼표로 구분해 입력합니다. 각 선거구에 같은 득표 프로필을 적용합니다.', districtsPlaceholder: '예: 10, 8, 7', reset: '예시로 초기화', allocatedSeatsLabel: '배분된 의석', voteShareLabel: '득표 비율', seatShareLabel: '의석 비율', excludedLabel: '기준선 미달', chamberLabel: '의석 구성', quotientLabel: '몫', remainderLabel: '나머지', eventLabel: '의석 배분 순서', eligibleVotesLabel: '유효 득표', excludedVotesLabel: '제외된 득표', effectiveThresholdLabel: '의석을 얻은 최저 득표율', sensitivityLabel: '기준선 민감도', lowerThresholdLabel: '기준선을 1포인트 낮춘 경우', higherThresholdLabel: '기준선을 1포인트 높인 경우', changedLabel: '변경된 의석', noChangesLabel: '이 테스트에서는 의석이 바뀌지 않습니다', districtAssumption: '선거구 모드는 시나리오입니다. 입력한 전국 득표 프로필을 모든 선거구에 반복하며 공식 선거구 결과를 대신하지 않습니다.', modelNotice: '교육용 모델입니다. 공식 선거 결과, 법률 자문 또는 예측이 아닙니다.', emptyState: '득표수를 입력하면 의석 구성이 표시됩니다.', invalidNumber: '음수가 아닌 유효한 숫자를 입력하세요.', seatUnit: '석',
|
|
12
|
+
};
|
|
13
|
+
const faq = [
|
|
14
|
+
{ question: '공식 선거 계산기인가요?', answer: '아닙니다. 오프라인 교육용 모델입니다. 실제 개표에는 법정 기준선, 지역 규칙, 특별 의석, 반올림, 동률 처리 등 이 일반 모델이 알 수 없는 조건이 포함될 수 있습니다.' },
|
|
15
|
+
{ question: '동트식, 생트라고식, 헤어식의 차이는 무엇인가요?', answer: '동트식과 생트라고식은 연속적인 몫을 순서대로 정렬합니다. 동트식은 1, 2, 3 등으로 나누고 생트라고식은 홀수 제수를 사용합니다. 헤어식은 정수 쿼터를 먼저 배분한 뒤 남은 의석을 최대 나머지로 정합니다.' },
|
|
16
|
+
{ question: '선거구 옵션은 무엇을 가정하나요?', answer: '입력한 득표 프로필을 모든 선거구에 반복하고 각 선거구의 의석을 따로 배분합니다. 선거구 규모의 효과를 살펴보는 기능이며 실제 지역별 득표를 재현하지 않습니다.' },
|
|
17
|
+
{ question: '고정된 시나리오를 공유할 수 있나요?', answer: '가능합니다. 시나리오를 입력한 뒤 공유 링크를 복사하세요. result 매개변수에 정당, 득표, 의석, 방식, 기준선, 선거구가 저장되어 같은 모델을 열 수 있습니다.' },
|
|
18
|
+
];
|
|
19
|
+
const howTo = [
|
|
20
|
+
{ name: '득표수 입력', text: '각 정당 또는 명부를 추가하고 득표수를 입력합니다.' },
|
|
21
|
+
{ name: '배분 규칙 선택', text: '동트식, 생트라고식 또는 헤어 최대 나머지 방식을 선택합니다.' },
|
|
22
|
+
{ name: '의석과 기준선 설정', text: '사용 가능한 의석과 시나리오에 필요한 자격 기준선을 입력합니다.' },
|
|
23
|
+
{ name: '배분 결과 확인', text: '의석 구성, 비율, 배분 순서, 제외표, 기준선 민감도를 검토합니다.' },
|
|
24
|
+
{ name: '시나리오 공유', text: '공유 링크를 복사해 다른 독자에게 같은 입력을 전달합니다.' },
|
|
25
|
+
];
|
|
26
|
+
const softwareApplication: SoftwareApplication = { '@type': 'SoftwareApplication', name: '선거 의석 배분 계산기', applicationCategory: 'EducationalApplication', operatingSystem: 'Any', description: '동트식, 생트라고식, 헤어 최대 나머지 방식으로 비례 의석 배분을 모델링합니다.', url: 'https://gamebob.dev/ko/election-seat-apportionment-calculator', offers: { '@type': 'Offer', price: '0', priceCurrency: 'USD' } };
|
|
27
|
+
const faqSchema: FAQPage = { '@type': 'FAQPage', mainEntity: faq.map((item) => ({ '@type': 'Question', name: item.question, acceptedAnswer: { '@type': 'Answer', text: item.answer } })) };
|
|
28
|
+
const howToSchema: HowTo = { '@type': 'HowTo', name: '비례 의석 배분 모델 만들기', step: howTo.map((step) => ({ '@type': 'HowToStep', name: step.name, text: step.text })) };
|
|
29
|
+
|
|
30
|
+
export const content: ToolLocaleContent<ElectionSeatLocaleContent['ui']> = {
|
|
31
|
+
slug: 'election-seat-apportionment-calculator', title: '선거 의석 배분 계산기', description: '득표수를 동트식, 생트라고식 또는 헤어식으로 의석에 배분합니다. 투명한 오프라인 시나리오에서 기준선과 선거구 규모를 비교하세요.', ui,
|
|
32
|
+
seo: [
|
|
33
|
+
{ type: 'title', text: '득표수에서 대표 구성으로', level: 2 },
|
|
34
|
+
{ type: 'paragraph', html: '의석 배분은 득표수와 의회 구성을 연결하는 단계입니다. 정당 또는 명부, 득표수, 이용 가능한 의석 수를 입력하면 의석 구성, 비율, 각 의석이 정해지는 순서를 확인할 수 있습니다. 학습과 설명을 위한 모델이며 당선자를 공식적으로 확정하지 않습니다.' },
|
|
35
|
+
{ type: 'title', text: '같은 데이터로 세 가지 방식 비교', level: 2 },
|
|
36
|
+
{ type: 'paragraph', html: '동트식과 생트라고식은 최고 평균 방식입니다. 가능한 다음 의석마다 몫을 만들고 가장 큰 몫을 선택합니다. 동트식은 1, 2, 3 등의 제수를 사용하고 생트라고식은 1, 3, 5 등의 홀수 제수를 사용하므로 같은 득표도 다른 대표 구성을 만들 수 있습니다.' },
|
|
37
|
+
{ type: 'paragraph', html: '헤어 최대 나머지 방식은 유효 득표를 의석 수로 나눈 쿼터에서 시작합니다. 각 명부에 정수 쿼터를 먼저 주고 남은 의석을 나머지가 큰 순서로 배분합니다. 실제 선거에서는 법률상 기준선과 동률 처리 규칙도 확인해야 합니다.' },
|
|
38
|
+
{ type: 'table', headers: ['방식', '배분 단계', '생각해 볼 질문'], rows: [['동트식', '득표수를 1, 2, 3 등으로 나누어 순위를 매깁니다.', '큰 명부에 얼마나 유리한가요?'], ['생트라고식', '득표수를 홀수 제수로 나누어 순위를 매깁니다.', '더 균등한 제수열은 구성을 어떻게 바꾸나요?'], ['헤어 최대 나머지', '정수 쿼터를 주고 남은 나머지를 순위화합니다.', '나머지가 마지막 의석을 결정하면 누가 유리한가요?']] },
|
|
39
|
+
{ type: 'title', text: '기준선과 선거구를 명시적인 가정으로 테스트', level: 2 },
|
|
40
|
+
{ type: 'paragraph', html: '기준선은 입력한 비율보다 적은 정당을 배분 전에 제외합니다. 제외된 득표수도 표시되므로 결과의 가정을 확인할 수 있습니다. 관찰된 최저 의석 득표율은 이번 계산에서 의석을 얻은 명부 중 가장 낮은 비율이며 법정 기준선이 아닙니다.' },
|
|
41
|
+
{ type: 'list', items: ['먼저 연구할 의회의 공식 의석 수를 입력합니다.', '선거 규칙에 실제 기준선이 있을 때만 입력합니다.', '방식을 비교할 때 득표수와 의석 수를 같게 유지합니다.', '민감도 카드에서 기준선 근처의 명부를 찾습니다.'] },
|
|
42
|
+
{ type: 'tip', title: '선거구 가정 이해하기', html: '선거구 모드는 같은 전국 득표 프로필을 모든 선거구에 반복합니다. 선거구 규모의 효과를 분리해 보지만 지역별 변화, 지역 정당, 특별 의석, 보정 의석, 연립 규칙은 표현하지 못합니다.' },
|
|
43
|
+
{ type: 'title', text: '이 모델이 결정할 수 없는 것', level: 2 },
|
|
44
|
+
{ type: 'paragraph', html: '선거법은 관할 지역마다 다릅니다. 실제 개표는 다른 기준선, 생트라고식 변형, 여러 단계의 배분, 지역 보정, 후보자 규칙 또는 무작위 동률 처리를 사용할 수 있습니다. 실제 결과를 설명하기 전에 선거관리기관과 적용 법령을 확인하세요.' },
|
|
45
|
+
{ type: 'tip', title: '의문을 검증으로 바꾸기', html: '몫과 나머지 표는 계산을 확인하는 단서입니다. 의석이 예상과 다르면 다음으로 탈락한 몫이나 나머지를 보고 해당 관할 지역의 정확한 규칙과 비교하세요.' },
|
|
46
|
+
],
|
|
47
|
+
faq, bibliography, howTo, schemas: [softwareApplication, faqSchema, howToSchema] as unknown as Record<string, unknown>[],
|
|
48
|
+
};
|