@kreiseck/kasseneck-api 0.9.4 → 0.11.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 (50) hide show
  1. package/CHANGELOG.md +118 -0
  2. package/README.md +41 -0
  3. package/dist/cjs/payments/hobex-hps/index.d.ts +2 -2
  4. package/dist/cjs/payments/hobex-hps/index.js +36 -1
  5. package/dist/cjs/payments/hobex-hps/outcome.d.ts +20 -1
  6. package/dist/cjs/payments/hobex-hps/outcome.js +11 -0
  7. package/dist/cjs/payments/hobex-hps/payments.d.ts +19 -0
  8. package/dist/cjs/payments/hobex-hps/payments.js +160 -33
  9. package/dist/cjs/payments/hobex-hps/transaction-response.d.ts +180 -31
  10. package/dist/cjs/payments/hobex-hps/transaction-response.js +308 -88
  11. package/dist/cjs/payments/index.d.ts +1 -1
  12. package/dist/cjs/payments/index.js +8 -1
  13. package/dist/cjs/printing/escpos.d.ts +85 -1
  14. package/dist/cjs/printing/escpos.js +140 -4
  15. package/dist/cjs/printing/index.d.ts +2 -1
  16. package/dist/cjs/printing/index.js +13 -1
  17. package/dist/cjs/printing/qr-groesse.d.ts +122 -0
  18. package/dist/cjs/printing/qr-groesse.js +126 -0
  19. package/dist/cjs/receipt/epos.d.ts +42 -1
  20. package/dist/cjs/receipt/epos.js +66 -5
  21. package/dist/cjs/receipt/index.d.ts +2 -2
  22. package/dist/cjs/receipt/index.js +3 -1
  23. package/dist/cjs/receipt/layout-escpos.d.ts +50 -2
  24. package/dist/cjs/receipt/layout-escpos.js +59 -2
  25. package/dist/esm/payments/hobex-hps/index.d.ts +2 -2
  26. package/dist/esm/payments/hobex-hps/index.js +2 -2
  27. package/dist/esm/payments/hobex-hps/outcome.d.ts +20 -1
  28. package/dist/esm/payments/hobex-hps/outcome.js +10 -0
  29. package/dist/esm/payments/hobex-hps/payments.d.ts +19 -0
  30. package/dist/esm/payments/hobex-hps/payments.js +161 -34
  31. package/dist/esm/payments/hobex-hps/transaction-response.d.ts +180 -31
  32. package/dist/esm/payments/hobex-hps/transaction-response.js +302 -87
  33. package/dist/esm/payments/index.d.ts +1 -1
  34. package/dist/esm/payments/index.js +1 -1
  35. package/dist/esm/printing/escpos.d.ts +85 -1
  36. package/dist/esm/printing/escpos.js +138 -4
  37. package/dist/esm/printing/index.d.ts +2 -1
  38. package/dist/esm/printing/index.js +2 -1
  39. package/dist/esm/printing/qr-groesse.d.ts +122 -0
  40. package/dist/esm/printing/qr-groesse.js +120 -0
  41. package/dist/esm/receipt/epos.d.ts +42 -1
  42. package/dist/esm/receipt/epos.js +65 -5
  43. package/dist/esm/receipt/index.d.ts +2 -2
  44. package/dist/esm/receipt/index.js +2 -2
  45. package/dist/esm/receipt/layout-escpos.d.ts +50 -2
  46. package/dist/esm/receipt/layout-escpos.js +59 -3
  47. package/fixtures/hobex-hps-codes.json +365 -15
  48. package/fixtures/kasse-texte.json +1 -1
  49. package/fixtures/oberflaeche.json +1 -1
  50. package/package.json +1 -1
@@ -27,6 +27,7 @@
27
27
  * Nicht enthalten (bewusst): Rasterbilder/Logos, Capability-Profile einzelner
28
28
  * Druckermodelle, Kassenlade, 1D-Barcodes.
29
29
  */
30
+ import { type QrModulGroesse } from './qr-groesse.js';
30
31
  /** Papierbreite der Bonrolle. */
31
32
  export type PosPaperSize = 'mm58' | 'mm80';
32
33
  /** Ausrichtung einer Textzeile bzw. innerhalb einer Spalte. */
@@ -43,6 +44,14 @@ export type PosTextSize = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;
43
44
  export type QrSize = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;
44
45
  /** Fehlerkorrekturstufe des QR-Codes. */
45
46
  export type QrCorrection = 'L' | 'M' | 'Q' | 'H';
47
+ /**
48
+ * Fertig gerechnetes QR-Raster, quadratisch, `true` = schwarzes Modul —
49
+ * **ohne** Ruhezone, die setzt der Drucker-Weg selbst.
50
+ *
51
+ * Dieses Paket rastert bewusst nicht selbst (keine Bildverarbeitung, siehe
52
+ * Kopf dieser Datei); wer den Bildweg braucht, bringt sein eigenes Raster mit.
53
+ */
54
+ export type QrMatrix = readonly (readonly boolean[])[];
46
55
  /** Textstil. Fehlende Felder gelten als Vorgabewert (nicht als "unveraendert"). */
