github.com/pdfcpu/pdfcpu@v0.11.1/internal/corefont/metrics/gen.go (about)

     1  // Copyright 2019 The pdfcpu Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  // 	http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  //go:build ignore
    16  // +build ignore
    17  
    18  package main
    19  
    20  import (
    21  	"bufio"
    22  	"bytes"
    23  	"flag"
    24  	"fmt"
    25  	"go/format"
    26  	"log"
    27  	"os"
    28  	"path/filepath"
    29  	"sort"
    30  	"strconv"
    31  	"strings"
    32  )
    33  
    34  var debug = flag.Bool("debug", false, "")
    35  
    36  func main() {
    37  	flag.Parse()
    38  
    39  	// Generate standard.go.
    40  	{
    41  		w := &bytes.Buffer{}
    42  		w.WriteString(header)
    43  		writeWinAnsiGlyphMap(w)
    44  		writeSymbolGlyphMap(w)
    45  		writeZapfDingbatsGlyphMap(w)
    46  		writeCoreFontMetrics(w)
    47  		finish(w, "standard.go")
    48  	}
    49  
    50  }
    51  
    52  func writeWinAnsiGlyphMap(w *bytes.Buffer) {
    53  	s := `// WinAnsiGlyphMap is a glyph lookup table for CP1252 character codes.
    54  	// See Annex D.2 Latin Character Set and Encodings.
    55  	var WinAnsiGlyphMap = map[int]string {
    56  	`
    57  	writeGlyphMap(w, s, winAnsiGlyphMap)
    58  }
    59  
    60  func writeSymbolGlyphMap(w *bytes.Buffer) {
    61  	s := `// SymbolGlyphMap is a glyph lookup table for Symbol character codes.
    62  	// See Annex D.5 Symbol Set and Encoding.
    63  	var SymbolGlyphMap = map[int]string {
    64  	`
    65  	writeGlyphMap(w, s, symbolGlyphMap)
    66  
    67  }
    68  
    69  func writeZapfDingbatsGlyphMap(w *bytes.Buffer) {
    70  	s := `// ZapfDingbatsGlyphMap is a glyph lookup table for ZapfDingbats character codes.
    71  	// See Annex D.6 ZapfDingbats Set and Encoding
    72  	var ZapfDingbatsGlyphMap = map[int]string {
    73  	`
    74  	writeGlyphMap(w, s, zapfDingbatsGlyphMap)
    75  }
    76  
    77  func writeGlyphMap(w *bytes.Buffer, varDec string, m map[int]string) {
    78  	w.WriteString(varDec)
    79  	keys := make([]int, 0, len(m))
    80  	for k := range m {
    81  		keys = append(keys, k)
    82  	}
    83  	sort.Ints(keys)
    84  	for _, k := range keys {
    85  		fmt.Fprintf(w, "%d: \"%s\", // %#U\n", k, m[k], rune(k))
    86  	}
    87  	w.WriteString("}\n\n")
    88  }
    89  
    90  func writeCoreFontMetrics(w *bytes.Buffer) {
    91  	s := `type fontMetrics struct {
    92  		FBox *types.Rectangle // font box
    93  		W    map[string]int // glyph widths
    94  	}
    95  
    96  	// CoreFontMetrics represents font metrics for the Adobe standard type 1 core fonts.
    97  	var CoreFontMetrics = map[string]fontMetrics{
    98  	`
    99  	w.WriteString(s)
   100  	dir := "../Core14_AFMs"
   101  	files, err := os.ReadDir(dir)
   102  	if err != nil {
   103  		log.Fatal(err)
   104  	}
   105  	for _, f := range files {
   106  		if !strings.HasSuffix(f.Name(), ".afm") {
   107  			continue
   108  		}
   109  		writeFontMetrics(w, dir, f.Name())
   110  	}
   111  	w.WriteString("}")
   112  }
   113  
   114  func writeFontBBox(w *bytes.Buffer, ss []string) {
   115  	if len(ss) != 5 {
   116  		panic("corrupt .afm file!")
   117  	}
   118  	f1, err := strconv.ParseFloat(ss[1], 64)
   119  	if err != nil {
   120  		log.Fatal(err)
   121  	}
   122  	f2, err := strconv.ParseFloat(ss[2], 64)
   123  	if err != nil {
   124  		log.Fatal(err)
   125  	}
   126  	f3, err := strconv.ParseFloat(ss[3], 64)
   127  	if err != nil {
   128  		log.Fatal(err)
   129  	}
   130  	f4, err := strconv.ParseFloat(ss[4], 64)
   131  	if err != nil {
   132  		log.Fatal(err)
   133  	}
   134  	fmt.Fprintf(w, "types.NewRectangle(%.1f, %.1f, %.1f, %.1f),\n", f1, f2, f3, f4)
   135  }
   136  
   137  func writeFontMetrics(w *bytes.Buffer, dir, fileName string) {
   138  	fmt.Fprintf(w, "\"%s\": {\n", fileName[:len(fileName)-4])
   139  	f, err := os.Open(filepath.Join(dir, fileName))
   140  	if err != nil {
   141  		log.Fatal(err)
   142  	}
   143  	defer f.Close()
   144  	s := bufio.NewScanner(f)
   145  	isHeader := true
   146  	var headerDigested bool
   147  	for s.Scan() {
   148  		ss := strings.Fields(s.Text())
   149  		if isHeader {
   150  			switch ss[0] {
   151  			case "FontBBox":
   152  				writeFontBBox(w, ss)
   153  				headerDigested = true
   154  			case "StartCharMetrics":
   155  				if !headerDigested {
   156  					panic("corrupt .afm file!")
   157  				}
   158  				isHeader = false
   159  				w.WriteString("map[string]int{")
   160  			}
   161  			continue
   162  		}
   163  		switch ss[0] {
   164  		case "C":
   165  			if len(ss) < 8 {
   166  				panic("corrupt .afm file!")
   167  			}
   168  			i, err := strconv.Atoi(ss[4])
   169  			if err != nil {
   170  				log.Fatal(err)
   171  			}
   172  			fmt.Fprintf(w, "\"%s\": %d, ", ss[7], i)
   173  		case "EndCharMetrics":
   174  			w.WriteString("},\n")
   175  			break
   176  		}
   177  	}
   178  	if err := s.Err(); err != nil {
   179  		log.Fatal(err)
   180  	}
   181  	w.WriteString("\n},\n")
   182  }
   183  
   184  const header = `// generated by "go run gen.go". DO NOT EDIT.
   185  
   186  package metrics
   187  
   188  import (	
   189  	"github.com/pdfcpu/pdfcpu/pkg/pdfcpu/types"
   190  )
   191  `
   192  
   193  func finish(w *bytes.Buffer, filename string) {
   194  	if *debug {
   195  		os.Stdout.Write(w.Bytes())
   196  		return
   197  	}
   198  	out, err := format.Source(w.Bytes())
   199  	if err != nil {
   200  		log.Fatalf("format.Source: %v", err)
   201  	}
   202  	if err := os.WriteFile(filename, out, 0660); err != nil {
   203  		log.Fatalf("os.WriteFile: %v", err)
   204  	}
   205  }
   206  
   207  // See Annex D.2 Latin Character Set and Encodings
   208  var winAnsiGlyphMap = map[int]string{
   209  	0101: "A",
   210  	0306: "AE",
   211  	0301: "Aacute",
   212  	0302: "Acircumflex",
   213  	0304: "Adieresis",
   214  	0300: "Agrave",
   215  	0305: "Aring",
   216  	0303: "Atilde",
   217  	0102: "B",
   218  	0103: "C",
   219  	0307: "Ccedilla",
   220  	0104: "D",
   221  	0105: "E",
   222  	0311: "Eacute",
   223  	0312: "Ecircumflex",
   224  	0313: "Edieresis",
   225  	0310: "Egrave",
   226  	0320: "Eth",
   227  	0200: "Euro",
   228  	0106: "F",
   229  	0107: "G",
   230  	0110: "H",
   231  	0111: "I",
   232  	0315: "Iacute",
   233  	0316: "Icircumflex",
   234  	0317: "Idieresis",
   235  	0314: "Igrave",
   236  	0112: "J",
   237  	0113: "K",
   238  	0114: "L",
   239  	0115: "M",
   240  	0116: "N",
   241  	0321: "Ntilde",
   242  	0117: "O",
   243  	0214: "OE",
   244  	0323: "Oacute",
   245  	0324: "Ocircumflex",
   246  	0326: "Odieresis",
   247  	0322: "Ograve",
   248  	0330: "Oslash",
   249  	0325: "Otilde",
   250  	0120: "P",
   251  	0121: "Q",
   252  	0122: "R",
   253  	0123: "S",
   254  	0212: "Scaron",
   255  	0124: "T",
   256  	0336: "Thorn",
   257  	0125: "U",
   258  	0332: "Uacute",
   259  	0333: "Ucircumflex",
   260  	0334: "Udieresis",
   261  	0331: "Ugrave",
   262  	0126: "V",
   263  	0127: "W",
   264  	0130: "X",
   265  	0131: "Y",
   266  	0335: "Yacute",
   267  	0237: "Ydieresis",
   268  	0132: "Z",
   269  	0216: "Zcaron",
   270  	0141: "a",
   271  	0341: "aacute",
   272  	0342: "acircumflex",
   273  	0264: "acute",
   274  	0344: "adieresis",
   275  	0346: "ae",
   276  	0340: "agrave",
   277  	0046: "ampersand",
   278  	0345: "aring",
   279  	0136: "asciicircum",
   280  	0176: "asciitilde",
   281  	0052: "asterisk",
   282  	0100: "at",
   283  	0343: "atilde",
   284  	0142: "b",
   285  	0134: "backslash",
   286  	0174: "bar",
   287  	0173: "braceleft",
   288  	0175: "braceright",
   289  	0133: "bracketleft",
   290  	0135: "bracketright",
   291  	0246: "brokenbar",
   292  	0225: "bullet",
   293  	0143: "c",
   294  	0347: "ccedilla",
   295  	0270: "cedilla",
   296  	0242: "cent",
   297  	0210: "circumflex",
   298  	0072: "colon",
   299  	0054: "comma",
   300  	0251: "copyright",
   301  	0244: "currency",
   302  	0144: "d",
   303  	0206: "dagger",
   304  	0207: "daggerdbl",
   305  	0260: "degree",
   306  	0250: "dieresis",
   307  	0367: "divide",
   308  	0044: "dollar",
   309  	0145: "e",
   310  	0351: "eacute",
   311  	0352: "ecircumflex",
   312  	0353: "edieresis",
   313  	0350: "egrave",
   314  	0070: "eight",
   315  	0205: "ellipsis",
   316  	0227: "emdash",
   317  	0226: "endash",
   318  	0075: "equal",
   319  	0360: "eth",
   320  	0041: "exclam",
   321  	0241: "exclamdown",
   322  	0146: "f",
   323  	0065: "five",
   324  	0203: "florin",
   325  	0064: "four",
   326  	0147: "g",
   327  	0337: "germandbls",
   328  	0140: "grave",
   329  	0076: "greater",
   330  	0253: "guillemotleft",
   331  	0273: "guillemotright",
   332  	0213: "guilsinglleft",
   333  	0233: "guilsinglright",
   334  	0150: "h",
   335  	0055: "hyphen",
   336  	0151: "i",
   337  	0355: "iacute",
   338  	0356: "icircumflex",
   339  	0357: "idieresis",
   340  	0354: "igrave",
   341  	0152: "j",
   342  	0153: "k",
   343  	0154: "l",
   344  	0074: "less",
   345  	0254: "logicalnot",
   346  	0155: "m",
   347  	0257: "macron",
   348  	0265: "mu",
   349  	0327: "multiply",
   350  	0156: "n",
   351  	0071: "nine",
   352  	0361: "ntilde",
   353  	0043: "numbersign",
   354  	0157: "o",
   355  	0363: "oacute",
   356  	0364: "ocircumflex",
   357  	0366: "odieresis",
   358  	0234: "oe",
   359  	0362: "ograve",
   360  	0061: "one",
   361  	0275: "onehalf",
   362  	0274: "onequarter",
   363  	0271: "onesuperior",
   364  	0252: "ordfeminine",
   365  	0272: "ordmasculine",
   366  	0370: "oslash",
   367  	0365: "otilde",
   368  	0160: "p",
   369  	0266: "paragraph",
   370  	0050: "parenleft",
   371  	0051: "parenright",
   372  	0045: "percent",
   373  	0056: "period",
   374  	0267: "periodcentered",
   375  	0211: "perthousand",
   376  	0053: "plus",
   377  	0261: "plusminus",
   378  	0161: "q",
   379  	0077: "question",
   380  	0277: "questiondown",
   381  	0042: "quotedbl",
   382  	0204: "quotedblbase",
   383  	0223: "quotedblleft",
   384  	0224: "quotedblright",
   385  	0221: "quoteleft",
   386  	0222: "quoteright",
   387  	0202: "quotesinglbase",
   388  	0047: "quotesingle",
   389  	0162: "r",
   390  	0256: "registered",
   391  	0163: "s",
   392  	0232: "scaron",
   393  	0247: "section",
   394  	0073: "semicolon",
   395  	0067: "seven",
   396  	0066: "six",
   397  	0057: "slash",
   398  	0040: "space",
   399  	0243: "sterling",
   400  	0164: "t",
   401  	0376: "thorn",
   402  	0063: "three",
   403  	0276: "threequarters",
   404  	0263: "threesuperior",
   405  	0230: "tilde",
   406  	0231: "trademark",
   407  	0062: "two",
   408  	0262: "twosuperior",
   409  	0165: "u",
   410  	0372: "uacute",
   411  	0373: "ucircumflex",
   412  	0374: "udieresis",
   413  	0371: "ugrave",
   414  	0137: "underscore",
   415  	0166: "v",
   416  	0167: "w",
   417  	0170: "x",
   418  	0171: "y",
   419  	0375: "yacute",
   420  	0377: "ydieresis",
   421  	0245: "yen",
   422  	0172: "z",
   423  	0236: "zcaron",
   424  	0060: "zero",
   425  }
   426  
   427  // See Annex D.5 Symbol Set and Encoding
   428  var symbolGlyphMap = map[int]string{
   429  	0101: "Alpha",
   430  	0102: "Beta",
   431  	0103: "Chi",
   432  	0104: "Delta",
   433  	0105: "Epsilon",
   434  	0110: "Eta",
   435  	0240: "Euro",
   436  	0107: "Gamma",
   437  	0301: "Ifraktur",
   438  	0111: "Iota",
   439  	0113: "Kappa",
   440  	0114: "Lambda",
   441  	0115: "Mu",
   442  	0116: "Nu",
   443  	0127: "Omega",
   444  	0117: "Omicron",
   445  	0106: "Phi",
   446  	0120: "Pi",
   447  	0131: "Psi",
   448  	0302: "Rfraktur",
   449  	0122: "Rho",
   450  	0123: "Sigma",
   451  	0124: "Tau",
   452  	0121: "Theta",
   453  	0125: "Upsilon",
   454  	0241: "Upsilon1",
   455  	0130: "Xi",
   456  	0132: "Zeta",
   457  	0300: "aleph",
   458  	0141: "alpha",
   459  	0046: "ampersand",
   460  	0320: "angle",
   461  	0341: "angleleft",
   462  	0361: "angleright",
   463  	0273: "approxequal",
   464  	0253: "arrowboth",
   465  	0333: "arrowdblboth",
   466  	0337: "arrowdbldown",
   467  	0334: "arrowdblleft",
   468  	0336: "arrowdblright",
   469  	0335: "arrowdblup",
   470  	0257: "arrowdown",
   471  	0276: "arrowhorizex",
   472  	0254: "arrowleft",
   473  	0256: "arrowright",
   474  	0255: "arrowup",
   475  	0275: "arrowvertex",
   476  	0052: "asteriskmath",
   477  	0174: "bar",
   478  	0142: "beta",
   479  	0173: "braceleft",
   480  	0175: "braceright",
   481  	0354: "bracelefttp",
   482  	0355: "braceleftmid",
   483  	0356: "braceleftbt",
   484  	0374: "bracerighttp",
   485  	0375: "bracerightmid",
   486  	0376: "bracerightbt",
   487  	0357: "braceex",
   488  	0133: "bracketleft",
   489  	0135: "bracketright",
   490  	0351: "bracketlefttp",
   491  	0352: "bracketleftex",
   492  	0353: "bracketleftbt",
   493  	0371: "bracketrighttp",
   494  	0372: "bracketrightex",
   495  	0373: "bracketrightbt",
   496  	0267: "bullet",
   497  	0277: "carriagereturn",
   498  	0143: "chi",
   499  	0304: "circlemultiply",
   500  	0305: "circleplus",
   501  	0247: "club",
   502  	0072: "colon",
   503  	0054: "comma",
   504  	0100: "congruent",
   505  	0343: "copyrightsans",
   506  	0323: "copyrightserif",
   507  	0260: "degree",
   508  	0144: "delta",
   509  	0250: "diamond",
   510  	0270: "divide",
   511  	0327: "dotmath",
   512  	0070: "eight",
   513  	0316: "element",
   514  	0274: "ellipsis",
   515  	0306: "emptyset",
   516  	0145: "epsilon",
   517  	0075: "equal",
   518  	0272: "equivalence",
   519  	0150: "eta",
   520  	0041: "exclam",
   521  	0044: "existential",
   522  	0065: "five",
   523  	0246: "florin",
   524  	0064: "four",
   525  	0244: "fraction",
   526  	0147: "gamma",
   527  	0321: "gradient",
   528  	0076: "greater",
   529  	0263: "greaterequal",
   530  	0251: "heart",
   531  	0245: "infinity",
   532  	0362: "integral",
   533  	0363: "integraltp",
   534  	0364: "integralex",
   535  	0365: "integralbt",
   536  	0307: "intersection",
   537  	0151: "iota",
   538  	0153: "kappa",
   539  	0154: "lambda",
   540  	0074: "less",
   541  	0243: "lessequal",
   542  	0331: "logicaland",
   543  	0330: "logicalnot",
   544  	0332: "logicalor",
   545  	0340: "lozenge",
   546  	0055: "minus",
   547  	0242: "minute",
   548  	0155: "mu",
   549  	0264: "multiply",
   550  	0071: "nine",
   551  	0317: "notelement",
   552  	0271: "notequal",
   553  	0313: "notsubset",
   554  	0156: "nu",
   555  	0043: "numbersign",
   556  	0167: "omega",
   557  	0166: "omega1",
   558  	0157: "omicron",
   559  	0061: "one",
   560  	0050: "parenleft",
   561  	0051: "parenright",
   562  	0346: "parenlefttp",
   563  	0347: "parenleftex",
   564  	0350: "parenleftbt",
   565  	0366: "parenrighttp",
   566  	0367: "parenrightex",
   567  	0370: "parenrightbt",
   568  	0266: "partialdiff",
   569  	0045: "percent",
   570  	0056: "period",
   571  	0136: "perpendicular",
   572  	0146: "phi",
   573  	0152: "phi1",
   574  	0160: "pi",
   575  	0053: "plus",
   576  	0261: "plusminus",
   577  	0325: "product",
   578  	0314: "propersubset",
   579  	0311: "propersuperset",
   580  	0265: "proportional",
   581  	0171: "psi",
   582  	0077: "question",
   583  	0326: "radical",
   584  	0140: "radicalex",
   585  	0315: "reflexsubset",
   586  	0312: "reflexsuperset",
   587  	0342: "registersans",
   588  	0322: "registerserif",
   589  	0162: "rho",
   590  	0262: "second",
   591  	0073: "semicolon",
   592  	0067: "seven",
   593  	0163: "sigma",
   594  	0126: "sigma1",
   595  	0176: "similar",
   596  	0066: "six",
   597  	0057: "slash",
   598  	0040: "space",
   599  	0252: "spade",
   600  	0047: "suchthat",
   601  	0345: "summation",
   602  	0164: "tau",
   603  	0134: "therefore",
   604  	0161: "theta",
   605  	0112: "theta1",
   606  	0063: "three",
   607  	0344: "trademarksans",
   608  	0324: "trademarkserif",
   609  	0062: "two",
   610  	0137: "underscore",
   611  	0310: "union",
   612  	0042: "universal",
   613  	0165: "upsilon",
   614  	0303: "weierstrass",
   615  	0170: "xi",
   616  	0060: "zero",
   617  	0172: "zeta",
   618  }
   619  
   620  // See Annex D.6 ZapfDingbats Set and Encoding
   621  var zapfDingbatsGlyphMap = map[int]string{
   622  	0040: "space",
   623  	0041: "a1",
   624  	0042: "a2",
   625  	0043: "a202",
   626  	0044: "a3",
   627  	0045: "a4",
   628  	0046: "a5",
   629  	0047: "a119",
   630  	0050: "a118",
   631  	0051: "a117",
   632  	0052: "a11",
   633  	0053: "a12",
   634  	0054: "a13",
   635  	0055: "a14",
   636  	0056: "a15",
   637  	0057: "a16",
   638  	0060: "a105",
   639  	0061: "a17",
   640  	0062: "a18",
   641  	0063: "a19",
   642  	0064: "a20",
   643  	0065: "a21",
   644  	0066: "a22",
   645  	0067: "a23",
   646  	0070: "a24",
   647  	0071: "a25",
   648  	0072: "a26",
   649  	0073: "a27",
   650  	0074: "a28",
   651  	0075: "a6",
   652  	0076: "a7",
   653  	0077: "a8",
   654  	0100: "a9",
   655  	0101: "a10",
   656  	0102: "a29",
   657  	0103: "a30",
   658  	0104: "a31",
   659  	0105: "a32",
   660  	0106: "a33",
   661  	0107: "a34",
   662  	0110: "a35",
   663  	0111: "a36",
   664  	0112: "a37",
   665  	0113: "a38",
   666  	0114: "a39",
   667  	0115: "a40",
   668  	0116: "a41",
   669  	0117: "a42",
   670  	0120: "a43",
   671  	0121: "a44",
   672  	0122: "a45",
   673  	0123: "a46",
   674  	0124: "a47",
   675  	0125: "a48",
   676  	0126: "a49",
   677  	0127: "a50",
   678  	0130: "a51",
   679  	0131: "a52",
   680  	0132: "a53",
   681  	0133: "a54",
   682  	0134: "a55",
   683  	0135: "a56",
   684  	0136: "a57",
   685  	0137: "a58",
   686  	0140: "a59",
   687  	0141: "a60",
   688  	0142: "a61",
   689  	0143: "a62",
   690  	0144: "a63",
   691  	0145: "a64",
   692  	0146: "a65",
   693  	0147: "a66",
   694  	0150: "a67",
   695  	0151: "a68",
   696  	0152: "a69",
   697  	0153: "a70",
   698  	0154: "a71",
   699  	0155: "a72",
   700  	0156: "a73",
   701  	0157: "a74",
   702  	0160: "a203",
   703  	0161: "a75",
   704  	0162: "a204",
   705  	0163: "a76",
   706  	0164: "a77",
   707  	0165: "a78",
   708  	0166: "a79",
   709  	0167: "a81",
   710  	0170: "a82",
   711  	0171: "a83",
   712  	0172: "a84",
   713  	0173: "a97",
   714  	0174: "a98",
   715  	0175: "a99",
   716  	0176: "a100",
   717  	0241: "a101",
   718  	0242: "a102",
   719  	0243: "a103",
   720  	0244: "a104",
   721  	0245: "a106",
   722  	0246: "a107",
   723  	0247: "a108",
   724  	0250: "a112",
   725  	0251: "a111",
   726  	0252: "a110",
   727  	0253: "a109",
   728  	0254: "a120",
   729  	0255: "a121",
   730  	0256: "a122",
   731  	0257: "a123",
   732  	0260: "a124",
   733  	0261: "a125",
   734  	0262: "a126",
   735  	0263: "a127",
   736  	0264: "a128",
   737  	0265: "a129",
   738  	0266: "a130",
   739  	0267: "a131",
   740  	0270: "a132",
   741  	0271: "a133",
   742  	0272: "a134",
   743  	0273: "a135",
   744  	0274: "a136",
   745  	0275: "a137",
   746  	0276: "a138",
   747  	0277: "a139",
   748  	0300: "a140",
   749  	0301: "a141",
   750  	0302: "a142",
   751  	0303: "a143",
   752  	0304: "a144",
   753  	0305: "a145",
   754  	0306: "a146",
   755  	0307: "a147",
   756  	0310: "a148",
   757  	0311: "a149",
   758  	0312: "a150",
   759  	0313: "a151",
   760  	0314: "a152",
   761  	0315: "a153",
   762  	0316: "a154",
   763  	0317: "a155",
   764  	0320: "a156",
   765  	0321: "a157",
   766  	0322: "a158",
   767  	0323: "a159",
   768  	0324: "a160",
   769  	0325: "a161",
   770  	0326: "a163",
   771  	0327: "a164",
   772  	0330: "a196",
   773  	0331: "a165",
   774  	0332: "a192",
   775  	0333: "a166",
   776  	0334: "a167",
   777  	0335: "a168",
   778  	0336: "a169",
   779  	0337: "a170",
   780  	0340: "a171",
   781  	0341: "a172",
   782  	0342: "a173",
   783  	0343: "a162",
   784  	0344: "a174",
   785  	0345: "a175",
   786  	0346: "a176",
   787  	0347: "a177",
   788  	0350: "a178",
   789  	0351: "a179",
   790  	0352: "a193",
   791  	0353: "a180",
   792  	0354: "a199",
   793  	0355: "a181",
   794  	0356: "a200",
   795  	0357: "a182",
   796  	0361: "a201",
   797  	0362: "a183",
   798  	0363: "a184",
   799  	0364: "a197",
   800  	0365: "a185",
   801  	0366: "a194",
   802  	0367: "a198",
   803  	0370: "a186",
   804  	0371: "a195",
   805  	0372: "a187",
   806  	0373: "a188",
   807  	0374: "a189",
   808  	0375: "a190",
   809  	0376: "a191",
   810  }