fix wrong git ignore

This commit is contained in:
Adrian Zürcher
2025-12-15 17:44:00 +01:00
parent ed9f31bb96
commit 8f313c00f0
126 changed files with 70589 additions and 1 deletions

View File

@@ -0,0 +1,34 @@
package textencoding
import "gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
type TextEncoder interface {
// Convert a raw utf8 string (series of runes) to an encoded string (series of character codes) to be used in PDF.
Encode(raw string) string
// Conversion between character code and glyph name.
// The bool return flag is true if there was a match, and false otherwise.
CharcodeToGlyph(code byte) (string, bool)
// Conversion between glyph name and character code.
// The bool return flag is true if there was a match, and false otherwise.
GlyphToCharcode(glyph string) (byte, bool)
// Convert rune to character code.
// The bool return flag is true if there was a match, and false otherwise.
RuneToCharcode(val rune) (byte, bool)
// Convert character code to rune.
// The bool return flag is true if there was a match, and false otherwise.
CharcodeToRune(charcode byte) (rune, bool)
// Convert rune to glyph name.
// The bool return flag is true if there was a match, and false otherwise.
RuneToGlyph(val rune) (string, bool)
// Convert glyph to rune.
// The bool return flag is true if there was a match, and false otherwise.
GlyphToRune(glyph string) (rune, bool)
ToPdfObject() core.PdfObject
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,409 @@
package textencoding
var zapfdingbatsGlyphToRuneMap = map[string]rune{
"a1": '\u2701',
"a10": '\u2721',
"a100": '\u275e',
"a101": '\u2761',
"a102": '\u2762',
"a103": '\u2763',
"a104": '\u2764',
"a105": '\u2710',
"a106": '\u2765',
"a107": '\u2766',
"a108": '\u2767',
"a109": '\u2660',
"a11": '\u261b',
"a110": '\u2665',
"a111": '\u2666',
"a112": '\u2663',
"a117": '\u2709',
"a118": '\u2708',
"a119": '\u2707',
"a12": '\u261e',
"a120": '\u2460',
"a121": '\u2461',
"a122": '\u2462',
"a123": '\u2463',
"a124": '\u2464',
"a125": '\u2465',
"a126": '\u2466',
"a127": '\u2467',
"a128": '\u2468',
"a129": '\u2469',
"a13": '\u270c',
"a130": '\u2776',
"a131": '\u2777',
"a132": '\u2778',
"a133": '\u2779',
"a134": '\u277a',
"a135": '\u277b',
"a136": '\u277c',
"a137": '\u277d',
"a138": '\u277e',
"a139": '\u277f',
"a14": '\u270d',
"a140": '\u2780',
"a141": '\u2781',
"a142": '\u2782',
"a143": '\u2783',
"a144": '\u2784',
"a145": '\u2785',
"a146": '\u2786',
"a147": '\u2787',
"a148": '\u2788',
"a149": '\u2789',
"a15": '\u270e',
"a150": '\u278a',
"a151": '\u278b',
"a152": '\u278c',
"a153": '\u278d',
"a154": '\u278e',
"a155": '\u278f',
"a156": '\u2790',
"a157": '\u2791',
"a158": '\u2792',
"a159": '\u2793',
"a16": '\u270f',
"a160": '\u2794',
"a161": '\u2192',
"a162": '\u27a3',
"a163": '\u2194',
"a164": '\u2195',
"a165": '\u2799',
"a166": '\u279b',
"a167": '\u279c',
"a168": '\u279d',
"a169": '\u279e',
"a17": '\u2711',
"a170": '\u279f',
"a171": '\u27a0',
"a172": '\u27a1',
"a173": '\u27a2',
"a174": '\u27a4',
"a175": '\u27a5',
"a176": '\u27a6',
"a177": '\u27a7',
"a178": '\u27a8',
"a179": '\u27a9',
"a18": '\u2712',
"a180": '\u27ab',
"a181": '\u27ad',
"a182": '\u27af',
"a183": '\u27b2',
"a184": '\u27b3',
"a185": '\u27b5',
"a186": '\u27b8',
"a187": '\u27ba',
"a188": '\u27bb',
"a189": '\u27bc',
"a19": '\u2713',
"a190": '\u27bd',
"a191": '\u27be',
"a192": '\u279a',
"a193": '\u27aa',
"a194": '\u27b6',
"a195": '\u27b9',
"a196": '\u2798',
"a197": '\u27b4',
"a198": '\u27b7',
"a199": '\u27ac',
"a2": '\u2702',
"a20": '\u2714',
"a200": '\u27ae',
"a201": '\u27b1',
"a202": '\u2703',
"a203": '\u2750',
"a204": '\u2752',
"a205": '\u276e',
"a206": '\u2770',
"a21": '\u2715',
"a22": '\u2716',
"a23": '\u2717',
"a24": '\u2718',
"a25": '\u2719',
"a26": '\u271a',
"a27": '\u271b',
"a28": '\u271c',
"a29": '\u2722',
"a3": '\u2704',
"a30": '\u2723',
"a31": '\u2724',
"a32": '\u2725',
"a33": '\u2726',
"a34": '\u2727',
"a35": '\u2605',
"a36": '\u2729',
"a37": '\u272a',
"a38": '\u272b',
"a39": '\u272c',
"a4": '\u260e',
"a40": '\u272d',
"a41": '\u272e',
"a42": '\u272f',
"a43": '\u2730',
"a44": '\u2731',
"a45": '\u2732',
"a46": '\u2733',
"a47": '\u2734',
"a48": '\u2735',
"a49": '\u2736',
"a5": '\u2706',
"a50": '\u2737',
"a51": '\u2738',
"a52": '\u2739',
"a53": '\u273a',
"a54": '\u273b',
"a55": '\u273c',
"a56": '\u273d',
"a57": '\u273e',
"a58": '\u273f',
"a59": '\u2740',
"a6": '\u271d',
"a60": '\u2741',
"a61": '\u2742',
"a62": '\u2743',
"a63": '\u2744',
"a64": '\u2745',
"a65": '\u2746',
"a66": '\u2747',
"a67": '\u2748',
"a68": '\u2749',
"a69": '\u274a',
"a7": '\u271e',
"a70": '\u274b',
"a71": '\u25cf',
"a72": '\u274d',
"a73": '\u25a0',
"a74": '\u274f',
"a75": '\u2751',
"a76": '\u25b2',
"a77": '\u25bc',
"a78": '\u25c6',
"a79": '\u2756',
"a8": '\u271f',
"a81": '\u25d7',
"a82": '\u2758',
"a83": '\u2759',
"a84": '\u275a',
"a85": '\u276f',
"a86": '\u2771',
"a87": '\u2772',
"a88": '\u2773',
"a89": '\u2768',
"a9": '\u2720',
"a90": '\u2769',
"a91": '\u276c',
"a92": '\u276d',
"a93": '\u276a',
"a94": '\u276b',
"a95": '\u2774',
"a96": '\u2775',
"a97": '\u275b',
"a98": '\u275c',
"a99": '\u275d',
}
var zapfdingbatsRuneToGlyphMap = map[rune]string{
'\u2701': "a1",
'\u2721': "a10",
'\u275e': "a100",
'\u2761': "a101",
'\u2762': "a102",
'\u2763': "a103",
'\u2764': "a104",
'\u2710': "a105",
'\u2765': "a106",
'\u2766': "a107",
'\u2767': "a108",
'\u2660': "a109",
'\u261b': "a11",
'\u2665': "a110",
'\u2666': "a111",
'\u2663': "a112",
'\u2709': "a117",
'\u2708': "a118",
'\u2707': "a119",
'\u261e': "a12",
'\u2460': "a120",
'\u2461': "a121",
'\u2462': "a122",
'\u2463': "a123",
'\u2464': "a124",
'\u2465': "a125",
'\u2466': "a126",
'\u2467': "a127",
'\u2468': "a128",
'\u2469': "a129",
'\u270c': "a13",
'\u2776': "a130",
'\u2777': "a131",
'\u2778': "a132",
'\u2779': "a133",
'\u277a': "a134",
'\u277b': "a135",
'\u277c': "a136",
'\u277d': "a137",
'\u277e': "a138",
'\u277f': "a139",
'\u270d': "a14",
'\u2780': "a140",
'\u2781': "a141",
'\u2782': "a142",
'\u2783': "a143",
'\u2784': "a144",
'\u2785': "a145",
'\u2786': "a146",
'\u2787': "a147",
'\u2788': "a148",
'\u2789': "a149",
'\u270e': "a15",
'\u278a': "a150",
'\u278b': "a151",
'\u278c': "a152",
'\u278d': "a153",
'\u278e': "a154",
'\u278f': "a155",
'\u2790': "a156",
'\u2791': "a157",
'\u2792': "a158",
'\u2793': "a159",
'\u270f': "a16",
'\u2794': "a160",
'\u2192': "a161",
'\u27a3': "a162",
'\u2194': "a163",
'\u2195': "a164",
'\u2799': "a165",
'\u279b': "a166",
'\u279c': "a167",
'\u279d': "a168",
'\u279e': "a169",
'\u2711': "a17",
'\u279f': "a170",
'\u27a0': "a171",
'\u27a1': "a172",
'\u27a2': "a173",
'\u27a4': "a174",
'\u27a5': "a175",
'\u27a6': "a176",
'\u27a7': "a177",
'\u27a8': "a178",
'\u27a9': "a179",
'\u2712': "a18",
'\u27ab': "a180",
'\u27ad': "a181",
'\u27af': "a182",
'\u27b2': "a183",
'\u27b3': "a184",
'\u27b5': "a185",
'\u27b8': "a186",
'\u27ba': "a187",
'\u27bb': "a188",
'\u27bc': "a189",
'\u2713': "a19",
'\u27bd': "a190",
'\u27be': "a191",
'\u279a': "a192",
'\u27aa': "a193",
'\u27b6': "a194",
'\u27b9': "a195",
'\u2798': "a196",
'\u27b4': "a197",
'\u27b7': "a198",
'\u27ac': "a199",
'\u2702': "a2",
'\u2714': "a20",
'\u27ae': "a200",
'\u27b1': "a201",
'\u2703': "a202",
'\u2750': "a203",
'\u2752': "a204",
'\u276e': "a205",
'\u2770': "a206",
'\u2715': "a21",
'\u2716': "a22",
'\u2717': "a23",
'\u2718': "a24",
'\u2719': "a25",
'\u271a': "a26",
'\u271b': "a27",
'\u271c': "a28",
'\u2722': "a29",
'\u2704': "a3",
'\u2723': "a30",
'\u2724': "a31",
'\u2725': "a32",
'\u2726': "a33",
'\u2727': "a34",
'\u2605': "a35",
'\u2729': "a36",
'\u272a': "a37",
'\u272b': "a38",
'\u272c': "a39",
'\u260e': "a4",
'\u272d': "a40",
'\u272e': "a41",
'\u272f': "a42",
'\u2730': "a43",
'\u2731': "a44",
'\u2732': "a45",
'\u2733': "a46",
'\u2734': "a47",
'\u2735': "a48",
'\u2736': "a49",
'\u2706': "a5",
'\u2737': "a50",
'\u2738': "a51",
'\u2739': "a52",
'\u273a': "a53",
'\u273b': "a54",
'\u273c': "a55",
'\u273d': "a56",
'\u273e': "a57",
'\u273f': "a58",
'\u2740': "a59",
'\u271d': "a6",
'\u2741': "a60",
'\u2742': "a61",
'\u2743': "a62",
'\u2744': "a63",
'\u2745': "a64",
'\u2746': "a65",
'\u2747': "a66",
'\u2748': "a67",
'\u2749': "a68",
'\u274a': "a69",
'\u271e': "a7",
'\u274b': "a70",
'\u25cf': "a71",
'\u274d': "a72",
'\u25a0': "a73",
'\u274f': "a74",
'\u2751': "a75",
'\u25b2': "a76",
'\u25bc': "a77",
'\u25c6': "a78",
'\u2756': "a79",
'\u271f': "a8",
'\u25d7': "a81",
'\u2758': "a82",
'\u2759': "a83",
'\u275a': "a84",
'\u276f': "a85",
'\u2771': "a86",
'\u2772': "a87",
'\u2773': "a88",
'\u2768': "a89",
'\u2720': "a9",
'\u2769': "a90",
'\u276c': "a91",
'\u276d': "a92",
'\u276a': "a93",
'\u276b': "a94",
'\u2774': "a95",
'\u2775': "a96",
'\u275b': "a97",
'\u275c': "a98",
'\u275d': "a99",
}

View File

@@ -0,0 +1,496 @@
package textencoding
import (
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/common"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
)
// Encoding for Symbol font.
type SymbolEncoder struct {
}
func NewSymbolEncoder() SymbolEncoder {
encoder := SymbolEncoder{}
return encoder
}
// Convert a raw utf8 string (series of runes) to an encoded string (series of character codes) to be used in PDF.
func (enc SymbolEncoder) Encode(raw string) string {
encoded := []byte{}
for _, rune := range raw {
code, found := enc.RuneToCharcode(rune)
if !found {
continue
}
encoded = append(encoded, code)
}
return string(encoded)
}
// Conversion between character code and glyph name.
// The bool return flag is true if there was a match, and false otherwise.
func (enc SymbolEncoder) CharcodeToGlyph(code byte) (string, bool) {
glyph, has := symbolEncodingCharcodeToGlyphMap[code]
if !has {
common.Log.Debug("Symbol encoding error: unable to find charcode->glyph entry (%v)", code)
return "", false
}
return glyph, true
}
// Conversion between glyph name and character code.
// The bool return flag is true if there was a match, and false otherwise.
func (enc SymbolEncoder) GlyphToCharcode(glyph string) (byte, bool) {
code, found := symbolEncodingGlyphToCharcodeMap[glyph]
if !found {
common.Log.Debug("Symbol encoding error: unable to find glyph->charcode entry (%s)", glyph)
return 0, false
}
return code, found
}
// Convert rune to character code.
// The bool return flag is true if there was a match, and false otherwise.
func (enc SymbolEncoder) RuneToCharcode(val rune) (byte, bool) {
glyph, found := runeToGlyph(val, glyphlistRuneToGlyphMap)
if !found {
common.Log.Debug("Symbol encoding error: unable to find rune->glyph entry (%v)", val)
return 0, false
}
code, found := symbolEncodingGlyphToCharcodeMap[glyph]
if !found {
common.Log.Debug("Symbol encoding error: unable to find glyph->charcode entry (%s)", glyph)
return 0, false
}
return code, true
}
// Convert character code to rune.
// The bool return flag is true if there was a match, and false otherwise.
func (enc SymbolEncoder) CharcodeToRune(charcode byte) (rune, bool) {
glyph, found := symbolEncodingCharcodeToGlyphMap[charcode]
if !found {
common.Log.Debug("Symbol encoding error: unable to find charcode->glyph entry (%d)", charcode)
return 0, false
}
val, found := glyphToRune(glyph, glyphlistGlyphToRuneMap)
if !found {
return 0, false
}
return val, true
}
// Convert rune to glyph name.
// The bool return flag is true if there was a match, and false otherwise.
func (enc SymbolEncoder) RuneToGlyph(val rune) (string, bool) {
return runeToGlyph(val, glyphlistRuneToGlyphMap)
}
// Convert glyph to rune.
// The bool return flag is true if there was a match, and false otherwise.
func (enc SymbolEncoder) GlyphToRune(glyph string) (rune, bool) {
return glyphToRune(glyph, glyphlistGlyphToRuneMap)
}
// Convert to PDF Object.
func (enc SymbolEncoder) ToPdfObject() core.PdfObject {
dict := core.MakeDict()
dict.Set("Type", core.MakeName("Encoding"))
// Returning an empty Encoding object with no differences. Indicates that we are using the font's built-in
// encoding.
return core.MakeIndirectObject(dict)
}
// Charcode to Glyph map (Symbol encoding)
var symbolEncodingCharcodeToGlyphMap map[byte]string = map[byte]string{
32: "space",
33: "exclam",
34: "universal",
35: "numbersign",
36: "existential",
37: "percent",
38: "ampersand",
39: "suchthat",
40: "parenleft",
41: "parenright",
42: "asteriskmath",
43: "plus",
44: "comma",
45: "minus",
46: "period",
47: "slash",
48: "zero",
49: "one",
50: "two",
51: "three",
52: "four",
53: "five",
54: "six",
55: "seven",
56: "eight",
57: "nine",
58: "colon",
59: "semicolon",
60: "less",
61: "equal",
62: "greater",
63: "question",
64: "congruent",
65: "Alpha",
66: "Beta",
67: "Chi",
68: "Delta",
69: "Epsilon",
70: "Phi",
71: "Gamma",
72: "Eta",
73: "Iota",
74: "theta1",
75: "Kappa",
76: "Lambda",
77: "Mu",
78: "Nu",
79: "Omicron",
80: "Pi",
81: "Theta",
82: "Rho",
83: "Sigma",
84: "Tau",
85: "Upsilon",
86: "sigma1",
87: "Omega",
88: "Xi",
89: "Psi",
90: "Zeta",
91: "bracketleft",
92: "therefore",
93: "bracketright",
94: "perpendicular",
95: "underscore",
96: "radicalex",
97: "alpha",
98: "beta",
99: "chi",
100: "delta",
101: "epsilon",
102: "phi",
103: "gamma",
104: "eta",
105: "iota",
106: "phi1",
107: "kappa",
108: "lambda",
109: "mu",
110: "nu",
111: "omicron",
112: "pi",
113: "theta",
114: "rho",
115: "sigma",
116: "tau",
117: "upsilon",
118: "omega1",
119: "omega",
120: "xi",
121: "psi",
122: "zeta",
123: "braceleft",
124: "bar",
125: "braceright",
126: "similar",
160: "Euro",
161: "Upsilon1",
162: "minute",
163: "lessequal",
164: "fraction",
165: "infinity",
166: "florin",
167: "club",
168: "diamond",
169: "heart",
170: "spade",
171: "arrowboth",
172: "arrowleft",
173: "arrowup",
174: "arrowright",
175: "arrowdown",
176: "degree",
177: "plusminus",
178: "second",
179: "greaterequal",
180: "multiply",
181: "proportional",
182: "partialdiff",
183: "bullet",
184: "divide",
185: "notequal",
186: "equivalence",
187: "approxequal",
188: "ellipsis",
189: "arrowvertex",
190: "arrowhorizex",
191: "carriagereturn",
192: "aleph",
193: "Ifraktur",
194: "Rfraktur",
195: "weierstrass",
196: "circlemultiply",
197: "circleplus",
198: "emptyset",
199: "intersection",
200: "union",
201: "propersuperset",
202: "reflexsuperset",
203: "notsubset",
204: "propersubset",
205: "reflexsubset",
206: "element",
207: "notelement",
208: "angle",
209: "gradient",
210: "registerserif",
211: "copyrightserif",
212: "trademarkserif",
213: "product",
214: "radical",
215: "dotmath",
216: "logicalnot",
217: "logicaland",
218: "logicalor",
219: "arrowdblboth",
220: "arrowdblleft",
221: "arrowdblup",
222: "arrowdblright",
223: "arrowdbldown",
224: "lozenge",
225: "angleleft",
226: "registersans",
227: "copyrightsans",
228: "trademarksans",
229: "summation",
230: "parenlefttp",
231: "parenleftex",
232: "parenleftbt",
233: "bracketlefttp",
234: "bracketleftex",
235: "bracketleftbt",
236: "bracelefttp",
237: "braceleftmid",
238: "braceleftbt",
239: "braceex",
241: "angleright",
242: "integral",
243: "integraltp",
244: "integralex",
245: "integralbt",
246: "parenrighttp",
247: "parenrightex",
248: "parenrightbt",
249: "bracketrighttp",
250: "bracketrightex",
251: "bracketrightbt",
252: "bracerighttp",
253: "bracerightmid",
254: "bracerightbt",
}
// Glyph to charcode map (Symbol encoding).
var symbolEncodingGlyphToCharcodeMap map[string]byte = map[string]byte{
"space": 32,
"exclam": 33,
"universal": 34,
"numbersign": 35,
"existential": 36,
"percent": 37,
"ampersand": 38,
"suchthat": 39,
"parenleft": 40,
"parenright": 41,
"asteriskmath": 42,
"plus": 43,
"comma": 44,
"minus": 45,
"period": 46,
"slash": 47,
"zero": 48,
"one": 49,
"two": 50,
"three": 51,
"four": 52,
"five": 53,
"six": 54,
"seven": 55,
"eight": 56,
"nine": 57,
"colon": 58,
"semicolon": 59,
"less": 60,
"equal": 61,
"greater": 62,
"question": 63,
"congruent": 64,
"Alpha": 65,
"Beta": 66,
"Chi": 67,
"Delta": 68,
"Epsilon": 69,
"Phi": 70,
"Gamma": 71,
"Eta": 72,
"Iota": 73,
"theta1": 74,
"Kappa": 75,
"Lambda": 76,
"Mu": 77,
"Nu": 78,
"Omicron": 79,
"Pi": 80,
"Theta": 81,
"Rho": 82,
"Sigma": 83,
"Tau": 84,
"Upsilon": 85,
"sigma1": 86,
"Omega": 87,
"Xi": 88,
"Psi": 89,
"Zeta": 90,
"bracketleft": 91,
"therefore": 92,
"bracketright": 93,
"perpendicular": 94,
"underscore": 95,
"radicalex": 96,
"alpha": 97,
"beta": 98,
"chi": 99,
"delta": 100,
"epsilon": 101,
"phi": 102,
"gamma": 103,
"eta": 104,
"iota": 105,
"phi1": 106,
"kappa": 107,
"lambda": 108,
"mu": 109,
"nu": 110,
"omicron": 111,
"pi": 112,
"theta": 113,
"rho": 114,
"sigma": 115,
"tau": 116,
"upsilon": 117,
"omega1": 118,
"omega": 119,
"xi": 120,
"psi": 121,
"zeta": 122,
"braceleft": 123,
"bar": 124,
"braceright": 125,
"similar": 126,
"Euro": 160,
"Upsilon1": 161,
"minute": 162,
"lessequal": 163,
"fraction": 164,
"infinity": 165,
"florin": 166,
"club": 167,
"diamond": 168,
"heart": 169,
"spade": 170,
"arrowboth": 171,
"arrowleft": 172,
"arrowup": 173,
"arrowright": 174,
"arrowdown": 175,
"degree": 176,
"plusminus": 177,
"second": 178,
"greaterequal": 179,
"multiply": 180,
"proportional": 181,
"partialdiff": 182,
"bullet": 183,
"divide": 184,
"notequal": 185,
"equivalence": 186,
"approxequal": 187,
"ellipsis": 188,
"arrowvertex": 189,
"arrowhorizex": 190,
"carriagereturn": 191,
"aleph": 192,
"Ifraktur": 193,
"Rfraktur": 194,
"weierstrass": 195,
"circlemultiply": 196,
"circleplus": 197,
"emptyset": 198,
"intersection": 199,
"union": 200,
"propersuperset": 201,
"reflexsuperset": 202,
"notsubset": 203,
"propersubset": 204,
"reflexsubset": 205,
"element": 206,
"notelement": 207,
"angle": 208,
"gradient": 209,
"registerserif": 210,
"copyrightserif": 211,
"trademarkserif": 212,
"product": 213,
"radical": 214,
"dotmath": 215,
"logicalnot": 216,
"logicaland": 217,
"logicalor": 218,
"arrowdblboth": 219,
"arrowdblleft": 220,
"arrowdblup": 221,
"arrowdblright": 222,
"arrowdbldown": 223,
"lozenge": 224,
"angleleft": 225,
"registersans": 226,
"copyrightsans": 227,
"trademarksans": 228,
"summation": 229,
"parenlefttp": 230,
"parenleftex": 231,
"parenleftbt": 232,
"bracketlefttp": 233,
"bracketleftex": 234,
"bracketleftbt": 235,
"bracelefttp": 236,
"braceleftmid": 237,
"braceleftbt": 238,
"braceex": 239,
"angleright": 241,
"integral": 242,
"integraltp": 243,
"integralex": 244,
"integralbt": 245,
"parenrighttp": 246,
"parenrightex": 247,
"parenrightbt": 248,
"bracketrighttp": 249,
"bracketrightex": 250,
"bracketrightbt": 251,
"bracerighttp": 252,
"bracerightmid": 253,
"bracerightbt": 254,
}

View File

@@ -0,0 +1,51 @@
package textencoding
import "gitea.tecamino.com/paadi/pdfmerge/internal/pdf/common"
func glyphToRune(glyph string, glyphToRuneMap map[string]rune) (rune, bool) {
ucode, found := glyphToRuneMap[glyph]
if found {
return ucode, true
}
//common.Log.Debug("Glyph->Rune ERROR: Unable to find glyph %s", glyph)
return 0, false
}
func runeToGlyph(ucode rune, runeToGlyphMap map[rune]string) (string, bool) {
glyph, found := runeToGlyphMap[ucode]
if found {
return glyph, true
}
//common.Log.Debug("Rune->Glyph ERROR: Unable to find rune %v", ucode)
return "", false
}
func splitWords(raw string, encoder TextEncoder) []string {
runes := []rune(raw)
words := []string{}
startsAt := 0
for idx, code := range runes {
glyph, found := encoder.RuneToGlyph(code)
if !found {
common.Log.Debug("Glyph not found for code: %s\n", string(code))
continue
}
if glyph == "space" {
word := runes[startsAt:idx]
words = append(words, string(word))
startsAt = idx + 1
}
}
word := runes[startsAt:]
if len(word) > 0 {
words = append(words, string(word))
}
return words
}

View File

@@ -0,0 +1,557 @@
package textencoding
import (
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/common"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
)
// WinAnsiEncoding.
type WinAnsiEncoder struct {
}
func NewWinAnsiTextEncoder() WinAnsiEncoder {
encoder := WinAnsiEncoder{}
return encoder
}
func (winenc WinAnsiEncoder) ToPdfObject() core.PdfObject {
return core.MakeName("WinAnsiEncoding")
}
// Convert a raw utf8 string (series of runes) to an encoded string (series of character codes) to be used in PDF.
func (winenc WinAnsiEncoder) Encode(raw string) string {
encoded := []byte{}
for _, rune := range raw {
code, has := winenc.RuneToCharcode(rune)
if has {
encoded = append(encoded, code)
}
}
return string(encoded)
}
// Conversion between character code and glyph name.
// The bool return flag is true if there was a match, and false otherwise.
func (winenc WinAnsiEncoder) CharcodeToGlyph(code byte) (string, bool) {
glyph, has := winansiEncodingCharcodeToGlyphMap[code]
if !has {
common.Log.Debug("Charcode -> Glyph error: charcode not found: %d\n", code)
return "", false
}
return glyph, true
}
// Conversion between glyph name and character code.
// The bool return flag is true if there was a match, and false otherwise.
func (winenc WinAnsiEncoder) GlyphToCharcode(glyph string) (byte, bool) {
code, found := winansiEncodingGlyphToCharcodeMap[glyph]
if !found {
common.Log.Debug("Glyph -> Charcode error: glyph not found: %s\n", glyph)
return 0, false
}
return code, true
}
// Convert rune to character code.
// The bool return flag is true if there was a match, and false otherwise.
func (winenc WinAnsiEncoder) RuneToCharcode(val rune) (byte, bool) {
glyph, found := winenc.RuneToGlyph(val)
if !found {
return 0, false
}
code, found := winansiEncodingGlyphToCharcodeMap[glyph]
if !found {
common.Log.Debug("Glyph -> Charcode error: glyph not found %s\n", glyph)
return 0, false
}
return code, true
}
// Convert character code to rune.
// The bool return flag is true if there was a match, and false otherwise.
func (winenc WinAnsiEncoder) CharcodeToRune(charcode byte) (rune, bool) {
glyph, found := winansiEncodingCharcodeToGlyphMap[charcode]
if !found {
common.Log.Debug("Charcode -> Glyph error: charcode not found: %d\n", charcode)
return 0, false
}
ucode, found := glyphToRune(glyph, glyphlistGlyphToRuneMap)
if !found {
return 0, false
}
return ucode, true
}
// Convert rune to glyph name.
// The bool return flag is true if there was a match, and false otherwise.
func (winenc WinAnsiEncoder) RuneToGlyph(val rune) (string, bool) {
return runeToGlyph(val, glyphlistRuneToGlyphMap)
}
// Convert glyph to rune.
// The bool return flag is true if there was a match, and false otherwise.
func (winenc WinAnsiEncoder) GlyphToRune(glyph string) (rune, bool) {
return glyphToRune(glyph, glyphlistGlyphToRuneMap)
}
// Charcode to glyph name map (WinAnsiEncoding).
var winansiEncodingCharcodeToGlyphMap = map[byte]string{
32: "space",
33: "exclam",
34: "quotedbl",
35: "numbersign",
36: "dollar",
37: "percent",
38: "ampersand",
39: "quotesingle",
40: "parenleft",
41: "parenright",
42: "asterisk",
43: "plus",
44: "comma",
45: "hyphen",
46: "period",
47: "slash",
48: "zero",
49: "one",
50: "two",
51: "three",
52: "four",
53: "five",
54: "six",
55: "seven",
56: "eight",
57: "nine",
58: "colon",
59: "semicolon",
60: "less",
61: "equal",
62: "greater",
63: "question",
64: "at",
65: "A",
66: "B",
67: "C",
68: "D",
69: "E",
70: "F",
71: "G",
72: "H",
73: "I",
74: "J",
75: "K",
76: "L",
77: "M",
78: "N",
79: "O",
80: "P",
81: "Q",
82: "R",
83: "S",
84: "T",
85: "U",
86: "V",
87: "W",
88: "X",
89: "Y",
90: "Z",
91: "bracketleft",
92: "backslash",
93: "bracketright",
94: "asciicircum",
95: "underscore",
96: "grave",
97: "a",
98: "b",
99: "c",
100: "d",
101: "e",
102: "f",
103: "g",
104: "h",
105: "i",
106: "j",
107: "k",
108: "l",
109: "m",
110: "n",
111: "o",
112: "p",
113: "q",
114: "r",
115: "s",
116: "t",
117: "u",
118: "v",
119: "w",
120: "x",
121: "y",
122: "z",
123: "braceleft",
124: "bar",
125: "braceright",
126: "asciitilde",
127: "bullet",
128: "Euro",
129: "bullet",
130: "quotesinglbase",
131: "florin",
132: "quotedblbase",
133: "ellipsis",
134: "dagger",
135: "daggerdbl",
136: "circumflex",
137: "perthousand",
138: "Scaron",
139: "guilsinglleft",
140: "OE",
141: "bullet",
142: "Zcaron",
143: "bullet",
144: "bullet",
145: "quoteleft",
146: "quoteright",
147: "quotedblleft",
148: "quotedblright",
149: "bullet",
150: "endash",
151: "emdash",
152: "tilde",
153: "trademark",
154: "scaron",
155: "guilsinglright",
156: "oe",
157: "bullet",
158: "zcaron",
159: "Ydieresis",
160: "space",
161: "exclamdown",
162: "cent",
163: "sterling",
164: "currency",
165: "yen",
166: "brokenbar",
167: "section",
168: "dieresis",
169: "copyright",
170: "ordfeminine",
171: "guillemotleft",
172: "logicalnot",
173: "hyphen",
174: "registered",
175: "macron",
176: "degree",
177: "plusminus",
178: "twosuperior",
179: "threesuperior",
180: "acute",
181: "mu",
182: "paragraph",
183: "periodcentered",
184: "cedilla",
185: "onesuperior",
186: "ordmasculine",
187: "guillemotright",
188: "onequarter",
189: "onehalf",
190: "threequarters",
191: "questiondown",
192: "Agrave",
193: "Aacute",
194: "Acircumflex",
195: "Atilde",
196: "Adieresis",
197: "Aring",
198: "AE",
199: "Ccedilla",
200: "Egrave",
201: "Eacute",
202: "Ecircumflex",
203: "Edieresis",
204: "Igrave",
205: "Iacute",
206: "Icircumflex",
207: "Idieresis",
208: "Eth",
209: "Ntilde",
210: "Ograve",
211: "Oacute",
212: "Ocircumflex",
213: "Otilde",
214: "Odieresis",
215: "multiply",
216: "Oslash",
217: "Ugrave",
218: "Uacute",
219: "Ucircumflex",
220: "Udieresis",
221: "Yacute",
222: "Thorn",
223: "germandbls",
224: "agrave",
225: "aacute",
226: "acircumflex",
227: "atilde",
228: "adieresis",
229: "aring",
230: "ae",
231: "ccedilla",
232: "egrave",
233: "eacute",
234: "ecircumflex",
235: "edieresis",
236: "igrave",
237: "iacute",
238: "icircumflex",
239: "idieresis",
240: "eth",
241: "ntilde",
242: "ograve",
243: "oacute",
244: "ocircumflex",
245: "otilde",
246: "odieresis",
247: "divide",
248: "oslash",
249: "ugrave",
250: "uacute",
251: "ucircumflex",
252: "udieresis",
253: "yacute",
254: "thorn",
255: "ydieresis",
}
// Glyph to charcode map (WinAnsiEncoding).
var winansiEncodingGlyphToCharcodeMap = map[string]byte{
"space": 32,
"exclam": 33,
"quotedbl": 34,
"numbersign": 35,
"dollar": 36,
"percent": 37,
"ampersand": 38,
"quotesingle": 39,
"parenleft": 40,
"parenright": 41,
"asterisk": 42,
"plus": 43,
"comma": 44,
"hyphen": 45,
"period": 46,
"slash": 47,
"zero": 48,
"one": 49,
"two": 50,
"three": 51,
"four": 52,
"five": 53,
"six": 54,
"seven": 55,
"eight": 56,
"nine": 57,
"colon": 58,
"semicolon": 59,
"less": 60,
"equal": 61,
"greater": 62,
"question": 63,
"at": 64,
"A": 65,
"B": 66,
"C": 67,
"D": 68,
"E": 69,
"F": 70,
"G": 71,
"H": 72,
"I": 73,
"J": 74,
"K": 75,
"L": 76,
"M": 77,
"N": 78,
"O": 79,
"P": 80,
"Q": 81,
"R": 82,
"S": 83,
"T": 84,
"U": 85,
"V": 86,
"W": 87,
"X": 88,
"Y": 89,
"Z": 90,
"bracketleft": 91,
"backslash": 92,
"bracketright": 93,
"asciicircum": 94,
"underscore": 95,
"grave": 96,
"a": 97,
"b": 98,
"c": 99,
"d": 100,
"e": 101,
"f": 102,
"g": 103,
"h": 104,
"i": 105,
"j": 106,
"k": 107,
"l": 108,
"m": 109,
"n": 110,
"o": 111,
"p": 112,
"q": 113,
"r": 114,
"s": 115,
"t": 116,
"u": 117,
"v": 118,
"w": 119,
"x": 120,
"y": 121,
"z": 122,
"braceleft": 123,
"bar": 124,
"braceright": 125,
"asciitilde": 126,
"bullet": 127,
"Euro": 128,
//"bullet": 129,
"quotesinglbase": 130,
"florin": 131,
"quotedblbase": 132,
"ellipsis": 133,
"dagger": 134,
"daggerdbl": 135,
"circumflex": 136,
"perthousand": 137,
"Scaron": 138,
"guilsinglleft": 139,
"OE": 140,
//"bullet": 141,
"Zcaron": 142,
//"bullet": 143,
//"bullet": 144,
"quoteleft": 145,
"quoteright": 146,
"quotedblleft": 147,
"quotedblright": 148,
//"bullet": 149,
"endash": 150,
"emdash": 151,
"tilde": 152,
"trademark": 153,
"scaron": 154,
"guilsinglright": 155,
"oe": 156,
//"bullet": 157,
"zcaron": 158,
"Ydieresis": 159,
//"space": 160,
"exclamdown": 161,
"cent": 162,
"sterling": 163,
"currency": 164,
"yen": 165,
"brokenbar": 166,
"section": 167,
"dieresis": 168,
"copyright": 169,
"ordfeminine": 170,
"guillemotleft": 171,
"logicalnot": 172,
//"hyphen": 173,
"registered": 174,
"macron": 175,
"degree": 176,
"plusminus": 177,
"twosuperior": 178,
"threesuperior": 179,
"acute": 180,
"mu": 181,
"paragraph": 182,
"periodcentered": 183,
"cedilla": 184,
"onesuperior": 185,
"ordmasculine": 186,
"guillemotright": 187,
"onequarter": 188,
"onehalf": 189,
"threequarters": 190,
"questiondown": 191,
"Agrave": 192,
"Aacute": 193,
"Acircumflex": 194,
"Atilde": 195,
"Adieresis": 196,
"Aring": 197,
"AE": 198,
"Ccedilla": 199,
"Egrave": 200,
"Eacute": 201,
"Ecircumflex": 202,
"Edieresis": 203,
"Igrave": 204,
"Iacute": 205,
"Icircumflex": 206,
"Idieresis": 207,
"Eth": 208,
"Ntilde": 209,
"Ograve": 210,
"Oacute": 211,
"Ocircumflex": 212,
"Otilde": 213,
"Odieresis": 214,
"multiply": 215,
"Oslash": 216,
"Ugrave": 217,
"Uacute": 218,
"Ucircumflex": 219,
"Udieresis": 220,
"Yacute": 221,
"Thorn": 222,
"germandbls": 223,
"agrave": 224,
"aacute": 225,
"acircumflex": 226,
"atilde": 227,
"adieresis": 228,
"aring": 229,
"ae": 230,
"ccedilla": 231,
"egrave": 232,
"eacute": 233,
"ecircumflex": 234,
"edieresis": 235,
"igrave": 236,
"iacute": 237,
"icircumflex": 238,
"idieresis": 239,
"eth": 240,
"ntilde": 241,
"ograve": 242,
"oacute": 243,
"ocircumflex": 244,
"otilde": 245,
"odieresis": 246,
"divide": 247,
"oslash": 248,
"ugrave": 249,
"uacute": 250,
"ucircumflex": 251,
"udieresis": 252,
"yacute": 253,
"thorn": 254,
"ydieresis": 255,
}

View File

@@ -0,0 +1,537 @@
package textencoding
import (
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/common"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
)
// Encoding for ZapfDingbats font.
type ZapfDingbatsEncoder struct {
}
func NewZapfDingbatsEncoder() ZapfDingbatsEncoder {
encoder := ZapfDingbatsEncoder{}
return encoder
}
// Convert a raw utf8 string (series of runes) to an encoded string (series of character codes) to be used in PDF.
func (enc ZapfDingbatsEncoder) Encode(raw string) string {
encoded := []byte{}
for _, rune := range raw {
code, found := enc.RuneToCharcode(rune)
if !found {
continue
}
encoded = append(encoded, code)
}
return string(encoded)
}
// Conversion between character code and glyph name.
// The bool return flag is true if there was a match, and false otherwise.
func (enc ZapfDingbatsEncoder) CharcodeToGlyph(code byte) (string, bool) {
glyph, has := zapfDingbatsEncodingCharcodeToGlyphMap[code]
if !has {
common.Log.Debug("ZapfDingbats encoding error: unable to find charcode->glyph entry (%v)", code)
return "", false
}
return glyph, true
}
// Conversion between glyph name and character code.
// The bool return flag is true if there was a match, and false otherwise.
func (enc ZapfDingbatsEncoder) GlyphToCharcode(glyph string) (byte, bool) {
code, found := zapfDingbatsEncodingGlyphToCharcodeMap[glyph]
if !found {
common.Log.Debug("ZapfDingbats encoding error: unable to find glyph->charcode entry (%s)", glyph)
return 0, false
}
return code, found
}
// Convert rune to character code.
// The bool return flag is true if there was a match, and false otherwise.
func (enc ZapfDingbatsEncoder) RuneToCharcode(val rune) (byte, bool) {
glyph, found := enc.RuneToGlyph(val)
if !found {
common.Log.Debug("ZapfDingbats encoding error: unable to find rune->glyph entry (%v)", val)
return 0, false
}
code, found := zapfDingbatsEncodingGlyphToCharcodeMap[glyph]
if !found {
common.Log.Debug("ZapfDingbats encoding error: unable to find glyph->charcode entry (%s)", glyph)
return 0, false
}
return code, true
}
// Convert character code to rune.
// The bool return flag is true if there was a match, and false otherwise.
func (enc ZapfDingbatsEncoder) CharcodeToRune(charcode byte) (rune, bool) {
glyph, found := zapfDingbatsEncodingCharcodeToGlyphMap[charcode]
if !found {
common.Log.Debug("ZapfDingbats encoding error: unable to find charcode->glyph entry (%d)", charcode)
return 0, false
}
return enc.GlyphToRune(glyph)
}
// Convert rune to glyph name.
// The bool return flag is true if there was a match, and false otherwise.
func (enc ZapfDingbatsEncoder) RuneToGlyph(val rune) (string, bool) {
// Seek in the zapfdingbats list first.
glyph, found := runeToGlyph(val, zapfdingbatsRuneToGlyphMap)
if !found {
// Then revert to glyphlist if not found.
glyph, found = runeToGlyph(val, glyphlistRuneToGlyphMap)
if !found {
common.Log.Debug("ZapfDingbats encoding error: unable to find rune->glyph entry (%v)", val)
return "", false
}
}
return glyph, true
}
// Convert glyph to rune.
// The bool return flag is true if there was a match, and false otherwise.
func (enc ZapfDingbatsEncoder) GlyphToRune(glyph string) (rune, bool) {
// Seek in the zapfdingbats list first.
val, found := glyphToRune(glyph, zapfdingbatsGlyphToRuneMap)
if !found {
// Then revert to glyphlist if not found.
val, found = glyphToRune(glyph, glyphlistGlyphToRuneMap)
if !found {
common.Log.Debug("Symbol encoding error: unable to find glyph->rune entry (%v)", glyph)
return 0, false
}
}
return val, true
}
// Convert to PDF Object.
func (enc ZapfDingbatsEncoder) ToPdfObject() core.PdfObject {
dict := core.MakeDict()
dict.Set("Type", core.MakeName("Encoding"))
// Returning an empty Encoding object with no differences. Indicates that we are using the font's built-in
// encoding.
return core.MakeIndirectObject(dict)
}
var zapfDingbatsEncodingCharcodeToGlyphMap = map[byte]string{
32: "space",
33: "a1",
34: "a2",
35: "a202",
36: "a3",
37: "a4",
38: "a5",
39: "a119",
40: "a118",
41: "a117",
42: "a11",
43: "a12",
44: "a13",
45: "a14",
46: "a15",
47: "a16",
48: "a105",
49: "a17",
50: "a18",
51: "a19",
52: "a20",
53: "a21",
54: "a22",
55: "a23",
56: "a24",
57: "a25",
58: "a26",
59: "a27",
60: "a28",
61: "a6",
62: "a7",
63: "a8",
64: "a9",
65: "a10",
66: "a29",
67: "a30",
68: "a31",
69: "a32",
70: "a33",
71: "a34",
72: "a35",
73: "a36",
74: "a37",
75: "a38",
76: "a39",
77: "a40",
78: "a41",
79: "a42",
80: "a43",
81: "a44",
82: "a45",
83: "a46",
84: "a47",
85: "a48",
86: "a49",
87: "a50",
88: "a51",
89: "a52",
90: "a53",
91: "a54",
92: "a55",
93: "a56",
94: "a57",
95: "a58",
96: "a59",
97: "a60",
98: "a61",
99: "a62",
100: "a63",
101: "a64",
102: "a65",
103: "a66",
104: "a67",
105: "a68",
106: "a69",
107: "a70",
108: "a71",
109: "a72",
110: "a73",
111: "a74",
112: "a203",
113: "a75",
114: "a204",
115: "a76",
116: "a77",
117: "a78",
118: "a79",
119: "a81",
120: "a82",
121: "a83",
122: "a84",
123: "a97",
124: "a98",
125: "a99",
126: "a100",
128: "a89",
129: "a90",
130: "a93",
131: "a94",
132: "a91",
133: "a92",
134: "a205",
135: "a85",
136: "a206",
137: "a86",
138: "a87",
139: "a88",
140: "a95",
141: "a96",
161: "a101",
162: "a102",
163: "a103",
164: "a104",
165: "a106",
166: "a107",
167: "a108",
168: "a112",
169: "a111",
170: "a110",
171: "a109",
172: "a120",
173: "a121",
174: "a122",
175: "a123",
176: "a124",
177: "a125",
178: "a126",
179: "a127",
180: "a128",
181: "a129",
182: "a130",
183: "a131",
184: "a132",
185: "a133",
186: "a134",
187: "a135",
188: "a136",
189: "a137",
190: "a138",
191: "a139",
192: "a140",
193: "a141",
194: "a142",
195: "a143",
196: "a144",
197: "a145",
198: "a146",
199: "a147",
200: "a148",
201: "a149",
202: "a150",
203: "a151",
204: "a152",
205: "a153",
206: "a154",
207: "a155",
208: "a156",
209: "a157",
210: "a158",
211: "a159",
212: "a160",
213: "a161",
214: "a163",
215: "a164",
216: "a196",
217: "a165",
218: "a192",
219: "a166",
220: "a167",
221: "a168",
222: "a169",
223: "a170",
224: "a171",
225: "a172",
226: "a173",
227: "a162",
228: "a174",
229: "a175",
230: "a176",
231: "a177",
232: "a178",
233: "a179",
234: "a193",
235: "a180",
236: "a199",
237: "a181",
238: "a200",
239: "a182",
241: "a201",
242: "a183",
243: "a184",
244: "a197",
245: "a185",
246: "a194",
247: "a198",
248: "a186",
249: "a195",
250: "a187",
251: "a188",
252: "a189",
253: "a190",
254: "a191",
}
var zapfDingbatsEncodingGlyphToCharcodeMap = map[string]byte{
"space": 32,
"a1": 33,
"a2": 34,
"a202": 35,
"a3": 36,
"a4": 37,
"a5": 38,
"a119": 39,
"a118": 40,
"a117": 41,
"a11": 42,
"a12": 43,
"a13": 44,
"a14": 45,
"a15": 46,
"a16": 47,
"a105": 48,
"a17": 49,
"a18": 50,
"a19": 51,
"a20": 52,
"a21": 53,
"a22": 54,
"a23": 55,
"a24": 56,
"a25": 57,
"a26": 58,
"a27": 59,
"a28": 60,
"a6": 61,
"a7": 62,
"a8": 63,
"a9": 64,
"a10": 65,
"a29": 66,
"a30": 67,
"a31": 68,
"a32": 69,
"a33": 70,
"a34": 71,
"a35": 72,
"a36": 73,
"a37": 74,
"a38": 75,
"a39": 76,
"a40": 77,
"a41": 78,
"a42": 79,
"a43": 80,
"a44": 81,
"a45": 82,
"a46": 83,
"a47": 84,
"a48": 85,
"a49": 86,
"a50": 87,
"a51": 88,
"a52": 89,
"a53": 90,
"a54": 91,
"a55": 92,
"a56": 93,
"a57": 94,
"a58": 95,
"a59": 96,
"a60": 97,
"a61": 98,
"a62": 99,
"a63": 100,
"a64": 101,
"a65": 102,
"a66": 103,
"a67": 104,
"a68": 105,
"a69": 106,
"a70": 107,
"a71": 108,
"a72": 109,
"a73": 110,
"a74": 111,
"a203": 112,
"a75": 113,
"a204": 114,
"a76": 115,
"a77": 116,
"a78": 117,
"a79": 118,
"a81": 119,
"a82": 120,
"a83": 121,
"a84": 122,
"a97": 123,
"a98": 124,
"a99": 125,
"a100": 126,
"a89": 128,
"a90": 129,
"a93": 130,
"a94": 131,
"a91": 132,
"a92": 133,
"a205": 134,
"a85": 135,
"a206": 136,
"a86": 137,
"a87": 138,
"a88": 139,
"a95": 140,
"a96": 141,
"a101": 161,
"a102": 162,
"a103": 163,
"a104": 164,
"a106": 165,
"a107": 166,
"a108": 167,
"a112": 168,
"a111": 169,
"a110": 170,
"a109": 171,
"a120": 172,
"a121": 173,
"a122": 174,
"a123": 175,
"a124": 176,
"a125": 177,
"a126": 178,
"a127": 179,
"a128": 180,
"a129": 181,
"a130": 182,
"a131": 183,
"a132": 184,
"a133": 185,
"a134": 186,
"a135": 187,
"a136": 188,
"a137": 189,
"a138": 190,
"a139": 191,
"a140": 192,
"a141": 193,
"a142": 194,
"a143": 195,
"a144": 196,
"a145": 197,
"a146": 198,
"a147": 199,
"a148": 200,
"a149": 201,
"a150": 202,
"a151": 203,
"a152": 204,
"a153": 205,
"a154": 206,
"a155": 207,
"a156": 208,
"a157": 209,
"a158": 210,
"a159": 211,
"a160": 212,
"a161": 213,
"a163": 214,
"a164": 215,
"a196": 216,
"a165": 217,
"a192": 218,
"a166": 219,
"a167": 220,
"a168": 221,
"a169": 222,
"a170": 223,
"a171": 224,
"a172": 225,
"a173": 226,
"a162": 227,
"a174": 228,
"a175": 229,
"a176": 230,
"a177": 231,
"a178": 232,
"a179": 233,
"a193": 234,
"a180": 235,
"a199": 236,
"a181": 237,
"a200": 238,
"a182": 239,
"a201": 241,
"a183": 242,
"a184": 243,
"a197": 244,
"a185": 245,
"a194": 246,
"a198": 247,
"a186": 248,
"a195": 249,
"a187": 250,
"a188": 251,
"a189": 252,
"a190": 253,
"a191": 254,
}