47
56
  export interface PosStyles {
48
57
  bold?: boolean;
@@ -88,8 +97,26 @@ export interface EscPosHrOptions {
88
97
  }
89
98
  export interface EscPosQrOptions {
90
99
  align?: PosAlign;
100
+ /**
101
+ * Feste Modulgroesse in Druckpunkten. Gesetzt schaltet sie die Rechnung ab —
102
+ * fuer Aufrufer, die genau wissen, was ihr Geraet kann. Ohne sie entscheidet
103
+ * die Regel in `qr-groesse.ts`.
104
+ */
91
105
  size?: QrSize;
92
106
  correction?: QrCorrection;
107
+ /** Deckel fuer die gerechnete Modulgroesse; wirkungslos neben `size`. */
108
+ groesse?: QrModulGroesse;
109
+ /** Modell 1 des Symbols ausdruecklich waehlen — siehe `qrCodeBytes`. */
110
+ modell1?: boolean;
111
+ }
112
+ export interface EscPosQrRasterOptions {
113
+ align?: PosAlign;
114
+ /** Feste Punkte je Modul; ohne Angabe gerechnet (mindestens 1). */
115
+ punkteJeModul?: number;
116
+ /** Deckel fuer die gerechnete Groesse. */
117
+ groesse?: QrModulGroesse;
118
+ /** Ruhezone je Seite in Modulen; Vorgabe `QR_RUHEZONE_MODULE` (4). */
119
+ ruhezoneModule?: number;
93
120
  }
94
121
  /** Interner Stilzustand — immer vollstaendig, nie teilbefuellt. */
95
122
  interface AktuelleStile {
@@ -111,6 +138,25 @@ interface AktuelleStile {
111
138
  export interface EscPosDocument {
112
139
  readonly paperSize: PosPaperSize;
113
140
  readonly spaceBetweenRows: number;
141
+ /**
142
+ * Der Beleg ging ohne QR hinaus — `null`, solange alles in Ordnung ist.
143
+ * Gesetzt, wenn das Symbol auch mit der Ausnahmegroesse nicht auf das Papier
144
+ * passt und kein Bildweg mitgegeben wurde. Auf einer oesterreichischen Kassa
145
+ * ist der QR die maschinenlesbare Signatur: das muss der Aufrufer erfahren,
146
+ * ohne den Bytestrom zu durchsuchen.
147
+ */
148
+ qrFehler: string | null;
149
+ /**
150
+ * Der QR steht auf dem Papier, aber nicht so wie eingestellt — `null`,
151
+ * solange nichts abgewichen ist. Zwei Faelle, beide mit Grund im Text: das
152
+ * Symbol war fuer den nativen Befehl zu breit und ging als Bild hinaus, oder
153
+ * es passte nur unter der Mindest-Modulgroesse.
154
+ *
155
+ * Getrennt von `qrFehler`, weil die Handlung eine andere ist: dort heisst es
156
+ * "Beleg ohne QR, nachdrucken oder elektronisch ausgeben", hier "gedruckt,
157
+ * aber der eingestellte Weg taugt fuer dieses Geraet nicht".
158
+ */
159
+ qrAusweich: string | null;
114
160
  /** intern: bisher erzeugte Bytes */
115
161
  readonly bytes: number[];
116
162
  /** intern: global gesetzte Codepage (ueberlebt `escPosReset`) */
@@ -213,7 +259,45 @@ export declare function escPosRow(doc: EscPosDocument, columns: readonly PosColu
213
259
  export declare function qrCodeBytes(text: string, options?: {
214
260
  size?: QrSize;
215
261
  correction?: QrCorrection;
262
+ modell1?: boolean;
216
263
  }): Uint8Array;
217
- /** Setzt die Ausrichtung und haengt den nativen QR-Befehl an. */
264
+ /**
265
+ * Setzt die Ausrichtung und haengt den nativen QR-Befehl an — mit
266
+ * **gerechneter** Modulgroesse, sofern `options.size` sie nicht festlegt.
267
+ *
268
+ * Ohne `size` entscheidet die Regel aus `qr-groesse.ts`: so gross wie
269
+ * moeglich, gedeckelt durch `options.groesse` (Vorgabe `auto` = der
270
+ * Bestandswert 4 dieses Pakets). Passt das Symbol auch mit der
271
+ * Ausnahmegroesse nicht aufs Papier, geht **kein** QR-Befehl hinaus und
272
+ * `doc.qrFehler` sagt warum: der Drucker schneidet ein zu breites Symbol
273
+ * nicht ab, er laesst es weg — ein Befehl, von dem man weiss, dass er nichts
274
+ * druckt, taeuschte nur einen Ausdruck vor. Den Bildweg kennt diese Ebene
275
+ * nicht; den faehrt `escPosQrRaster` bzw. der Belegweg in `layout-escpos.ts`.
276
+ *
277
+ * Eine leere Nutzlast geht unveraendert durch (fester Bestandsweg, keine
278
+ * Rechnung): sie ist ein Datenfehler, kein Papierfehler, und der Aufrufer
279
+ * behandelt sie ohnehin schon.
280
+ */
218
281
  export declare function escPosQrCode(doc: EscPosDocument, text: string, options?: EscPosQrOptions): void;
282
+ /**
283
+ * Der Bildweg: ein fertiges QR-Raster als Rasterbild (`GS v 0`) — der
284
+ * Notausgang, wenn der native Befehl das Symbol nicht auf das Papier bringt.
285
+ *
286
+ * Ein Pflichtbeleg ohne QR ist der schlechteste aller Ausgaenge; als Bild
287
+ * geht jedes Symbol hinaus, weil die Punkte je Modul hier bis auf 1 fallen
288
+ * duerfen. Dafuer ist das Bild langsamer und auf manchen Geraeten blasser.
289
+ *
290
+ * Das Raster selbst kommt vom Aufrufer (siehe `QrMatrix`): dieses Paket
291
+ * rechnet keine QR-Codes und verarbeitet keine Bilder.
292
+ */
293
+ export declare function escPosQrRaster(doc: EscPosDocument, matrix: QrMatrix, options?: EscPosQrRasterOptions): void;
294
+ /**
295
+ * Punkte je Modul, mit denen `escPosQrRaster` ein Raster dieser Groesse auf
296
+ * dieses Papier bringt — dieselbe Rechnung, nur ohne Untergrenze 3: ein Bild
297
+ * darf bis auf einen Punkt je Modul schrumpfen und passt darum immer.
298
+ */
299
+ export declare function qrRasterPunkte(paperSize: PosPaperSize, moduleAnzahl: number, options?: {
300
+ groesse?: QrModulGroesse;
301
+ ruhezoneModule?: number;
302
+ }): number;
219
303
  export {};
@@ -47,6 +47,9 @@ exports.escPosHr = escPosHr;
47
47
  exports.escPosRow = escPosRow;
48
48
  exports.qrCodeBytes = qrCodeBytes;
49
49
  exports.escPosQrCode = escPosQrCode;
50
+ exports.escPosQrRaster = escPosQrRaster;
51
+ exports.qrRasterPunkte = qrRasterPunkte;
52
+ const qr_groesse_js_1 = require("./qr-groesse.js");
50
53
  // -------------------------------------------------------------- Befehlsbytes
51
54
  // Wortwoertlich aus commands.dart. Die Zahlen sind ASCII-Codes der dortigen
52
55
  // Zeichenketten: cCutFull = '$gs' + 'V0' ist GS 0x56 0x30 — die Ziffer '0',
@@ -81,6 +84,8 @@ const ZEILENUMBRUCH = 0x0a;
81
84
  const CODEPAGE_ID = { CP437: 0, CP1252: 16 };
82
85
  /** Korrekturstufen fuer GS ( k Funktion 169 — aus qrcode.dart. */
83
86
  const QR_KORREKTUR = { L: 48, M: 49, Q: 50, H: 51 };
87
+ /** Nennbreite der Rolle in Millimetern — nur fuer Meldungstexte. */
88
+ const PAPIER_MM = { mm58: 58, mm80: 80 };
84
89
  /** Druckbreite in Punkten je Papierformat — aus enums.dart (EscPaperSize.width). */
85
90
  const PAPIER_BREITE = { mm58: 372, mm80: 558 };
86
91
  /** Zeichen je Zeile nach Papier und Schrift — aus generator.dart. */
@@ -231,6 +236,8 @@ function createEscPosDocument(options = {}) {
231
236
  globalFont: null,
232
237
  maxCharsPerLine: null,
233
238
  styles: vollstaendigeStile(),
239
+ qrFehler: null,
240
+ qrAusweich: null,
234
241
  };
235
242
  }
236
243
  /** Die bisher erzeugten Bytes als Kopie. */
@@ -245,6 +252,10 @@ function escPosBytes(doc) {
245
252
  function escPosReset(doc) {
246
253
  anhaengen(doc, C_INIT);
247
254
  doc.styles = vollstaendigeStile();
255
+ // Wie `PrintPaper.reset()` im Flutter-Zwilling: ein neu begonnener Beleg
256
+ // erbt die QR-Meldungen des vorigen nicht.
257
+ doc.qrFehler = null;
258
+ doc.qrAusweich = null;
248
259
  escPosSetGlobalCodeTable(doc, doc.globalCodeTable);
249
260
  escPosSetGlobalFont(doc, doc.globalFont);
250
261
  }
@@ -609,6 +620,16 @@ function qrCodeBytes(text, options = {}) {
609
620
  throw new Error('QR-Inhalt ist zu lang');
610
621
  }
611
622
  const bytes = [];
623
+ // Funktion 165: Symboltyp. Ohne diesen Befehl — dem Bestandsweg — waehlt der
624
+ // Drucker sein eigenes Modell, in aller Regel Modell 2. Genau das koennen
625
+ // manche guenstigen Geraete nicht: belegt ist eines, das unter dem Code eine
626
+ // "0" ausgibt, das Parameterbyte 0x30 des Druckbefehls, das es nicht als
627
+ // Befehl erkannt hat. Der Befehl geht deshalb nur hinaus, wenn er
628
+ // ausdruecklich verlangt ist; ein aufgedraengtes "Modell 2 fuer alle" waere
629
+ // eine stille Umstellung an jedem Bestandsgeraet.
630
+ if (options.modell1 === true) {
631
+ bytes.push(...C_QR_HEADER, 0x04, 0x00, 0x31, 0x41, 0x31, 0x00);
632
+ }
612
633
  // Funktion 167: Modulgroesse
613
634
  bytes.push(...C_QR_HEADER, 0x03, 0x00, 0x31, 0x43, size);
614
635
  // Funktion 169: Fehlerkorrektur
@@ -624,15 +645,57 @@ function qrCodeBytes(text, options = {}) {
624
645
  bytes.push(...C_QR_HEADER, 0x03, 0x00, 0x31, 0x51, 0x30);
625
646
  return Uint8Array.from(bytes);
626
647
  }
627
- /** Setzt die Ausrichtung und haengt den nativen QR-Befehl an. */
648
+ /**
649
+ * Setzt die Ausrichtung und haengt den nativen QR-Befehl an — mit
650
+ * **gerechneter** Modulgroesse, sofern `options.size` sie nicht festlegt.
651
+ *
652
+ * Ohne `size` entscheidet die Regel aus `qr-groesse.ts`: so gross wie
653
+ * moeglich, gedeckelt durch `options.groesse` (Vorgabe `auto` = der
654
+ * Bestandswert 4 dieses Pakets). Passt das Symbol auch mit der
655
+ * Ausnahmegroesse nicht aufs Papier, geht **kein** QR-Befehl hinaus und
656
+ * `doc.qrFehler` sagt warum: der Drucker schneidet ein zu breites Symbol
657
+ * nicht ab, er laesst es weg — ein Befehl, von dem man weiss, dass er nichts
658
+ * druckt, taeuschte nur einen Ausdruck vor. Den Bildweg kennt diese Ebene
659
+ * nicht; den faehrt `escPosQrRaster` bzw. der Belegweg in `layout-escpos.ts`.
660
+ *
661
+ * Eine leere Nutzlast geht unveraendert durch (fester Bestandsweg, keine
662
+ * Rechnung): sie ist ein Datenfehler, kein Papierfehler, und der Aufrufer
663
+ * behandelt sie ohnehin schon.
664
+ */
628
665
  function escPosQrCode(doc, text, options = {}) {
629
666
  escPosSetStyles(doc, { align: options.align ?? 'center' });
630
667
  const qrOptionen = {};
631
- if (options.size !== undefined)
632
- qrOptionen.size = options.size;
633
668
  if (options.correction !== undefined)
634
669
  qrOptionen.correction = options.correction;
635
- anhaengen(doc, qrCodeBytes(text, qrOptionen));
670
+ if (options.modell1 !== undefined)
671
+ qrOptionen.modell1 = options.modell1;
672
+ let drucken = true;
673
+ if (options.size !== undefined) {
674
+ qrOptionen.size = options.size;
675
+ }
676
+ else if (text !== '') {
677
+ const mass = (0, qr_groesse_js_1.qrGroesseFuer)({
678
+ nutzlast: text,
679
+ papierbreitePunkte: qr_groesse_js_1.QR_DRUCK_PUNKTE[doc.paperSize],
680
+ groesse: options.groesse ?? 'auto',
681
+ });
682
+ if (!mass.passt) {
683
+ doc.qrFehler =
684
+ `QR mit ${mass.module} Modulen ist fuer ${PAPIER_MM[doc.paperSize]} mm ` +
685
+ `(${qr_groesse_js_1.QR_DRUCK_PUNKTE[doc.paperSize]} Punkte) zu breit`;
686
+ drucken = false;
687
+ }
688
+ else {
689
+ if (mass.unterMindestmass) {
690
+ doc.qrAusweich =
691
+ `QR mit ${mass.module} Modulen passt nur mit ${String(mass.punkte)} Punkten ` +
692
+ `je Modul — unter dem Mindestmass von ${qr_groesse_js_1.QR_MINDEST_PUNKTE}`;
693
+ }
694
+ qrOptionen.size = mass.punkte;
695
+ }
696
+ }
697
+ if (drucken)
698
+ anhaengen(doc, qrCodeBytes(text, qrOptionen));
636
699
  // Ausrichtung SOFORT zuruecksetzen: `ESC a` gilt nur am Zeilenanfang. Die
637
700
  // Spalten-Positionierung (`ESC $`) schickt ihren Reset sonst mitten in der
638
701
  // Zeile — Epson ignoriert ihn, und alles nach dem QR rueckte nach rechts
@@ -641,3 +704,76 @@ function escPosQrCode(doc, text, options = {}) {
641
704
  escPosSetStyles(doc, { align: 'left' });
642
705
  }
643
706
  }
707
+ /**
708
+ * Der Bildweg: ein fertiges QR-Raster als Rasterbild (`GS v 0`) — der
709
+ * Notausgang, wenn der native Befehl das Symbol nicht auf das Papier bringt.
710
+ *
711
+ * Ein Pflichtbeleg ohne QR ist der schlechteste aller Ausgaenge; als Bild
712
+ * geht jedes Symbol hinaus, weil die Punkte je Modul hier bis auf 1 fallen
713
+ * duerfen. Dafuer ist das Bild langsamer und auf manchen Geraeten blasser.
714
+ *
715
+ * Das Raster selbst kommt vom Aufrufer (siehe `QrMatrix`): dieses Paket
716
+ * rechnet keine QR-Codes und verarbeitet keine Bilder.
717
+ */
718
+ function escPosQrRaster(doc, matrix, options = {}) {
719
+ const module = matrix.length;
720
+ if (module <= 0)
721
+ throw new Error('QR-Raster ist leer');
722
+ for (const zeile of matrix) {
723
+ if (zeile.length !== module)
724
+ throw new Error('QR-Raster ist nicht quadratisch');
725
+ }
726
+ const ruhezone = options.ruhezoneModule ?? qr_groesse_js_1.QR_RUHEZONE_MODULE;
727
+ if (!istGanzzahl(ruhezone) || ruhezone < 0) {
728
+ throw new Error('ruhezoneModule muss eine Ganzzahl >= 0 sein');
729
+ }
730
+ const gesamtModule = module + 2 * ruhezone;
731
+ let punkte = options.punkteJeModul;
732
+ if (punkte === undefined) {
733
+ const deckel = qr_groesse_js_1.QR_MODUL_DECKEL[options.groesse ?? 'auto'];
734
+ punkte = Math.max(1, Math.min(deckel, Math.floor(qr_groesse_js_1.QR_DRUCK_PUNKTE[doc.paperSize] / gesamtModule)));
735
+ }
736
+ if (!istGanzzahl(punkte) || punkte < 1) {
737
+ throw new Error('punkteJeModul muss eine Ganzzahl >= 1 sein');
738
+ }
739
+ const breite = gesamtModule * punkte;
740
+ const byteJeZeile = Math.ceil(breite / 8);
741
+ const daten = new Uint8Array(byteJeZeile * breite);
742
+ for (let y = 0; y < breite; y++) {
743
+ const modulY = Math.floor(y / punkte) - ruhezone;
744
+ if (modulY < 0 || modulY >= module)
745
+ continue;
746
+ const zeile = matrix[modulY];
747
+ for (let x = 0; x < breite; x++) {
748
+ const modulX = Math.floor(x / punkte) - ruhezone;
749
+ if (modulX < 0 || modulX >= module)
750
+ continue;
751
+ if (zeile[modulX] !== true)
752
+ continue;
753
+ const i = y * byteJeZeile + (x >> 3);
754
+ daten[i] = daten[i] | (0x80 >> (x & 7));
755
+ }
756
+ }
757
+ escPosSetStyles(doc, { align: options.align ?? 'center' });
758
+ // GS v 0 m xL xH yL yH d1...dk — m = 0: normale Dichte, 1:1.
759
+ anhaengen(doc, [
760
+ GS, 0x76, 0x30, 0x00,
761
+ byteJeZeile & 0xff, (byteJeZeile >> 8) & 0xff,
762
+ breite & 0xff, (breite >> 8) & 0xff,
763
+ ...daten,
764
+ ]);
765
+ anhaengen(doc, [ZEILENUMBRUCH]);
766
+ if ((options.align ?? 'center') !== 'left') {
767
+ escPosSetStyles(doc, { align: 'left' });
768
+ }
769
+ }
770
+ /**
771
+ * Punkte je Modul, mit denen `escPosQrRaster` ein Raster dieser Groesse auf
772
+ * dieses Papier bringt — dieselbe Rechnung, nur ohne Untergrenze 3: ein Bild
773
+ * darf bis auf einen Punkt je Modul schrumpfen und passt darum immer.
774
+ */
775
+ function qrRasterPunkte(paperSize, moduleAnzahl, options = {}) {
776
+ const ruhezone = options.ruhezoneModule ?? qr_groesse_js_1.QR_RUHEZONE_MODULE;
777
+ const deckel = qr_groesse_js_1.QR_MODUL_DECKEL[options.groesse ?? 'auto'];
778
+ return Math.max(1, Math.min(deckel, Math.floor(qr_groesse_js_1.QR_DRUCK_PUNKTE[paperSize] / (moduleAnzahl + 2 * ruhezone))));
779
+ }
@@ -1,3 +1,4 @@
1
- export { type PosPaperSize, type PosAlign, type PosFont, type PosCutMode, type PosCodeTable, type PosTextSize, type QrSize, type QrCorrection, type PosStyles, type PosColumn, type EscPosOptions, type EscPosTextOptions, type EscPosHrOptions, type EscPosQrOptions, type EscPosDocument, createEscPosDocument, escPosBytes, escPosReset, escPosSetGlobalCodeTable, escPosSetGlobalFont, escPosSetStyles, escPosText, escPosEmptyLines, escPosFeed, escPosCut, escPosHr, escPosRow, escPosQrCode, encodeEscPosText, qrCodeBytes, escPosMaxCharsPerLine, escPosWortzeilen, wortzeilenText, } from './escpos.js';
1
+ export { type PosPaperSize, type PosAlign, type PosFont, type PosCutMode, type PosCodeTable, type PosTextSize, type QrSize, type QrCorrection, type QrMatrix, type PosStyles, type PosColumn, type EscPosOptions, type EscPosTextOptions, type EscPosHrOptions, type EscPosQrOptions, type EscPosQrRasterOptions, type EscPosDocument, createEscPosDocument, escPosBytes, escPosReset, escPosSetGlobalCodeTable, escPosSetGlobalFont, escPosSetStyles, escPosText, escPosEmptyLines, escPosFeed, escPosCut, escPosHr, escPosRow, escPosQrCode, escPosQrRaster, qrRasterPunkte, encodeEscPosText, qrCodeBytes, escPosMaxCharsPerLine, escPosWortzeilen, wortzeilenText, } from './escpos.js';
2
+ export { type QrModulGroesse, type QrGroesse, QR_MODUL_DECKEL, QR_RUHEZONE_MODULE, QR_MINDEST_PUNKTE, QR_AUSNAHME_PUNKTE, QR_HOECHST_PUNKTE, QR_DRUCK_PUNKTE, qrModulAnzahl, qrGroesseBerechnen, qrGroesseFuer, } from './qr-groesse.js';
2
3
  export { escPosPrintableText } from './printable.js';
3
4
  export { type UsbEndpointLike, type UsbAlternateLike, type UsbInterfaceLike, type UsbConfigurationLike, type UsbTransferOutResultLike, type UsbWriterLike, type UsbIdentityLike, type UsbDeviceLike, type UsbPrinterEndpoint, type UsbPrinterConnection, USB_VENDOR_EPSON, USB_CLASS_PRINTER, UsbTimeoutError, usbDeviceKey, usbFindPrinterEndpoint, usbWriteAll, usbConnectPrinter, usbPrint, usbDisconnect, } from './webusb.js';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.usbDisconnect = exports.usbPrint = exports.usbConnectPrinter = exports.usbWriteAll = exports.usbFindPrinterEndpoint = exports.usbDeviceKey = exports.UsbTimeoutError = exports.USB_CLASS_PRINTER = exports.USB_VENDOR_EPSON = exports.escPosPrintableText = exports.wortzeilenText = exports.escPosWortzeilen = exports.escPosMaxCharsPerLine = exports.qrCodeBytes = exports.encodeEscPosText = exports.escPosQrCode = exports.escPosRow = exports.escPosHr = exports.escPosCut = exports.escPosFeed = exports.escPosEmptyLines = exports.escPosText = exports.escPosSetStyles = exports.escPosSetGlobalFont = exports.escPosSetGlobalCodeTable = exports.escPosReset = exports.escPosBytes = exports.createEscPosDocument = void 0;
3
+ exports.usbDisconnect = exports.usbPrint = exports.usbConnectPrinter = exports.usbWriteAll = exports.usbFindPrinterEndpoint = exports.usbDeviceKey = exports.UsbTimeoutError = exports.USB_CLASS_PRINTER = exports.USB_VENDOR_EPSON = exports.escPosPrintableText = exports.qrGroesseFuer = exports.qrGroesseBerechnen = exports.qrModulAnzahl = exports.QR_DRUCK_PUNKTE = exports.QR_HOECHST_PUNKTE = exports.QR_AUSNAHME_PUNKTE = exports.QR_MINDEST_PUNKTE = exports.QR_RUHEZONE_MODULE = exports.QR_MODUL_DECKEL = exports.wortzeilenText = exports.escPosWortzeilen = exports.escPosMaxCharsPerLine = exports.qrCodeBytes = exports.encodeEscPosText = exports.qrRasterPunkte = exports.escPosQrRaster = exports.escPosQrCode = exports.escPosRow = exports.escPosHr = exports.escPosCut = exports.escPosFeed = exports.escPosEmptyLines = exports.escPosText = exports.escPosSetStyles = exports.escPosSetGlobalFont = exports.escPosSetGlobalCodeTable = exports.escPosReset = exports.escPosBytes = exports.createEscPosDocument = void 0;
4
4
  var escpos_js_1 = require("./escpos.js");
5
5
  Object.defineProperty(exports, "createEscPosDocument", { enumerable: true, get: function () { return escpos_js_1.createEscPosDocument; } });
6
6
  Object.defineProperty(exports, "escPosBytes", { enumerable: true, get: function () { return escpos_js_1.escPosBytes; } });
@@ -15,11 +15,23 @@ Object.defineProperty(exports, "escPosCut", { enumerable: true, get: function ()
15
15
  Object.defineProperty(exports, "escPosHr", { enumerable: true, get: function () { return escpos_js_1.escPosHr; } });
16
16
  Object.defineProperty(exports, "escPosRow", { enumerable: true, get: function () { return escpos_js_1.escPosRow; } });
17
17
  Object.defineProperty(exports, "escPosQrCode", { enumerable: true, get: function () { return escpos_js_1.escPosQrCode; } });
18
+ Object.defineProperty(exports, "escPosQrRaster", { enumerable: true, get: function () { return escpos_js_1.escPosQrRaster; } });
19
+ Object.defineProperty(exports, "qrRasterPunkte", { enumerable: true, get: function () { return escpos_js_1.qrRasterPunkte; } });
18
20
  Object.defineProperty(exports, "encodeEscPosText", { enumerable: true, get: function () { return escpos_js_1.encodeEscPosText; } });
19
21
  Object.defineProperty(exports, "qrCodeBytes", { enumerable: true, get: function () { return escpos_js_1.qrCodeBytes; } });
20
22
  Object.defineProperty(exports, "escPosMaxCharsPerLine", { enumerable: true, get: function () { return escpos_js_1.escPosMaxCharsPerLine; } });
21
23
  Object.defineProperty(exports, "escPosWortzeilen", { enumerable: true, get: function () { return escpos_js_1.escPosWortzeilen; } });
22
24
  Object.defineProperty(exports, "wortzeilenText", { enumerable: true, get: function () { return escpos_js_1.wortzeilenText; } });
25
+ var qr_groesse_js_1 = require("./qr-groesse.js");
26
+ Object.defineProperty(exports, "QR_MODUL_DECKEL", { enumerable: true, get: function () { return qr_groesse_js_1.QR_MODUL_DECKEL; } });
27
+ Object.defineProperty(exports, "QR_RUHEZONE_MODULE", { enumerable: true, get: function () { return qr_groesse_js_1.QR_RUHEZONE_MODULE; } });
28
+ Object.defineProperty(exports, "QR_MINDEST_PUNKTE", { enumerable: true, get: function () { return qr_groesse_js_1.QR_MINDEST_PUNKTE; } });
29
+ Object.defineProperty(exports, "QR_AUSNAHME_PUNKTE", { enumerable: true, get: function () { return qr_groesse_js_1.QR_AUSNAHME_PUNKTE; } });
30
+ Object.defineProperty(exports, "QR_HOECHST_PUNKTE", { enumerable: true, get: function () { return qr_groesse_js_1.QR_HOECHST_PUNKTE; } });
31
+ Object.defineProperty(exports, "QR_DRUCK_PUNKTE", { enumerable: true, get: function () { return qr_groesse_js_1.QR_DRUCK_PUNKTE; } });
32
+ Object.defineProperty(exports, "qrModulAnzahl", { enumerable: true, get: function () { return qr_groesse_js_1.qrModulAnzahl; } });
33
+ Object.defineProperty(exports, "qrGroesseBerechnen", { enumerable: true, get: function () { return qr_groesse_js_1.qrGroesseBerechnen; } });
34
+ Object.defineProperty(exports, "qrGroesseFuer", { enumerable: true, get: function () { return qr_groesse_js_1.qrGroesseFuer; } });
23
35
  var printable_js_1 = require("./printable.js");
24
36
  Object.defineProperty(exports, "escPosPrintableText", { enumerable: true, get: function () { return printable_js_1.escPosPrintableText; } });
25
37
  var webusb_js_1 = require("./webusb.js");
@@ -0,0 +1,122 @@
1
+ import type { PosPaperSize, QrSize } from './escpos.js';
2
+ /**
3
+ * Die Rechenregel fuer die Modulgroesse des Beleg-QR — rein, ohne Drucker.
4
+ * Zwilling von `kasseneck_api/lib/src/printing/qr_groesse.dart` (Flutter).
5
+ *
6
+ * Vorgeschichte: der native QR-Befehl bekommt eine feste Modulgroesse in
7
+ * Druckpunkten mit und rechnet nicht nach, ob das Symbol aufs Papier passt.
8
+ * Ein Beleg-QR mit realer RKSV-Nutzlast hat 57 Module, mit Ruhezone also
9
+ * (57 + 8) Module breit; bei sechs Punkten je Modul sind das 390 Druckpunkte,
10
+ * und ein 58-mm-Kopf hat 384. Zu breit heisst bei den meisten Geraeten nicht
11
+ * "abgeschnitten", sondern **gar kein QR** — auf einem Pflichtbeleg der
12
+ * schlechteste aller Ausgaenge. (Im Flutter-Zwilling war genau das der
13
+ * belegte Fehler; dieses Paket druckt seit jeher mit vier Punkten und blieb
14
+ * darum verschont. Die Regel ist trotzdem dieselbe: sie deckelt auch eine
15
+ * ausdruecklich gewaehlte groessere Modulgroesse gegen den Papierrand ab.)
16
+ */
17
+ /**
18
+ * Wie gross die Module des Beleg-QR werden duerfen — ein **Deckel**, keine
19
+ * Vorgabe: gedruckt wird immer die groesste Groesse, die noch aufs Papier
20
+ * passt, hoechstens aber diese hier.
21
+ *
22
+ * `auto` und `klein` decken beide bei 4 — das ist kein Versehen. 4 ist der
23
+ * Wert, den der native Weg dieses Pakets seit jeher druckt
24
+ * (`qrCodeBytes(..., size ?? 4)`); ohne diesen Deckel bekaeme jedes Geraet ab
25
+ * sofort ungefragt einen groesseren QR als gestern. `auto` heisst also
26
+ * "rechne, aber aendere den Bestand nicht".
27
+ *
28
+ * **Abweichung zum Flutter-Zwilling, bewusst:** dort deckelt `auto` bei 6,
29
+ * weil dort 6 der Bestandswert ist. Die Regel ist in beiden Paketen
30
+ * dieselbe — "so gross wie moeglich, hoechstens der Bestandswert" —, nur der
31
+ * Bestandswert unterscheidet sich. `mittel` (6) und `gross` (8) sind in
32
+ * beiden Paketen gleich; sie waehlt ein Mensch.
33
+ */
34
+ export type QrModulGroesse = 'auto' | 'klein' | 'mittel' | 'gross';
35
+ /** Groesste Modulgroesse in Druckpunkten, die der jeweilige Deckel zulaesst. */
36
+ export declare const QR_MODUL_DECKEL: Readonly<Record<QrModulGroesse, number>>;
37
+ /**
38
+ * Ergebnis der Modulgroessen-Rechnung.
39
+ *
40
+ * Traegt bewusst mehr als die Zahl: ob ueberhaupt etwas passt (`passt`), ob
41
+ * nur unter der Mindestgroesse (`unterMindestmass`) und wie breit das Symbol
42
+ * wird (`breitePunkte`). Eine blosse Zahl haette die Ausnahme verschwiegen.
43
+ */
44
+ export interface QrGroesse {
45
+ /**
46
+ * Modulgroesse in Druckpunkten, `null` wenn das Symbol auch mit der
47
+ * Ausnahmegroesse nicht aufs Papier passt.
48
+ */
49
+ readonly punkte: QrSize | null;
50
+ /** Modulanzahl des Symbols (ohne Ruhezone). */
51
+ readonly module: number;
52
+ /** Gesamtbreite inklusive Ruhezone in Druckpunkten; 0, wenn nichts passt. */
53
+ readonly breitePunkte: number;
54
+ /**
55
+ * Gedruckt wird unter `QR_MINDEST_PUNKTE`. Erlaubt, aber eine Ausnahme, von
56
+ * der der Aufrufer erfahren muss — billige Thermodrucker und Handykameras
57
+ * tun sich damit schwer, besonders auf gewelltem Papier.
58
+ */
59
+ readonly unterMindestmass: boolean;
60
+ /** Kurz fuer `punkte !== null`. */
61
+ readonly passt: boolean;
62
+ }
63
+ /** Ruhezone je Seite, in Modulen (QR-Norm). */
64
+ export declare const QR_RUHEZONE_MODULE = 4;
65
+ /** Untergrenze: 4 Punkte sind bei 203 dpi rund 0,5 mm je Modul. */
66
+ export declare const QR_MINDEST_PUNKTE = 4;
67
+ /** Ausnahme, wenn `QR_MINDEST_PUNKTE` nicht passt — gemeldet, nicht still. */
68
+ export declare const QR_AUSNAHME_PUNKTE = 3;
69
+ /** Obergrenze des Druckbefehls in diesem Stack (`GS ( k` Funktion 167: 1..8). */
70
+ export declare const QR_HOECHST_PUNKTE = 8;
71
+ /**
72
+ * Druckbreite des Kopfes in Punkten (203 dpi): 58 mm = 384, 80 mm = 576 —
73
+ * Zwilling von `KeckPaperSize.druckPunkte`.
74
+ *
75
+ * Nicht dasselbe wie die Spaltenbreite in `escpos.ts` (372/558): die stammt
76
+ * aus `EscPaperSize.width` und laesst absichtlich Rand fuer die
77
+ * Textpositionierung. Wer rechnet, ob ein Symbol aufs Papier passt, braucht
78
+ * die echte Kopfbreite — ein QR, der auch nur einen Punkt zu breit ist, wird
79
+ * von den meisten Geraeten gar nicht gedruckt.
80
+ */
81
+ export declare const QR_DRUCK_PUNKTE: Readonly<Record<PosPaperSize, number>>;
82
+ /**
83
+ * Modulanzahl, die `nutzlast` bei Fehlerkorrektur **M** braucht.
84
+ *
85
+ * Warum M, obwohl der native Befehl mit L druckt: M braucht bei gleicher
86
+ * Nutzlast gleich viele oder mehr Module als L. Wer mit M rechnet und mit L
87
+ * druckt, druckt nie breiter als gerechnet — die Rechnung ist konservativ,
88
+ * nie knapp. Umgekehrt waere sie eine Rechnung, die aufgeht, und ein Symbol,
89
+ * das ueber den Papierrand laeuft. Dasselbe gilt fuer die Byte-Zaehlung: hier
90
+ * zaehlt UTF-8 (wie im Flutter-Zwilling), waehrend `qrCodeBytes` die Nutzlast
91
+ * als Latin-1 sendet — UTF-8 ist nie kuerzer, die Rechnung also nie zu klein.
92
+ *
93
+ * Wirft, wenn die Nutzlast in keine Version passt — wie `qrCodeBytes` bei zu
94
+ * langem Inhalt. Ein still zurueckgegebenes "passt nicht" haette den
95
+ * Datenfehler als Papierfehler getarnt.
96
+ */
97
+ export declare function qrModulAnzahl(nutzlast: string): number;
98
+ /**
99
+ * Groesste Modulgroesse, mit der `moduleAnzahl` Module **samt Ruhezone** in
100
+ * `papierbreitePunkte` passen, gedeckelt durch `groesse`.
101
+ *
102
+ * Wirft bei sinnlosen Eingaben: eine Papierbreite von 0 oder ein Symbol ohne
103
+ * Module ist ein Programmierfehler, und ein still zurueckgegebenes "passt
104
+ * nicht" haette ihn als Druckerproblem getarnt.
105
+ */
106
+ export declare function qrGroesseBerechnen(options: {
107
+ papierbreitePunkte: number;
108
+ moduleAnzahl: number;
109
+ groesse?: QrModulGroesse;
110
+ }): QrGroesse;
111
+ /**
112
+ * Wie `qrGroesseBerechnen`, nur mit der Modulanzahl aus `nutzlast`.
113
+ *
114
+ * Eine leere Nutzlast ergibt kein Symbol — sie "passt nicht", statt zu
115
+ * werfen: der Aufrufer behandelt den Fall ohnehin schon (leerer QR am Beleg
116
+ * ist ein Datenfehler, kein Papierfehler).
117
+ */
118
+ export declare function qrGroesseFuer(options: {
119
+ nutzlast: string;
120
+ papierbreitePunkte: number;
121
+ groesse?: QrModulGroesse;
122
+ }): QrGroesse;
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.QR_DRUCK_PUNKTE = exports.QR_HOECHST_PUNKTE = exports.QR_AUSNAHME_PUNKTE = exports.QR_MINDEST_PUNKTE = exports.QR_RUHEZONE_MODULE = exports.QR_MODUL_DECKEL = void 0;
4
+ exports.qrModulAnzahl = qrModulAnzahl;
5
+ exports.qrGroesseBerechnen = qrGroesseBerechnen;
6
+ exports.qrGroesseFuer = qrGroesseFuer;
7
+ /** Groesste Modulgroesse in Druckpunkten, die der jeweilige Deckel zulaesst. */
8
+ exports.QR_MODUL_DECKEL = {
9
+ auto: 4,
10
+ klein: 4,
11
+ mittel: 6,
12
+ gross: 8,
13
+ };
14
+ // --------------------------------------------------------------- Konstanten
15
+ /** Ruhezone je Seite, in Modulen (QR-Norm). */
16
+ exports.QR_RUHEZONE_MODULE = 4;
17
+ /** Untergrenze: 4 Punkte sind bei 203 dpi rund 0,5 mm je Modul. */
18
+ exports.QR_MINDEST_PUNKTE = 4;
19
+ /** Ausnahme, wenn `QR_MINDEST_PUNKTE` nicht passt — gemeldet, nicht still. */
20
+ exports.QR_AUSNAHME_PUNKTE = 3;
21
+ /** Obergrenze des Druckbefehls in diesem Stack (`GS ( k` Funktion 167: 1..8). */
22
+ exports.QR_HOECHST_PUNKTE = 8;
23
+ /**
24
+ * Druckbreite des Kopfes in Punkten (203 dpi): 58 mm = 384, 80 mm = 576 —
25
+ * Zwilling von `KeckPaperSize.druckPunkte`.
26
+ *
27
+ * Nicht dasselbe wie die Spaltenbreite in `escpos.ts` (372/558): die stammt
28
+ * aus `EscPaperSize.width` und laesst absichtlich Rand fuer die
29
+ * Textpositionierung. Wer rechnet, ob ein Symbol aufs Papier passt, braucht
30
+ * die echte Kopfbreite — ein QR, der auch nur einen Punkt zu breit ist, wird
31
+ * von den meisten Geraeten gar nicht gedruckt.
32
+ */
33
+ exports.QR_DRUCK_PUNKTE = { mm58: 384, mm80: 576 };
34
+ /**
35
+ * Nutzlast in Byte, die eine QR-Version 1..40 bei Fehlerkorrektur **M** im
36
+ * Byte-Modus aufnimmt (ISO/IEC 18004, Tabelle 7).
37
+ *
38
+ * Byte-Modus, weil die RKSV-Nutzlast beliebige Zeichen traegt; Ziffern- oder
39
+ * Alphanumerik-Modus waere enger gefasst und wuerde fuer denselben Text
40
+ * weniger Module ergeben — also zu klein rechnen.
41
+ */
42
+ const BYTE_KAPAZITAET_M = [
43
+ 14, 26, 42, 62, 84, 106, 122, 152, 180, 213,
44
+ 251, 287, 331, 362, 412, 450, 504, 560, 624, 666,
45
+ 711, 779, 857, 911, 997, 1059, 1125, 1190, 1264, 1370,
46
+ 1452, 1538, 1628, 1722, 1809, 1911, 1989, 2099, 2213, 2331,
47
+ ];
48
+ // ------------------------------------------------------------- oeffentlich
49
+ /**
50
+ * Modulanzahl, die `nutzlast` bei Fehlerkorrektur **M** braucht.
51
+ *
52
+ * Warum M, obwohl der native Befehl mit L druckt: M braucht bei gleicher
53
+ * Nutzlast gleich viele oder mehr Module als L. Wer mit M rechnet und mit L
54
+ * druckt, druckt nie breiter als gerechnet — die Rechnung ist konservativ,
55
+ * nie knapp. Umgekehrt waere sie eine Rechnung, die aufgeht, und ein Symbol,
56
+ * das ueber den Papierrand laeuft. Dasselbe gilt fuer die Byte-Zaehlung: hier
57
+ * zaehlt UTF-8 (wie im Flutter-Zwilling), waehrend `qrCodeBytes` die Nutzlast
58
+ * als Latin-1 sendet — UTF-8 ist nie kuerzer, die Rechnung also nie zu klein.
59
+ *
60
+ * Wirft, wenn die Nutzlast in keine Version passt — wie `qrCodeBytes` bei zu
61
+ * langem Inhalt. Ein still zurueckgegebenes "passt nicht" haette den
62
+ * Datenfehler als Papierfehler getarnt.
63
+ */
64
+ function qrModulAnzahl(nutzlast) {
65
+ const laenge = new TextEncoder().encode(nutzlast).length;
66
+ for (let i = 0; i < BYTE_KAPAZITAET_M.length; i++) {
67
+ if (laenge <= BYTE_KAPAZITAET_M[i])
68
+ return 17 + 4 * (i + 1);
69
+ }
70
+ throw new Error('QR-Inhalt ist zu lang');
71
+ }
72
+ /**
73
+ * Groesste Modulgroesse, mit der `moduleAnzahl` Module **samt Ruhezone** in
74
+ * `papierbreitePunkte` passen, gedeckelt durch `groesse`.
75
+ *
76
+ * Wirft bei sinnlosen Eingaben: eine Papierbreite von 0 oder ein Symbol ohne
77
+ * Module ist ein Programmierfehler, und ein still zurueckgegebenes "passt
78
+ * nicht" haette ihn als Druckerproblem getarnt.
79
+ */
80
+ function qrGroesseBerechnen(options) {
81
+ const { papierbreitePunkte, moduleAnzahl } = options;
82
+ const groesse = options.groesse ?? 'auto';
83
+ if (!Number.isInteger(papierbreitePunkte) || papierbreitePunkte <= 0) {
84
+ throw new Error('papierbreitePunkte muss eine Ganzzahl > 0 sein');
85
+ }
86
+ if (!Number.isInteger(moduleAnzahl) || moduleAnzahl <= 0) {
87
+ throw new Error('moduleAnzahl muss eine Ganzzahl > 0 sein');
88
+ }
89
+ const roh = exports.QR_MODUL_DECKEL[groesse];
90
+ if (roh === undefined) {
91
+ throw new Error(`Unbekannte QR-Modulgroesse: ${String(groesse)}`);
92
+ }
93
+ const gesamtModule = moduleAnzahl + exports.QR_RUHEZONE_MODULE * 2;
94
+ const passend = Math.floor(papierbreitePunkte / gesamtModule);
95
+ if (passend < exports.QR_AUSNAHME_PUNKTE) {
96
+ return { punkte: null, module: moduleAnzahl, breitePunkte: 0, unterMindestmass: false, passt: false };
97
+ }
98
+ const deckel = Math.min(Math.max(roh, exports.QR_AUSNAHME_PUNKTE), exports.QR_HOECHST_PUNKTE);
99
+ const punkte = passend < exports.QR_MINDEST_PUNKTE ? exports.QR_AUSNAHME_PUNKTE : Math.min(passend, deckel);
100
+ return {
101
+ punkte: punkte,
102
+ module: moduleAnzahl,
103
+ breitePunkte: gesamtModule * punkte,
104
+ unterMindestmass: punkte < exports.QR_MINDEST_PUNKTE,
105
+ passt: true,
106
+ };
107
+ }
108
+ /**
109
+ * Wie `qrGroesseBerechnen`, nur mit der Modulanzahl aus `nutzlast`.
110
+ *
111
+ * Eine leere Nutzlast ergibt kein Symbol — sie "passt nicht", statt zu
112
+ * werfen: der Aufrufer behandelt den Fall ohnehin schon (leerer QR am Beleg
113
+ * ist ein Datenfehler, kein Papierfehler).
114
+ */
115
+ function qrGroesseFuer(options) {
116
+ if (options.nutzlast === '') {
117
+ return { punkte: null, module: 0, breitePunkte: 0, unterMindestmass: false, passt: false };
118
+ }
119
+ const weiter = {
120
+ papierbreitePunkte: options.papierbreitePunkte,
121
+ moduleAnzahl: qrModulAnzahl(options.nutzlast),
122
+ };
123
+ if (options.groesse !== undefined)
124
+ weiter.groesse = options.groesse;
125
+ return qrGroesseBerechnen(weiter);
126
+ }