Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
589 / 589
100.00% covered (success)
100.00%
12 / 12
CRAP
100.00% covered (success)
100.00%
1 / 1
StandardFontMetrics
100.00% covered (success)
100.00%
589 / 589
100.00% covered (success)
100.00%
12 / 12
14
100.00% covered (success)
100.00%
1 / 1
 get
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 buildRegistry
100.00% covered (success)
100.00%
157 / 157
100.00% covered (success)
100.00%
1 / 1
1
 helveticaWidths
100.00% covered (success)
100.00%
56 / 56
100.00% covered (success)
100.00%
1 / 1
1
 helveticaBoldWidths
100.00% covered (success)
100.00%
56 / 56
100.00% covered (success)
100.00%
1 / 1
1
 timesRomanWidths
100.00% covered (success)
100.00%
56 / 56
100.00% covered (success)
100.00%
1 / 1
1
 timesBoldWidths
100.00% covered (success)
100.00%
56 / 56
100.00% covered (success)
100.00%
1 / 1
1
 timesItalicWidths
100.00% covered (success)
100.00%
56 / 56
100.00% covered (success)
100.00%
1 / 1
1
 timesBoldItalicWidths
100.00% covered (success)
100.00%
56 / 56
100.00% covered (success)
100.00%
1 / 1
1
 courierWidths
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 courierGlyphs
100.00% covered (success)
100.00%
38 / 38
100.00% covered (success)
100.00%
1 / 1
1
 symbolWidths
100.00% covered (success)
100.00%
28 / 28
100.00% covered (success)
100.00%
1 / 1
1
 zapfDingbatsWidths
100.00% covered (success)
100.00%
22 / 22
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace Phpdftk\FontMetrics;
6
7final class StandardFontMetrics
8{
9    /** @var array<string, AfmData>|null */
10    private static ?array $registry = null;
11
12    public static function get(string $postScriptName): AfmData
13    {
14        self::$registry ??= self::buildRegistry();
15        if (!isset(self::$registry[$postScriptName])) {
16            throw new \InvalidArgumentException("Unknown standard font: $postScriptName");
17        }
18        return self::$registry[$postScriptName];
19    }
20
21    /** @return array<string, AfmData> */
22    private static function buildRegistry(): array
23    {
24        $reg = [];
25
26        // -----------------------------------------------------------------------
27        // Helvetica
28        // -----------------------------------------------------------------------
29        $reg['Helvetica'] = new AfmData(
30            ascender: 718,
31            descender: -207,
32            capHeight: 718,
33            xHeight: 523,
34            italicAngle: 0,
35            stemV: 88,
36            missingWidth: 278,
37            fontBBox: [-166, -225, 1000, 931],
38            widths: self::helveticaWidths(),
39        );
40
41        // -----------------------------------------------------------------------
42        // Helvetica-Bold
43        // -----------------------------------------------------------------------
44        $reg['Helvetica-Bold'] = new AfmData(
45            ascender: 718,
46            descender: -207,
47            capHeight: 718,
48            xHeight: 532,
49            italicAngle: 0,
50            stemV: 140,
51            missingWidth: 278,
52            fontBBox: [-170, -228, 1003, 962],
53            widths: self::helveticaBoldWidths(),
54        );
55
56        // -----------------------------------------------------------------------
57        // Helvetica-Oblique (same widths as Helvetica)
58        // -----------------------------------------------------------------------
59        $reg['Helvetica-Oblique'] = new AfmData(
60            ascender: 718,
61            descender: -207,
62            capHeight: 718,
63            xHeight: 523,
64            italicAngle: -12,
65            stemV: 88,
66            missingWidth: 278,
67            fontBBox: [-166, -225, 1000, 931],
68            widths: self::helveticaWidths(),
69        );
70
71        // -----------------------------------------------------------------------
72        // Helvetica-BoldOblique (same widths as Helvetica-Bold)
73        // -----------------------------------------------------------------------
74        $reg['Helvetica-BoldOblique'] = new AfmData(
75            ascender: 718,
76            descender: -207,
77            capHeight: 718,
78            xHeight: 532,
79            italicAngle: -12,
80            stemV: 140,
81            missingWidth: 278,
82            fontBBox: [-170, -228, 1003, 962],
83            widths: self::helveticaBoldWidths(),
84        );
85
86        // -----------------------------------------------------------------------
87        // Times-Roman
88        // -----------------------------------------------------------------------
89        $reg['Times-Roman'] = new AfmData(
90            ascender: 683,
91            descender: -217,
92            capHeight: 662,
93            xHeight: 450,
94            italicAngle: 0,
95            stemV: 84,
96            missingWidth: 250,
97            fontBBox: [-168, -218, 1000, 898],
98            widths: self::timesRomanWidths(),
99        );
100
101        // -----------------------------------------------------------------------
102        // Times-Bold
103        // -----------------------------------------------------------------------
104        $reg['Times-Bold'] = new AfmData(
105            ascender: 683,
106            descender: -217,
107            capHeight: 676,
108            xHeight: 461,
109            italicAngle: 0,
110            stemV: 139,
111            missingWidth: 250,
112            fontBBox: [-168, -218, 1000, 935],
113            widths: self::timesBoldWidths(),
114        );
115
116        // -----------------------------------------------------------------------
117        // Times-Italic
118        // -----------------------------------------------------------------------
119        $reg['Times-Italic'] = new AfmData(
120            ascender: 683,
121            descender: -217,
122            capHeight: 653,
123            xHeight: 441,
124            italicAngle: -15.5,
125            stemV: 76,
126            missingWidth: 250,
127            fontBBox: [-169, -217, 1010, 883],
128            widths: self::timesItalicWidths(),
129        );
130
131        // -----------------------------------------------------------------------
132        // Times-BoldItalic
133        // -----------------------------------------------------------------------
134        $reg['Times-BoldItalic'] = new AfmData(
135            ascender: 683,
136            descender: -217,
137            capHeight: 669,
138            xHeight: 462,
139            italicAngle: -15,
140            stemV: 121,
141            missingWidth: 250,
142            fontBBox: [-200, -218, 996, 921],
143            widths: self::timesBoldItalicWidths(),
144        );
145
146        // -----------------------------------------------------------------------
147        // Courier (all glyphs = 600)
148        // -----------------------------------------------------------------------
149        $courierWidths = self::courierWidths();
150        $reg['Courier'] = new AfmData(
151            ascender: 629,
152            descender: -157,
153            capHeight: 562,
154            xHeight: 426,
155            italicAngle: 0,
156            stemV: 51,
157            missingWidth: 600,
158            fontBBox: [-23, -250, 715, 805],
159            widths: $courierWidths,
160        );
161
162        // -----------------------------------------------------------------------
163        // Courier-Bold
164        // -----------------------------------------------------------------------
165        $reg['Courier-Bold'] = new AfmData(
166            ascender: 629,
167            descender: -157,
168            capHeight: 562,
169            xHeight: 426,
170            italicAngle: 0,
171            stemV: 106,
172            missingWidth: 600,
173            fontBBox: [-23, -250, 715, 805],
174            widths: $courierWidths,
175        );
176
177        // -----------------------------------------------------------------------
178        // Courier-Oblique
179        // -----------------------------------------------------------------------
180        $reg['Courier-Oblique'] = new AfmData(
181            ascender: 629,
182            descender: -157,
183            capHeight: 562,
184            xHeight: 426,
185            italicAngle: -12,
186            stemV: 51,
187            missingWidth: 600,
188            fontBBox: [-23, -250, 715, 805],
189            widths: $courierWidths,
190        );
191
192        // -----------------------------------------------------------------------
193        // Courier-BoldOblique
194        // -----------------------------------------------------------------------
195        $reg['Courier-BoldOblique'] = new AfmData(
196            ascender: 629,
197            descender: -157,
198            capHeight: 562,
199            xHeight: 426,
200            italicAngle: -12,
201            stemV: 106,
202            missingWidth: 600,
203            fontBBox: [-23, -250, 715, 805],
204            widths: $courierWidths,
205        );
206
207        // -----------------------------------------------------------------------
208        // Symbol
209        // -----------------------------------------------------------------------
210        $reg['Symbol'] = new AfmData(
211            ascender: 0,
212            descender: 0,
213            capHeight: 0,
214            xHeight: 0,
215            italicAngle: 0,
216            stemV: 85,
217            missingWidth: 250,
218            fontBBox: [-180, -293, 1090, 1010],
219            widths: self::symbolWidths(),
220        );
221
222        // -----------------------------------------------------------------------
223        // ZapfDingbats
224        // -----------------------------------------------------------------------
225        $reg['ZapfDingbats'] = new AfmData(
226            ascender: 0,
227            descender: 0,
228            capHeight: 0,
229            xHeight: 0,
230            italicAngle: 0,
231            stemV: 90,
232            missingWidth: 278,
233            fontBBox: [-1, -143, 981, 820],
234            widths: self::zapfDingbatsWidths(),
235        );
236
237        return $reg;
238    }
239
240    /** @return array<string, int> */
241    private static function helveticaWidths(): array
242    {
243        return [
244            'A' => 667, 'AE' => 1000, 'Aacute' => 667, 'Acircumflex' => 667,
245            'Adieresis' => 667, 'Agrave' => 667, 'Aring' => 667, 'Atilde' => 667,
246            'B' => 667, 'C' => 722, 'Ccedilla' => 722, 'D' => 722,
247            'E' => 667, 'Eacute' => 667, 'Ecircumflex' => 667, 'Edieresis' => 667,
248            'Egrave' => 667, 'Eth' => 722, 'Euro' => 556, 'F' => 611,
249            'G' => 778, 'H' => 722, 'I' => 278, 'Iacute' => 278,
250            'Icircumflex' => 278, 'Idieresis' => 278, 'Igrave' => 278, 'J' => 500,
251            'K' => 667, 'L' => 556, 'M' => 833, 'N' => 722,
252            'Ntilde' => 722, 'O' => 778, 'OE' => 1000, 'Oacute' => 778,
253            'Ocircumflex' => 778, 'Odieresis' => 778, 'Ograve' => 778, 'Oslash' => 778,
254            'Otilde' => 778, 'P' => 667, 'Q' => 778, 'R' => 722,
255            'S' => 667, 'Scaron' => 667, 'T' => 611, 'Thorn' => 667,
256            'U' => 722, 'Uacute' => 722, 'Ucircumflex' => 722, 'Udieresis' => 722,
257            'Ugrave' => 722, 'V' => 667, 'W' => 944, 'X' => 667,
258            'Y' => 667, 'Yacute' => 667, 'Ydieresis' => 667, 'Z' => 611,
259            'Zcaron' => 611, 'a' => 556, 'aacute' => 556, 'acircumflex' => 556,
260            'acute' => 333, 'adieresis' => 556, 'ae' => 889, 'agrave' => 556,
261            'ampersand' => 667, 'aring' => 556, 'asciicircum' => 469, 'asciitilde' => 584,
262            'asterisk' => 389, 'at' => 1015, 'atilde' => 556, 'b' => 556,
263            'backslash' => 278, 'bar' => 260, 'braceleft' => 334, 'braceright' => 334,
264            'bracketleft' => 278, 'bracketright' => 278, 'brokenbar' => 260, 'bullet' => 350,
265            'c' => 500, 'ccedilla' => 500, 'cedilla' => 333, 'cent' => 556,
266            'circumflex' => 333, 'colon' => 278, 'comma' => 278, 'copyright' => 737,
267            'currency' => 556, 'd' => 556, 'dagger' => 556, 'daggerdbl' => 556,
268            'degree' => 400, 'dieresis' => 333, 'divide' => 584, 'dollar' => 556,
269            'e' => 556, 'eacute' => 556, 'ecircumflex' => 556, 'edieresis' => 556,
270            'egrave' => 556, 'eight' => 556, 'ellipsis' => 1000, 'emdash' => 1000,
271            'endash' => 556, 'equal' => 584, 'eth' => 556, 'exclam' => 278,
272            'exclamdown' => 333, 'f' => 278, 'five' => 556, 'florin' => 556,
273            'four' => 556, 'g' => 556, 'germandbls' => 611, 'grave' => 333,
274            'greater' => 584, 'guillemotleft' => 556, 'guillemotright' => 556, 'guilsinglleft' => 333,
275            'guilsinglright' => 333, 'h' => 556, 'hyphen' => 333, 'i' => 222,
276            'iacute' => 278, 'icircumflex' => 278, 'idieresis' => 278, 'igrave' => 278,
277            'j' => 222, 'k' => 500, 'l' => 222, 'less' => 584,
278            'logicalnot' => 584, 'm' => 833, 'macron' => 333, 'mu' => 556,
279            'multiply' => 584, 'n' => 556, 'nine' => 556, 'ntilde' => 556,
280            'numbersign' => 556, 'o' => 556, 'oacute' => 556, 'ocircumflex' => 556,
281            'odieresis' => 556, 'oe' => 944, 'ograve' => 556, 'one' => 556,
282            'onehalf' => 834, 'onequarter' => 834, 'onesuperior' => 333, 'ordfeminine' => 370,
283            'ordmasculine' => 365, 'oslash' => 611, 'otilde' => 556, 'p' => 556,
284            'paragraph' => 537, 'parenleft' => 333, 'parenright' => 333, 'percent' => 889,
285            'period' => 278, 'periodcentered' => 278, 'perthousand' => 1000, 'plus' => 584,
286            'plusminus' => 584, 'q' => 556, 'question' => 556, 'questiondown' => 611,
287            'quotedbl' => 355, 'quotedblbase' => 333, 'quotedblleft' => 333, 'quotedblright' => 333,
288            'quoteleft' => 222, 'quoteright' => 222, 'quotesinglbase' => 222, 'quotesingle' => 191,
289            'r' => 333, 'registered' => 737, 's' => 500, 'scaron' => 500,
290            'section' => 556, 'semicolon' => 278, 'seven' => 556, 'six' => 556,
291            'slash' => 278, 'space' => 278, 'sterling' => 556, 't' => 278,
292            'thorn' => 556, 'three' => 556, 'threequarters' => 834, 'threesuperior' => 333,
293            'tilde' => 333, 'trademark' => 1000, 'two' => 556, 'twosuperior' => 333,
294            'u' => 556, 'uacute' => 556, 'ucircumflex' => 556, 'udieresis' => 556,
295            'ugrave' => 556, 'underscore' => 556, 'v' => 500, 'w' => 722,
296            'x' => 500, 'y' => 500, 'yacute' => 500, 'ydieresis' => 500,
297            'yen' => 556, 'z' => 500, 'zcaron' => 500, 'zero' => 556,
298        ];
299    }
300
301    /** @return array<string, int> */
302    private static function helveticaBoldWidths(): array
303    {
304        return [
305            'A' => 722, 'AE' => 1000, 'Aacute' => 722, 'Acircumflex' => 722,
306            'Adieresis' => 722, 'Agrave' => 722, 'Aring' => 722, 'Atilde' => 722,
307            'B' => 722, 'C' => 722, 'Ccedilla' => 722, 'D' => 722,
308            'E' => 667, 'Eacute' => 667, 'Ecircumflex' => 667, 'Edieresis' => 667,
309            'Egrave' => 667, 'Eth' => 722, 'Euro' => 556, 'F' => 611,
310            'G' => 778, 'H' => 722, 'I' => 278, 'Iacute' => 278,
311            'Icircumflex' => 278, 'Idieresis' => 278, 'Igrave' => 278, 'J' => 556,
312            'K' => 722, 'L' => 611, 'M' => 833, 'N' => 722,
313            'Ntilde' => 722, 'O' => 778, 'OE' => 1000, 'Oacute' => 778,
314            'Ocircumflex' => 778, 'Odieresis' => 778, 'Ograve' => 778, 'Oslash' => 778,
315            'Otilde' => 778, 'P' => 667, 'Q' => 778, 'R' => 722,
316            'S' => 667, 'Scaron' => 667, 'T' => 611, 'Thorn' => 667,
317            'U' => 722, 'Uacute' => 722, 'Ucircumflex' => 722, 'Udieresis' => 722,
318            'Ugrave' => 722, 'V' => 667, 'W' => 944, 'X' => 667,
319            'Y' => 667, 'Yacute' => 667, 'Ydieresis' => 667, 'Z' => 611,
320            'Zcaron' => 611, 'a' => 556, 'aacute' => 556, 'acircumflex' => 556,
321            'acute' => 333, 'adieresis' => 556, 'ae' => 889, 'agrave' => 556,
322            'ampersand' => 722, 'aring' => 556, 'asciicircum' => 584, 'asciitilde' => 584,
323            'asterisk' => 389, 'at' => 975, 'atilde' => 556, 'b' => 611,
324            'backslash' => 278, 'bar' => 280, 'braceleft' => 389, 'braceright' => 389,
325            'bracketleft' => 333, 'bracketright' => 333, 'brokenbar' => 280, 'bullet' => 350,
326            'c' => 556, 'ccedilla' => 556, 'cedilla' => 333, 'cent' => 556,
327            'circumflex' => 333, 'colon' => 333, 'comma' => 278, 'copyright' => 737,
328            'currency' => 556, 'd' => 611, 'dagger' => 556, 'daggerdbl' => 556,
329            'degree' => 400, 'dieresis' => 333, 'divide' => 584, 'dollar' => 556,
330            'e' => 556, 'eacute' => 556, 'ecircumflex' => 556, 'edieresis' => 556,
331            'egrave' => 556, 'eight' => 556, 'ellipsis' => 1000, 'emdash' => 1000,
332            'endash' => 556, 'equal' => 584, 'eth' => 611, 'exclam' => 333,
333            'exclamdown' => 333, 'f' => 333, 'five' => 556, 'florin' => 556,
334            'four' => 556, 'g' => 611, 'germandbls' => 611, 'grave' => 333,
335            'greater' => 584, 'guillemotleft' => 556, 'guillemotright' => 556, 'guilsinglleft' => 333,
336            'guilsinglright' => 333, 'h' => 611, 'hyphen' => 333, 'i' => 278,
337            'iacute' => 278, 'icircumflex' => 278, 'idieresis' => 278, 'igrave' => 278,
338            'j' => 278, 'k' => 556, 'l' => 278, 'less' => 584,
339            'logicalnot' => 584, 'm' => 889, 'macron' => 333, 'mu' => 611,
340            'multiply' => 584, 'n' => 611, 'nine' => 556, 'ntilde' => 611,
341            'numbersign' => 556, 'o' => 611, 'oacute' => 611, 'ocircumflex' => 611,
342            'odieresis' => 611, 'oe' => 944, 'ograve' => 611, 'one' => 556,
343            'onehalf' => 834, 'onequarter' => 834, 'onesuperior' => 333, 'ordfeminine' => 370,
344            'ordmasculine' => 365, 'oslash' => 611, 'otilde' => 611, 'p' => 611,
345            'paragraph' => 556, 'parenleft' => 333, 'parenright' => 333, 'percent' => 889,
346            'period' => 278, 'periodcentered' => 278, 'perthousand' => 1000, 'plus' => 584,
347            'plusminus' => 584, 'q' => 611, 'question' => 611, 'questiondown' => 611,
348            'quotedbl' => 474, 'quotedblbase' => 500, 'quotedblleft' => 500, 'quotedblright' => 500,
349            'quoteleft' => 278, 'quoteright' => 278, 'quotesinglbase' => 278, 'quotesingle' => 238,
350            'r' => 389, 'registered' => 737, 's' => 556, 'scaron' => 556,
351            'section' => 556, 'semicolon' => 333, 'seven' => 556, 'six' => 556,
352            'slash' => 278, 'space' => 278, 'sterling' => 556, 't' => 333,
353            'thorn' => 611, 'three' => 556, 'threequarters' => 834, 'threesuperior' => 333,
354            'tilde' => 333, 'trademark' => 1000, 'two' => 556, 'twosuperior' => 333,
355            'u' => 611, 'uacute' => 611, 'ucircumflex' => 611, 'udieresis' => 611,
356            'ugrave' => 611, 'underscore' => 556, 'v' => 556, 'w' => 778,
357            'x' => 556, 'y' => 556, 'yacute' => 556, 'ydieresis' => 556,
358            'yen' => 556, 'z' => 500, 'zcaron' => 500, 'zero' => 556,
359        ];
360    }
361
362    /** @return array<string, int> */
363    private static function timesRomanWidths(): array
364    {
365        return [
366            'A' => 722, 'AE' => 889, 'Aacute' => 722, 'Acircumflex' => 722,
367            'Adieresis' => 722, 'Agrave' => 722, 'Aring' => 722, 'Atilde' => 722,
368            'B' => 667, 'C' => 667, 'Ccedilla' => 667, 'D' => 722,
369            'E' => 611, 'Eacute' => 611, 'Ecircumflex' => 611, 'Edieresis' => 611,
370            'Egrave' => 611, 'Eth' => 722, 'Euro' => 500, 'F' => 556,
371            'G' => 722, 'H' => 722, 'I' => 333, 'Iacute' => 333,
372            'Icircumflex' => 333, 'Idieresis' => 333, 'Igrave' => 333, 'J' => 389,
373            'K' => 722, 'L' => 611, 'M' => 889, 'N' => 722,
374            'Ntilde' => 722, 'O' => 722, 'OE' => 889, 'Oacute' => 722,
375            'Ocircumflex' => 722, 'Odieresis' => 722, 'Ograve' => 722, 'Oslash' => 722,
376            'Otilde' => 722, 'P' => 556, 'Q' => 722, 'R' => 667,
377            'S' => 556, 'Scaron' => 556, 'T' => 611, 'Thorn' => 556,
378            'U' => 722, 'Uacute' => 722, 'Ucircumflex' => 722, 'Udieresis' => 722,
379            'Ugrave' => 722, 'V' => 722, 'W' => 944, 'X' => 722,
380            'Y' => 722, 'Yacute' => 722, 'Ydieresis' => 722, 'Z' => 611,
381            'Zcaron' => 611, 'a' => 444, 'aacute' => 444, 'acircumflex' => 444,
382            'acute' => 333, 'adieresis' => 444, 'ae' => 667, 'agrave' => 444,
383            'ampersand' => 778, 'aring' => 444, 'asciicircum' => 469, 'asciitilde' => 541,
384            'asterisk' => 500, 'at' => 921, 'atilde' => 444, 'b' => 500,
385            'backslash' => 278, 'bar' => 200, 'braceleft' => 480, 'braceright' => 480,
386            'bracketleft' => 333, 'bracketright' => 333, 'brokenbar' => 200, 'bullet' => 350,
387            'c' => 444, 'ccedilla' => 444, 'cedilla' => 333, 'cent' => 500,
388            'circumflex' => 333, 'colon' => 278, 'comma' => 250, 'copyright' => 760,
389            'currency' => 500, 'd' => 500, 'dagger' => 500, 'daggerdbl' => 500,
390            'degree' => 400, 'dieresis' => 333, 'divide' => 564, 'dollar' => 500,
391            'e' => 444, 'eacute' => 444, 'ecircumflex' => 444, 'edieresis' => 444,
392            'egrave' => 444, 'eight' => 500, 'ellipsis' => 1000, 'emdash' => 1000,
393            'endash' => 500, 'equal' => 564, 'eth' => 500, 'exclam' => 333,
394            'exclamdown' => 333, 'f' => 333, 'five' => 500, 'florin' => 500,
395            'four' => 500, 'g' => 500, 'germandbls' => 500, 'grave' => 333,
396            'greater' => 564, 'guillemotleft' => 500, 'guillemotright' => 500, 'guilsinglleft' => 333,
397            'guilsinglright' => 333, 'h' => 500, 'hyphen' => 333, 'i' => 278,
398            'iacute' => 278, 'icircumflex' => 278, 'idieresis' => 278, 'igrave' => 278,
399            'j' => 278, 'k' => 500, 'l' => 278, 'less' => 564,
400            'logicalnot' => 564, 'm' => 778, 'macron' => 333, 'mu' => 500,
401            'multiply' => 564, 'n' => 500, 'nine' => 500, 'ntilde' => 500,
402            'numbersign' => 500, 'o' => 500, 'oacute' => 500, 'ocircumflex' => 500,
403            'odieresis' => 500, 'oe' => 722, 'ograve' => 500, 'one' => 500,
404            'onehalf' => 750, 'onequarter' => 750, 'onesuperior' => 300, 'ordfeminine' => 276,
405            'ordmasculine' => 310, 'oslash' => 500, 'otilde' => 500, 'p' => 500,
406            'paragraph' => 453, 'parenleft' => 333, 'parenright' => 333, 'percent' => 833,
407            'period' => 250, 'periodcentered' => 250, 'perthousand' => 1000, 'plus' => 564,
408            'plusminus' => 564, 'q' => 500, 'question' => 444, 'questiondown' => 444,
409            'quotedbl' => 408, 'quotedblbase' => 444, 'quotedblleft' => 444, 'quotedblright' => 444,
410            'quoteleft' => 333, 'quoteright' => 333, 'quotesinglbase' => 333, 'quotesingle' => 180,
411            'r' => 333, 'registered' => 760, 's' => 389, 'scaron' => 389,
412            'section' => 500, 'semicolon' => 278, 'seven' => 500, 'six' => 500,
413            'slash' => 278, 'space' => 250, 'sterling' => 500, 't' => 278,
414            'thorn' => 500, 'three' => 500, 'threequarters' => 750, 'threesuperior' => 300,
415            'tilde' => 333, 'trademark' => 980, 'two' => 500, 'twosuperior' => 300,
416            'u' => 500, 'uacute' => 500, 'ucircumflex' => 500, 'udieresis' => 500,
417            'ugrave' => 500, 'underscore' => 500, 'v' => 500, 'w' => 722,
418            'x' => 500, 'y' => 500, 'yacute' => 500, 'ydieresis' => 500,
419            'yen' => 500, 'z' => 444, 'zcaron' => 444, 'zero' => 500,
420        ];
421    }
422
423    /** @return array<string, int> */
424    private static function timesBoldWidths(): array
425    {
426        return [
427            'A' => 722, 'AE' => 1000, 'Aacute' => 722, 'Acircumflex' => 722,
428            'Adieresis' => 722, 'Agrave' => 722, 'Aring' => 722, 'Atilde' => 722,
429            'B' => 667, 'C' => 722, 'Ccedilla' => 722, 'D' => 722,
430            'E' => 667, 'Eacute' => 667, 'Ecircumflex' => 667, 'Edieresis' => 667,
431            'Egrave' => 667, 'Eth' => 722, 'Euro' => 500, 'F' => 611,
432            'G' => 778, 'H' => 778, 'I' => 389, 'Iacute' => 389,
433            'Icircumflex' => 389, 'Idieresis' => 389, 'Igrave' => 389, 'J' => 500,
434            'K' => 778, 'L' => 667, 'M' => 944, 'N' => 722,
435            'Ntilde' => 722, 'O' => 778, 'OE' => 1000, 'Oacute' => 778,
436            'Ocircumflex' => 778, 'Odieresis' => 778, 'Ograve' => 778, 'Oslash' => 778,
437            'Otilde' => 778, 'P' => 611, 'Q' => 778, 'R' => 722,
438            'S' => 556, 'Scaron' => 556, 'T' => 667, 'Thorn' => 611,
439            'U' => 722, 'Uacute' => 722, 'Ucircumflex' => 722, 'Udieresis' => 722,
440            'Ugrave' => 722, 'V' => 722, 'W' => 1000, 'X' => 722,
441            'Y' => 722, 'Yacute' => 722, 'Ydieresis' => 722, 'Z' => 667,
442            'Zcaron' => 667, 'a' => 500, 'aacute' => 500, 'acircumflex' => 500,
443            'acute' => 333, 'adieresis' => 500, 'ae' => 722, 'agrave' => 500,
444            'ampersand' => 833, 'aring' => 500, 'asciicircum' => 581, 'asciitilde' => 520,
445            'asterisk' => 500, 'at' => 930, 'atilde' => 500, 'b' => 556,
446            'backslash' => 278, 'bar' => 220, 'braceleft' => 394, 'braceright' => 394,
447            'bracketleft' => 333, 'bracketright' => 333, 'brokenbar' => 220, 'bullet' => 350,
448            'c' => 444, 'ccedilla' => 444, 'cedilla' => 333, 'cent' => 500,
449            'circumflex' => 333, 'colon' => 333, 'comma' => 250, 'copyright' => 747,
450            'currency' => 500, 'd' => 556, 'dagger' => 500, 'daggerdbl' => 500,
451            'degree' => 400, 'dieresis' => 333, 'divide' => 570, 'dollar' => 500,
452            'e' => 444, 'eacute' => 444, 'ecircumflex' => 444, 'edieresis' => 444,
453            'egrave' => 444, 'eight' => 500, 'ellipsis' => 1000, 'emdash' => 1000,
454            'endash' => 500, 'equal' => 570, 'eth' => 500, 'exclam' => 333,
455            'exclamdown' => 333, 'f' => 333, 'five' => 500, 'florin' => 500,
456            'four' => 500, 'g' => 500, 'germandbls' => 556, 'grave' => 333,
457            'greater' => 570, 'guillemotleft' => 500, 'guillemotright' => 500, 'guilsinglleft' => 333,
458            'guilsinglright' => 333, 'h' => 556, 'hyphen' => 333, 'i' => 278,
459            'iacute' => 278, 'icircumflex' => 278, 'idieresis' => 278, 'igrave' => 278,
460            'j' => 333, 'k' => 556, 'l' => 278, 'less' => 570,
461            'logicalnot' => 570, 'm' => 833, 'macron' => 333, 'mu' => 556,
462            'multiply' => 570, 'n' => 556, 'nine' => 500, 'ntilde' => 556,
463            'numbersign' => 500, 'o' => 500, 'oacute' => 500, 'ocircumflex' => 500,
464            'odieresis' => 500, 'oe' => 722, 'ograve' => 500, 'one' => 500,
465            'onehalf' => 750, 'onequarter' => 750, 'onesuperior' => 300, 'ordfeminine' => 300,
466            'ordmasculine' => 330, 'oslash' => 500, 'otilde' => 500, 'p' => 556,
467            'paragraph' => 540, 'parenleft' => 333, 'parenright' => 333, 'percent' => 1000,
468            'period' => 250, 'periodcentered' => 250, 'perthousand' => 1000, 'plus' => 570,
469            'plusminus' => 570, 'q' => 556, 'question' => 500, 'questiondown' => 500,
470            'quotedbl' => 555, 'quotedblbase' => 500, 'quotedblleft' => 500, 'quotedblright' => 500,
471            'quoteleft' => 333, 'quoteright' => 333, 'quotesinglbase' => 333, 'quotesingle' => 278,
472            'r' => 444, 'registered' => 747, 's' => 389, 'scaron' => 389,
473            'section' => 500, 'semicolon' => 333, 'seven' => 500, 'six' => 500,
474            'slash' => 278, 'space' => 250, 'sterling' => 500, 't' => 333,
475            'thorn' => 556, 'three' => 500, 'threequarters' => 750, 'threesuperior' => 300,
476            'tilde' => 333, 'trademark' => 1000, 'two' => 500, 'twosuperior' => 300,
477            'u' => 556, 'uacute' => 556, 'ucircumflex' => 556, 'udieresis' => 556,
478            'ugrave' => 556, 'underscore' => 500, 'v' => 500, 'w' => 722,
479            'x' => 500, 'y' => 500, 'yacute' => 500, 'ydieresis' => 500,
480            'yen' => 500, 'z' => 444, 'zcaron' => 444, 'zero' => 500,
481        ];
482    }
483
484    /** @return array<string, int> */
485    private static function timesItalicWidths(): array
486    {
487        return [
488            'A' => 611, 'AE' => 889, 'Aacute' => 611, 'Acircumflex' => 611,
489            'Adieresis' => 611, 'Agrave' => 611, 'Aring' => 611, 'Atilde' => 611,
490            'B' => 611, 'C' => 667, 'Ccedilla' => 667, 'D' => 722,
491            'E' => 611, 'Eacute' => 611, 'Ecircumflex' => 611, 'Edieresis' => 611,
492            'Egrave' => 611, 'Eth' => 722, 'Euro' => 500, 'F' => 611,
493            'G' => 722, 'H' => 722, 'I' => 333, 'Iacute' => 333,
494            'Icircumflex' => 333, 'Idieresis' => 333, 'Igrave' => 333, 'J' => 444,
495            'K' => 667, 'L' => 556, 'M' => 833, 'N' => 667,
496            'Ntilde' => 667, 'O' => 722, 'OE' => 944, 'Oacute' => 722,
497            'Ocircumflex' => 722, 'Odieresis' => 722, 'Ograve' => 722, 'Oslash' => 722,
498            'Otilde' => 722, 'P' => 611, 'Q' => 722, 'R' => 611,
499            'S' => 500, 'Scaron' => 500, 'T' => 556, 'Thorn' => 611,
500            'U' => 722, 'Uacute' => 722, 'Ucircumflex' => 722, 'Udieresis' => 722,
501            'Ugrave' => 722, 'V' => 611, 'W' => 833, 'X' => 611,
502            'Y' => 556, 'Yacute' => 556, 'Ydieresis' => 556, 'Z' => 556,
503            'Zcaron' => 556, 'a' => 500, 'aacute' => 500, 'acircumflex' => 500,
504            'acute' => 333, 'adieresis' => 500, 'ae' => 667, 'agrave' => 500,
505            'ampersand' => 778, 'aring' => 500, 'asciicircum' => 422, 'asciitilde' => 541,
506            'asterisk' => 500, 'at' => 920, 'atilde' => 500, 'b' => 500,
507            'backslash' => 278, 'bar' => 275, 'braceleft' => 400, 'braceright' => 400,
508            'bracketleft' => 389, 'bracketright' => 389, 'brokenbar' => 275, 'bullet' => 350,
509            'c' => 444, 'ccedilla' => 444, 'cedilla' => 333, 'cent' => 500,
510            'circumflex' => 333, 'colon' => 333, 'comma' => 250, 'copyright' => 760,
511            'currency' => 500, 'd' => 500, 'dagger' => 500, 'daggerdbl' => 500,
512            'degree' => 400, 'dieresis' => 333, 'divide' => 675, 'dollar' => 500,
513            'e' => 444, 'eacute' => 444, 'ecircumflex' => 444, 'edieresis' => 444,
514            'egrave' => 444, 'eight' => 500, 'ellipsis' => 889, 'emdash' => 889,
515            'endash' => 500, 'equal' => 675, 'eth' => 500, 'exclam' => 333,
516            'exclamdown' => 389, 'f' => 278, 'five' => 500, 'florin' => 500,
517            'four' => 500, 'g' => 500, 'germandbls' => 500, 'grave' => 333,
518            'greater' => 675, 'guillemotleft' => 500, 'guillemotright' => 500, 'guilsinglleft' => 333,
519            'guilsinglright' => 333, 'h' => 500, 'hyphen' => 333, 'i' => 278,
520            'iacute' => 278, 'icircumflex' => 278, 'idieresis' => 278, 'igrave' => 278,
521            'j' => 278, 'k' => 444, 'l' => 278, 'less' => 675,
522            'logicalnot' => 675, 'm' => 722, 'macron' => 333, 'mu' => 500,
523            'multiply' => 675, 'n' => 500, 'nine' => 500, 'ntilde' => 500,
524            'numbersign' => 500, 'o' => 500, 'oacute' => 500, 'ocircumflex' => 500,
525            'odieresis' => 500, 'oe' => 667, 'ograve' => 500, 'one' => 500,
526            'onehalf' => 750, 'onequarter' => 750, 'onesuperior' => 300, 'ordfeminine' => 276,
527            'ordmasculine' => 310, 'oslash' => 500, 'otilde' => 500, 'p' => 500,
528            'paragraph' => 523, 'parenleft' => 333, 'parenright' => 333, 'percent' => 833,
529            'period' => 250, 'periodcentered' => 250, 'perthousand' => 1000, 'plus' => 675,
530            'plusminus' => 675, 'q' => 500, 'question' => 500, 'questiondown' => 500,
531            'quotedbl' => 420, 'quotedblbase' => 556, 'quotedblleft' => 556, 'quotedblright' => 556,
532            'quoteleft' => 333, 'quoteright' => 333, 'quotesinglbase' => 333, 'quotesingle' => 214,
533            'r' => 389, 'registered' => 760, 's' => 389, 'scaron' => 389,
534            'section' => 500, 'semicolon' => 333, 'seven' => 500, 'six' => 500,
535            'slash' => 278, 'space' => 250, 'sterling' => 500, 't' => 278,
536            'thorn' => 500, 'three' => 500, 'threequarters' => 750, 'threesuperior' => 300,
537            'tilde' => 333, 'trademark' => 980, 'two' => 500, 'twosuperior' => 300,
538            'u' => 500, 'uacute' => 500, 'ucircumflex' => 500, 'udieresis' => 500,
539            'ugrave' => 500, 'underscore' => 500, 'v' => 444, 'w' => 667,
540            'x' => 444, 'y' => 444, 'yacute' => 444, 'ydieresis' => 444,
541            'yen' => 500, 'z' => 389, 'zcaron' => 389, 'zero' => 500,
542        ];
543    }
544
545    /** @return array<string, int> */
546    private static function timesBoldItalicWidths(): array
547    {
548        return [
549            'A' => 667, 'AE' => 944, 'Aacute' => 667, 'Acircumflex' => 667,
550            'Adieresis' => 667, 'Agrave' => 667, 'Aring' => 667, 'Atilde' => 667,
551            'B' => 667, 'C' => 667, 'Ccedilla' => 667, 'D' => 722,
552            'E' => 667, 'Eacute' => 667, 'Ecircumflex' => 667, 'Edieresis' => 667,
553            'Egrave' => 667, 'Eth' => 722, 'Euro' => 500, 'F' => 667,
554            'G' => 722, 'H' => 778, 'I' => 389, 'Iacute' => 389,
555            'Icircumflex' => 389, 'Idieresis' => 389, 'Igrave' => 389, 'J' => 500,
556            'K' => 667, 'L' => 611, 'M' => 889, 'N' => 722,
557            'Ntilde' => 722, 'O' => 722, 'OE' => 944, 'Oacute' => 722,
558            'Ocircumflex' => 722, 'Odieresis' => 722, 'Ograve' => 722, 'Oslash' => 722,
559            'Otilde' => 722, 'P' => 611, 'Q' => 722, 'R' => 667,
560            'S' => 556, 'Scaron' => 556, 'T' => 611, 'Thorn' => 611,
561            'U' => 722, 'Uacute' => 722, 'Ucircumflex' => 722, 'Udieresis' => 722,
562            'Ugrave' => 722, 'V' => 667, 'W' => 889, 'X' => 667,
563            'Y' => 611, 'Yacute' => 611, 'Ydieresis' => 611, 'Z' => 611,
564            'Zcaron' => 611, 'a' => 500, 'aacute' => 500, 'acircumflex' => 500,
565            'acute' => 333, 'adieresis' => 500, 'ae' => 722, 'agrave' => 500,
566            'ampersand' => 778, 'aring' => 500, 'asciicircum' => 570, 'asciitilde' => 570,
567            'asterisk' => 500, 'at' => 832, 'atilde' => 500, 'b' => 500,
568            'backslash' => 278, 'bar' => 220, 'braceleft' => 348, 'braceright' => 348,
569            'bracketleft' => 333, 'bracketright' => 333, 'brokenbar' => 220, 'bullet' => 350,
570            'c' => 444, 'ccedilla' => 444, 'cedilla' => 333, 'cent' => 500,
571            'circumflex' => 333, 'colon' => 333, 'comma' => 250, 'copyright' => 747,
572            'currency' => 500, 'd' => 500, 'dagger' => 500, 'daggerdbl' => 500,
573            'degree' => 400, 'dieresis' => 333, 'divide' => 570, 'dollar' => 500,
574            'e' => 444, 'eacute' => 444, 'ecircumflex' => 444, 'edieresis' => 444,
575            'egrave' => 444, 'eight' => 500, 'ellipsis' => 1000, 'emdash' => 1000,
576            'endash' => 500, 'equal' => 570, 'eth' => 500, 'exclam' => 389,
577            'exclamdown' => 389, 'f' => 333, 'five' => 500, 'florin' => 500,
578            'four' => 500, 'g' => 500, 'germandbls' => 500, 'grave' => 333,
579            'greater' => 570, 'guillemotleft' => 500, 'guillemotright' => 500, 'guilsinglleft' => 333,
580            'guilsinglright' => 333, 'h' => 556, 'hyphen' => 333, 'i' => 278,
581            'iacute' => 278, 'icircumflex' => 278, 'idieresis' => 278, 'igrave' => 278,
582            'j' => 278, 'k' => 500, 'l' => 278, 'less' => 570,
583            'logicalnot' => 606, 'm' => 778, 'macron' => 333, 'mu' => 576,
584            'multiply' => 570, 'n' => 556, 'nine' => 500, 'ntilde' => 556,
585            'numbersign' => 500, 'o' => 500, 'oacute' => 500, 'ocircumflex' => 500,
586            'odieresis' => 500, 'oe' => 722, 'ograve' => 500, 'one' => 500,
587            'onehalf' => 750, 'onequarter' => 750, 'onesuperior' => 300, 'ordfeminine' => 266,
588            'ordmasculine' => 300, 'oslash' => 500, 'otilde' => 500, 'p' => 500,
589            'paragraph' => 500, 'parenleft' => 333, 'parenright' => 333, 'percent' => 833,
590            'period' => 250, 'periodcentered' => 250, 'perthousand' => 1000, 'plus' => 570,
591            'plusminus' => 570, 'q' => 500, 'question' => 500, 'questiondown' => 500,
592            'quotedbl' => 555, 'quotedblbase' => 500, 'quotedblleft' => 500, 'quotedblright' => 500,
593            'quoteleft' => 333, 'quoteright' => 333, 'quotesinglbase' => 333, 'quotesingle' => 278,
594            'r' => 389, 'registered' => 747, 's' => 389, 'scaron' => 389,
595            'section' => 500, 'semicolon' => 333, 'seven' => 500, 'six' => 500,
596            'slash' => 278, 'space' => 250, 'sterling' => 500, 't' => 278,
597            'thorn' => 500, 'three' => 500, 'threequarters' => 750, 'threesuperior' => 300,
598            'tilde' => 333, 'trademark' => 1000, 'two' => 500, 'twosuperior' => 300,
599            'u' => 556, 'uacute' => 556, 'ucircumflex' => 556, 'udieresis' => 556,
600            'ugrave' => 556, 'underscore' => 500, 'v' => 444, 'w' => 667,
601            'x' => 500, 'y' => 444, 'yacute' => 444, 'ydieresis' => 444,
602            'yen' => 500, 'z' => 389, 'zcaron' => 389, 'zero' => 500,
603        ];
604    }
605
606    /** @return array<string, int> */
607    private static function courierWidths(): array
608    {
609        // Every WinAnsi glyph in the Courier family is 600 units wide.
610        $widths = [];
611        foreach (self::courierGlyphs() as $glyph) {
612            $widths[$glyph] = 600;
613        }
614        return $widths;
615    }
616
617    /** @return list<string> */
618    private static function courierGlyphs(): array
619    {
620        return [
621            'A', 'AE', 'Aacute', 'Acircumflex', 'Adieresis', 'Agrave',
622            'Aring', 'Atilde', 'B', 'C', 'Ccedilla', 'D',
623            'E', 'Eacute', 'Ecircumflex', 'Edieresis', 'Egrave', 'Eth',
624            'Euro', 'F', 'G', 'H', 'I', 'Iacute',
625            'Icircumflex', 'Idieresis', 'Igrave', 'J', 'K', 'L',
626            'M', 'N', 'Ntilde', 'O', 'OE', 'Oacute',
627            'Ocircumflex', 'Odieresis', 'Ograve', 'Oslash', 'Otilde', 'P',
628            'Q', 'R', 'S', 'Scaron', 'T', 'Thorn',
629            'U', 'Uacute', 'Ucircumflex', 'Udieresis', 'Ugrave', 'V',
630            'W', 'X', 'Y', 'Yacute', 'Ydieresis', 'Z',
631            'Zcaron', 'a', 'aacute', 'acircumflex', 'acute', 'adieresis',
632            'ae', 'agrave', 'ampersand', 'aring', 'asciicircum', 'asciitilde',
633            'asterisk', 'at', 'atilde', 'b', 'backslash', 'bar',
634            'braceleft', 'braceright', 'bracketleft', 'bracketright', 'brokenbar', 'bullet',
635            'c', 'ccedilla', 'cedilla', 'cent', 'circumflex', 'colon',
636            'comma', 'copyright', 'currency', 'd', 'dagger', 'daggerdbl',
637            'degree', 'dieresis', 'divide', 'dollar', 'e', 'eacute',
638            'ecircumflex', 'edieresis', 'egrave', 'eight', 'ellipsis', 'emdash',
639            'endash', 'equal', 'eth', 'exclam', 'exclamdown', 'f',
640            'five', 'florin', 'four', 'g', 'germandbls', 'grave',
641            'greater', 'guillemotleft', 'guillemotright', 'guilsinglleft', 'guilsinglright', 'h',
642            'hyphen', 'i', 'iacute', 'icircumflex', 'idieresis', 'igrave',
643            'j', 'k', 'l', 'less', 'logicalnot', 'm',
644            'macron', 'mu', 'multiply', 'n', 'nine', 'ntilde',
645            'numbersign', 'o', 'oacute', 'ocircumflex', 'odieresis', 'oe',
646            'ograve', 'one', 'onehalf', 'onequarter', 'onesuperior', 'ordfeminine',
647            'ordmasculine', 'oslash', 'otilde', 'p', 'paragraph', 'parenleft',
648            'parenright', 'percent', 'period', 'periodcentered', 'perthousand', 'plus',
649            'plusminus', 'q', 'question', 'questiondown', 'quotedbl', 'quotedblbase',
650            'quotedblleft', 'quotedblright', 'quoteleft', 'quoteright', 'quotesinglbase', 'quotesingle',
651            'r', 'registered', 's', 'scaron', 'section', 'semicolon',
652            'seven', 'six', 'slash', 'space', 'sterling', 't',
653            'thorn', 'three', 'threequarters', 'threesuperior', 'tilde', 'trademark',
654            'two', 'twosuperior', 'u', 'uacute', 'ucircumflex', 'udieresis',
655            'ugrave', 'underscore', 'v', 'w', 'x', 'y',
656            'yacute', 'ydieresis', 'yen', 'z', 'zcaron', 'zero',
657        ];
658    }
659
660    /** @return array<string, int> */
661    private static function symbolWidths(): array
662    {
663        return [
664            'space' => 250, 'exclam' => 333, 'universal' => 713, 'numbersign' => 500,
665            'existential' => 549, 'percent' => 833, 'ampersand' => 778, 'suchthat' => 439,
666            'parenleft' => 333, 'parenright' => 333, 'asteriskmath' => 500, 'plus' => 549,
667            'comma' => 250, 'minus' => 549, 'period' => 250, 'slash' => 278,
668            'zero' => 500, 'one' => 500, 'two' => 500, 'three' => 500,
669            'four' => 500, 'five' => 500, 'six' => 500, 'seven' => 500,
670            'eight' => 500, 'nine' => 500,
671            'colon' => 278, 'semicolon' => 278, 'less' => 549, 'equal' => 549,
672            'greater' => 549, 'question' => 444, 'congruent' => 549,
673            'Alpha' => 722, 'Beta' => 667, 'Chi' => 667, 'Delta' => 612,
674            'Epsilon' => 611, 'Phi' => 763, 'Gamma' => 603, 'Eta' => 722,
675            'Iota' => 333, 'theta1' => 631, 'Kappa' => 722, 'Lambda' => 686,
676            'Mu' => 889, 'Nu' => 722, 'Omicron' => 722, 'Pi' => 768,
677            'Theta' => 741, 'Rho' => 556, 'Sigma' => 592, 'Tau' => 611,
678            'Upsilon' => 690, 'sigma1' => 439, 'Omega' => 768, 'Xi' => 645,
679            'Psi' => 795, 'Zeta' => 611,
680            'bracketleft' => 333, 'therefore' => 863, 'bracketright' => 333,
681            'perpendicular' => 658, 'underscore' => 500, 'radicalex' => 500,
682            'alpha' => 631, 'beta' => 549, 'chi' => 549, 'delta' => 494,
683            'epsilon' => 439, 'phi' => 521, 'gamma' => 411, 'eta' => 603,
684            'iota' => 329, 'phi1' => 603, 'kappa' => 549, 'lambda' => 549,
685            'mu' => 576, 'nu' => 521, 'omicron' => 549, 'pi' => 549,
686            'theta' => 521, 'rho' => 549, 'sigma' => 603, 'tau' => 439,
687            'upsilon' => 576, 'omega1' => 713, 'omega' => 686, 'xi' => 493,
688            'psi' => 686, 'zeta' => 494,
689            'braceleft' => 480, 'bar' => 200, 'braceright' => 480, 'similar' => 549,
690        ];
691    }
692
693    /** @return array<string, int> */
694    private static function zapfDingbatsWidths(): array
695    {
696        return [
697            'space' => 278,
698            'a1' => 974, 'a2' => 961, 'a202' => 974, 'a3' => 980, 'a4' => 719,
699            'a5' => 789, 'a119' => 790, 'a118' => 791, 'a117' => 690, 'a11' => 960,
700            'a12' => 939, 'a13' => 549, 'a14' => 855, 'a15' => 911, 'a16' => 933,
701            'a105' => 911, 'a17' => 945, 'a18' => 974, 'a19' => 755, 'a20' => 846,
702            'a21' => 762, 'a22' => 761, 'a23' => 571, 'a24' => 677, 'a25' => 763,
703            'a26' => 760, 'a27' => 759, 'a28' => 754, 'a6' => 494, 'a7' => 552,
704            'a8' => 537, 'a9' => 577, 'a10' => 692, 'a29' => 786, 'a30' => 788,
705            'a31' => 788, 'a32' => 790, 'a33' => 793, 'a34' => 794, 'a35' => 816,
706            'a36' => 823, 'a37' => 789, 'a38' => 841, 'a39' => 823, 'a40' => 833,
707            'a41' => 816, 'a42' => 831, 'a43' => 923, 'a44' => 744, 'a45' => 723,
708            'a46' => 749, 'a47' => 790, 'a48' => 792, 'a49' => 695, 'a50' => 776,
709            'a51' => 768, 'a52' => 792, 'a53' => 759, 'a54' => 707, 'a55' => 708,
710            'a56' => 682, 'a57' => 701, 'a58' => 826, 'a59' => 815, 'a60' => 789,
711            'a61' => 789, 'a62' => 707, 'a63' => 687, 'a64' => 696, 'a65' => 689,
712            'a66' => 786, 'a67' => 787, 'a68' => 713, 'a69' => 791, 'a70' => 785,
713            'a71' => 791, 'a72' => 873, 'a73' => 761, 'a74' => 762, 'a203' => 762,
714            'a75' => 759, 'a204' => 759, 'a76' => 892, 'a77' => 892, 'a78' => 788,
715            'a79' => 784, 'a81' => 438, 'a82' => 138, 'a83' => 277, 'a84' => 415,
716            'a97' => 392, 'a98' => 392, 'a99' => 668, 'a100' => 668,
717        ];
718    }
719}