Changeset 69558 in spip-zone for _plugins_/pdfjs


Ignore:
Timestamp:
Jan 31, 2013, 4:27:10 PM (6 years ago)
Author:
joseph@…
Message:

Mise à jour de pdfjs avec une version plus récente de la lib

Location:
_plugins_/pdfjs
Files:
82 added
2 deleted
9 edited

Legend:

Unmodified
Added
Removed
  • _plugins_/pdfjs/lib/pdfjs/build/pdf.js

    r66714 r69558  
    1717
    1818var PDFJS = {};
     19PDFJS.version = '0.7.131';
     20PDFJS.build = 'c53fa62';
    1921
    2022(function pdfjsWrapper() {
    2123  // Use strict in our context only - users might not want it
    2224  'use strict';
    23 
    24   PDFJS.build =
    25 '15f0e58';
    2625
    2726/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     
    120119
    121120var Page = (function PageClosure() {
    122   function Page(xref, pageNumber, pageDict, ref) {
    123     this.pageNumber = pageNumber;
     121  function Page(xref, pageIndex, pageDict, ref) {
     122    this.pageIndex = pageIndex;
    124123    this.pageDict = pageDict;
    125124    this.xref = xref;
     
    190189      return shadow(this, 'rotate', rotate);
    191190    },
    192 
    193     getOperatorList: function Page_getOperatorList(handler, dependency) {
    194       var xref = this.xref;
     191    getContentStream: function Page_getContentStream() {
    195192      var content = this.content;
    196       var resources = this.resources;
    197193      if (isArray(content)) {
    198194        // fetching items
    199         var streams = [];
     195        var xref = this.xref;
    200196        var i, n = content.length;
    201197        var streams = [];
     
    207203      } else if (!content) {
    208204        // replacing non-existent page content with empty one
    209         content = new Stream(new Uint8Array(0));
    210       }
    211 
     205        content = new NullStream();
     206      }
     207      return content;
     208    },
     209    getOperatorList: function Page_getOperatorList(handler, dependency) {
     210      var xref = this.xref;
     211      var contentStream = this.getContentStream();
     212      var resources = this.resources;
    212213      var pe = this.pe = new PartialEvaluator(
    213                                 xref, handler, 'p' + this.pageNumber + '_');
    214 
    215       return pe.getOperatorList(content, resources, dependency);
     214                                xref, handler, this.pageIndex,
     215                                'p' + this.pageIndex + '_');
     216
     217      var list = pe.getOperatorList(contentStream, resources, dependency);
     218      pe.optimizeQueue(list);
     219      return list;
    216220    },
    217221    extractTextContent: function Page_extractTextContent() {
     
    222226
    223227      var xref = this.xref;
    224       var content = xref.fetchIfRef(this.content);
     228      var contentStream = this.getContentStream();
    225229      var resources = xref.fetchIfRef(this.resources);
    226       if (isArray(content)) {
    227         // fetching items
    228         var i, n = content.length;
    229         var streams = [];
    230         for (i = 0; i < n; ++i)
    231           streams.push(xref.fetchIfRef(content[i]));
    232         content = new StreamsSequenceStream(streams);
    233       } else if (isStream(content)) {
    234         content.reset();
    235       }
    236230
    237231      var pe = new PartialEvaluator(
    238                      xref, handler, 'p' + this.pageNumber + '_');
    239       return pe.getTextContent(content, resources);
    240     },
    241 
    242     ensureFonts: function Page_ensureFonts(fonts, callback) {
    243       this.stats.time('Font Loading');
    244       // Convert the font names to the corresponding font obj.
    245       for (var i = 0, ii = fonts.length; i < ii; i++) {
    246         fonts[i] = this.objs.objs[fonts[i]].data;
    247       }
    248 
    249       // Load all the fonts
    250       FontLoader.bind(
    251         fonts,
    252         function pageEnsureFontsFontObjs(fontObjs) {
    253           this.stats.timeEnd('Font Loading');
    254 
    255           callback.call(this);
    256         }.bind(this)
    257       );
     232                     xref, handler, this.pageIndex,
     233                     'p' + this.pageIndex + '_');
     234      return pe.getTextContent(contentStream, resources);
    258235    },
    259236    getLinks: function Page_getLinks() {
     
    329306                  item.dest = a.get('D');
    330307                  break;
     308                case 'GoToR':
     309                  var url = a.get('F');
     310                  if (isDict(url)) {
     311                    // We assume that the 'url' is a Filspec dictionary
     312                    // and fetch the url without checking any further
     313                    url = url.get('F') || '';
     314                  }
     315
     316                  // TODO: pdf reference says that GoToR
     317                  // can also have 'NewWindow' attribute
     318                  if (!isValidUrl(url))
     319                    url = '';
     320                  item.url = url;
     321                  item.dest = a.get('D');
     322                  break;
    331323                default:
    332                   TODO('other link types');
     324                  TODO('unrecognized link type: ' + a.get('S').name);
    333325              }
    334326            } else if (annotation.has('Dest')) {
     
    472464          warn('The linearization data is not available ' +
    473465               'or unreadable pdf data is found');
     466          linearization = false;
    474467        }
    475468      }
     
    532525        // Found the header, trim off any garbage before it.
    533526        stream.moveStart();
     527        // Reading file format version
     528        var MAX_VERSION_LENGTH = 12;
     529        var version = '', ch;
     530        while ((ch = stream.getChar()) > ' ') {
     531          if (version.length >= MAX_VERSION_LENGTH) {
     532            break;
     533          }
     534          version += ch;
     535        }
     536        // removing "%PDF-"-prefix
     537        this.pdfFormatVersion = version.substring(5);
    534538        return;
    535539      }
     
    552556    },
    553557    getDocumentInfo: function PDFDocument_getDocumentInfo() {
    554       var docInfo;
     558      var docInfo = {
     559        PDFFormatVersion: this.pdfFormatVersion
     560      };
    555561      if (this.xref.trailer.has('Info')) {
    556562        var infoDict = this.xref.trailer.get('Info');
    557563
    558         docInfo = {};
    559564        var validEntries = DocumentInfoValidators.entries;
    560565        // Only fill the document info with valid entries from the spec.
     
    673678// absolute URL, it will be returned as is.
    674679function combineUrl(baseUrl, url) {
     680  if (!url)
     681    return baseUrl;
    675682  if (url.indexOf(':') >= 0)
    676683    return url;
     
    736743})();
    737744
     745var UnknownErrorException = (function UnknownErrorExceptionClosure() {
     746  function UnknownErrorException(msg, details) {
     747    this.name = 'UnknownErrorException';
     748    this.message = msg;
     749    this.details = details;
     750  }
     751
     752  UnknownErrorException.prototype = new Error();
     753  UnknownErrorException.constructor = UnknownErrorException;
     754
     755  return UnknownErrorException;
     756})();
     757
     758var InvalidPDFException = (function InvalidPDFExceptionClosure() {
     759  function InvalidPDFException(msg) {
     760    this.name = 'InvalidPDFException';
     761    this.message = msg;
     762  }
     763
     764  InvalidPDFException.prototype = new Error();
     765  InvalidPDFException.constructor = InvalidPDFException;
     766
     767  return InvalidPDFException;
     768})();
     769
     770var MissingPDFException = (function MissingPDFExceptionClosure() {
     771  function MissingPDFException(msg) {
     772    this.name = 'MissingPDFException';
     773    this.message = msg;
     774  }
     775
     776  MissingPDFException.prototype = new Error();
     777  MissingPDFException.constructor = MissingPDFException;
     778
     779  return MissingPDFException;
     780})();
     781
    738782function bytesToString(bytes) {
    739783  var str = '';
     
    757801  function Util() {}
    758802
    759   Util.makeCssRgb = function Util_makeCssRgb(r, g, b) {
    760     var ri = (255 * r) | 0, gi = (255 * g) | 0, bi = (255 * b) | 0;
    761     return 'rgb(' + ri + ',' + gi + ',' + bi + ')';
     803  Util.makeCssRgb = function Util_makeCssRgb(rgb) {
     804    return 'rgb(' + rgb[0] + ',' + rgb[1] + ',' + rgb[2] + ')';
    762805  };
    763806
    764   Util.makeCssCmyk = function Util_makeCssCmyk(c, m, y, k) {
    765     c = (new DeviceCmykCS()).getRgb([c, m, y, k]);
    766     var ri = (255 * c[0]) | 0, gi = (255 * c[1]) | 0, bi = (255 * c[2]) | 0;
    767     return 'rgb(' + ri + ',' + gi + ',' + bi + ')';
     807  Util.makeCssCmyk = function Util_makeCssCmyk(cmyk) {
     808    var cs = new DeviceCmykCS();
     809    Util.makeCssCmyk = function makeCssCmyk(cmyk) {
     810      var rgb = cs.getRgb(cmyk, 0);
     811      return Util.makeCssRgb(rgb);
     812    };
     813    return Util.makeCssCmyk(cmyk);
    768814  };
    769815
     
    10001046
    10011047function isDict(v, type) {
    1002   return v instanceof Dict && (!type || v.get('Type').name == type);
     1048  if (!(v instanceof Dict)) {
     1049    return false;
     1050  }
     1051  if (!type) {
     1052    return true;
     1053  }
     1054  var dictType = v.get('Type');
     1055  return isName(dictType) && dictType.name == type;
    10031056}
    10041057
     
    10551108    this.isRejected = false;
    10561109    this.error = null;
     1110    this.exception = null;
    10571111    // If you build a promise and pass in some data it's already resolved.
    10581112    if (data != null) {
     
    11631217      this.isRejected = true;
    11641218      this.error = reason || null;
     1219      this.exception = exception || null;
    11651220      var errbacks = this.errbacks;
    11661221
     
    11811236      } else if (this.isRejected && errback) {
    11821237        var error = this.error;
    1183         errback.call(null, error);
     1238        var exception = this.exception;
     1239        errback.call(null, error, exception);
    11841240      } else {
    11851241        this.callbacks.push(callback);
     
    13311387    get fingerprint() {
    13321388      return this.pdfInfo.fingerprint;
     1389    },
     1390    /**
     1391     * @return {boolean} true if embedded document fonts are in use. Will be
     1392     * set during rendering of the pages.
     1393     */
     1394    get embeddedFontsUsed() {
     1395      return this.transport.embeddedFontsUsed;
    13331396    },
    13341397    /**
     
    14141477    this.stats = new StatTimer();
    14151478    this.stats.enabled = !!globalScope.PDFJS.enableStats;
    1416     this.objs = transport.objs;
     1479    this.commonObjs = transport.commonObjs;
     1480    this.objs = new PDFObjects();
    14171481    this.renderInProgress = false;
     1482    this.cleanupAfterRender = false;
    14181483  }
    14191484  PDFPageProxy.prototype = {
     
    15051570      function complete(error) {
    15061571        self.renderInProgress = false;
    1507         if (self.destroyed) {
     1572        if (self.destroyed || self.cleanupAfterRender) {
     1573          delete self.displayReadyPromise;
    15081574          delete self.operatorList;
    1509           delete self.displayReadyPromise;
     1575          self.objs.clear();
    15101576        }
    15111577
     
    15251591          }
    15261592
    1527           var gfx = new CanvasGraphics(params.canvasContext,
     1593          var gfx = new CanvasGraphics(params.canvasContext, this.commonObjs,
    15281594            this.objs, params.textLayer);
    15291595          try {
     
    15711637      var fontObjs = [];
    15721638      for (var i = 0, ii = fonts.length; i < ii; i++) {
    1573         var obj = this.objs.objs[fonts[i]].data;
     1639        var obj = this.commonObjs.getData(fonts[i]);
    15741640        if (obj.error) {
    15751641          warn('Error during font loading: ' + obj.error);
    15761642          continue;
     1643        }
     1644        if (!obj.coded) {
     1645          this.transport.embeddedFontsUsed = true;
    15771646        }
    15781647        fontObjs.push(obj);
     
    16651734        delete this.operatorList;
    16661735        delete this.displayReadyPromise;
     1736        this.objs.clear();
    16671737      }
    16681738    }
     
    16761746  function WorkerTransport(workerInitializedPromise, workerReadyPromise) {
    16771747    this.workerReadyPromise = workerReadyPromise;
    1678     this.objs = new PDFObjects();
     1748    this.commonObjs = new PDFObjects();
    16791749
    16801750    this.pageCache = [];
    16811751    this.pagePromises = [];
    1682     this.fontsLoading = {};
     1752    this.embeddedFontsUsed = false;
    16831753
    16841754    // If worker support isn't disabled explicit and the browser has worker
     
    16941764
    16951765      try {
    1696         var worker;
    16971766        // Some versions of FF can't create a worker on localhost, see:
    16981767        // https://bugzilla.mozilla.org/show_bug.cgi?id=683280
    1699         worker = new Worker(workerSrc);
     1768        var worker = new Worker(workerSrc);
    17001769        var messageHandler = new MessageHandler('main', worker);
    17011770        this.messageHandler = messageHandler;
     
    17721841      }, this);
    17731842
     1843      messageHandler.on('InvalidPDF', function transportInvalidPDF(data) {
     1844        this.workerReadyPromise.reject(data.exception.name, data.exception);
     1845      }, this);
     1846
     1847      messageHandler.on('MissingPDF', function transportMissingPDF(data) {
     1848        this.workerReadyPromise.reject(data.exception.message, data.exception);
     1849      }, this);
     1850
     1851      messageHandler.on('UnknownError', function transportUnknownError(data) {
     1852        this.workerReadyPromise.reject(data.exception.message, data.exception);
     1853      }, this);
     1854
    17741855      messageHandler.on('GetPage', function transportPage(data) {
    17751856        var pageInfo = data.pageInfo;
     
    17941875      }, this);
    17951876
    1796       messageHandler.on('obj', function transportObj(data) {
     1877      messageHandler.on('commonobj', function transportObj(data) {
    17971878        var id = data[0];
    17981879        var type = data[1];
    1799         if (this.objs.hasData(id))
     1880        if (this.commonObjs.hasData(id))
    18001881          return;
    18011882
    18021883        switch (type) {
    1803           case 'JpegStream':
    1804             var imageData = data[2];
    1805             loadJpegStream(id, imageData, this.objs);
    1806             break;
    1807           case 'Image':
    1808             var imageData = data[2];
    1809             this.objs.resolve(id, imageData);
    1810             break;
    18111884          case 'Font':
    18121885            var exportedData = data[2];
     
    18191892            else
    18201893              font = new Font(exportedData);
    1821             this.objs.resolve(id, font);
     1894            this.commonObjs.resolve(id, font);
    18221895            break;
    18231896          default:
    1824             error('Got unkown object type ' + type);
     1897            error('Got unknown common object type ' + type);
     1898        }
     1899      }, this);
     1900
     1901      messageHandler.on('obj', function transportObj(data) {
     1902        var id = data[0];
     1903        var pageIndex = data[1];
     1904        var type = data[2];
     1905        var pageProxy = this.pageCache[pageIndex];
     1906        if (pageProxy.objs.hasData(id))
     1907          return;
     1908
     1909        switch (type) {
     1910          case 'JpegStream':
     1911            var imageData = data[3];
     1912            loadJpegStream(id, imageData, pageProxy.objs);
     1913            break;
     1914          case 'Image':
     1915            var imageData = data[3];
     1916            pageProxy.objs.resolve(id, imageData);
     1917
     1918            // heuristics that will allow not to store large data
     1919            var MAX_IMAGE_SIZE_TO_STORE = 8000000;
     1920            if ('data' in imageData &&
     1921                imageData.data.length > MAX_IMAGE_SIZE_TO_STORE) {
     1922              pageProxy.cleanupAfterRender = true;
     1923            }
     1924            break;
     1925          default:
     1926            error('Got unknown object type ' + type);
    18251927        }
    18261928      }, this);
     
    19222024  STROKE_ADD_TO_PATH: 5,
    19232025  FILL_STROKE_ADD_TO_PATH: 6,
    1924   ADD_TO_PATH: 7
     2026  ADD_TO_PATH: 7,
     2027  ADD_TO_PATH_FLAG: 4
    19252028};
    19262029
     
    19392042  if (!ctx.mozCurrentTransform) {
    19402043    // Store the original context
     2044    ctx._scaleX = ctx._scaleX || 1.0;
     2045    ctx._scaleY = ctx._scaleY || 1.0;
    19412046    ctx._originalSave = ctx.save;
    19422047    ctx._originalRestore = ctx.restore;
     
    19462051    ctx._originalTransform = ctx.transform;
    19472052
    1948     ctx._transformMatrix = [1, 0, 0, 1, 0, 0];
     2053    ctx._transformMatrix = [ctx._scaleX, 0, 0, ctx._scaleY, 0, 0];
    19492054    ctx._transformStack = [];
    19502055
     
    20522157    this.fontSizeScale = 1;
    20532158    this.textMatrix = IDENTITY_MATRIX;
    2054     this.fontMatrix = IDENTITY_MATRIX;
     2159    this.fontMatrix = FONT_IDENTITY_MATRIX;
    20552160    this.leading = 0;
    20562161    // Current point (in user coordinates)
     
    20802185    this.strokeAlpha = 1;
    20812186    this.lineWidth = 1;
     2187    this.paintFormXObjectDepth = 0;
    20822188
    20832189    this.old = old;
     
    20992205  // Defines the time the executeOperatorList is going to be executing
    21002206  // before it stops and shedules a continue of execution.
    2101   var kExecutionTime = 15;
    2102 
    2103   function CanvasGraphics(canvasCtx, objs, textLayer) {
     2207  var EXECUTION_TIME = 15;
     2208
     2209  function CanvasGraphics(canvasCtx, commonObjs, objs, textLayer) {
    21042210    this.ctx = canvasCtx;
    21052211    this.current = new CanvasExtraState();
     
    21082214    this.res = null;
    21092215    this.xobjs = null;
     2216    this.commonObjs = commonObjs;
    21102217    this.objs = objs;
    21112218    this.textLayer = textLayer;
     
    21132220      addContextCurrentTransform(canvasCtx);
    21142221    }
     2222  }
     2223
     2224  function applyStencilMask(imgArray, width, height, inverseDecode, buffer) {
     2225    var imgArrayPos = 0;
     2226    var i, j, mask, buf;
     2227    // removing making non-masked pixels transparent
     2228    var bufferPos = 3; // alpha component offset
     2229    for (i = 0; i < height; i++) {
     2230      mask = 0;
     2231      for (j = 0; j < width; j++) {
     2232        if (!mask) {
     2233          buf = imgArray[imgArrayPos++];
     2234          mask = 128;
     2235        }
     2236        if (!(buf & mask) == inverseDecode) {
     2237          buffer[bufferPos] = 0;
     2238        }
     2239        bufferPos += 4;
     2240        mask >>= 1;
     2241      }
     2242    }
     2243  }
     2244
     2245  function putBinaryImageData(ctx, data, w, h) {
     2246    var tmpImgData = 'createImageData' in ctx ? ctx.createImageData(w, h) :
     2247      ctx.getImageData(0, 0, w, h);
     2248
     2249    var tmpImgDataPixels = tmpImgData.data;
     2250    if ('set' in tmpImgDataPixels)
     2251      tmpImgDataPixels.set(data);
     2252    else {
     2253      // Copy over the imageData pixel by pixel.
     2254      for (var i = 0, ii = tmpImgDataPixels.length; i < ii; i++)
     2255        tmpImgDataPixels[i] = data[i];
     2256    }
     2257
     2258    ctx.putImageData(tmpImgData, 0, 0);
     2259  }
     2260
     2261  function prescaleImage(pixels, width, height, widthScale, heightScale) {
     2262    pixels = new Uint8Array(pixels); // creating a copy
     2263    while (widthScale > 2 || heightScale > 2) {
     2264      if (heightScale > 2) {
     2265        // scaling image twice vertically
     2266        var rowSize = width * 4;
     2267        var k = 0, l = 0;
     2268        for (var i = 0; i < height - 1; i += 2) {
     2269          for (var j = 0; j < width; j++) {
     2270            var alpha1 = pixels[k + 3], alpha2 = pixels[k + 3 + rowSize];
     2271            if (alpha1 === alpha2) {
     2272              pixels[l] = (pixels[k] + pixels[k + rowSize]) >> 1;
     2273              pixels[l + 1] = (pixels[k + 1] + pixels[k + 1 + rowSize]) >> 1;
     2274              pixels[l + 2] = (pixels[k + 2] + pixels[k + 2 + rowSize]) >> 1;
     2275              pixels[l + 3] = alpha1;
     2276            } else if (alpha1 < alpha2) {
     2277              var d = 256 - alpha2 + alpha1;
     2278              pixels[l] = (pixels[k] * d + (pixels[k + rowSize] << 8)) >> 9;
     2279              pixels[l + 1] = (pixels[k + 1] * d +
     2280                              (pixels[k + 1 + rowSize] << 8)) >> 9;
     2281              pixels[l + 2] = (pixels[k + 2] * d +
     2282                              (pixels[k + 2 + rowSize] << 8)) >> 9;
     2283              pixels[l + 3] = alpha2;
     2284            } else {
     2285              var d = 256 - alpha1 + alpha2;
     2286              pixels[l] = ((pixels[k] << 8) + pixels[k + rowSize] * d) >> 9;
     2287              pixels[l + 1] = ((pixels[k + 1] << 8) +
     2288                              pixels[k + 1 + rowSize] * d) >> 9;
     2289              pixels[l + 2] = ((pixels[k + 2] << 8) +
     2290                              pixels[k + 2 + rowSize] * d) >> 9;
     2291              pixels[l + 3] = alpha1;
     2292            }
     2293            k += 4; l += 4;
     2294          }
     2295          k += rowSize;
     2296        }
     2297        if (height & 1) {
     2298          for (var i = 0; i < rowSize; i++) {
     2299            pixels[l++] = pixels[k++];
     2300          }
     2301        }
     2302        height = (height + 1) >> 1;
     2303        heightScale /= 2;
     2304      }
     2305      if (widthScale > 2) {
     2306        // scaling image twice horizontally
     2307        var k = 0, l = 0;
     2308        for (var i = 0; i < height; i++) {
     2309          for (var j = 0; j < width - 1; j += 2) {
     2310            var alpha1 = pixels[k + 3], alpha2 = pixels[k + 7];
     2311            if (alpha1 === alpha2) {
     2312              pixels[l] = (pixels[k] + pixels[k + 4]) >> 1;
     2313              pixels[l + 1] = (pixels[k + 1] + pixels[k + 5]) >> 1;
     2314              pixels[l + 2] = (pixels[k + 2] + pixels[k + 6]) >> 1;
     2315              pixels[l + 3] = alpha1;
     2316            } else if (alpha1 < alpha2) {
     2317              var d = 256 - alpha2 + alpha1;
     2318              pixels[l] = (pixels[k] * d + (pixels[k + 4] << 8)) >> 9;
     2319              pixels[l + 1] = (pixels[k + 1] * d + (pixels[k + 5] << 8)) >> 9;
     2320              pixels[l + 2] = (pixels[k + 2] * d + (pixels[k + 6] << 8)) >> 9;
     2321              pixels[l + 3] = alpha2;
     2322            } else {
     2323              var d = 256 - alpha1 + alpha2;
     2324              pixels[l] = ((pixels[k] << 8) + pixels[k + 4] * d) >> 9;
     2325              pixels[l + 1] = ((pixels[k + 1] << 8) + pixels[k + 5] * d) >> 9;
     2326              pixels[l + 2] = ((pixels[k + 2] << 8) + pixels[k + 6] * d) >> 9;
     2327              pixels[l + 3] = alpha1;
     2328            }
     2329            k += 8; l += 4;
     2330          }
     2331          if (width & 1) {
     2332            pixels[l++] = pixels[k++];
     2333            pixels[l++] = pixels[k++];
     2334            pixels[l++] = pixels[k++];
     2335            pixels[l++] = pixels[k++];
     2336          }
     2337        }
     2338        width = (width + 1) >> 1;
     2339        widthScale /= 2;
     2340      }
     2341    }
     2342
     2343    var tmpCanvas = createScratchCanvas(width, height);
     2344    var tmpCtx = tmpCanvas.getContext('2d');
     2345    putBinaryImageData(tmpCtx, pixels.subarray(0, width * height * 4),
     2346                               width, height);
     2347
     2348    return tmpCanvas;
    21152349  }
    21162350
     
    21462380      'paintJpegXObject': true,
    21472381      'paintImageXObject': true,
     2382      'paintInlineImageXObject': true,
     2383      'paintInlineImageXObjectGroup': true,
    21482384      'paintImageMaskXObject': true,
     2385      'paintImageMaskXObjectGroup': true,
    21492386      'shadingFill': true
    21502387    },
     
    21742411
    21752412      var executionEndIdx;
    2176       var endTime = Date.now() + kExecutionTime;
    2177 
     2413      var endTime = Date.now() + EXECUTION_TIME;
     2414
     2415      var commonObjs = this.commonObjs;
    21782416      var objs = this.objs;
    21792417      var fnName;
     
    21942432          for (var n = 0, nn = deps.length; n < nn; n++) {
    21952433            var depObjId = deps[n];
     2434            var common = depObjId.substring(0, 2) == 'g_';
    21962435
    21972436            // If the promise isn't resolved yet, add the continueCallback
    21982437            // to the promise and bail out.
    2199             if (!objs.isResolved(depObjId)) {
     2438            if (!common && !objs.isResolved(depObjId)) {
    22002439              objs.get(depObjId, continueCallback);
     2440              return i;
     2441            }
     2442            if (common && !commonObjs.isResolved(depObjId)) {
     2443              commonObjs.get(depObjId, continueCallback);
    22012444              return i;
    22022445            }
     
    22462489    },
    22472490    setDash: function CanvasGraphics_setDash(dashArray, dashPhase) {
    2248       this.ctx.mozDash = dashArray;
    2249       this.ctx.mozDashOffset = dashPhase;
    2250       this.ctx.webkitLineDash = dashArray;
    2251       this.ctx.webkitLineDashOffset = dashPhase;
     2491      var ctx = this.ctx;
     2492      if ('setLineDash' in ctx) {
     2493        ctx.setLineDash(dashArray);
     2494        ctx.lineDashOffset = dashPhase;
     2495      } else {
     2496        ctx.mozDash = dashArray;
     2497        ctx.mozDashOffset = dashPhase;
     2498      }
    22522499    },
    22532500    setRenderingIntent: function CanvasGraphics_setRenderingIntent(intent) {
     
    23082555    },
    23092556    restore: function CanvasGraphics_restore() {
     2557      if ('textClipLayers' in this) {
     2558        this.completeTextClipping();
     2559      }
     2560
    23102561      var prev = this.stateStack.pop();
    23112562      if (prev) {
     
    24372688    },
    24382689    endText: function CanvasGraphics_endText() {
     2690      if ('textClipLayers' in this) {
     2691        this.swapImageForTextClipping();
     2692      }
     2693    },
     2694    getCurrentTextClipping: function CanvasGraphics_getCurrentTextClipping() {
     2695      var ctx = this.ctx;
     2696      var transform = ctx.mozCurrentTransform;
     2697      if ('textClipLayers' in this) {
     2698        // we need to reset only font and transform
     2699        var maskCtx = this.textClipLayers.maskCtx;
     2700        maskCtx.setTransform.apply(maskCtx, transform);
     2701        maskCtx.font = ctx.font;
     2702        return maskCtx;
     2703      }
     2704
     2705      var canvasWidth = ctx.canvas.width;
     2706      var canvasHeight = ctx.canvas.height;
     2707      // keeping track of the text clipping of the separate canvas
     2708      var maskCanvas = createScratchCanvas(canvasWidth, canvasHeight);
     2709      var maskCtx = maskCanvas.getContext('2d');
     2710      maskCtx.setTransform.apply(maskCtx, transform);
     2711      maskCtx.font = ctx.font;
     2712      var textClipLayers = {
     2713        maskCanvas: maskCanvas,
     2714        maskCtx: maskCtx
     2715      };
     2716      this.textClipLayers = textClipLayers;
     2717      return maskCtx;
     2718    },
     2719    swapImageForTextClipping:
     2720      function CanvasGraphics_swapImageForTextClipping() {
     2721      var ctx = this.ctx;
     2722      var canvasWidth = ctx.canvas.width;
     2723      var canvasHeight = ctx.canvas.height;
     2724      // saving current image content and clearing whole canvas
     2725      ctx.save();
     2726      ctx.setTransform(1, 0, 0, 1, 0, 0);
     2727      var data = ctx.getImageData(0, 0, canvasWidth, canvasHeight);
     2728      this.textClipLayers.imageData = data;
     2729      ctx.clearRect(0, 0, canvasWidth, canvasHeight);
     2730      ctx.restore();
     2731    },
     2732    completeTextClipping: function CanvasGraphics_completeTextClipping() {
     2733      var ctx = this.ctx;
     2734      // applying mask to the image (result is saved in maskCanvas)
     2735      var maskCtx = this.textClipLayers.maskCtx;
     2736      maskCtx.setTransform(1, 0, 0, 1, 0, 0);
     2737      maskCtx.globalCompositeOperation = 'source-in';
     2738      maskCtx.drawImage(ctx.canvas, 0, 0);
     2739
     2740      // restoring image data and applying the result of masked drawing
     2741      ctx.save();
     2742      ctx.setTransform(1, 0, 0, 1, 0, 0);
     2743      ctx.putImageData(this.textClipLayers.imageData, 0, 0);
     2744      ctx.drawImage(this.textClipLayers.maskCanvas, 0, 0);
     2745      ctx.restore();
     2746
     2747      delete this.textClipLayers;
    24392748    },
    24402749    setCharSpacing: function CanvasGraphics_setCharSpacing(spacing) {
     
    24512760    },
    24522761    setFont: function CanvasGraphics_setFont(fontRefName, size) {
    2453       var fontObj = this.objs.get(fontRefName);
     2762      var fontObj = this.commonObjs.get(fontRefName);
    24542763      var current = this.current;
    24552764
     
    24572766        error('Can\'t find font for ' + fontRefName);
    24582767
    2459       // Slice-clone matrix so we can manipulate it without affecting original
    2460       if (fontObj.fontMatrix)
    2461         current.fontMatrix = fontObj.fontMatrix.slice(0);
    2462       else
    2463         current.fontMatrix = IDENTITY_MATRIX.slice(0);
     2768      current.fontMatrix = fontObj.fontMatrix ? fontObj.fontMatrix :
     2769                                                FONT_IDENTITY_MATRIX;
    24642770
    24652771      // A valid matrix needs all main diagonal elements to be non-zero
     
    24722778      // The spec for Tf (setFont) says that 'size' specifies the font 'scale',
    24732779      // and in some docs this can be negative (inverted x-y axes).
    2474       // We implement this condition with fontMatrix.
    24752780      if (size < 0) {
    24762781        size = -size;
    2477         current.fontMatrix[0] *= -1;
    2478         current.fontMatrix[3] *= -1;
     2782        current.fontDirection = -1;
     2783      } else {
     2784        current.fontDirection = 1;
    24792785      }
    24802786
     
    25042810    },
    25052811    setTextRenderingMode: function CanvasGraphics_setTextRenderingMode(mode) {
    2506       if (mode >= TextRenderingMode.FILL_ADD_TO_PATH)
    2507         TODO('unsupported text rendering mode: ' + mode);
    25082812      this.current.textRenderingMode = mode;
    25092813    },
     
    25312835      var ctx = this.ctx;
    25322836      var current = this.current;
    2533       var textHScale = current.textHScale;
    2534       var fontMatrix = current.fontMatrix || IDENTITY_MATRIX;
    2535 
    25362837      ctx.transform.apply(ctx, current.textMatrix);
    2537       ctx.scale(1, -1);
    2538       ctx.translate(current.x, -current.y - current.textRise);
    2539       ctx.transform.apply(ctx, fontMatrix);
    2540       ctx.scale(textHScale, 1);
     2838      ctx.translate(current.x, current.y + current.textRise);
     2839      if (current.fontDirection > 0) {
     2840        ctx.scale(current.textHScale, -1);
     2841      } else {
     2842        ctx.scale(-current.textHScale, 1);
     2843      }
    25412844    },
    25422845    createTextGeometry: function CanvasGraphics_createTextGeometry() {
     
    25692872      var charSpacing = current.charSpacing;
    25702873      var wordSpacing = current.wordSpacing;
    2571       var textHScale = current.textHScale;
    2572       var fontMatrix = current.fontMatrix || IDENTITY_MATRIX;
    2573       var textHScale2 = textHScale * fontMatrix[0];
     2874      var textHScale = current.textHScale * current.fontDirection;
     2875      var fontMatrix = current.fontMatrix || FONT_IDENTITY_MATRIX;
    25742876      var glyphsLength = glyphs.length;
    25752877      var textLayer = this.textLayer;
     
    26102912
    26112913          var transformed = Util.applyTransform([glyph.width, 0], fontMatrix);
    2612           var width = transformed[0] * fontSize +
    2613               Util.sign(current.fontMatrix[0]) * charSpacing;
     2914          var width = (transformed[0] * fontSize + charSpacing) *
     2915                      current.fontDirection;
    26142916
    26152917          ctx.translate(width, 0);
     
    26242926
    26252927        var lineWidth = current.lineWidth;
    2626         var scale = Math.abs(current.textMatrix[0] * fontMatrix[0]);
     2928        var a1 = current.textMatrix[0], b1 = current.textMatrix[1];
     2929        var scale = Math.sqrt(a1 * a1 + b1 * b1);
    26272930        if (scale == 0 || lineWidth == 0)
    26282931          lineWidth = this.getSinglePixelWidth();
     
    26452948          if (glyph === null) {
    26462949            // word break
    2647             x += Util.sign(current.fontMatrix[0]) * wordSpacing;
     2950            x += current.fontDirection * wordSpacing;
    26482951            continue;
    26492952          }
    26502953
    26512954          var character = glyph.fontChar;
    2652           var charWidth = glyph.width * fontSize * 0.001 +
    2653               Util.sign(current.fontMatrix[0]) * charSpacing;
     2955          var charWidth = glyph.width * fontSize * current.fontMatrix[0] +
     2956                          charSpacing * current.fontDirection;
    26542957
    26552958          if (!glyph.disabled) {
     
    26712974                break;
    26722975              case TextRenderingMode.INVISIBLE:
     2976              case TextRenderingMode.ADD_TO_PATH:
    26732977                break;
    26742978            }
     2979            if (textRenderingMode & TextRenderingMode.ADD_TO_PATH_FLAG) {
     2980              var clipCtx = this.getCurrentTextClipping();
     2981              clipCtx.fillText(character, scaledX, 0);
     2982            }
    26752983          }
    26762984
    26772985          x += charWidth;
    2678 
    2679           var glyphUnicode = glyph.unicode === ' ' ? '\u00A0' : glyph.unicode;
    2680           if (glyphUnicode in NormalizedUnicodes)
    2681             glyphUnicode = NormalizedUnicodes[glyphUnicode];
    26822986
    26832987          canvasWidth += charWidth;
    26842988        }
    2685         current.x += x * textHScale2;
     2989        current.x += x * textHScale;
    26862990        ctx.restore();
    26872991      }
     
    26993003      var font = current.font;
    27003004      var fontSize = current.fontSize;
    2701       var textHScale = current.textHScale;
    2702       if (!font.coded)
    2703         textHScale *= (current.fontMatrix || IDENTITY_MATRIX)[0];
     3005      var textHScale = current.textHScale * (current.fontMatrix && !font.coded ?
     3006        current.fontMatrix[0] : FONT_IDENTITY_MATRIX[0]) *
     3007        current.fontDirection;
    27043008      var arrLength = arr.length;
    27053009      var textLayer = this.textLayer;
     
    27103014      if (textSelection) {
    27113015        ctx.save();
    2712         // Type3 fonts - each glyph is a "mini-PDF" (see also showText)
    2713         if (font.coded) {
    2714           ctx.transform.apply(ctx, current.textMatrix);
    2715           ctx.scale(1, -1);
    2716           ctx.translate(current.x, -1 * current.y);
    2717           ctx.scale(textHScale, 1);
    2718         } else
    2719           this.applyTextTransforms();
     3016        this.applyTextTransforms();
    27203017        geom = this.createTextGeometry();
    27213018        ctx.restore();
     
    27253022        var e = arr[i];
    27263023        if (isNum(e)) {
    2727           var spacingLength = -e * 0.001 * fontSize * textHScale;
     3024          var spacingLength = -e * fontSize * textHScale;
    27283025          current.x += spacingLength;
    27293026
     
    27853082    setStrokeColor: function CanvasGraphics_setStrokeColor(/*...*/) {
    27863083      var cs = this.current.strokeColorSpace;
    2787       var rgbColor = cs.getRgb(arguments);
    2788       var color = Util.makeCssRgb(rgbColor[0], rgbColor[1], rgbColor[2]);
     3084      var rgbColor = cs.getRgb(arguments, 0);
     3085      var color = Util.makeCssRgb(rgbColor);
    27893086      this.ctx.strokeStyle = color;
    27903087      this.current.strokeColor = color;
     
    27983095          var baseComps = base.numComps;
    27993096
    2800           color = [];
    2801           for (var i = 0; i < baseComps; ++i)
    2802             color.push(args[i]);
    2803 
    2804           color = base.getRgb(color);
     3097          color = base.getRgb(args, 0);
    28053098        }
    28063099        var pattern = new TilingPattern(IR, color, this.ctx, this.objs);
     
    28233116    setFillColor: function CanvasGraphics_setFillColor(/*...*/) {
    28243117      var cs = this.current.fillColorSpace;
    2825       var rgbColor = cs.getRgb(arguments);
    2826       var color = Util.makeCssRgb(rgbColor[0], rgbColor[1], rgbColor[2]);
     3118      var rgbColor = cs.getRgb(arguments, 0);
     3119      var color = Util.makeCssRgb(rgbColor);
    28273120      this.ctx.fillStyle = color;
    28283121      this.current.fillColor = color;
     
    28413134        this.current.strokeColorSpace = new DeviceGrayCS();
    28423135
    2843       var color = Util.makeCssRgb(gray, gray, gray);
     3136      var rgbColor = this.current.strokeColorSpace.getRgb(arguments, 0);
     3137      var color = Util.makeCssRgb(rgbColor);
    28443138      this.ctx.strokeStyle = color;
    28453139      this.current.strokeColor = color;
     
    28493143        this.current.fillColorSpace = new DeviceGrayCS();
    28503144
    2851       var color = Util.makeCssRgb(gray, gray, gray);
     3145      var rgbColor = this.current.fillColorSpace.getRgb(arguments, 0);
     3146      var color = Util.makeCssRgb(rgbColor);
    28523147      this.ctx.fillStyle = color;
    28533148      this.current.fillColor = color;
     
    28573152        this.current.strokeColorSpace = new DeviceRgbCS();
    28583153
    2859       var color = Util.makeCssRgb(r, g, b);
     3154      var rgbColor = this.current.strokeColorSpace.getRgb(arguments, 0);
     3155      var color = Util.makeCssRgb(rgbColor);
    28603156      this.ctx.strokeStyle = color;
    28613157      this.current.strokeColor = color;
     
    28653161        this.current.fillColorSpace = new DeviceRgbCS();
    28663162
    2867       var color = Util.makeCssRgb(r, g, b);
     3163      var rgbColor = this.current.fillColorSpace.getRgb(arguments, 0);
     3164      var color = Util.makeCssRgb(rgbColor);
    28683165      this.ctx.fillStyle = color;
    28693166      this.current.fillColor = color;
     
    28733170        this.current.strokeColorSpace = new DeviceCmykCS();
    28743171
    2875       var color = Util.makeCssCmyk(c, m, y, k);
     3172      var color = Util.makeCssCmyk(arguments);
    28763173      this.ctx.strokeStyle = color;
    28773174      this.current.strokeColor = color;
     
    28813178        this.current.fillColorSpace = new DeviceCmykCS();
    28823179
    2883       var color = Util.makeCssCmyk(c, m, y, k);
     3180      var color = Util.makeCssCmyk(arguments);
    28843181      this.ctx.fillStyle = color;
    28853182      this.current.fillColor = color;
     
    29343231                                                                        bbox) {
    29353232      this.save();
     3233      this.current.paintFormXObjectDepth++;
    29363234
    29373235      if (matrix && isArray(matrix) && 6 == matrix.length)
     
    29483246
    29493247    paintFormXObjectEnd: function CanvasGraphics_paintFormXObjectEnd() {
    2950       this.restore();
     3248      var depth = this.current.paintFormXObjectDepth;
     3249      do {
     3250        this.restore();
     3251        // some pdf don't close all restores inside object
     3252        // closing those for them
     3253      } while (this.current.paintFormXObjectDepth >= depth);
    29513254    },
    29523255
     
    29713274    paintImageMaskXObject: function CanvasGraphics_paintImageMaskXObject(
    29723275                             imgArray, inverseDecode, width, height) {
    2973       function applyStencilMask(buffer, inverseDecode) {
    2974         var imgArrayPos = 0;
    2975         var i, j, mask, buf;
    2976         // removing making non-masked pixels transparent
    2977         var bufferPos = 3; // alpha component offset
    2978         for (i = 0; i < height; i++) {
    2979           mask = 0;
    2980           for (j = 0; j < width; j++) {
    2981             if (!mask) {
    2982               buf = imgArray[imgArrayPos++];
    2983               mask = 128;
    2984             }
    2985             if (!(buf & mask) == inverseDecode) {
    2986               buffer[bufferPos] = 0;
    2987             }
    2988             bufferPos += 4;
    2989             mask >>= 1;
    2990           }
    2991         }
    2992       }
    2993       function rescaleImage(pixels, widthScale, heightScale) {
    2994         var scaledWidth = Math.ceil(width / widthScale);
    2995         var scaledHeight = Math.ceil(height / heightScale);
    2996 
    2997         var itemsSum = new Uint32Array(scaledWidth * scaledHeight * 4);
    2998         var itemsCount = new Uint32Array(scaledWidth * scaledHeight);
    2999         for (var i = 0, position = 0; i < height; i++) {
    3000           var lineOffset = (0 | (i / heightScale)) * scaledWidth;
    3001           for (var j = 0; j < width; j++) {
    3002             var countOffset = lineOffset + (0 | (j / widthScale));
    3003             var sumOffset = countOffset << 2;
    3004             itemsSum[sumOffset] += pixels[position];
    3005             itemsSum[sumOffset + 1] += pixels[position + 1];
    3006             itemsSum[sumOffset + 2] += pixels[position + 2];
    3007             itemsSum[sumOffset + 3] += pixels[position + 3];
    3008             itemsCount[countOffset]++;
    3009             position += 4;
    3010           }
    3011         }
    3012         var tmpCanvas = createScratchCanvas(scaledWidth, scaledHeight);
    3013         var tmpCtx = tmpCanvas.getContext('2d');
    3014         var imgData = tmpCtx.getImageData(0, 0, scaledWidth, scaledHeight);
    3015         pixels = imgData.data;
    3016         for (var i = 0, j = 0, ii = scaledWidth * scaledHeight; i < ii; i++) {
    3017           var count = itemsCount[i];
    3018           pixels[j] = itemsSum[j] / count;
    3019           pixels[j + 1] = itemsSum[j + 1] / count;
    3020           pixels[j + 2] = itemsSum[j + 2] / count;
    3021           pixels[j + 3] = itemsSum[j + 3] / count;
    3022           j += 4;
    3023         }
    3024         tmpCtx.putImageData(imgData, 0, 0);
    3025         return tmpCanvas;
    3026       }
    3027 
    3028       this.save();
    3029 
    30303276      var ctx = this.ctx;
    3031       var w = width, h = height;
    3032       // scale the image to the unit square
    3033       ctx.scale(1 / w, -1 / h);
    3034 
    3035       var tmpCanvas = createScratchCanvas(w, h);
     3277      var tmpCanvas = createScratchCanvas(width, height);
    30363278      var tmpCtx = tmpCanvas.getContext('2d');
    30373279
     
    30403282                          fillColor.type === 'Pattern') ?
    30413283                          fillColor.getPattern(tmpCtx) : fillColor;
    3042       tmpCtx.fillRect(0, 0, w, h);
    3043 
    3044       var imgData = tmpCtx.getImageData(0, 0, w, h);
     3284      tmpCtx.fillRect(0, 0, width, height);
     3285
     3286      var imgData = tmpCtx.getImageData(0, 0, width, height);
    30453287      var pixels = imgData.data;
    30463288
    3047       applyStencilMask(pixels, inverseDecode);
    3048 
    3049       var currentTransform = ctx.mozCurrentTransformInverse;
    3050       var widthScale = Math.max(Math.abs(currentTransform[0]), 1);
    3051       var heightScale = Math.max(Math.abs(currentTransform[3]), 1);
    3052       if (widthScale >= 2 || heightScale >= 2) {
    3053         // canvas does not resize well large images to small -- using simple
    3054         // algorithm to perform pre-scaling
    3055         tmpCanvas = rescaleImage(imgData.data, widthScale, heightScale);
    3056         ctx.scale(widthScale, heightScale);
    3057         ctx.drawImage(tmpCanvas, 0, -h / heightScale);
    3058       } else {
     3289      applyStencilMask(imgArray, width, height, inverseDecode, pixels);
     3290
     3291      this.paintInlineImageXObject(imgData);
     3292    },
     3293
     3294    paintImageMaskXObjectGroup:
     3295      function CanvasGraphics_paintImageMaskXObjectGroup(images) {
     3296      var ctx = this.ctx;
     3297      var tmpCanvasWidth = 0, tmpCanvasHeight = 0, tmpCanvas, tmpCtx;
     3298      for (var i = 0, ii = images.length; i < ii; i++) {
     3299        var image = images[i];
     3300        var w = image.width, h = image.height;
     3301        if (w > tmpCanvasWidth || h > tmpCanvasHeight) {
     3302          tmpCanvasWidth = Math.max(w, tmpCanvasWidth);
     3303          tmpCanvasHeight = Math.max(h, tmpCanvasHeight);
     3304          tmpCanvas = createScratchCanvas(tmpCanvasWidth, tmpCanvasHeight);
     3305          tmpCtx = tmpCanvas.getContext('2d');
     3306
     3307          var fillColor = this.current.fillColor;
     3308          tmpCtx.fillStyle = (fillColor && fillColor.hasOwnProperty('type') &&
     3309                              fillColor.type === 'Pattern') ?
     3310                              fillColor.getPattern(tmpCtx) : fillColor;
     3311        }
     3312        tmpCtx.fillRect(0, 0, w, h);
     3313
     3314        var imgData = tmpCtx.getImageData(0, 0, w, h);
     3315        var pixels = imgData.data;
     3316
     3317        applyStencilMask(image.data, w, h, image.inverseDecode, pixels);
     3318
    30593319        tmpCtx.putImageData(imgData, 0, 0);
    3060         ctx.drawImage(tmpCanvas, 0, -h);
    3061       }
    3062       this.restore();
     3320
     3321        ctx.save();
     3322        ctx.transform.apply(ctx, image.transform);
     3323        ctx.scale(1, -1);
     3324        ctx.drawImage(tmpCanvas, 0, 0, w, h,
     3325                      0, -1, 1, 1);
     3326        ctx.restore();
     3327      }
    30633328    },
    30643329
     
    30683333        error('Dependent image isn\'t ready yet');
    30693334
     3335      this.paintInlineImageXObject(imgData);
     3336    },
     3337
     3338    paintInlineImageXObject:
     3339      function CanvasGraphics_paintInlineImageXObject(imgData) {
     3340      var width = imgData.width;
     3341      var height = imgData.height;
     3342      var ctx = this.ctx;
    30703343      this.save();
     3344      // scale the image to the unit square
     3345      ctx.scale(1 / width, -1 / height);
     3346
     3347      var currentTransform = ctx.mozCurrentTransformInverse;
     3348      var widthScale = Math.max(Math.abs(currentTransform[0]), 1);
     3349      var heightScale = Math.max(Math.abs(currentTransform[3]), 1);
     3350      var tmpCanvas = createScratchCanvas(width, height);
     3351      var tmpCtx = tmpCanvas.getContext('2d');
     3352
     3353      if (widthScale > 2 || heightScale > 2) {
     3354        // canvas does not resize well large images to small -- using simple
     3355        // algorithm to perform pre-scaling
     3356        tmpCanvas = prescaleImage(imgData.data,
     3357                                 width, height,
     3358                                 widthScale, heightScale);
     3359        ctx.drawImage(tmpCanvas, 0, 0, tmpCanvas.width, tmpCanvas.height,
     3360                                 0, -height, width, height);
     3361      } else {
     3362        if (typeof ImageData !== 'undefined' && imgData instanceof ImageData) {
     3363          tmpCtx.putImageData(imgData, 0, 0);
     3364        } else {
     3365          putBinaryImageData(tmpCtx, imgData.data, width, height);
     3366        }
     3367        ctx.drawImage(tmpCanvas, 0, -height);
     3368      }
     3369      this.restore();
     3370    },
     3371
     3372    paintInlineImageXObjectGroup:
     3373      function CanvasGraphics_paintInlineImageXObjectGroup(imgData, map) {
    30713374      var ctx = this.ctx;
    30723375      var w = imgData.width;
    30733376      var h = imgData.height;
    3074       // scale the image to the unit square
    3075       ctx.scale(1 / w, -1 / h);
    30763377
    30773378      var tmpCanvas = createScratchCanvas(w, h);
    30783379      var tmpCtx = tmpCanvas.getContext('2d');
    3079       this.putBinaryImageData(tmpCtx, imgData, w, h);
    3080 
    3081       ctx.drawImage(tmpCanvas, 0, -h);
    3082       this.restore();
    3083     },
    3084 
    3085     putBinaryImageData: function CanvasGraphics_putBinaryImageData() {
    3086       //
     3380      putBinaryImageData(tmpCtx, imgData.data, w, h);
     3381
     3382      for (var i = 0, ii = map.length; i < ii; i++) {
     3383        var entry = map[i];
     3384        ctx.save();
     3385        ctx.transform.apply(ctx, entry.transform);
     3386        ctx.scale(1, -1);
     3387        ctx.drawImage(tmpCanvas, entry.x, entry.y, entry.w, entry.h,
     3388                      0, -1, 1, 1);
     3389        ctx.restore();
     3390      }
    30873391    },
    30883392
     
    31443448    getSinglePixelWidth: function CanvasGraphics_getSinglePixelWidth(scale) {
    31453449      var inverse = this.ctx.mozCurrentTransformInverse;
    3146       return Math.abs(inverse[0] + inverse[2]);
     3450      // max of the current horizontal and vertical scale
     3451      return Math.sqrt(Math.max(
     3452        (inverse[0] * inverse[0] + inverse[1] * inverse[1]),
     3453        (inverse[2] * inverse[2] + inverse[3] * inverse[3])));
    31473454    }
    31483455  };
     
    31513458})();
    31523459
    3153 function checkPutBinaryImageDataCompatibility() {
    3154   // Feature detection if the browser can use an Uint8Array directly as imgData.
    3155   var canvas = document.createElement('canvas');
    3156   canvas.width = 1;
    3157   canvas.height = 1;
    3158   var ctx = canvas.getContext('2d');
    3159 
    3160   try {
    3161     ctx.putImageData({
    3162       width: 1,
    3163       height: 1,
    3164       data: new Uint8Array(4)
    3165     }, 0, 0);
    3166 
    3167     CanvasGraphics.prototype.putBinaryImageData =
    3168       function CanvasGraphicsPutBinaryImageDataNative(ctx, imgData) {
    3169         ctx.putImageData(imgData, 0, 0);
    3170       };
    3171   } catch (e) {
    3172     CanvasGraphics.prototype.putBinaryImageData =
    3173       function CanvasGraphicsPutBinaryImageDataShim(ctx, imgData, w, h) {
    3174         var tmpImgData = 'createImageData' in ctx ? ctx.createImageData(w, h) :
    3175           ctx.getImageData(0, 0, w, h);
    3176 
    3177         var tmpImgDataPixels = tmpImgData.data;
    3178         var data = imgData.data;
    3179         if ('set' in tmpImgDataPixels)
    3180           tmpImgDataPixels.set(data);
    3181         else {
    3182           // Copy over the imageData pixel by pixel.
    3183           for (var i = 0, ii = tmpImgDataPixels.length; i < ii; i++)
    3184             tmpImgDataPixels[i] = data[i];
    3185         }
    3186 
    3187         ctx.putImageData(tmpImgData, 0, 0);
    3188       };
    3189   }
    3190 }
    3191 if (!isWorker) {
    3192   checkPutBinaryImageDataCompatibility();
    3193 }
    31943460
    31953461
     
    34843750          }
    34853751          var names = obj.get('Names');
    3486           for (i = 0, n = names.length; i < n; i += 2) {
    3487             dests[names[i]] = fetchDestination(xref.fetchIfRef(names[i + 1]));
     3752          if (names) {
     3753            for (i = 0, n = names.length; i < n; i += 2) {
     3754              dests[names[i]] = fetchDestination(xref.fetchIfRef(names[i + 1]));
     3755            }
    34883756          }
    34893757        }
     
    35173785    var encrypt = trailerDict.get('Encrypt');
    35183786    if (encrypt) {
    3519       var fileId = trailerDict.get('ID');
    3520       this.encrypt = new CipherTransformFactory(encrypt, fileId[0], password);
     3787      var ids = trailerDict.get('ID');
     3788      var fileId = (ids && ids.length) ? ids[0] : '';
     3789      this.encrypt = new CipherTransformFactory(encrypt, fileId, password);
    35213790    }
    35223791
     
    37514020        return dict;
    37524021      // nothing helps
    3753       error('Invalid PDF structure');
     4022      // calling error() would reject worker with an UnknownErrorException.
     4023      throw new InvalidPDFException('Invalid PDF structure');
    37544024    },
    37554025    readXRef: function XRef_readXRef(startXRef, recoveryMode) {
     
    38774147
    38784148      // compressed entry
    3879       stream = this.fetch(new Ref(e.offset, 0));
     4149      var tableOffset = e.offset;
     4150      stream = this.fetch(new Ref(tableOffset, 0));
    38804151      if (!isStream(stream))
    38814152        error('bad ObjStm stream');
     
    38864157      }
    38874158      parser = new Parser(new Lexer(stream), false, this);
     4159      parser.allowStreams = true;
    38884160      var i, entries = [], nums = [];
    38894161      // read the object numbers to populate cache
     
    39024174      for (i = 0; i < n; ++i) {
    39034175        entries.push(parser.getObj());
    3904         this.cache[nums[i]] = entries[i];
     4176        num = nums[i];
     4177        var entry = this.entries[num];
     4178        if (entry && entry.offset === tableOffset && entry.gen === i) {
     4179          this.cache[num] = entries[i];
     4180        }
    39054181      }
    39064182      e = entries[e.gen];
     
    39304206
    39314207  PDFObjects.prototype = {
    3932     objs: null,
    3933 
    39344208    /**
    39354209     * Internal function.
     
    40094283
    40104284    /**
     4285     * Returns the data of `objId` if object exists, null otherwise.
     4286     */
     4287    getData: function PDFObjects_getData(objId) {
     4288      var objs = this.objs;
     4289      if (!objs[objId] || !objs[objId].hasData) {
     4290        return null;
     4291      } else {
     4292        return objs[objId].data;
     4293      }
     4294    },
     4295
     4296    /**
    40114297     * Sets the data of an object but *doesn't* resolve it.
    40124298     */
     
    40154301      // create a *resolved* promise which shouldn't be the case!
    40164302      this.ensureObj(objId).data = data;
     4303    },
     4304
     4305    clear: function PDFObjects_clear() {
     4306      this.objs = {};
    40174307    }
    40184308  };
     
    47074997    this.lexer = lexer;
    47084998    this.operators = [];
    4709     this.token;
    4710     this.prev;
     4999    this.token = null;
     5000    this.prev = null;
    47115001  }
    47125002  PostScriptParser.prototype = {
     
    50105300    {f: 16, c: 199}, 0, {f: 6, c: 217}, {f: 6, c: 224}, {f: 16, c: 231}, 0,
    50115301    {f: 7, c: 249}, 352, 376, 381, [773, 8254], 353, 8482, 382, 0, 8194,
    5012     {s: 91}, 65512, {s: 3}, {f: 63, c: 65377}, {s: 243}, [8195, 12288],
     5302    {f: 59, c: 33}, 165, {f: 31, c: 93}, 65512, {f: 2, c: 125}, 0,
     5303    {f: 63, c: 65377}, {s: 243}, [8195, 12288],
    50135304    {f: 2, c: 12289}, 65292, 65294, 12539, {f: 2, c: 65306}, 65311, 65281,
    50145305    {f: 2, c: 12443}, 180, 65344, 168, 65342, 65507, 65343, {f: 2, c: 12541},
     
    57626053    38715, 38723, 38733, 38735, [12205, 38737], 0, 38999, 39013,
    57636054    {f: 2, c: 64042}, 39207, 64044, 39326, 39502, 39641, 39644, 39797, 39794,
    5764     39823, 39857, 39867, 39936, 40304, 40299, 64045, 40473, 40657, {s: 636},
    5765     8364, 8486, 0, 0, 64256, {f: 2, c: 64259}, 257, 299, 363, 275, 333, 256,
    5766     298, 362, 274, 332, {f: 4, c: 8539}, {f: 2, c: 8531}, 8304,
     6055    39823, 39857, 39867, 39936, 40304, 40299, 64045, 40473, 40657, 0, 92,
     6056    {s: 634}, 8364, 8486, 0, 0, 64256, {f: 2, c: 64259}, 257, 299, 363, 275,
     6057    333, 256, 298, 362, 274, 332, {f: 4, c: 8539}, {f: 2, c: 8531}, 8304,
    57676058    {f: 6, c: 8308}, {f: 10, c: 8320}, 461, 282, 0, 7868, 463, 0, 296, 465, 0,
    57686059    467, 366, 360, 462, 283, 0, 7869, 464, 0, 297, 466, 0, 468, 367, 361, 593,
     
    1193612227
    1193712228  ColorSpace.prototype = {
    11938     // Input: array of size numComps representing color component values
    11939     // Output: array of rgb values, each value ranging from [0.1]
    11940     getRgb: function ColorSpace_getRgb(color) {
    11941       error('Should not call ColorSpace.getRgb: ' + color);
     12229    /**
     12230     * Converts the color value to the RGB color. The color components are
     12231     * located in the src array starting from the srcOffset. Returns the array
     12232     * of the rgb components, each value ranging from [0,255].
     12233     */
     12234    getRgb: function ColorSpace_getRgb(src, srcOffset) {
     12235      error('Should not call ColorSpace.getRgb');
    1194212236    },
    11943     // Input: Uint8Array of component values, each value scaled to [0,255]
    11944     // Output: Uint8Array of rgb values, each value scaled to [0,255]
    11945     getRgbBuffer: function ColorSpace_getRgbBuffer(input) {
    11946       error('Should not call ColorSpace.getRgbBuffer: ' + input);
     12237    /**
     12238     * Converts the color value to the RGB color, similar to the getRgb method.
     12239     * The result placed into the dest array starting from the destOffset.
     12240     */
     12241    getRgbItem: function ColorSpace_getRgb(src, srcOffset, dest, destOffset) {
     12242      error('Should not call ColorSpace.getRgbItem');
     12243    },
     12244    /**
     12245     * Converts the specified number of the color values to the RGB colors.
     12246     * The colors are located in the src array starting from the srcOffset.
     12247     * The result is placed into the dest array starting from the destOffset.
     12248     * The src array items shall be in [0,2^bits) range, the dest array items
     12249     * will be in [0,255] range.
     12250     */
     12251    getRgbBuffer: function ColorSpace_getRgbBuffer(src, srcOffset, count,
     12252                                                   dest, destOffset, bits) {
     12253      error('Should not call ColorSpace.getRgbBuffer');
     12254    },
     12255    /**
     12256     * Determines amount of the bytes is required to store the reslut of the
     12257     * conversion that done by the getRgbBuffer method.
     12258     */
     12259    getOutputLength: function ColorSpace_getOutputLength(inputLength) {
     12260      error('Should not call ColorSpace.getOutputLength');
     12261    },
     12262    /**
     12263     * Returns true if source data will be equal the result/output data.
     12264     */
     12265    isPassthrough: function ColorSpace_isPassthrough(bits) {
     12266      return false;
     12267    },
     12268    /**
     12269     * Creates the output buffer and converts the specified number of the color
     12270     * values to the RGB colors, similar to the getRgbBuffer.
     12271     */
     12272    createRgbBuffer: function ColorSpace_createRgbBuffer(src, srcOffset,
     12273                                                         count, bits) {
     12274      if (this.isPassthrough(bits)) {
     12275        return src.subarray(srcOffset);
     12276      }
     12277      var destLength = this.getOutputLength(count * this.numComps);
     12278      var dest = new Uint8Array(destLength);
     12279      this.getRgbBuffer(src, srcOffset, count, dest, 0, bits);
     12280      return dest;
    1194712281    }
    1194812282  };
     
    1212812462    this.name = 'Alternate';
    1212912463    this.numComps = numComps;
    12130     this.defaultColor = [];
    12131     for (var i = 0; i < numComps; ++i)
    12132       this.defaultColor.push(1);
     12464    this.defaultColor = new Float32Array(numComps);
     12465    for (var i = 0; i < numComps; ++i) {
     12466      this.defaultColor[i] = 1;
     12467    }
    1213312468    this.base = base;
    1213412469    this.tintFn = tintFn;
     
    1213612471
    1213712472  AlternateCS.prototype = {
    12138     getRgb: function AlternateCS_getRgb(color) {
    12139       var tinted = this.tintFn(color);
    12140       return this.base.getRgb(tinted);
     12473    getRgb: function AlternateCS_getRgb(src, srcOffset) {
     12474      var rgb = new Uint8Array(3);
     12475      this.getRgbItem(src, srcOffset, rgb, 0);
     12476      return rgb;
    1214112477    },
    12142     getRgbBuffer: function AlternateCS_getRgbBuffer(input, bits) {
     12478    getRgbItem: function AlternateCS_getRgbItem(src, srcOffset,
     12479                                                dest, destOffset) {
     12480      var baseNumComps = this.base.numComps;
     12481      var input = 'subarray' in src ?
     12482        src.subarray(srcOffset, srcOffset + this.numComps) :
     12483        Array.prototype.slice.call(src, srcOffset, srcOffset + this.numComps);
     12484      var tinted = this.tintFn(input);
     12485      this.base.getRgbItem(tinted, 0, dest, destOffset);
     12486    },
     12487    getRgbBuffer: function AlternateCS_getRgbBuffer(src, srcOffset, count,
     12488                                                    dest, destOffset, bits) {
    1214312489      var tintFn = this.tintFn;
    1214412490      var base = this.base;
    1214512491      var scale = 1 / ((1 << bits) - 1);
    12146       var length = input.length;
    12147       var pos = 0;
    1214812492      var baseNumComps = base.numComps;
    12149       var baseBuf = new Uint8Array(baseNumComps * length);
     12493      var isGetRgbBufferSupported = 'getRgbBuffer' in base;
     12494      var isPassthrough = base.isPassthrough(8) || !isGetRgbBufferSupported;
     12495      var pos = isPassthrough ? destOffset : 0;
     12496      var baseBuf = isPassthrough ? dest : new Uint8Array(baseNumComps * count);
    1215012497      var numComps = this.numComps;
    12151       var scaled = [];
    12152 
    12153       for (var i = 0; i < length; i += numComps) {
    12154         for (var z = 0; z < numComps; ++z)
    12155           scaled[z] = input[i + z] * scale;
    12156 
     12498
     12499      var scaled = new Float32Array(numComps);
     12500      for (var i = 0; i < count; i++) {
     12501        for (var j = 0; j < numComps; j++) {
     12502          scaled[j] = src[srcOffset++] * scale;
     12503        }
    1215712504        var tinted = tintFn(scaled);
    12158         for (var j = 0; j < baseNumComps; ++j)
    12159           baseBuf[pos++] = 255 * tinted[j];
    12160       }
    12161       return base.getRgbBuffer(baseBuf, 8);
     12505        if (isGetRgbBufferSupported) {
     12506          for (var j = 0; j < baseNumComps; j++) {
     12507            baseBuf[pos++] = tinted[j] * 255;
     12508          }
     12509        } else {
     12510          base.getRgbItem(tinted, 0, baseBuf, pos);
     12511          pos += baseNumComps;
     12512        }
     12513      }
     12514      if (!isPassthrough) {
     12515        base.getRgbBuffer(baseBuf, 0, count, dest, destOffset, 8);
     12516      }
    1216212517    },
     12518    getOutputLength: function AlternateCS_getOutputLength(inputLength) {
     12519      return this.base.getOutputLength(inputLength *
     12520                                       this.base.numComps / this.numComps);
     12521    },
     12522    isPassthrough: ColorSpace.prototype.isPassthrough,
     12523    createRgbBuffer: ColorSpace.prototype.createRgbBuffer,
    1216312524    isDefaultDecode: function AlternateCS_isDefaultDecode(decodeMap) {
    1216412525      return ColorSpace.isDefaultDecode(decodeMap, this.numComps);
     
    1218312544    this.name = 'Indexed';
    1218412545    this.numComps = 1;
    12185     this.defaultColor = [0];
     12546    this.defaultColor = new Uint8Array([0]);
    1218612547    this.base = base;
    1218712548    this.highVal = highVal;
     
    1220812569
    1220912570  IndexedCS.prototype = {
    12210     getRgb: function IndexedCS_getRgb(color) {
     12571    getRgb: function IndexedCS_getRgb(src, srcOffset) {
    1221112572      var numComps = this.base.numComps;
    12212       var start = color[0] * numComps;
    12213       var c = [];
    12214 
    12215       for (var i = start, ii = start + numComps; i < ii; ++i)
    12216         c.push(this.lookup[i]);
    12217 
    12218       return this.base.getRgb(c);
     12573      var start = src[srcOffset] * numComps;
     12574      return this.base.getRgb(this.lookup, start);
    1221912575    },
    12220     getRgbBuffer: function IndexedCS_getRgbBuffer(input) {
     12576    getRgbItem: function IndexedCS_getRgbItem(src, srcOffset,
     12577                                              dest, destOffset) {
     12578      var numComps = this.base.numComps;
     12579      var start = src[srcOffset] * numComps;
     12580      this.base.getRgbItem(this.lookup, start, dest, destOffset);
     12581    },
     12582    getRgbBuffer: function IndexedCS_getRgbBuffer(src, srcOffset, count,
     12583                                                  dest, destOffset) {
    1222112584      var base = this.base;
    1222212585      var numComps = base.numComps;
     12586      var outputDelta = base.getOutputLength(numComps);
    1222312587      var lookup = this.lookup;
    12224       var length = input.length;
    12225       var baseBuf = new Uint8Array(length * numComps);
    12226       var baseBufPos = 0;
    12227 
    12228       for (var i = 0; i < length; ++i) {
    12229         var lookupPos = input[i] * numComps;
    12230         for (var j = 0; j < numComps; ++j) {
    12231           baseBuf[baseBufPos++] = lookup[lookupPos + j];
    12232         }
    12233       }
    12234 
    12235       return base.getRgbBuffer(baseBuf, 8);
     12588
     12589      for (var i = 0; i < count; ++i) {
     12590        var lookupPos = src[srcOffset++] * numComps;
     12591        base.getRgbBuffer(lookup, lookupPos, 1, dest, destOffset, 8);
     12592        destOffset += outputDelta;
     12593      }
    1223612594    },
     12595    getOutputLength: function IndexedCS_getOutputLength(inputLength) {
     12596      return this.base.getOutputLength(inputLength * this.base.numComps);
     12597    },
     12598    isPassthrough: ColorSpace.prototype.isPassthrough,
     12599    createRgbBuffer: ColorSpace.prototype.createRgbBuffer,
    1223712600    isDefaultDecode: function IndexedCS_isDefaultDecode(decodeMap) {
    1223812601      // indexed color maps shouldn't be changed
     
    1224712610    this.name = 'DeviceGray';
    1224812611    this.numComps = 1;
    12249     this.defaultColor = [0];
     12612    this.defaultColor = new Float32Array([0]);
    1225012613  }
    1225112614
    1225212615  DeviceGrayCS.prototype = {
    12253     getRgb: function DeviceGrayCS_getRgb(color) {
    12254       var c = color[0];
    12255       return [c, c, c];
     12616    getRgb: function DeviceGrayCS_getRgb(src, srcOffset) {
     12617      var rgb = new Uint8Array(3);
     12618      this.getRgbItem(src, srcOffset, rgb, 0);
     12619      return rgb;
    1225612620    },
    12257     getRgbBuffer: function DeviceGrayCS_getRgbBuffer(input, bits) {
     12621    getRgbItem: function DeviceGrayCS_getRgbItem(src, srcOffset,
     12622                                                 dest, destOffset) {
     12623      var c = (src[srcOffset] * 255) | 0;
     12624      c = c < 0 ? 0 : c > 255 ? 255 : c;
     12625      dest[destOffset] = dest[destOffset + 1] = dest[destOffset + 2] = c;
     12626    },
     12627    getRgbBuffer: function DeviceGrayCS_getRgbBuffer(src, srcOffset, count,
     12628                                                     dest, destOffset, bits) {
    1225812629      var scale = 255 / ((1 << bits) - 1);
    12259       var length = input.length;
    12260       var rgbBuf = new Uint8Array(length * 3);
    12261       for (var i = 0, j = 0; i < length; ++i) {
    12262         var c = (scale * input[i]) | 0;
    12263         rgbBuf[j++] = c;
    12264         rgbBuf[j++] = c;
    12265         rgbBuf[j++] = c;
    12266       }
    12267       return rgbBuf;
     12630      var j = srcOffset, q = destOffset;
     12631      for (var i = 0; i < count; ++i) {
     12632        var c = (scale * src[j++]) | 0;
     12633        dest[q++] = c;
     12634        dest[q++] = c;
     12635        dest[q++] = c;
     12636      }
    1226812637    },
     12638    getOutputLength: function DeviceGrayCS_getOutputLength(inputLength) {
     12639      return inputLength * 3;
     12640    },
     12641    isPassthrough: ColorSpace.prototype.isPassthrough,
     12642    createRgbBuffer: ColorSpace.prototype.createRgbBuffer,
    1226912643    isDefaultDecode: function DeviceGrayCS_isDefaultDecode(decodeMap) {
    1227012644      return ColorSpace.isDefaultDecode(decodeMap, this.numComps);
     
    1227812652    this.name = 'DeviceRGB';
    1227912653    this.numComps = 3;
    12280     this.defaultColor = [0, 0, 0];
     12654    this.defaultColor = new Float32Array([0, 0, 0]);
    1228112655  }
    1228212656  DeviceRgbCS.prototype = {
    12283     getRgb: function DeviceRgbCS_getRgb(color) {
    12284       return color;
     12657    getRgb: function DeviceRgbCS_getRgb(src, srcOffset) {
     12658      var rgb = new Uint8Array(3);
     12659      this.getRgbItem(src, srcOffset, rgb, 0);
     12660      return rgb;
    1228512661    },
    12286     getRgbBuffer: function DeviceRgbCS_getRgbBuffer(input, bits) {
    12287       if (bits == 8)
    12288         return input;
     12662    getRgbItem: function DeviceRgbCS_getRgbItem(src, srcOffset,
     12663                                                dest, destOffset) {
     12664      var r = src[srcOffset] * 255;
     12665      var g = src[srcOffset + 1] * 255;
     12666      var b = src[srcOffset + 2] * 255;
     12667      dest[destOffset] = r < 0 ? 0 : r > 255 ? 255 : r;
     12668      dest[destOffset + 1] = g < 0 ? 0 : g > 255 ? 255 : g;
     12669      dest[destOffset + 2] = b < 0 ? 0 : b > 255 ? 255 : b;
     12670    },
     12671    getRgbBuffer: function DeviceRgbCS_getRgbBuffer(src, srcOffset, count,
     12672                                                    dest, destOffset, bits) {
     12673      var length = count * 3;
     12674      if (bits == 8) {
     12675        dest.set(src.subarray(srcOffset, srcOffset + length), destOffset);
     12676        return;
     12677      }
    1228912678      var scale = 255 / ((1 << bits) - 1);
    12290       var i, length = input.length;
    12291       var rgbBuf = new Uint8Array(length);
    12292       for (i = 0; i < length; ++i)
    12293         rgbBuf[i] = (scale * input[i]) | 0;
    12294       return rgbBuf;
     12679      var j = srcOffset, q = destOffset;
     12680      for (var i = 0; i < length; ++i) {
     12681        dest[q++] = (scale * input[j++]) | 0;
     12682      }
    1229512683    },
     12684    getOutputLength: function DeviceRgbCS_getOutputLength(inputLength) {
     12685      return inputLength;
     12686    },
     12687    isPassthrough: function DeviceRgbCS_isPassthrough(bits) {
     12688      return bits == 8;
     12689    },
     12690    createRgbBuffer: ColorSpace.prototype.createRgbBuffer,
    1229612691    isDefaultDecode: function DeviceRgbCS_isDefaultDecode(decodeMap) {
    1229712692      return ColorSpace.isDefaultDecode(decodeMap, this.numComps);
     
    1230212697
    1230312698var DeviceCmykCS = (function DeviceCmykCSClosure() {
     12699  // Sampled RGB colors from CMYK US Web Coated (SWOP) colorspace
     12700  var lut = new Uint8Array([
     12701    255, 255, 254, 221, 222, 223, 191, 193, 195, 161, 163, 166, 133, 136, 138,
     12702    105, 107, 109, 75, 75, 77, 35, 31, 32, 255, 252, 224, 226, 220, 198, 195,
     12703    191, 173, 164, 162, 147, 136, 134, 122, 107, 106, 96, 75, 74, 66, 33, 29,
     12704    24, 255, 249, 197, 229, 218, 174, 198, 190, 153, 166, 160, 129, 138, 133,
     12705    107, 108, 104, 83, 76, 73, 56, 33, 28, 15, 255, 247, 168, 232, 216, 149,
     12706    200, 188, 130, 168, 158, 110, 139, 131, 90, 110, 103, 70, 77, 72, 45, 32,
     12707    27, 4, 255, 245, 140, 234, 214, 124, 202, 186, 108, 170, 157, 91, 140, 130,
     12708    74, 110, 102, 56, 77, 71, 33, 31, 27, 0, 255, 243, 107, 235, 212, 95, 203,
     12709    184, 83, 171, 155, 69, 141, 129, 55, 111, 101, 40, 77, 70, 19, 29, 26, 0,
     12710    255, 241, 64, 237, 211, 59, 204, 183, 52, 171, 154, 42, 142, 128, 31, 111,
     12711    100, 16, 77, 69, 0, 27, 26, 0, 255, 240, 0, 238, 209, 0, 205, 182, 3, 172,
     12712    153, 0, 142, 127, 0, 112, 100, 0, 77, 69, 0, 26, 25, 0, 251, 225, 236, 218,
     12713    196, 207, 189, 171, 181, 160, 144, 154, 133, 120, 128, 105, 94, 101, 74, 64,
     12714    70, 35, 21, 25, 255, 222, 208, 222, 195, 184, 192, 169, 161, 162, 143, 136,
     12715    135, 118, 113, 106, 92, 88, 75, 63, 60, 34, 20, 17, 255, 220, 184, 225, 193,
     12716    162, 195, 168, 142, 164, 142, 120, 136, 117, 99, 107, 91, 77, 75, 62, 50,
     12717    33, 20, 8, 255, 218, 157, 227, 191, 139, 197, 166, 121, 165, 140, 102, 137,
     12718    116, 84, 108, 90, 64, 76, 61, 40, 32, 19, 0, 255, 216, 132, 229, 189, 116,
     12719    198, 165, 101, 167, 139, 85, 138, 115, 69, 109, 89, 51, 76, 61, 28, 31, 18,
     12720    0, 255, 214, 102, 230, 188, 90, 199, 163, 78, 167, 138, 65, 139, 114, 51,
     12721    109, 89, 35, 76, 60, 14, 29, 18, 0, 255, 213, 65, 232, 186, 58, 200, 162,
     12722    50, 168, 136, 39, 139, 113, 28, 110, 88, 12, 76, 60, 0, 27, 18, 0, 255, 212,
     12723    8, 232, 185, 13, 201, 161, 11, 169, 136, 3, 139, 112, 0, 110, 87, 0, 76, 59,
     12724    0, 26, 18, 0, 248, 197, 219, 216, 172, 192, 187, 150, 168, 158, 126, 143,
     12725    132, 104, 119, 104, 81, 93, 74, 54, 64, 35, 10, 19, 251, 195, 193, 219, 171,
     12726    171, 190, 149, 150, 161, 125, 127, 133, 103, 105, 106, 80, 81, 75, 53, 54,
     12727    34, 10, 10, 254, 193, 171, 221, 169, 151, 192, 148, 132, 162, 124, 112, 134,
     12728    102, 92, 106, 79, 70, 75, 52, 45, 34, 9, 1, 255, 191, 147, 223, 168, 130,
     12729    193, 146, 113, 163, 123, 95, 135, 101, 77, 107, 78, 58, 75, 52, 35, 32, 9,
     12730    0, 255, 190, 124, 225, 166, 109, 195, 145, 95, 164, 122, 79, 136, 100, 63,
     12731    107, 77, 46, 76, 51, 24, 31, 9, 0, 255, 188, 97, 226, 165, 85, 196, 143, 74,
     12732    165, 121, 60, 137, 99, 47, 108, 77, 31, 75, 51, 10, 29, 9, 0, 255, 187, 64,
     12733    227, 164, 56, 196, 142, 48, 165, 120, 37, 137, 98, 25, 108, 76, 9, 75, 50,
     12734    0, 28, 9, 0, 255, 186, 23, 228, 163, 21, 197, 142, 15, 166, 119, 5, 137, 98,
     12735    0, 108, 76, 0, 75, 50, 0, 27, 8, 0, 245, 168, 201, 214, 147, 177, 186, 128,
     12736    155, 157, 107, 131, 131, 88, 109, 104, 67, 85, 74, 42, 57, 35, 0, 12, 248,
     12737    166, 178, 216, 146, 157, 188, 127, 138, 159, 107, 116, 132, 87, 96, 105, 66,
     12738    74, 74, 41, 48, 35, 0, 3, 250, 165, 158, 218, 145, 139, 189, 126, 122, 160,
     12739    106, 103, 133, 86, 84, 105, 66, 64, 75, 41, 39, 33, 0, 0, 252, 164, 136,
     12740    220, 144, 120, 190, 125, 104, 161, 105, 87, 134, 86, 71, 106, 65, 52, 75,
     12741    41, 29, 32, 0, 0, 253, 162, 115, 221, 142, 101, 191, 124, 88, 161, 104, 72,
     12742    134, 85, 58, 106, 64, 41, 75, 40, 19, 31, 0, 0, 254, 161, 91, 222, 141, 80,
     12743    192, 123, 68, 162, 103, 55, 134, 84, 42, 106, 64, 26, 75, 40, 6, 29, 0, 0,
     12744    255, 160, 62, 223, 140, 54, 193, 122, 45, 162, 102, 34, 135, 83, 22, 106,
     12745    63, 5, 74, 40, 0, 28, 0, 0, 255, 159, 29, 223, 140, 25, 193, 121, 18, 163,
     12746    101, 7, 135, 83, 0, 107, 63, 0, 74, 40, 0, 28, 0, 0, 243, 142, 185, 212,
     12747    123, 163, 184, 107, 142, 156, 89, 120, 130, 72, 100, 104, 53, 77, 74, 29,
     12748    51, 35, 0, 4, 245, 140, 164, 214, 123, 145, 186, 106, 127, 157, 89, 107,
     12749    131, 72, 88, 104, 53, 67, 74, 29, 42, 34, 0, 0, 247, 139, 146, 215, 122,
     12750    129, 187, 106, 112, 158, 88, 94, 132, 71, 77, 104, 53, 57, 74, 29, 33, 33,
     12751    0, 0, 248, 138, 126, 217, 121, 111, 188, 105, 96, 159, 87, 80, 132, 70, 64,
     12752    105, 52, 47, 74, 29, 24, 31, 0, 0, 249, 137, 107, 218, 120, 94, 189, 104,
     12753    81, 159, 86, 66, 132, 70, 52, 105, 52, 36, 74, 29, 15, 30, 0, 0, 250, 136,
     12754    85, 218, 119, 74, 189, 103, 63, 160, 86, 51, 133, 69, 38, 105, 51, 22, 74,
     12755    29, 2, 29, 0, 0, 251, 135, 59, 219, 118, 51, 190, 102, 42, 160, 85, 31, 133,
     12756    69, 19, 105, 51, 3, 74, 29, 0, 29, 0, 0, 252, 134, 31, 219, 118, 26, 190,
     12757    102, 19, 160, 85, 7, 133, 69, 0, 105, 51, 0, 73, 29, 0, 28, 0, 0, 240, 113,
     12758    169, 210, 98, 149, 183, 84, 130, 155, 69, 110, 129, 54, 90, 103, 37, 70, 74,
     12759    11, 44, 32, 0, 1, 242, 111, 150, 212, 97, 132, 184, 84, 116, 156, 69, 97,
     12760    130, 54, 79, 103, 37, 60, 74, 12, 36, 31, 0, 0, 244, 111, 134, 213, 97, 118,
     12761    185, 83, 102, 157, 68, 86, 130, 54, 69, 104, 37, 51, 74, 13, 28, 30, 0, 0,
     12762    245, 110, 116, 214, 96, 102, 186, 83, 88, 157, 68, 73, 131, 53, 58, 104, 37,
     12763    41, 74, 14, 19, 29, 0, 0, 246, 110, 98, 215, 96, 86, 186, 82, 74, 157, 67,
     12764    60, 131, 53, 46, 104, 37, 30, 73, 14, 10, 28, 0, 0, 247, 109, 79, 215, 95,
     12765    69, 187, 82, 58, 158, 67, 46, 131, 53, 33, 104, 37, 18, 73, 15, 1, 28, 0, 0,
     12766    247, 108, 56, 216, 95, 48, 187, 82, 40, 158, 67, 29, 131, 53, 16, 104, 37,
     12767    0, 73, 15, 0, 27, 0, 0, 248, 108, 32, 216, 94, 27, 187, 81, 20, 158, 67, 8,
     12768    131, 53, 0, 104, 37, 0, 72, 16, 0, 27, 0, 0, 238, 78, 154, 208, 66, 135,
     12769    181, 55, 118, 154, 43, 99, 129, 30, 81, 103, 12, 62, 74, 0, 38, 27, 0, 0,
     12770    240, 77, 136, 210, 66, 120, 183, 56, 105, 155, 43, 88, 129, 30, 71, 103, 13,
     12771    53, 73, 0, 29, 26, 0, 0, 241, 77, 122, 211, 66, 107, 183, 56, 93, 155, 44,
     12772    77, 129, 31, 62, 103, 14, 44, 73, 0, 23, 26, 0, 0, 242, 77, 106, 211, 66,
     12773    92, 184, 56, 80, 155, 44, 65, 129, 31, 51, 103, 15, 35, 73, 0, 14, 25, 0, 0,
     12774    243, 77, 90, 212, 66, 79, 184, 56, 67, 156, 44, 54, 129, 32, 41, 103, 16,
     12775    25, 73, 0, 6, 25, 0, 0, 243, 77, 73, 213, 66, 63, 184, 56, 53, 156, 44, 41,
     12776    130, 32, 28, 103, 17, 13, 72, 0, 0, 25, 0, 0, 244, 77, 53, 213, 67, 45, 185,
     12777    56, 37, 156, 45, 26, 130, 33, 13, 103, 18, 0, 72, 0, 0, 25, 0, 0, 244, 77,
     12778    33, 213, 67, 28, 185, 57, 21, 156, 45, 9, 130, 33, 0, 103, 19, 0, 72, 0, 0,
     12779    24, 0, 0, 237, 13, 138, 207, 4, 122, 180, 0, 106, 153, 0, 89, 128, 0, 72,
     12780    102, 0, 54, 73, 0, 31, 21, 0, 0, 238, 16, 123, 208, 6, 108, 181, 0, 94, 154,
     12781    0, 78, 128, 0, 63, 102, 0, 46, 72, 0, 24, 21, 0, 0, 239, 20, 110, 209, 11,
     12782    96, 181, 1, 83, 154, 0, 69, 128, 0, 54, 102, 0, 38, 72, 0, 17, 22, 0, 0,
     12783    239, 23, 96, 209, 15, 84, 182, 5, 72, 154, 0, 58, 128, 0, 45, 102, 0, 29,
     12784    72, 0, 9, 22, 0, 0, 240, 26, 82, 210, 19, 71, 182, 10, 60, 154, 0, 48, 128,
     12785    0, 35, 102, 0, 20, 72, 0, 3, 22, 0, 0, 241, 27, 67, 210, 21, 58, 182, 14,
     12786    48, 154, 3, 37, 128, 0, 24, 102, 0, 8, 71, 0, 0, 22, 0, 0, 241, 29, 50, 210,
     12787    23, 42, 183, 17, 34, 154, 6, 23, 129, 0, 10, 102, 0, 0, 71, 0, 0, 22, 0, 0,
     12788    241, 30, 34, 211, 25, 28, 183, 19, 21, 155, 9, 10, 129, 0, 0, 102, 0, 0, 71,
     12789    0, 0, 22, 0, 0, 211, 239, 252, 184, 210, 221, 160, 183, 194, 135, 155, 164,
     12790    111, 128, 137, 87, 101, 109, 59, 70, 76, 22, 28, 32, 218, 237, 223, 190,
     12791    208, 196, 165, 181, 172, 139, 153, 146, 114, 127, 121, 89, 100, 95, 61, 69,
     12792    66, 21, 27, 25, 223, 235, 196, 195, 206, 174, 169, 179, 152, 142, 151, 129,
     12793    117, 126, 107, 91, 99, 83, 62, 68, 56, 20, 26, 17, 227, 232, 168, 198, 204,
     12794    149, 171, 177, 130, 144, 150, 110, 119, 124, 91, 93, 98, 70, 63, 68, 46, 20,
     12795    25, 6, 231, 230, 142, 201, 202, 125, 174, 176, 109, 146, 148, 92, 120, 123,
     12796    75, 94, 97, 57, 63, 67, 35, 19, 25, 0, 234, 229, 112, 203, 200, 98, 176,
     12797    174, 86, 147, 147, 71, 121, 122, 57, 94, 96, 42, 64, 66, 21, 17, 24, 0, 236,
     12798    227, 75, 205, 199, 66, 177, 173, 57, 148, 146, 47, 122, 121, 35, 95, 95, 21,
     12799    64, 65, 2, 14, 24, 0, 238, 226, 32, 207, 198, 30, 178, 172, 25, 149, 145,
     12800    17, 123, 120, 6, 95, 94, 0, 64, 65, 0, 11, 24, 0, 211, 211, 233, 184, 186,
     12801    206, 160, 162, 180, 135, 137, 153, 112, 113, 127, 88, 89, 100, 61, 60, 70,
     12802    23, 18, 26, 217, 209, 207, 190, 184, 183, 165, 161, 160, 139, 136, 136, 115,
     12803    112, 113, 90, 88, 88, 62, 59, 60, 23, 17, 19, 221, 208, 183, 193, 183, 162,
     12804    167, 159, 142, 141, 134, 120, 116, 111, 99, 91, 87, 77, 62, 59, 51, 22, 17,
     12805    10, 224, 206, 158, 196, 181, 139, 170, 157, 122, 143, 133, 103, 118, 110,
     12806    84, 92, 86, 64, 63, 58, 40, 22, 16, 0, 227, 204, 133, 198, 179, 118, 172,
     12807    156, 102, 144, 132, 86, 119, 109, 70, 93, 85, 52, 64, 57, 30, 20, 16, 0,
     12808    230, 203, 106, 200, 178, 93, 173, 155, 81, 145, 130, 67, 120, 108, 53, 94,
     12809    84, 37, 64, 57, 17, 17, 16, 0, 232, 201, 73, 202, 177, 64, 175, 154, 55,
     12810    146, 129, 44, 121, 107, 33, 94, 83, 18, 64, 56, 0, 15, 16, 0, 233, 201, 38,
     12811    203, 176, 32, 175, 153, 27, 147, 129, 18, 121, 106, 6, 94, 83, 0, 64, 56, 0,
     12812    13, 16, 0, 210, 186, 216, 184, 163, 191, 160, 143, 167, 136, 120, 142, 112,
     12813    99, 118, 88, 77, 93, 61, 50, 64, 24, 6, 21, 215, 184, 192, 189, 162, 170,
     12814    164, 141, 149, 138, 119, 126, 115, 98, 104, 90, 76, 81, 62, 50, 54, 24, 6,
     12815    12, 219, 183, 171, 192, 161, 151, 166, 140, 132, 140, 118, 112, 116, 97, 92,
     12816    91, 75, 71, 63, 49, 46, 23, 6, 3, 222, 181, 148, 194, 159, 130, 168, 139,
     12817    114, 142, 117, 95, 117, 96, 78, 92, 74, 59, 63, 49, 36, 22, 6, 0, 224, 180,
     12818    125, 196, 158, 110, 170, 138, 96, 143, 116, 80, 118, 95, 64, 92, 74, 47, 64,
     12819    48, 25, 20, 6, 0, 226, 178, 100, 197, 157, 88, 171, 136, 76, 144, 115, 62,
     12820    119, 94, 49, 93, 73, 33, 64, 48, 13, 18, 6, 0, 228, 177, 71, 199, 156, 62,
     12821    172, 135, 52, 144, 114, 41, 119, 94, 30, 93, 72, 14, 64, 47, 0, 16, 6, 0,
     12822    229, 177, 40, 200, 155, 34, 173, 135, 27, 145, 113, 18, 120, 93, 5, 93, 72,
     12823    0, 63, 47, 0, 15, 6, 0, 210, 159, 199, 184, 140, 176, 160, 122, 154, 136,
     12824    102, 131, 113, 84, 108, 89, 64, 85, 62, 39, 57, 25, 0, 14, 214, 158, 177,
     12825    188, 139, 157, 163, 121, 137, 138, 102, 116, 114, 83, 96, 90, 63, 74, 63,
     12826    38, 48, 25, 0, 5, 217, 157, 158, 190, 138, 139, 165, 120, 122, 139, 101,
     12827    103, 115, 82, 84, 91, 62, 64, 63, 38, 40, 23, 0, 0, 219, 156, 137, 192, 137,
     12828    120, 167, 119, 105, 140, 100, 88, 116, 82, 71, 91, 62, 53, 63, 38, 30, 22,
     12829    0, 0, 221, 155, 116, 193, 136, 102, 168, 118, 89, 141, 99, 73, 117, 81, 59,
     12830    92, 61, 42, 63, 38, 21, 20, 0, 0, 223, 153, 94, 195, 135, 82, 169, 117, 70,
     12831    142, 98, 57, 117, 80, 44, 92, 61, 29, 63, 37, 8, 18, 0, 0, 224, 153, 68,
     12832    196, 134, 58, 170, 116, 49, 143, 97, 38, 118, 80, 26, 92, 60, 11, 63, 37, 0,
     12833    17, 0, 0, 225, 152, 41, 197, 133, 34, 170, 116, 27, 143, 97, 17, 118, 79, 4,
     12834    92, 60, 0, 63, 37, 0, 16, 0, 0, 209, 134, 183, 183, 118, 162, 160, 102, 142,
     12835    136, 85, 120, 113, 69, 100, 89, 50, 77, 62, 26, 51, 23, 0, 6, 213, 133, 163,
     12836    187, 117, 144, 163, 102, 126, 137, 85, 107, 114, 68, 88, 90, 50, 67, 63, 26,
     12837    43, 22, 0, 1, 215, 133, 146, 188, 116, 129, 164, 101, 112, 139, 84, 94, 115,
     12838    68, 77, 91, 50, 58, 63, 27, 34, 20, 0, 0, 217, 132, 127, 190, 116, 111, 165,
     12839    100, 97, 139, 84, 81, 116, 67, 65, 91, 49, 48, 63, 27, 25, 19, 0, 0, 219,
     12840    131, 108, 191, 115, 95, 166, 100, 82, 140, 83, 68, 116, 67, 53, 91, 49, 37,
     12841    63, 27, 17, 17, 0, 0, 220, 130, 88, 192, 114, 76, 167, 99, 65, 141, 82, 53,
     12842    116, 66, 40, 91, 49, 24, 63, 27, 5, 16, 0, 0, 221, 129, 64, 193, 113, 55,
     12843    168, 98, 46, 141, 82, 35, 117, 66, 23, 91, 49, 7, 63, 27, 0, 14, 0, 0, 222,
     12844    129, 41, 194, 113, 34, 168, 98, 26, 141, 81, 16, 117, 66, 3, 92, 48, 0, 62,
     12845    27, 0, 13, 0, 0, 209, 108, 168, 183, 94, 148, 160, 81, 130, 135, 66, 110,
     12846    113, 51, 91, 89, 35, 70, 63, 8, 45, 18, 0, 1, 212, 107, 150, 186, 94, 132,
     12847    162, 81, 116, 137, 66, 97, 114, 52, 80, 90, 35, 60, 63, 9, 37, 16, 0, 0,
     12848    214, 107, 134, 187, 93, 118, 163, 80, 103, 138, 66, 86, 114, 51, 70, 90, 35,
     12849    52, 63, 10, 29, 15, 0, 0, 215, 106, 117, 188, 93, 103, 164, 80, 89, 138, 66,
     12850    74, 115, 51, 59, 90, 35, 42, 63, 11, 21, 13, 0, 0, 216, 106, 100, 189, 92,
     12851    88, 164, 79, 75, 139, 65, 62, 115, 51, 48, 91, 35, 32, 63, 12, 12, 12, 0, 0,
     12852    217, 105, 82, 190, 92, 71, 165, 79, 60, 139, 65, 48, 115, 51, 35, 91, 35,
     12853    20, 62, 13, 3, 11, 0, 0, 218, 105, 61, 191, 92, 52, 166, 79, 43, 140, 65,
     12854    32, 116, 51, 20, 91, 35, 3, 62, 14, 0, 10, 0, 0, 219, 104, 41, 192, 91, 34,
     12855    166, 78, 26, 140, 65, 15, 116, 51, 2, 91, 35, 0, 62, 14, 0, 10, 0, 0, 208,
     12856    76, 153, 183, 65, 135, 159, 54, 118, 135, 42, 99, 113, 29, 82, 89, 10, 62,
     12857    62, 0, 38, 10, 0, 0, 211, 76, 137, 185, 65, 121, 161, 55, 105, 136, 43, 88,
     12858    114, 30, 72, 90, 12, 54, 63, 0, 31, 9, 0, 0, 212, 76, 122, 186, 66, 108,
     12859    162, 55, 94, 137, 43, 78, 114, 30, 63, 90, 13, 45, 62, 0, 24, 9, 0, 0, 213,
     12860    76, 107, 187, 66, 94, 162, 55, 81, 137, 43, 67, 114, 31, 52, 90, 15, 36, 62,
     12861    0, 16, 8, 0, 0, 214, 76, 92, 188, 66, 80, 163, 55, 69, 138, 44, 56, 114, 31,
     12862    42, 90, 16, 27, 62, 0, 8, 8, 0, 0, 215, 76, 76, 188, 66, 65, 164, 55, 55,
     12863    138, 44, 43, 114, 32, 31, 90, 16, 16, 62, 0, 1, 7, 0, 0, 216, 76, 57, 189,
     12864    66, 49, 164, 56, 40, 138, 44, 29, 115, 32, 16, 90, 17, 1, 61, 0, 0, 7, 0, 0,
     12865    217, 76, 40, 190, 66, 33, 164, 56, 25, 138, 44, 14, 114, 33, 1, 90, 18, 0,
     12866    61, 0, 0, 7, 0, 0, 207, 26, 139, 182, 16, 122, 159, 3, 106, 135, 0, 89, 113,
     12867    0, 73, 89, 0, 55, 62, 0, 32, 4, 0, 0, 210, 27, 124, 184, 18, 109, 160, 7,
     12868    95, 136, 0, 79, 113, 0, 64, 90, 0, 47, 62, 0, 25, 4, 0, 0, 211, 30, 111,
     12869    185, 21, 98, 161, 11, 84, 136, 0, 70, 113, 0, 55, 90, 0, 39, 62, 0, 18, 4,
     12870    0, 0, 212, 32, 98, 185, 24, 85, 161, 15, 73, 136, 2, 60, 113, 0, 46, 90, 0,
     12871    30, 61, 0, 11, 4, 0, 0, 213, 34, 85, 186, 26, 73, 162, 17, 62, 137, 5, 50,
     12872    113, 0, 37, 89, 0, 22, 61, 0, 5, 4, 0, 0, 213, 35, 70, 187, 27, 60, 162, 19,
     12873    50, 137, 8, 39, 114, 0, 26, 89, 0, 11, 61, 0, 0, 4, 0, 0, 214, 35, 54, 187,
     12874    29, 45, 163, 21, 37, 137, 11, 26, 114, 0, 13, 89, 0, 0, 60, 0, 0, 4, 0, 0,
     12875    214, 35, 40, 188, 29, 32, 163, 22, 24, 137, 12, 13, 114, 0, 0, 89, 0, 0, 60,
     12876    0, 0, 4, 0, 0, 169, 226, 249, 148, 199, 219, 129, 173, 192, 108, 147, 163,
     12877    88, 122, 136, 68, 96, 108, 43, 66, 76, 4, 25, 33, 178, 224, 221, 156, 197,
     12878    195, 136, 172, 171, 114, 145, 145, 93, 121, 120, 71, 95, 95, 46, 65, 66, 4,
     12879    24, 25, 185, 222, 196, 162, 195, 173, 140, 170, 151, 117, 144, 128, 96, 119,
     12880    106, 74, 94, 83, 47, 65, 57, 4, 24, 18, 190, 220, 169, 166, 193, 149, 144,
     12881    168, 130, 120, 142, 110, 99, 118, 91, 76, 93, 70, 49, 64, 46, 3, 23, 8, 195,
     12882    218, 143, 170, 191, 126, 147, 167, 110, 123, 141, 93, 100, 117, 76, 77, 92,
     12883    58, 50, 63, 36, 3, 23, 0, 199, 216, 115, 173, 190, 101, 149, 165, 88, 125,
     12884    140, 74, 102, 116, 59, 78, 91, 43, 51, 63, 23, 0, 23, 0, 202, 215, 83, 176,
     12885    189, 72, 152, 164, 62, 126, 138, 51, 103, 115, 39, 79, 90, 25, 51, 62, 6, 0,
     12886    22, 0, 204, 214, 50, 178, 188, 43, 153, 163, 37, 127, 138, 28, 104, 114, 18,
     12887    80, 89, 3, 51, 62, 0, 0, 22, 0, 172, 200, 231, 152, 176, 204, 132, 154, 178,
     12888    111, 130, 152, 91, 108, 126, 70, 84, 100, 46, 57, 70, 9, 15, 27, 180, 198,
     12889    205, 158, 175, 182, 138, 153, 159, 116, 129, 135, 95, 107, 112, 73, 83, 88,
     12890    48, 56, 60, 8, 15, 20, 186, 197, 182, 163, 173, 161, 141, 151, 141, 119,
     12891    128, 119, 97, 106, 99, 75, 82, 77, 49, 55, 51, 8, 14, 11, 190, 195, 158,
     12892    166, 172, 139, 144, 150, 122, 121, 127, 103, 99, 105, 84, 77, 81, 65, 50,
     12893    55, 41, 8, 14, 2, 194, 193, 135, 169, 170, 119, 147, 148, 103, 123, 125, 87,
     12894    101, 104, 70, 78, 81, 53, 51, 54, 31, 5, 14, 0, 197, 192, 109, 172, 169, 96,
     12895    149, 147, 83, 124, 124, 69, 102, 103, 55, 79, 80, 39, 51, 54, 19, 2, 14, 0,
     12896    200, 191, 80, 174, 168, 69, 150, 146, 59, 126, 123, 48, 103, 102, 36, 79,
     12897    79, 22, 52, 53, 2, 0, 14, 0, 202, 190, 51, 176, 167, 43, 152, 145, 36, 127,
     12898    123, 27, 103, 101, 16, 80, 79, 1, 52, 53, 0, 0, 14, 0, 175, 176, 215, 154,
     12899    156, 190, 134, 136, 166, 113, 115, 141, 93, 94, 118, 72, 73, 93, 48, 47, 64,
     12900    12, 2, 22, 182, 175, 191, 160, 154, 169, 139, 135, 148, 117, 114, 126, 96,
     12901    94, 104, 75, 72, 81, 50, 47, 55, 12, 3, 14, 186, 174, 170, 163, 153, 151,
     12902    142, 134, 132, 119, 113, 111, 98, 93, 92, 76, 71, 71, 51, 46, 46, 11, 3, 5,
     12903    190, 172, 148, 166, 152, 130, 144, 132, 114, 121, 112, 96, 100, 92, 78, 77,
     12904    71, 59, 51, 46, 36, 9, 4, 0, 192, 171, 127, 169, 151, 111, 146, 131, 97,
     12905    123, 111, 81, 101, 91, 65, 78, 70, 48, 52, 45, 26, 6, 4, 0, 195, 170, 103,
     12906    171, 150, 90, 148, 130, 78, 124, 110, 64, 102, 90, 51, 79, 70, 35, 52, 45,
     12907    15, 3, 5, 0, 198, 169, 76, 173, 149, 66, 149, 129, 56, 125, 109, 45, 103,
     12908    89, 33, 79, 69, 18, 52, 45, 0, 1, 5, 0, 199, 168, 51, 174, 148, 43, 150,
     12909    129, 35, 126, 108, 26, 103, 89, 14, 80, 69, 0, 52, 45, 0, 0, 5, 0, 177, 151,
     12910    198, 156, 134, 175, 136, 117, 153, 115, 98, 130, 95, 80, 108, 74, 60, 85,
     12911    50, 36, 58, 11, 0, 15, 183, 150, 176, 161, 133, 156, 140, 116, 137, 118, 97,
     12912    116, 97, 79, 96, 76, 60, 74, 51, 36, 49, 11, 0, 6, 186, 150, 158, 163, 132,
     12913    139, 142, 115, 122, 120, 97, 103, 99, 79, 84, 77, 59, 64, 52, 36, 41, 9, 0,
     12914    1, 189, 148, 137, 166, 131, 121, 144, 114, 105, 121, 96, 88, 100, 78, 72,
     12915    78, 59, 54, 52, 36, 31, 7, 0, 0, 191, 147, 118, 168, 130, 103, 145, 113, 90,
     12916    122, 95, 75, 101, 77, 60, 78, 59, 43, 52, 35, 22, 5, 0, 0, 193, 147, 97,
     12917    169, 129, 84, 147, 112, 72, 123, 94, 59, 101, 77, 46, 79, 58, 31, 52, 35,
     12918    11, 4, 0, 0, 195, 146, 73, 171, 128, 62, 148, 111, 53, 124, 93, 41, 102, 76,
     12919    30, 79, 58, 15, 52, 35, 0, 3, 0, 0, 197, 145, 50, 172, 128, 42, 149, 111,
     12920    34, 125, 93, 24, 102, 76, 12, 79, 57, 0, 52, 35, 0, 2, 0, 0, 179, 128, 183,
     12921    157, 113, 162, 137, 98, 142, 116, 82, 120, 96, 66, 100, 75, 48, 78, 51, 24,
     12922    52, 5, 0, 8, 183, 128, 163, 161, 113, 144, 140, 98, 126, 119, 81, 107, 98,
     12923    65, 88, 76, 48, 68, 52, 24, 43, 6, 0, 1, 186, 127, 146, 163, 112, 129, 142,
     12924    97, 112, 120, 81, 95, 99, 65, 77, 77, 47, 58, 52, 24, 35, 4, 0, 0, 188, 126,
     12925    128, 165, 111, 112, 144, 96, 97, 121, 80, 81, 100, 65, 66, 78, 47, 48, 53,
     12926    24, 26, 3, 0, 0, 190, 126, 110, 167, 110, 96, 145, 96, 83, 122, 80, 69, 101,
     12927    64, 54, 78, 47, 38, 52, 25, 18, 2, 0, 0, 192, 125, 90, 168, 110, 79, 146,
     12928    95, 67, 123, 79, 54, 101, 64, 42, 79, 47, 26, 52, 25, 7, 2, 0, 0, 194, 124,
     12929    69, 170, 109, 59, 147, 95, 49, 123, 79, 38, 101, 63, 26, 79, 47, 11, 52, 25,
     12930    0, 1, 0, 0, 195, 124, 49, 171, 109, 40, 148, 94, 32, 124, 78, 22, 102, 63,
     12931    9, 79, 46, 0, 52, 25, 0, 1, 0, 0, 180, 104, 168, 158, 91, 148, 138, 78, 130,
     12932    117, 64, 110, 97, 49, 91, 76, 33, 70, 52, 7, 46, 2, 0, 1, 184, 103, 150,
     12933    162, 91, 133, 141, 78, 116, 119, 64, 98, 99, 50, 80, 77, 33, 61, 52, 8, 37,
     12934    2, 0, 0, 186, 103, 135, 163, 90, 119, 142, 78, 103, 120, 64, 87, 99, 50, 70,
     12935    78, 33, 52, 52, 10, 30, 1, 0, 0, 188, 103, 118, 165, 90, 103, 143, 77, 90,
     12936    121, 63, 75, 100, 49, 60, 78, 33, 43, 52, 11, 22, 1, 0, 0, 189, 102, 102,
     12937    166, 89, 89, 144, 77, 76, 121, 63, 63, 100, 49, 49, 78, 34, 33, 52, 12, 14,
     12938    0, 0, 0, 191, 102, 84, 167, 89, 73, 145, 77, 62, 122, 63, 50, 101, 49, 37,
     12939    78, 34, 22, 52, 13, 4, 0, 0, 0, 192, 101, 65, 168, 89, 55, 146, 76, 46, 123,
     12940    63, 35, 101, 49, 23, 78, 34, 7, 51, 13, 0, 0, 0, 0, 193, 101, 48, 169, 88,
     12941    39, 146, 76, 31, 123, 63, 20, 101, 49, 8, 78, 34, 0, 51, 14, 0, 0, 0, 0,
     12942    181, 75, 154, 159, 64, 136, 139, 54, 118, 118, 41, 100, 98, 28, 82, 77, 8,
     12943    63, 51, 0, 39, 0, 0, 0, 184, 75, 137, 162, 65, 121, 141, 54, 106, 119, 42,
     12944    89, 99, 29, 72, 77, 11, 54, 52, 0, 32, 0, 0, 0, 186, 75, 123, 163, 65, 109,
     12945    142, 54, 94, 120, 43, 79, 99, 30, 63, 78, 12, 46, 52, 0, 25, 0, 0, 0, 187,
     12946    76, 108, 164, 65, 95, 143, 55, 82, 121, 43, 68, 100, 31, 54, 78, 14, 37, 52,
     12947    0, 17, 0, 0, 0, 188, 76, 94, 165, 65, 82, 144, 55, 70, 121, 43, 57, 100, 31,
     12948    44, 78, 15, 28, 51, 0, 9, 0, 0, 0, 189, 75, 78, 166, 65, 68, 144, 55, 57,
     12949    121, 43, 45, 100, 31, 33, 78, 16, 18, 51, 0, 2, 0, 0, 0, 190, 75, 61, 167,
     12950    65, 52, 145, 55, 42, 122, 44, 31, 100, 32, 19, 78, 16, 4, 51, 0, 0, 0, 0, 0,
     12951    191, 75, 46, 168, 65, 37, 145, 55, 29, 122, 44, 18, 100, 32, 5, 78, 17, 0,
     12952    50, 0, 0, 0, 0, 0, 181, 35, 140, 160, 24, 123, 140, 12, 107, 118, 0, 90, 98,
     12953    0, 74, 77, 0, 56, 51, 0, 33, 0, 0, 0, 184, 34, 125, 162, 26, 110, 141, 15,
     12954    96, 120, 1, 80, 99, 0, 65, 78, 0, 48, 51, 0, 26, 0, 0, 0, 186, 36, 113, 163,
     12955    27, 99, 142, 18, 86, 120, 5, 71, 99, 0, 57, 78, 0, 40, 51, 0, 20, 0, 0, 0,
     12956    187, 38, 99, 164, 30, 87, 142, 21, 74, 120, 8, 61, 99, 0, 48, 78, 0, 32, 51,
     12957    0, 12, 0, 0, 0, 187, 39, 87, 164, 31, 75, 143, 22, 64, 120, 11, 51, 100, 0,
     12958    39, 78, 0, 24, 51, 0, 6, 0, 0, 0, 188, 40, 73, 165, 32, 62, 143, 24, 52,
     12959    121, 13, 40, 100, 0, 28, 78, 0, 14, 51, 0, 0, 0, 0, 0, 189, 40, 58, 166, 33,
     12960    48, 144, 25, 39, 121, 15, 28, 100, 1, 16, 78, 0, 2, 50, 0, 0, 0, 0, 0, 190,
     12961    40, 45, 166, 34, 36, 144, 26, 27, 121, 16, 17, 100, 3, 3, 77, 0, 0, 49, 0,
     12962    0, 0, 0, 0, 120, 213, 247, 106, 188, 217, 92, 164, 190, 76, 139, 162, 60,
     12963    115, 135, 43, 91, 107, 21, 62, 76, 0, 22, 34, 134, 211, 219, 118, 186, 193,
     12964    102, 162, 169, 84, 138, 144, 67, 114, 120, 49, 90, 95, 26, 62, 66, 0, 22,
     12965    26, 143, 209, 195, 125, 184, 172, 108, 161, 151, 90, 136, 128, 72, 113, 106,
     12966    53, 89, 83, 29, 61, 57, 0, 22, 19, 150, 207, 169, 131, 182, 149, 113, 159,
     12967    130, 94, 135, 110, 76, 112, 91, 56, 88, 71, 31, 60, 47, 0, 21, 9, 156, 205,
     12968    145, 136, 181, 127, 117, 158, 111, 97, 133, 94, 78, 111, 77, 58, 87, 59, 33,
     12969    60, 37, 0, 21, 0, 161, 204, 118, 141, 179, 104, 121, 156, 90, 100, 132, 75,
     12970    81, 110, 61, 60, 86, 45, 35, 59, 25, 0, 21, 0, 165, 203, 89, 144, 178, 77,
     12971    124, 155, 67, 102, 131, 55, 82, 109, 43, 62, 85, 29, 36, 59, 10, 0, 21, 0,
     12972    169, 202, 62, 147, 178, 53, 126, 155, 45, 104, 131, 36, 84, 108, 25, 62, 85,
     12973    11, 36, 58, 0, 0, 21, 0, 129, 189, 229, 114, 167, 202, 99, 146, 177, 83,
     12974    124, 151, 67, 102, 126, 49, 79, 99, 28, 53, 70, 0, 12, 28, 140, 188, 204,
     12975    124, 166, 180, 107, 145, 158, 89, 123, 134, 72, 101, 111, 54, 79, 88, 31,
     12976    53, 60, 0, 12, 21, 148, 186, 182, 130, 164, 161, 112, 144, 141, 93, 121,
     12977    119, 76, 100, 99, 56, 78, 77, 33, 52, 51, 0, 12, 13, 153, 184, 158, 134,
     12978    163, 140, 116, 142, 122, 97, 120, 103, 78, 99, 85, 59, 77, 65, 35, 52, 42,
     12979    0, 12, 3, 158, 183, 136, 138, 161, 120, 119, 141, 104, 99, 119, 87, 80, 98,
     12980    71, 60, 77, 54, 36, 51, 32, 0, 12, 0, 162, 182, 112, 142, 160, 98, 122, 140,
     12981    85, 102, 118, 70, 82, 97, 56, 62, 76, 41, 37, 51, 21, 0, 11, 0, 166, 181,
     12982    85, 145, 159, 74, 125, 139, 63, 103, 117, 51, 84, 97, 39, 63, 75, 25, 37,
     12983    51, 6, 0, 11, 0, 168, 180, 60, 147, 158, 51, 126, 138, 43, 105, 116, 34, 85,
     12984    96, 23, 64, 75, 8, 38, 50, 0, 0, 11, 0, 136, 167, 213, 120, 148, 188, 105,
     12985    129, 165, 88, 109, 140, 71, 90, 117, 54, 69, 92, 32, 44, 64, 0, 2, 23, 145,
     12986    166, 190, 128, 147, 168, 111, 128, 147, 93, 108, 125, 75, 89, 104, 57, 68,
     12987    81, 34, 44, 55, 0, 2, 15, 151, 165, 170, 133, 146, 150, 115, 127, 131, 96,
     12988    107, 111, 78, 88, 92, 59, 68, 71, 36, 43, 46, 0, 2, 6, 155, 163, 148, 136,
     12989    144, 131, 118, 126, 114, 99, 106, 96, 80, 87, 79, 61, 67, 60, 37, 43, 37, 0,
     12990    2, 0, 159, 162, 128, 140, 143, 112, 121, 125, 97, 101, 105, 82, 82, 87, 66,
     12991    62, 67, 49, 38, 43, 27, 0, 2, 0, 163, 161, 105, 142, 142, 92, 123, 124, 80,
     12992    103, 104, 66, 83, 86, 52, 63, 66, 37, 39, 43, 17, 0, 2, 0, 166, 160, 81,
     12993    145, 141, 70, 125, 123, 59, 104, 104, 48, 84, 85, 36, 64, 66, 21, 39, 42, 2,
     12994    0, 1, 0, 168, 160, 59, 147, 141, 50, 126, 122, 41, 105, 103, 32, 85, 85, 20,
     12995    64, 65, 6, 39, 42, 0, 0, 1, 0, 142, 144, 197, 125, 128, 174, 109, 111, 153,
     12996    92, 93, 130, 75, 76, 108, 57, 57, 85, 36, 33, 58, 0, 0, 16, 149, 143, 176,
     12997    131, 127, 156, 114, 110, 136, 96, 93, 116, 78, 75, 96, 60, 57, 74, 37, 33,
     12998    49, 0, 0, 7, 153, 142, 157, 135, 126, 139, 117, 110, 122, 98, 92, 103, 80,
     12999    75, 84, 61, 56, 65, 38, 33, 41, 0, 0, 1, 157, 142, 138, 138, 125, 121, 120,
     13000    109, 106, 100, 91, 89, 82, 74, 72, 62, 56, 54, 39, 33, 32, 0, 0, 0, 160,
     13001    141, 119, 140, 124, 105, 122, 108, 91, 102, 91, 76, 83, 74, 61, 63, 56, 44,
     13002    40, 33, 23, 0, 0, 0, 163, 140, 99, 143, 123, 86, 124, 107, 74, 103, 90, 61,
     13003    84, 73, 48, 64, 55, 32, 40, 33, 13, 0, 0, 0, 165, 139, 77, 145, 122, 66,
     13004    125, 107, 56, 104, 89, 44, 85, 73, 33, 65, 55, 18, 40, 33, 1, 0, 0, 0, 167,
     13005    139, 57, 146, 122, 48, 126, 106, 39, 105, 89, 29, 86, 72, 18, 65, 55, 3, 40,
     13006    33, 0, 0, 0, 0, 146, 123, 182, 129, 108, 161, 113, 94, 141, 95, 78, 120, 78,
     13007    62, 99, 60, 45, 78, 38, 21, 52, 0, 0, 9, 152, 122, 163, 134, 108, 144, 117,
     13008    94, 126, 98, 78, 107, 80, 62, 88, 61, 45, 68, 39, 22, 44, 0, 0, 1, 156, 122,
     13009    146, 137, 107, 129, 119, 93, 113, 100, 77, 95, 82, 62, 78, 63, 45, 59, 40,
     13010    22, 36, 0, 0, 0, 158, 121, 128, 139, 107, 113, 121, 92, 98, 101, 77, 82, 83,
     13011    62, 66, 64, 45, 49, 40, 23, 27, 0, 0, 0, 161, 120, 111, 141, 106, 97, 122,
     13012    92, 84, 103, 77, 70, 84, 62, 56, 64, 45, 40, 40, 23, 19, 0, 0, 0, 163, 120,
     13013    93, 143, 105, 81, 124, 91, 69, 104, 76, 56, 85, 61, 43, 65, 45, 28, 40, 24,
     13014    9, 0, 0, 0, 165, 119, 73, 145, 105, 62, 125, 91, 52, 105, 76, 41, 85, 61,
     13015    29, 65, 44, 15, 40, 24, 0, 0, 0, 0, 166, 119, 55, 146, 104, 46, 126, 90, 37,
     13016    105, 75, 27, 86, 61, 15, 65, 44, 0, 40, 24, 0, 0, 0, 0, 150, 100, 168, 132,
     13017    88, 148, 115, 75, 130, 97, 61, 110, 80, 47, 91, 62, 30, 71, 39, 7, 46, 0, 0,
     13018    2, 154, 100, 150, 136, 88, 133, 119, 75, 116, 100, 61, 98, 82, 47, 81, 63,
     13019    31, 62, 40, 9, 38, 0, 0, 0, 157, 100, 135, 138, 87, 119, 120, 75, 104, 101,
     13020    61, 87, 83, 48, 71, 64, 31, 53, 40, 10, 31, 0, 0, 0, 159, 99, 119, 140, 87,
     13021    104, 122, 75, 91, 102, 61, 75, 84, 48, 61, 64, 32, 44, 40, 11, 23, 0, 0, 0,
     13022    161, 99, 104, 141, 87, 90, 123, 74, 78, 103, 61, 64, 84, 48, 50, 65, 32, 35,
     13023    40, 12, 15, 0, 0, 0, 163, 99, 87, 143, 86, 75, 124, 74, 64, 104, 61, 52, 85,
     13024    47, 39, 65, 32, 24, 40, 13, 6, 0, 0, 0, 164, 98, 69, 144, 86, 58, 125, 74,
     13025    49, 104, 61, 38, 85, 47, 26, 65, 32, 11, 40, 13, 0, 0, 0, 0, 166, 98, 53,
     13026    145, 86, 44, 126, 74, 35, 105, 60, 25, 86, 47, 13, 65, 32, 0, 40, 14, 0, 0,
     13027    0, 0, 152, 75, 154, 134, 64, 136, 117, 53, 119, 99, 41, 101, 82, 27, 83, 63,
     13028    7, 64, 39, 0, 40, 0, 0, 0, 156, 74, 138, 138, 64, 122, 120, 53, 106, 101,
     13029    41, 90, 83, 28, 73, 64, 10, 55, 40, 0, 33, 0, 0, 0, 158, 74, 124, 139, 64,
     13030    110, 121, 54, 95, 102, 42, 80, 84, 29, 64, 65, 12, 47, 41, 0, 26, 0, 0, 0,
     13031    160, 75, 110, 140, 64, 96, 122, 54, 83, 103, 42, 69, 84, 30, 55, 65, 13, 39,
     13032    41, 0, 18, 0, 0, 0, 161, 75, 96, 142, 64, 83, 123, 54, 71, 103, 43, 58, 85,
     13033    30, 45, 65, 14, 30, 41, 0, 11, 0, 0, 0, 163, 75, 81, 143, 64, 70, 124, 54,
     13034    59, 104, 43, 47, 85, 31, 35, 65, 15, 20, 41, 0, 3, 0, 0, 0, 164, 74, 65,
     13035    144, 64, 55, 125, 54, 45, 104, 43, 34, 85, 31, 22, 66, 16, 7, 41, 0, 0, 0,
     13036    0, 0, 165, 74, 51, 145, 64, 42, 125, 54, 33, 105, 43, 22, 86, 32, 10, 65,
     13037    17, 0, 40, 0, 0, 0, 0, 0, 154, 41, 142, 136, 30, 124, 119, 19, 108, 101, 3,
     13038    91, 83, 0, 75, 64, 0, 57, 39, 0, 34, 0, 0, 0, 158, 40, 127, 139, 31, 112,
     13039    121, 21, 97, 102, 7, 81, 84, 0, 66, 65, 0, 49, 40, 0, 27, 0, 0, 0, 159, 41,
     13040    114, 140, 32, 100, 122, 23, 87, 103, 10, 72, 85, 0, 58, 65, 0, 42, 40, 0,
     13041    21, 0, 0, 0, 160, 43, 101, 141, 34, 88, 123, 25, 76, 103, 13, 62, 85, 0, 49,
     13042    65, 0, 33, 41, 0, 14, 0, 0, 0, 161, 44, 89, 142, 35, 77, 123, 26, 65, 103,
     13043    15, 53, 85, 1, 40, 65, 0, 25, 41, 0, 7, 0, 0, 0, 162, 44, 75, 143, 36, 64,
     13044    124, 28, 54, 104, 17, 42, 85, 3, 30, 65, 0, 16, 40, 0, 1, 0, 0, 0, 164, 45,
     13045    61, 144, 37, 51, 124, 29, 42, 104, 18, 31, 85, 4, 19, 65, 0, 4, 40, 0, 0, 0,
     13046    0, 0, 164, 45, 49, 144, 37, 40, 125, 29, 31, 105, 19, 20, 86, 6, 7, 65, 0,
     13047    0, 39, 0, 0, 0, 0, 0, 49, 202, 244, 45, 178, 215, 38, 156, 188, 28, 132,
     13048    160, 14, 110, 134, 0, 86, 107, 0, 59, 76, 0, 20, 34, 80, 200, 217, 70, 176,
     13049    192, 60, 154, 168, 47, 131, 143, 34, 109, 119, 16, 85, 94, 0, 58, 66, 0, 20,
     13050    27, 95, 198, 194, 84, 175, 171, 71, 153, 150, 57, 130, 127, 42, 108, 106,
     13051    25, 84, 83, 0, 58, 57, 0, 20, 19, 107, 196, 169, 93, 173, 149, 79, 151, 130,
     13052    64, 128, 110, 49, 106, 91, 32, 84, 71, 3, 57, 47, 0, 19, 10, 115, 195, 145,
     13053    100, 171, 128, 86, 150, 112, 69, 127, 94, 53, 105, 78, 36, 83, 59, 8, 57,
     13054    37, 0, 19, 1, 122, 193, 120, 107, 170, 106, 91, 149, 92, 74, 126, 77, 57,
     13055    104, 62, 39, 82, 46, 13, 56, 26, 0, 18, 0, 128, 192, 93, 112, 169, 81, 95,
     13056    148, 70, 77, 125, 58, 60, 104, 46, 42, 81, 31, 15, 56, 13, 0, 17, 0, 132,
     13057    191, 69, 115, 168, 60, 98, 147, 51, 79, 124, 41, 62, 103, 30, 43, 81, 17,
     13058    16, 56, 0, 0, 17, 0, 77, 180, 227, 69, 159, 200, 60, 139, 176, 48, 118, 150,
     13059    35, 97, 125, 20, 75, 99, 0, 50, 70, 0, 9, 29, 96, 178, 203, 85, 158, 179,
     13060    73, 138, 157, 59, 117, 133, 45, 96, 111, 29, 75, 87, 3, 50, 60, 0, 9, 21,
     13061    107, 177, 181, 94, 156, 160, 80, 137, 140, 65, 116, 119, 51, 96, 98, 34, 74,
     13062    77, 9, 49, 52, 0, 8, 14, 115, 175, 158, 101, 155, 140, 86, 135, 122, 71,
     13063    114, 103, 55, 95, 85, 38, 73, 65, 14, 49, 42, 0, 7, 4, 121, 174, 137, 106,
     13064    153, 120, 91, 134, 105, 74, 113, 88, 58, 94, 72, 41, 73, 54, 17, 49, 33, 0,
     13065    6, 0, 127, 173, 114, 111, 152, 100, 95, 133, 86, 78, 112, 72, 61, 93, 58,
     13066    43, 72, 42, 19, 48, 22, 0, 6, 0, 132, 172, 88, 115, 151, 77, 98, 132, 66,
     13067    80, 112, 54, 63, 92, 42, 45, 72, 28, 20, 48, 9, 0, 5, 0, 135, 171, 67, 118,
     13068    151, 57, 100, 131, 49, 82, 111, 39, 65, 92, 28, 46, 71, 13, 21, 48, 0, 0, 5,
     13069    0, 93, 159, 211, 83, 141, 187, 72, 123, 164, 59, 104, 140, 46, 85, 116, 31,
     13070    65, 92, 8, 41, 64, 0, 1, 23, 106, 158, 189, 94, 140, 167, 81, 122, 147, 67,
     13071    103, 124, 52, 85, 103, 36, 65, 81, 14, 41, 55, 0, 0, 15, 114, 157, 169, 100,
     13072    139, 150, 87, 121, 131, 71, 102, 111, 56, 84, 92, 40, 64, 71, 17, 41, 47, 0,
     13073    0, 7, 121, 156, 148, 106, 138, 131, 91, 120, 114, 75, 101, 96, 60, 83, 79,
     13074    43, 64, 60, 20, 40, 37, 0, 0, 1, 126, 155, 129, 110, 136, 113, 95, 119, 98,
     13075    78, 101, 82, 62, 83, 67, 45, 63, 50, 22, 40, 28, 0, 0, 0, 130, 154, 107,
     13076    114, 135, 94, 98, 118, 81, 81, 100, 67, 64, 82, 54, 46, 63, 38, 23, 40, 18,
     13077    0, 0, 0, 134, 153, 84, 117, 135, 73, 101, 117, 62, 83, 99, 51, 66, 81, 39,
     13078    48, 62, 24, 24, 40, 5, 0, 0, 0, 137, 152, 65, 119, 134, 55, 102, 117, 46,
     13079    84, 99, 36, 67, 81, 25, 48, 62, 11, 24, 40, 0, 0, 0, 0, 105, 138, 196, 93,
     13080    122, 173, 81, 106, 152, 67, 89, 129, 53, 72, 107, 38, 54, 84, 17, 30, 58, 0,
     13081    0, 17, 115, 137, 175, 101, 121, 155, 88, 106, 136, 73, 89, 115, 58, 72, 95,
     13082    42, 54, 74, 21, 31, 49, 0, 0, 8, 120, 136, 157, 106, 120, 139, 92, 105, 121,
     13083    76, 88, 103, 61, 71, 84, 44, 53, 65, 23, 31, 41, 0, 0, 1, 125, 135, 138,
     13084    110, 119, 122, 95, 104, 106, 79, 87, 89, 63, 71, 73, 46, 53, 55, 25, 31, 33,
     13085    0, 0, 0, 129, 134, 120, 113, 119, 105, 98, 103, 91, 81, 87, 76, 65, 71, 61,
     13086    48, 53, 45, 26, 31, 24, 0, 0, 0, 133, 134, 101, 116, 118, 88, 100, 103, 76,
     13087    83, 86, 62, 67, 70, 49, 49, 53, 34, 27, 31, 14, 0, 0, 0, 136, 133, 80, 119,
     13088    117, 69, 102, 102, 58, 85, 86, 47, 68, 70, 35, 50, 52, 20, 27, 31, 3, 0, 0,
     13089    0, 138, 133, 62, 121, 117, 52, 104, 102, 43, 86, 85, 33, 69, 69, 22, 50, 52,
     13090    7, 27, 31, 0, 0, 0, 0, 114, 118, 182, 100, 104, 161, 87, 90, 141, 73, 75,
     13091    120, 59, 59, 99, 43, 42, 78, 22, 20, 52, 0, 0, 10, 121, 117, 163, 106, 104,
     13092    144, 92, 90, 126, 77, 75, 107, 62, 59, 88, 46, 42, 68, 24, 21, 44, 0, 0, 2,
     13093    125, 117, 146, 110, 103, 129, 95, 89, 113, 79, 74, 95, 64, 59, 78, 47, 42,
     13094    59, 26, 21, 36, 0, 0, 0, 129, 116, 129, 113, 102, 113, 98, 89, 99, 82, 74,
     13095    83, 66, 59, 67, 49, 42, 50, 27, 22, 28, 0, 0, 0, 132, 116, 112, 116, 102,
     13096    98, 100, 88, 85, 83, 73, 71, 67, 59, 57, 50, 43, 41, 28, 22, 20, 0, 0, 0,
     13097    134, 115, 95, 118, 101, 82, 102, 88, 71, 85, 73, 58, 68, 59, 45, 51, 43, 30,
     13098    29, 22, 11, 0, 0, 0, 137, 115, 76, 120, 101, 65, 104, 87, 55, 86, 73, 44,
     13099    69, 58, 32, 51, 42, 18, 29, 22, 1, 0, 0, 0, 139, 114, 60, 122, 100, 50, 105,
     13100    87, 41, 87, 72, 31, 70, 58, 19, 51, 42, 4, 29, 22, 0, 0, 0, 0, 120, 97, 168,
     13101    106, 85, 149, 92, 73, 130, 77, 59, 110, 63, 45, 91, 47, 28, 71, 25, 6, 47,
     13102    0, 0, 3, 126, 97, 151, 111, 85, 133, 96, 73, 117, 80, 59, 98, 65, 46, 81,
     13103    48, 29, 62, 27, 7, 39, 0, 0, 0, 129, 97, 136, 113, 85, 120, 98, 73, 104, 82,
     13104    59, 88, 67, 46, 72, 50, 30, 54, 29, 8, 32, 0, 0, 0, 132, 96, 120, 116, 84,
     13105    105, 100, 72, 91, 84, 59, 76, 68, 46, 61, 51, 30, 45, 29, 9, 24, 0, 0, 0,
     13106    134, 96, 105, 117, 84, 92, 102, 72, 79, 85, 59, 65, 69, 46, 52, 51, 30, 36,
     13107    30, 10, 16, 0, 0, 0, 136, 96, 89, 119, 84, 77, 103, 72, 66, 86, 59, 53, 69,
     13108    46, 41, 52, 31, 26, 30, 11, 7, 0, 0, 0, 138, 95, 71, 121, 83, 61, 105, 72,
     13109    51, 87, 59, 40, 70, 46, 28, 52, 31, 14, 30, 11, 0, 0, 0, 0, 139, 95, 57,
     13110    122, 83, 47, 106, 71, 38, 88, 59, 28, 71, 46, 17, 52, 31, 2, 29, 12, 0, 0,
     13111    0, 0, 125, 74, 155, 110, 63, 137, 96, 52, 120, 81, 40, 101, 66, 27, 83, 49,
     13112    7, 64, 27, 0, 41, 0, 0, 0, 129, 73, 139, 114, 63, 123, 99, 53, 107, 83, 41,
     13113    90, 68, 28, 74, 51, 10, 56, 29, 0, 33, 0, 0, 0, 132, 74, 125, 116, 63, 110,
     13114    101, 53, 96, 84, 41, 80, 69, 29, 65, 51, 12, 48, 30, 0, 27, 0, 0, 0, 134,
     13115    74, 111, 118, 64, 97, 102, 53, 84, 85, 42, 70, 69, 29, 56, 52, 13, 40, 30,
     13116    0, 19, 0, 0, 0, 136, 74, 97, 119, 64, 85, 103, 53, 73, 86, 42, 60, 70, 30,
     13117    47, 52, 14, 31, 30, 0, 12, 0, 0, 0, 137, 74, 83, 121, 64, 71, 104, 54, 61,
     13118    87, 42, 49, 71, 30, 36, 53, 15, 22, 30, 0, 5, 0, 0, 0, 139, 74, 67, 122, 64,
     13119    57, 105, 54, 47, 88, 42, 36, 71, 31, 25, 53, 16, 9, 30, 0, 0, 0, 0, 0, 140,
     13120    73, 54, 123, 64, 45, 106, 54, 36, 88, 43, 26, 71, 31, 14, 53, 17, 1, 29, 0,
     13121    0, 0, 0, 0, 129, 44, 143, 114, 34, 126, 99, 24, 110, 84, 9, 92, 68, 0, 76,
     13122    51, 0, 58, 28, 0, 35, 0, 0, 0, 132, 44, 128, 117, 35, 113, 102, 25, 98, 85,
     13123    12, 82, 69, 0, 67, 52, 0, 50, 29, 0, 28, 0, 0, 0, 134, 45, 116, 118, 36,
     13124    102, 103, 27, 88, 86, 14, 73, 70, 0, 59, 52, 0, 43, 29, 0, 22, 0, 0, 0, 136,
     13125    46, 103, 119, 37, 90, 103, 28, 77, 87, 17, 64, 71, 1, 50, 53, 0, 35, 30, 0,
     13126    15, 0, 0, 0, 137, 47, 90, 120, 38, 78, 104, 29, 67, 87, 18, 54, 71, 3, 42,
     13127    53, 0, 27, 29, 0, 8, 0, 0, 0, 138, 47, 77, 121, 39, 66, 105, 30, 56, 88, 19,
     13128    44, 71, 5, 32, 53, 0, 18, 29, 0, 2, 0, 0, 0, 139, 48, 63, 122, 39, 53, 106,
     13129    31, 44, 88, 20, 33, 71, 7, 21, 53, 0, 6, 28, 0, 0, 0, 0, 0, 140, 48, 52,
     13130    123, 40, 42, 107, 31, 33, 89, 21, 23, 72, 8, 10, 53, 0, 0, 27, 0, 0, 0, 0,
     13131    0, 0, 192, 242, 0, 169, 213, 0, 148, 187, 0, 125, 159, 0, 104, 133, 0, 82,
     13132    106, 0, 56, 76, 0, 18, 34, 0, 189, 216, 0, 167, 190, 0, 147, 167, 0, 124,
     13133    142, 0, 103, 119, 0, 81, 94, 0, 55, 66, 0, 16, 27, 0, 188, 193, 0, 166, 170,
     13134    0, 145, 149, 0, 123, 127, 0, 102, 105, 0, 80, 83, 0, 55, 57, 0, 15, 20, 32,
     13135    186, 168, 27, 164, 149, 17, 144, 130, 0, 122, 110, 0, 101, 91, 0, 79, 71, 0,
     13136    55, 47, 0, 14, 11, 56, 184, 146, 47, 163, 129, 37, 142, 113, 23, 121, 95, 5,
     13137    100, 78, 0, 79, 60, 0, 54, 38, 0, 14, 2, 70, 183, 122, 60, 161, 107, 49,
     13138    141, 94, 35, 120, 79, 20, 100, 64, 0, 78, 48, 0, 54, 27, 0, 13, 0, 80, 182,
     13139    96, 69, 160, 84, 57, 140, 73, 43, 119, 61, 28, 99, 48, 6, 78, 34, 0, 53, 15,
     13140    0, 13, 0, 87, 181, 74, 75, 160, 65, 62, 140, 56, 47, 119, 46, 32, 98, 35,
     13141    12, 77, 21, 0, 53, 2, 0, 13, 0, 0, 171, 225, 0, 151, 199, 0, 132, 174, 0,
     13142    112, 149, 0, 92, 124, 0, 71, 98, 0, 47, 69, 0, 4, 29, 0, 169, 201, 0, 150,
     13143    178, 0, 131, 156, 0, 111, 133, 0, 92, 111, 0, 71, 87, 0, 47, 60, 0, 3, 22,
     13144    41, 168, 180, 36, 148, 159, 28, 130, 140, 15, 110, 118, 0, 91, 98, 0, 70,
     13145    77, 0, 46, 52, 0, 2, 14, 61, 166, 158, 53, 147, 139, 43, 129, 122, 31, 109,
     13146    103, 17, 90, 85, 0, 70, 66, 0, 46, 43, 0, 2, 5, 73, 165, 137, 64, 146, 121,
     13147    53, 128, 106, 40, 108, 89, 26, 89, 73, 6, 69, 55, 0, 46, 33, 0, 1, 0, 83,
     13148    164, 115, 72, 145, 101, 60, 127, 88, 46, 107, 73, 32, 89, 59, 14, 69, 43, 0,
     13149    46, 23, 0, 1, 0, 90, 163, 91, 78, 144, 80, 65, 126, 69, 51, 106, 57, 37, 88,
     13150    44, 19, 68, 30, 0, 45, 11, 0, 1, 0, 95, 163, 72, 82, 143, 62, 69, 125, 53,
     13151    54, 106, 43, 39, 88, 32, 22, 68, 18, 0, 45, 0, 0, 1, 0, 0, 152, 210, 0, 134,
     13152    186, 0, 117, 163, 0, 99, 139, 0, 81, 116, 0, 62, 92, 0, 38, 64, 0, 1, 24,
     13153    47, 151, 188, 42, 133, 167, 35, 117, 146, 24, 98, 124, 10, 81, 103, 0, 61,
     13154    81, 0, 38, 55, 0, 0, 16, 65, 150, 169, 57, 132, 149, 47, 116, 131, 36, 98,
     13155    111, 23, 80, 92, 4, 61, 71, 0, 38, 47, 0, 0, 7, 76, 148, 148, 67, 131, 131,
     13156    56, 115, 114, 44, 97, 96, 31, 79, 79, 14, 61, 61, 0, 38, 38, 0, 0, 1, 84,
     13157    147, 129, 74, 130, 114, 62, 114, 99, 49, 96, 83, 35, 79, 68, 19, 60, 50, 0,
     13158    37, 29, 0, 0, 0, 91, 146, 109, 80, 129, 95, 67, 113, 83, 53, 95, 69, 39, 78,
     13159    55, 23, 60, 39, 1, 37, 20, 0, 0, 0, 97, 146, 87, 84, 128, 76, 71, 112, 65,
     13160    57, 95, 53, 42, 78, 41, 26, 60, 26, 4, 37, 7, 0, 0, 0, 101, 145, 69, 88,
     13161    128, 59, 74, 112, 50, 59, 94, 40, 44, 77, 29, 27, 59, 15, 4, 37, 0, 0, 0, 0,
     13162    52, 132, 195, 47, 117, 172, 40, 102, 151, 30, 85, 129, 19, 69, 107, 2, 51,
     13163    84, 0, 28, 58, 0, 0, 18, 70, 131, 175, 61, 116, 155, 52, 101, 135, 41, 85,
     13164    115, 29, 68, 95, 13, 51, 74, 0, 28, 49, 0, 0, 9, 80, 130, 157, 70, 115, 139,
     13165    59, 100, 121, 47, 84, 103, 35, 68, 85, 19, 51, 65, 0, 28, 42, 0, 0, 1, 87,
     13166    130, 138, 76, 114, 122, 65, 100, 106, 52, 84, 89, 39, 68, 73, 24, 50, 55, 4,
     13167    28, 33, 0, 0, 0, 93, 129, 121, 81, 114, 106, 69, 99, 92, 56, 83, 77, 42, 67,
     13168    62, 27, 50, 46, 7, 29, 25, 0, 0, 0, 98, 128, 102, 86, 113, 89, 73, 98, 77,
     13169    59, 82, 64, 45, 67, 50, 29, 50, 35, 9, 29, 16, 0, 0, 0, 102, 127, 82, 89,
     13170    112, 71, 76, 98, 61, 61, 82, 49, 47, 66, 37, 31, 50, 23, 11, 29, 4, 0, 0, 0,
     13171    105, 127, 66, 92, 112, 56, 78, 97, 47, 63, 82, 37, 48, 66, 25, 32, 50, 11,
     13172    10, 29, 0, 0, 0, 0, 72, 114, 181, 63, 100, 160, 54, 87, 140, 44, 72, 119,
     13173    32, 57, 99, 18, 39, 78, 0, 18, 52, 0, 0, 11, 83, 113, 163, 73, 100, 144, 62,
     13174    86, 126, 50, 71, 107, 38, 57, 88, 24, 40, 68, 3, 19, 44, 0, 0, 3, 89, 113,
     13175    147, 78, 99, 129, 67, 86, 113, 55, 71, 95, 42, 57, 78, 27, 40, 60, 8, 19,
     13176    37, 0, 0, 0, 95, 112, 129, 83, 98, 114, 71, 85, 99, 58, 71, 83, 45, 56, 67,
     13177    30, 40, 50, 11, 20, 29, 0, 0, 0, 99, 111, 113, 86, 98, 99, 74, 85, 86, 60,
     13178    70, 72, 47, 56, 57, 31, 40, 41, 12, 20, 21, 0, 0, 0, 103, 111, 96, 90, 97,
     13179    84, 77, 84, 72, 63, 70, 59, 49, 56, 46, 33, 40, 31, 13, 21, 12, 0, 0, 0,
     13180    106, 110, 78, 93, 97, 67, 79, 84, 57, 64, 70, 46, 50, 56, 34, 34, 40, 19,
     13181    13, 21, 2, 0, 0, 0, 108, 110, 63, 95, 97, 53, 81, 84, 44, 66, 69, 34, 51,
     13182    56, 22, 35, 40, 7, 13, 21, 0, 0, 0, 0, 85, 94, 168, 74, 82, 149, 64, 70,
     13183    130, 53, 57, 110, 41, 43, 91, 27, 26, 71, 5, 5, 47, 0, 0, 4, 92, 94, 151,
     13184    81, 82, 134, 70, 70, 117, 57, 57, 99, 45, 44, 81, 30, 27, 62, 10, 7, 39, 0,
     13185    0, 0, 97, 94, 136, 85, 82, 120, 73, 70, 105, 60, 57, 88, 47, 44, 72, 32, 28,
     13186    54, 13, 8, 32, 0, 0, 0, 101, 94, 121, 88, 82, 106, 76, 70, 92, 62, 57, 77,
     13187    49, 44, 62, 34, 28, 45, 14, 9, 25, 0, 0, 0, 104, 93, 106, 91, 81, 93, 78,
     13188    70, 80, 64, 57, 66, 50, 44, 52, 35, 29, 37, 14, 10, 17, 0, 0, 0, 106, 93,
     13189    90, 93, 81, 78, 80, 69, 67, 66, 57, 55, 52, 44, 42, 36, 29, 27, 15, 11, 8,
     13190    0, 0, 0, 109, 92, 74, 96, 81, 63, 82, 69, 53, 67, 57, 42, 53, 44, 30, 36,
     13191    29, 16, 15, 11, 1, 0, 0, 0, 111, 92, 60, 97, 80, 50, 83, 69, 41, 68, 57, 31,
     13192    53, 44, 20, 37, 30, 5, 15, 11, 0, 0, 0, 0, 94, 73, 155, 82, 63, 137, 72, 52,
     13193    120, 59, 40, 102, 47, 26, 84, 32, 8, 65, 9, 0, 42, 0, 0, 0, 99, 73, 140, 87,
     13194    63, 124, 76, 52, 108, 62, 40, 91, 49, 27, 75, 34, 11, 57, 12, 0, 34, 0, 0,
     13195    0, 103, 73, 126, 90, 63, 111, 78, 53, 97, 64, 41, 81, 51, 28, 66, 35, 13,
     13196    49, 13, 0, 27, 0, 0, 0, 105, 73, 112, 92, 63, 98, 80, 53, 85, 66, 41, 71,
     13197    52, 29, 57, 36, 14, 41, 15, 0, 20, 0, 0, 0, 107, 73, 99, 94, 63, 86, 81, 53,
     13198    74, 67, 41, 61, 53, 29, 48, 37, 15, 32, 16, 0, 13, 0, 0, 0, 110, 73, 85, 96,
     13199    63, 73, 83, 53, 62, 68, 42, 50, 54, 30, 38, 38, 16, 23, 16, 1, 5, 0, 0, 0,
     13200    112, 73, 69, 98, 63, 59, 84, 53, 49, 69, 42, 38, 55, 30, 27, 38, 16, 12, 17,
     13201    1, 0, 0, 0, 0, 113, 73, 57, 99, 63, 47, 85, 53, 38, 70, 42, 28, 55, 30, 17,
     13202    38, 17, 3, 16, 2, 0, 0, 0, 0, 101, 47, 144, 88, 38, 127, 77, 27, 111, 64,
     13203    14, 94, 51, 0, 77, 35, 0, 59, 9, 0, 36, 0, 0, 0, 105, 47, 129, 92, 38, 114,
     13204    80, 28, 99, 66, 16, 83, 53, 0, 68, 37, 0, 51, 13, 0, 29, 0, 0, 0, 107, 48,
     13205    117, 94, 39, 103, 81, 29, 89, 67, 18, 74, 54, 2, 60, 38, 0, 44, 15, 0, 23,
     13206    0, 0, 0, 109, 49, 104, 95, 40, 91, 82, 31, 79, 68, 19, 65, 54, 5, 51, 39, 0,
     13207    36, 17, 0, 16, 0, 0, 0, 110, 50, 92, 97, 40, 80, 84, 31, 68, 69, 20, 56, 55,
     13208    7, 43, 39, 0, 28, 17, 0, 9, 0, 0, 0, 112, 50, 79, 98, 41, 68, 85, 32, 57,
     13209    70, 21, 46, 56, 8, 34, 40, 0, 20, 18, 0, 3, 0, 0, 0, 113, 50, 65, 100, 41,
     13210    55, 86, 33, 46, 71, 22, 35, 56, 10, 23, 40, 0, 8, 17, 0, 0, 0, 0, 0, 115,
     13211    50, 54, 101, 41, 44, 87, 33, 36, 71, 23, 25, 56, 11, 14, 40, 0, 1, 16, 0, 0,
     13212    0, 0, 0, 0, 182, 240, 0, 161, 212, 0, 141, 185, 0, 120, 158, 0, 99, 132, 0,
     13213    78, 106, 0, 53, 75, 0, 12, 35, 0, 180, 214, 0, 159, 189, 0, 140, 166, 0,
     13214    119, 141, 0, 99, 118, 0, 77, 94, 0, 53, 66, 0, 11, 28, 0, 179, 192, 0, 158,
     13215    169, 0, 138, 149, 0, 118, 126, 0, 98, 105, 0, 77, 83, 0, 52, 57, 0, 10, 21,
     13216    0, 177, 168, 0, 156, 149, 0, 137, 130, 0, 116, 110, 0, 97, 91, 0, 76, 71, 0,
     13217    52, 48, 0, 9, 12, 0, 175, 146, 0, 155, 129, 0, 136, 113, 0, 115, 96, 0, 96,
     13218    79, 0, 75, 60, 0, 51, 39, 0, 9, 3, 0, 174, 123, 0, 154, 109, 0, 135, 95, 0,
     13219    115, 80, 0, 95, 65, 0, 75, 49, 0, 51, 28, 0, 8, 0, 0, 173, 98, 0, 153, 87,
     13220    0, 134, 76, 0, 114, 63, 0, 95, 50, 0, 74, 35, 0, 51, 17, 0, 8, 0, 0, 172,
     13221    78, 0, 152, 70, 0, 134, 60, 0, 114, 49, 0, 94, 38, 0, 74, 24, 0, 51, 5, 0,
     13222    8, 0, 0, 163, 224, 0, 144, 198, 0, 126, 173, 0, 107, 148, 0, 88, 123, 0, 68,
     13223    98, 0, 44, 69, 0, 1, 29, 0, 162, 200, 0, 143, 177, 0, 125, 155, 0, 106, 132,
     13224    0, 88, 110, 0, 68, 87, 0, 44, 60, 0, 1, 22, 0, 160, 180, 0, 142, 159, 0,
     13225    124, 139, 0, 105, 118, 0, 87, 98, 0, 67, 77, 0, 44, 52, 0, 0, 15, 0, 159,
     13226    158, 0, 140, 139, 0, 123, 122, 0, 104, 103, 0, 86, 85, 0, 67, 66, 0, 43, 43,
     13227    0, 0, 5, 0, 157, 138, 0, 139, 121, 0, 122, 106, 0, 103, 89, 0, 85, 73, 0,
     13228    66, 56, 0, 43, 34, 0, 0, 0, 0, 156, 116, 0, 138, 102, 0, 121, 89, 0, 103,
     13229    75, 0, 85, 60, 0, 66, 44, 0, 43, 24, 0, 0, 0, 6, 155, 94, 2, 137, 82, 0,
     13230    120, 71, 0, 102, 59, 0, 84, 46, 0, 65, 32, 0, 43, 13, 0, 0, 0, 30, 155, 75,
     13231    23, 137, 66, 11, 120, 57, 0, 102, 46, 0, 84, 35, 0, 65, 20, 0, 43, 2, 0, 0,
     13232    0, 0, 145, 209, 0, 129, 185, 0, 112, 162, 0, 95, 138, 0, 77, 115, 0, 59, 91,
     13233    0, 35, 64, 0, 1, 24, 0, 144, 188, 0, 128, 166, 0, 112, 145, 0, 94, 124, 0,
     13234    77, 103, 0, 58, 81, 0, 35, 55, 0, 0, 16, 0, 143, 168, 0, 127, 149, 0, 111,
     13235    130, 0, 93, 111, 0, 77, 92, 0, 58, 71, 0, 35, 47, 0, 0, 8, 0, 142, 148, 0,
     13236    126, 131, 0, 110, 114, 0, 93, 97, 0, 76, 79, 0, 58, 61, 0, 35, 38, 0, 0, 1,
     13237    0, 141, 130, 0, 125, 114, 0, 109, 100, 0, 92, 84, 0, 75, 68, 0, 58, 51, 0,
     13238    35, 30, 0, 0, 0, 27, 140, 110, 22, 124, 97, 12, 108, 84, 0, 91, 70, 0, 75,
     13239    56, 0, 57, 40, 0, 35, 21, 0, 0, 0, 43, 139, 89, 36, 123, 78, 26, 108, 67,
     13240    12, 91, 55, 0, 74, 43, 0, 57, 28, 0, 35, 9, 0, 0, 0, 51, 139, 72, 43, 123,
     13241    63, 33, 107, 53, 20, 90, 43, 3, 74, 31, 0, 57, 18, 0, 35, 1, 0, 0, 0, 0,
     13242    127, 194, 0, 112, 172, 0, 98, 151, 0, 81, 128, 0, 66, 107, 0, 48, 84, 0, 26,
     13243    58, 0, 0, 18, 0, 126, 174, 0, 111, 154, 0, 97, 135, 0, 81, 115, 0, 65, 95,
     13244    0, 48, 74, 0, 26, 50, 0, 0, 9, 0, 125, 157, 0, 111, 139, 0, 96, 121, 0, 81,
     13245    103, 0, 65, 85, 0, 48, 65, 0, 27, 42, 0, 0, 2, 20, 125, 139, 17, 110, 122,
     13246    9, 96, 107, 0, 80, 90, 0, 65, 73, 0, 48, 56, 0, 27, 34, 0, 0, 0, 39, 124,
     13247    122, 33, 109, 107, 25, 95, 93, 13, 80, 78, 0, 65, 63, 0, 48, 46, 0, 27, 26,
     13248    0, 0, 0, 51, 123, 103, 43, 108, 90, 34, 94, 78, 23, 79, 65, 8, 64, 51, 0,
     13249    48, 36, 0, 27, 17, 0, 0, 0, 59, 122, 84, 51, 108, 73, 41, 94, 63, 29, 79,
     13250    51, 15, 64, 39, 0, 47, 24, 0, 27, 6, 0, 0, 0, 64, 122, 69, 55, 107, 59, 45,
     13251    94, 50, 32, 78, 39, 19, 64, 28, 0, 47, 14, 0, 27, 0, 0, 0, 0, 0, 110, 181,
     13252    0, 97, 160, 0, 83, 140, 0, 69, 119, 0, 54, 99, 0, 37, 78, 0, 16, 53, 0, 0,
     13253    12, 7, 109, 163, 8, 96, 144, 3, 83, 126, 0, 69, 107, 0, 54, 88, 0, 38, 68,
     13254    0, 17, 45, 0, 0, 3, 34, 109, 147, 30, 96, 129, 23, 83, 113, 13, 69, 95, 0,
     13255    54, 78, 0, 38, 60, 0, 18, 37, 0, 0, 0, 48, 108, 130, 41, 95, 114, 33, 82,
     13256    99, 23, 68, 84, 10, 54, 68, 0, 38, 51, 0, 18, 29, 0, 0, 0, 56, 108, 114, 49,
     13257    94, 100, 40, 82, 87, 29, 68, 72, 16, 54, 58, 0, 38, 42, 0, 18, 22, 0, 0, 0,
     13258    63, 107, 97, 55, 94, 85, 45, 81, 73, 34, 68, 60, 21, 54, 47, 5, 38, 32, 0,
     13259    18, 13, 0, 0, 0, 68, 106, 80, 59, 93, 69, 49, 81, 59, 37, 67, 47, 25, 54,
     13260    35, 9, 38, 21, 0, 18, 4, 0, 0, 0, 72, 106, 66, 63, 93, 56, 52, 81, 47, 40,
     13261    67, 36, 27, 53, 25, 11, 38, 11, 0, 18, 0, 0, 0, 0, 28, 92, 168, 24, 80, 149,
     13262    19, 68, 130, 11, 55, 111, 0, 41, 92, 0, 25, 71, 0, 6, 47, 0, 0, 5, 46, 92,
     13263    151, 40, 80, 134, 33, 68, 117, 24, 55, 99, 12, 42, 81, 0, 26, 63, 0, 7, 40,
     13264    0, 0, 0, 55, 91, 137, 48, 80, 121, 40, 68, 105, 30, 55, 89, 18, 42, 72, 2,
     13265    27, 55, 0, 8, 32, 0, 0, 0, 62, 91, 121, 54, 79, 107, 45, 68, 93, 34, 55, 77,
     13266    23, 42, 62, 7, 27, 46, 0, 8, 25, 0, 0, 0, 67, 91, 107, 58, 79, 93, 49, 68,
     13267    81, 38, 55, 67, 26, 42, 53, 12, 27, 37, 0, 8, 18, 0, 0, 0, 72, 90, 91, 62,
     13268    79, 79, 52, 67, 68, 41, 55, 56, 29, 42, 43, 15, 28, 28, 1, 9, 9, 0, 0, 0,
     13269    76, 90, 75, 66, 78, 65, 56, 67, 55, 43, 55, 44, 31, 42, 32, 17, 28, 18, 2,
     13270    9, 2, 0, 0, 0, 78, 90, 62, 68, 78, 52, 58, 67, 43, 45, 55, 33, 32, 42, 22,
     13271    19, 28, 7, 2, 9, 0, 0, 0, 0, 53, 72, 156, 46, 62, 138, 39, 51, 121, 30, 39,
     13272    102, 20, 25, 84, 2, 9, 65, 0, 0, 42, 0, 0, 0, 62, 72, 140, 55, 62, 124, 46,
     13273    52, 108, 36, 40, 91, 25, 27, 75, 9, 11, 57, 0, 0, 34, 0, 0, 0, 68, 72, 127,
     13274    59, 62, 112, 50, 52, 97, 39, 40, 82, 28, 27, 66, 13, 12, 49, 0, 0, 28, 0, 0,
     13275    0, 72, 73, 113, 63, 62, 99, 53, 52, 86, 42, 40, 71, 30, 28, 57, 17, 13, 41,
     13276    0, 0, 21, 0, 0, 0, 76, 72, 100, 66, 62, 87, 56, 52, 75, 44, 41, 62, 32, 29,
     13277    48, 19, 14, 33, 3, 0, 13, 0, 0, 0, 79, 72, 86, 69, 62, 74, 58, 52, 63, 46,
     13278    41, 51, 34, 29, 39, 21, 15, 24, 4, 1, 6, 0, 0, 0, 81, 72, 71, 71, 62, 61,
     13279    60, 52, 51, 48, 41, 40, 35, 29, 28, 22, 15, 13, 5, 1, 0, 0, 0, 0, 83, 72,
     13280    59, 73, 62, 49, 62, 52, 41, 49, 41, 31, 36, 30, 20, 22, 16, 5, 4, 2, 0, 0,
     13281    0, 0, 67, 49, 144, 59, 40, 128, 50, 30, 112, 40, 18, 95, 29, 2, 78, 13, 0,
     13282    60, 0, 0, 37, 0, 0, 0, 73, 50, 130, 64, 40, 115, 55, 31, 100, 44, 19, 84,
     13283    32, 4, 69, 18, 0, 52, 0, 0, 30, 0, 0, 0, 76, 50, 118, 67, 41, 104, 57, 32,
     13284    90, 46, 20, 75, 34, 7, 61, 20, 0, 45, 0, 0, 24, 0, 0, 0, 79, 51, 105, 69,
     13285    42, 92, 59, 33, 80, 47, 21, 66, 35, 9, 52, 22, 0, 37, 1, 0, 16, 0, 0, 0, 81,
     13286    52, 93, 71, 42, 81, 61, 33, 70, 49, 22, 57, 36, 11, 44, 23, 0, 29, 2, 0, 9,
     13287    0, 0, 0, 83, 52, 80, 73, 43, 69, 62, 34, 59, 50, 23, 47, 37, 12, 35, 23, 0,
     13288    21, 3, 0, 3, 0, 0, 0, 85, 52, 67, 75, 43, 57, 64, 34, 47, 51, 24, 36, 38,
     13289    13, 25, 24, 0, 10, 3, 0, 0, 0, 0, 0, 87, 52, 56, 76, 43, 46, 65, 34, 37, 52,
     13290    24, 27, 39, 14, 16, 24, 0, 2, 2, 0, 0, 0, 0, 0, 0, 174, 238, 0, 154, 210, 0,
     13291    135, 184, 0, 115, 157, 0, 95, 132, 0, 75, 105, 0, 50, 75, 0, 6, 35, 0, 172,
     13292    213, 0, 153, 188, 0, 134, 165, 0, 114, 141, 0, 94, 118, 0, 74, 93, 0, 50,
     13293    66, 0, 5, 28, 0, 171, 191, 0, 151, 169, 0, 133, 148, 0, 113, 126, 0, 94,
     13294    105, 0, 73, 83, 0, 50, 57, 0, 5, 21, 0, 169, 168, 0, 150, 148, 0, 131, 130,
     13295    0, 112, 110, 0, 93, 92, 0, 73, 71, 0, 49, 48, 0, 5, 13, 0, 167, 146, 0, 148,
     13296    130, 0, 130, 113, 0, 111, 96, 0, 92, 79, 0, 72, 61, 0, 49, 39, 0, 4, 3, 0,
     13297    166, 124, 0, 147, 110, 0, 129, 96, 0, 110, 81, 0, 92, 66, 0, 72, 49, 0, 49,
     13298    29, 0, 4, 0, 0, 165, 100, 0, 146, 89, 0, 129, 78, 0, 110, 65, 0, 91, 52, 0,
     13299    72, 37, 0, 49, 18, 0, 4, 0, 0, 164, 82, 0, 146, 73, 0, 128, 64, 0, 109, 52,
     13300    0, 91, 41, 0, 72, 26, 0, 49, 8, 0, 4, 0, 0, 157, 223, 0, 138, 197, 0, 121,
     13301    172, 0, 102, 147, 0, 84, 123, 0, 65, 98, 0, 41, 69, 0, 1, 30, 0, 155, 199,
     13302    0, 137, 176, 0, 120, 155, 0, 102, 132, 0, 84, 110, 0, 65, 87, 0, 41, 60, 0,
     13303    1, 22, 0, 154, 179, 0, 136, 158, 0, 119, 139, 0, 101, 118, 0, 83, 98, 0, 64,
     13304    77, 0, 41, 52, 0, 0, 15, 0, 152, 158, 0, 135, 139, 0, 118, 122, 0, 100, 103,
     13305    0, 83, 85, 0, 64, 66, 0, 41, 43, 0, 0, 6, 0, 151, 138, 0, 133, 122, 0, 117,
     13306    106, 0, 99, 90, 0, 82, 74, 0, 64, 56, 0, 41, 35, 0, 0, 0, 0, 150, 117, 0,
     13307    133, 103, 0, 116, 90, 0, 99, 76, 0, 82, 61, 0, 63, 45, 0, 41, 25, 0, 0, 0,
     13308    0, 149, 95, 0, 132, 84, 0, 116, 73, 0, 98, 61, 0, 81, 48, 0, 63, 33, 0, 41,
     13309    15, 0, 0, 0, 0, 148, 78, 0, 131, 69, 0, 115, 59, 0, 98, 49, 0, 81, 37, 0,
     13310    63, 23, 0, 40, 4, 0, 0, 0, 0, 140, 208, 0, 124, 184, 0, 108, 161, 0, 91,
     13311    137, 0, 74, 115, 0, 56, 91, 0, 33, 64, 0, 1, 24, 0, 139, 187, 0, 123, 165,
     13312    0, 107, 145, 0, 90, 123, 0, 74, 102, 0, 56, 80, 0, 33, 55, 0, 0, 17, 0, 138,
     13313    168, 0, 122, 149, 0, 106, 130, 0, 90, 110, 0, 73, 91, 0, 56, 71, 0, 33, 47,
     13314    0, 0, 8, 0, 136, 148, 0, 121, 131, 0, 105, 115, 0, 89, 97, 0, 73, 80, 0, 55,
     13315    61, 0, 33, 39, 0, 0, 1, 0, 135, 130, 0, 120, 115, 0, 105, 100, 0, 88, 84, 0,
     13316    72, 69, 0, 55, 52, 0, 33, 30, 0, 0, 0, 0, 135, 111, 0, 119, 98, 0, 104, 85,
     13317    0, 88, 71, 0, 72, 57, 0, 55, 41, 0, 33, 22, 0, 0, 0, 0, 134, 91, 0, 118, 80,
     13318    0, 103, 69, 0, 87, 57, 0, 72, 44, 0, 54, 30, 0, 33, 11, 0, 0, 0, 0, 133, 75,
     13319    0, 118, 65, 0, 103, 56, 0, 87, 45, 0, 71, 34, 0, 54, 20, 0, 33, 2, 0, 0, 0,
     13320    0, 123, 194, 0, 108, 171, 0, 94, 150, 0, 78, 128, 0, 63, 106, 0, 46, 84, 0,
     13321    24, 58, 0, 0, 19, 0, 122, 174, 0, 107, 154, 0, 93, 135, 0, 78, 114, 0, 63,
     13322    95, 0, 46, 74, 0, 25, 50, 0, 0, 10, 0, 121, 157, 0, 107, 139, 0, 93, 121, 0,
     13323    78, 103, 0, 63, 85, 0, 46, 65, 0, 25, 42, 0, 0, 2, 0, 120, 139, 0, 106, 122,
     13324    0, 92, 107, 0, 77, 90, 0, 62, 74, 0, 46, 56, 0, 25, 34, 0, 0, 0, 0, 119,
     13325    122, 0, 105, 107, 0, 91, 93, 0, 77, 78, 0, 62, 63, 0, 45, 47, 0, 25, 26, 0,
     13326    0, 0, 0, 119, 104, 0, 104, 91, 0, 91, 79, 0, 76, 66, 0, 62, 52, 0, 45, 37,
     13327    0, 25, 18, 0, 0, 0, 0, 118, 86, 0, 104, 75, 0, 90, 64, 0, 76, 52, 0, 61, 40,
     13328    0, 45, 26, 0, 25, 7, 0, 0, 0, 0, 118, 71, 0, 104, 61, 0, 90, 52, 0, 75, 42,
     13329    0, 61, 30, 0, 45, 17, 0, 24, 1, 0, 0, 0, 0, 107, 181, 0, 94, 160, 0, 81,
     13330    140, 0, 66, 119, 0, 52, 99, 0, 35, 78, 0, 15, 53, 0, 0, 13, 0, 106, 163, 0,
     13331    93, 144, 0, 80, 126, 0, 66, 107, 0, 52, 88, 0, 36, 68, 0, 15, 45, 0, 0, 4,
     13332    0, 106, 147, 0, 93, 130, 0, 80, 113, 0, 66, 96, 0, 52, 79, 0, 36, 60, 0, 16,
     13333    37, 0, 0, 0, 0, 105, 130, 0, 92, 115, 0, 79, 100, 0, 66, 84, 0, 52, 68, 0,
     13334    36, 51, 0, 16, 30, 0, 0, 0, 0, 104, 115, 0, 91, 101, 0, 79, 87, 0, 65, 73,
     13335    0, 52, 59, 0, 36, 43, 0, 16, 22, 0, 0, 0, 0, 104, 98, 0, 91, 86, 0, 79, 74,
     13336    0, 65, 61, 0, 52, 48, 0, 36, 33, 0, 16, 14, 0, 0, 0, 0, 103, 81, 0, 90, 70,
     13337    0, 78, 60, 0, 65, 49, 0, 52, 37, 0, 36, 22, 0, 16, 5, 0, 0, 0, 0, 103, 68,
     13338    0, 90, 58, 0, 78, 49, 0, 65, 38, 0, 51, 27, 0, 36, 13, 0, 16, 0, 0, 0, 0, 0,
     13339    90, 168, 0, 78, 149, 0, 67, 130, 0, 54, 111, 0, 40, 92, 0, 24, 72, 0, 6, 47,
     13340    0, 0, 6, 0, 90, 152, 0, 78, 134, 0, 67, 117, 0, 54, 99, 0, 40, 82, 0, 25,
     13341    63, 0, 6, 40, 0, 0, 0, 0, 89, 137, 0, 78, 121, 0, 66, 106, 0, 54, 89, 0, 41,
     13342    73, 0, 26, 55, 0, 7, 33, 0, 0, 0, 0, 89, 122, 0, 77, 107, 0, 66, 93, 0, 54,
     13343    78, 0, 41, 63, 0, 26, 46, 0, 7, 25, 0, 0, 0, 0, 89, 108, 0, 77, 94, 0, 66,
     13344    81, 0, 53, 68, 0, 41, 54, 0, 26, 38, 0, 8, 18, 0, 0, 0, 7, 88, 92, 4, 77,
     13345    80, 0, 66, 69, 0, 53, 57, 0, 41, 44, 0, 27, 29, 0, 8, 10, 0, 0, 0, 23, 88,
     13346    77, 19, 76, 66, 11, 65, 56, 0, 53, 45, 0, 41, 33, 0, 27, 19, 0, 8, 3, 0, 0,
     13347    0, 30, 88, 64, 26, 76, 54, 18, 65, 45, 4, 53, 35, 0, 41, 24, 0, 27, 9, 0, 8,
     13348    0, 0, 0, 0, 0, 72, 156, 0, 62, 138, 0, 51, 121, 0, 39, 103, 0, 26, 85, 0, 9,
     13349    66, 0, 0, 42, 0, 0, 0, 0, 72, 141, 0, 62, 125, 0, 51, 109, 0, 39, 92, 0, 27,
     13350    75, 0, 11, 57, 0, 0, 35, 0, 0, 0, 0, 72, 128, 0, 62, 113, 0, 51, 98, 0, 40,
     13351    82, 0, 27, 67, 0, 12, 50, 0, 1, 28, 0, 0, 0, 17, 72, 114, 13, 62, 100, 6,
     13352    51, 87, 0, 40, 72, 0, 28, 58, 0, 13, 42, 0, 1, 21, 0, 0, 0, 28, 72, 101, 23,
     13353    61, 88, 16, 51, 76, 4, 40, 62, 0, 28, 49, 0, 14, 34, 0, 1, 14, 0, 0, 0, 36,
     13354    72, 87, 30, 61, 75, 23, 51, 64, 12, 40, 52, 1, 28, 40, 0, 14, 25, 0, 1, 7,
     13355    0, 0, 0, 41, 71, 72, 35, 61, 62, 28, 51, 52, 17, 40, 41, 5, 28, 29, 0, 14,
     13356    15, 0, 0, 0, 0, 0, 0, 45, 71, 60, 39, 61, 51, 31, 51, 42, 20, 40, 32, 8, 29,
     13357    21, 0, 15, 6, 0, 0, 0, 0, 0, 0, 0, 51, 145, 0, 42, 129, 0, 33, 113, 0, 20,
     13358    96, 0, 5, 79, 0, 0, 60, 0, 0, 37, 0, 0, 0, 24, 52, 131, 21, 42, 116, 15, 33,
     13359    101, 5, 21, 85, 0, 7, 69, 0, 0, 52, 0, 1, 30, 0, 0, 0, 34, 52, 119, 29, 43,
     13360    105, 22, 33, 91, 12, 22, 76, 0, 8, 61, 0, 0, 45, 0, 1, 24, 0, 0, 0, 40, 53,
     13361    106, 34, 43, 93, 27, 34, 80, 17, 23, 67, 5, 9, 53, 0, 0, 37, 0, 0, 16, 0, 0,
     13362    0, 45, 53, 94, 38, 44, 82, 31, 34, 70, 20, 24, 58, 10, 11, 45, 0, 0, 29, 0,
     13363    0, 9, 0, 0, 0, 48, 53, 81, 42, 44, 70, 34, 35, 60, 24, 24, 48, 13, 12, 36,
     13364    0, 0, 21, 0, 0, 3, 0, 0, 0, 51, 53, 68, 45, 44, 58, 37, 35, 48, 26, 25, 37,
     13365    15, 13, 26, 2, 1, 11, 0, 0, 0, 0, 0, 0, 54, 54, 57, 47, 44, 47, 39, 35, 39,
     13366    28, 25, 29, 17, 13, 17, 4, 1, 3, 0, 0, 0, 0, 0, 0]);
     13367
     13368  function convertToRgb(src, srcOffset, srcScale, dest, destOffset) {
     13369    // using lut as in spline interpolation (see function.js)
     13370    var cubeVertices = 16; // 1 << number of colors
     13371    var cubeN = new Float32Array(cubeVertices);
     13372    var cubeVertex = new Uint32Array(cubeVertices);
     13373    for (var j = 0; j < cubeVertices; j++)
     13374      cubeN[j] = 1;
     13375
     13376    var k = 3, pos = 1;
     13377    var lutDomain = 7, lutStep = 8;
     13378    for (var i = 3; i >= 0; i--) {
     13379      var e = src[srcOffset + i] * srcScale * lutDomain;
     13380
     13381      var e0 = e < lutDomain ? Math.floor(e) : e - 1; // e1 = e0 + 1;
     13382      var n0 = e0 + 1 - e; // (e1 - e) / (e1 - e0);
     13383      var n1 = e - e0; // (e - e0) / (e1 - e0);
     13384      var offset0 = e0 * k;
     13385      var offset1 = offset0 + k; // e1 * k
     13386      for (var j = 0; j < cubeVertices; j++) {
     13387        if (j & pos) {
     13388          cubeN[j] *= n1;
     13389          cubeVertex[j] += offset1;
     13390        } else {
     13391          cubeN[j] *= n0;
     13392          cubeVertex[j] += offset0;
     13393        }
     13394      }
     13395
     13396      k *= lutStep;
     13397      pos <<= 1;
     13398    }
     13399    var y0 = 0, y1 = 0, y2 = 0;
     13400    for (var i = 0; i < cubeVertices; i++)
     13401      y0 += lut[cubeVertex[i]] * cubeN[i];
     13402    for (var i = 0; i < cubeVertices; i++)
     13403      y1 += lut[cubeVertex[i] + 1] * cubeN[i];
     13404    for (var i = 0; i < cubeVertices; i++)
     13405      y2 += lut[cubeVertex[i] + 2] * cubeN[i];
     13406    dest[destOffset] = y0 > 255 ? 255 : y0;
     13407    dest[destOffset + 1] = y1 > 255 ? 255 : y1;
     13408    dest[destOffset + 2] = y2 > 255 ? 255 : y2;
     13409  }
     13410
    1230413411  function DeviceCmykCS() {
    1230513412    this.name = 'DeviceCMYK';
    1230613413    this.numComps = 4;
    12307     this.defaultColor = [0, 0, 0, 1];
     13414    this.defaultColor = new Float32Array([0, 0, 0, 1]);
    1230813415  }
    1230913416  DeviceCmykCS.prototype = {
    12310     getRgb: function DeviceCmykCS_getRgb(color) {
    12311       var c = color[0], m = color[1], y = color[2], k = color[3];
    12312 
    12313       // CMYK -> CMY: http://www.easyrgb.com/index.php?X=MATH&H=14#text14
    12314       c = (c * (1 - k) + k);
    12315       m = (m * (1 - k) + k);
    12316       y = (y * (1 - k) + k);
    12317 
    12318       // CMY -> RGB: http://www.easyrgb.com/index.php?X=MATH&H=12#text12
    12319       var r = (1 - c);
    12320       var g = (1 - m);
    12321       var b = (1 - y);
    12322 
    12323       return [r, g, b];
     13417    getRgb: function DeviceCmykCS_getRgb(src, srcOffset) {
     13418      var rgb = new Uint8Array(3);
     13419      convertToRgb(src, srcOffset, 1, rgb, 0);
     13420      return rgb;
    1232413421    },
    12325     getRgbBuffer: function DeviceCmykCS_getRgbBuffer(colorBuf, bits) {
     13422    getRgbItem: function DeviceCmykCS_getRgbItem(src, srcOffset,
     13423                                                 dest, destOffset) {
     13424      convertToRgb(src, srcOffset, 1, dest, destOffset);
     13425    },
     13426    getRgbBuffer: function DeviceCmykCS_getRgbBuffer(src, srcOffset, count,
     13427                                                     dest, destOffset, bits) {
    1232613428      var scale = 1 / ((1 << bits) - 1);
    12327       var length = colorBuf.length / 4;
    12328       var rgbBuf = new Uint8Array(length * 3);
    12329       var rgbBufPos = 0;
    12330       var colorBufPos = 0;
    12331 
    12332       for (var i = 0; i < length; i++) {
    12333         var cmyk = [];
    12334         for (var j = 0; j < 4; ++j)
    12335           cmyk.push(scale * colorBuf[colorBufPos++]);
    12336 
    12337         var rgb = this.getRgb(cmyk);
    12338         for (var j = 0; j < 3; ++j)
    12339           rgbBuf[rgbBufPos++] = Math.round(rgb[j] * 255);
    12340       }
    12341 
    12342       return rgbBuf;
     13429      for (var i = 0; i < count; i++) {
     13430        convertToRgb(src, srcOffset, scale, dest, destOffset);
     13431        srcOffset += 4;
     13432        destOffset += 3;
     13433      }
    1234313434    },
     13435    getOutputLength: function DeviceCmykCS_getOutputLength(inputLength) {
     13436      return (inputLength >> 2) * 3;
     13437    },
     13438    isPassthrough: ColorSpace.prototype.isPassthrough,
     13439    createRgbBuffer: ColorSpace.prototype.createRgbBuffer,
    1234413440    isDefaultDecode: function DeviceCmykCS_isDefaultDecode(decodeMap) {
    1234513441      return ColorSpace.isDefaultDecode(decodeMap, this.numComps);
     
    1235713453    this.name = 'Lab';
    1235813454    this.numComps = 3;
    12359     this.defaultColor = [0, 0, 0];
     13455    this.defaultColor = new Float32Array([0, 0, 0]);
    1236013456
    1236113457    if (!whitePoint)
     
    1239813494
    1239913495  // Function g(x) from spec
    12400   function g(x) {
     13496  function fn_g(x) {
    1240113497    if (x >= 6 / 29)
    1240213498      return x * x * x;
     
    1240513501  }
    1240613502
     13503  function convertToRgb(cs, src, srcOffset, dest, destOffset) {
     13504    // Ls,as,bs <---> L*,a*,b* in the spec
     13505    var Ls = src[srcOffset];
     13506    var as = src[srcOffset + 1];
     13507    var bs = src[srcOffset + 2];
     13508
     13509    // Adjust limits of 'as' and 'bs'
     13510    as = as > cs.amax ? cs.amax : as < cs.amin ? cs.amin : as;
     13511    bs = bs > cs.bmax ? cs.bmax : bs < cs.bmin ? cs.bmin : bs;
     13512
     13513    // Computes intermediate variables X,Y,Z as per spec
     13514    var M = (Ls + 16) / 116;
     13515    var L = M + (as / 500);
     13516    var N = M - (bs / 200);
     13517
     13518    var X = cs.XW * fn_g(L);
     13519    var Y = cs.YW * fn_g(M);
     13520    var Z = cs.ZW * fn_g(N);
     13521
     13522    var r, g, b;
     13523    // Using different conversions for D50 and D65 white points,
     13524    // per http://www.color.org/srgb.pdf
     13525    if (cs.ZW < 1) {
     13526      // Assuming D50 (X=0.9642, Y=1.00, Z=0.8249)
     13527      r = X * 3.1339 + Y * -1.6170 + Z * -0.4906;
     13528      g = X * -0.9785 + Y * 1.9160 + Z * 0.0333;
     13529      b = X * 0.0720 + Y * -0.2290 + Z * 1.4057;
     13530    } else {
     13531      // Assuming D65 (X=0.9505, Y=1.00, Z=1.0888)
     13532      r = X * 3.2406 + Y * -1.5372 + Z * -0.4986;
     13533      g = X * -0.9689 + Y * 1.8758 + Z * 0.0415;
     13534      b = X * 0.0557 + Y * -0.2040 + Z * 1.0570;
     13535    }
     13536
     13537    // clamp color values to [0,255] range
     13538    dest[destOffset] = r < 0 ? 0 : r > 1 ? 255 : r * 255;
     13539    dest[destOffset + 1] = g < 0 ? 0 : g > 1 ? 255 : g * 255;
     13540    dest[destOffset + 2] = b < 0 ? 0 : b > 1 ? 255 : b * 255;
     13541  }
     13542
    1240713543  LabCS.prototype = {
    12408     getRgb: function LabCS_getRgb(color) {
    12409       // Ls,as,bs <---> L*,a*,b* in the spec
    12410       var Ls = color[0], as = color[1], bs = color[2];
    12411 
    12412       // Adjust limits of 'as' and 'bs'
    12413       as = as > this.amax ? this.amax : as;
    12414       as = as < this.amin ? this.amin : as;
    12415       bs = bs > this.bmax ? this.bmax : bs;
    12416       bs = bs < this.bmin ? this.bmin : bs;
    12417 
    12418       // Computes intermediate variables X,Y,Z as per spec
    12419       var M = (Ls + 16) / 116;
    12420       var L = M + (as / 500);
    12421       var N = M - (bs / 200);
    12422       var X = this.XW * g(L);
    12423       var Y = this.YW * g(M);
    12424       var Z = this.ZW * g(N);
    12425 
    12426       // XYZ to RGB 3x3 matrix, from:
    12427       // http://www.poynton.com/notes/colour_and_gamma/ColorFAQ.html#RTFToC18
    12428       var XYZtoRGB = [3.240479, -1.537150, -0.498535,
    12429                       -0.969256, 1.875992, 0.041556,
    12430                       0.055648, -0.204043, 1.057311];
    12431 
    12432       return Util.apply3dTransform(XYZtoRGB, [X, Y, Z]);
     13544    getRgb: function LabCS_getRgb(src, srcOffset) {
     13545      var rgb = new Uint8Array(3);
     13546      convertToRgb(this, src, srcOffset, rgb, 0);
     13547      return rgb;
    1243313548    },
    12434     getRgbBuffer: function LabCS_getRgbBuffer(input, bits) {
    12435       if (bits == 8)
    12436         return input;
    12437       var scale = 255 / ((1 << bits) - 1);
    12438       var i, length = input.length / 3;
    12439       var rgbBuf = new Uint8Array(length);
    12440 
    12441       var j = 0;
    12442       for (i = 0; i < length; ++i) {
    12443         // Convert L*, a*, s* into RGB
    12444         var rgb = this.getRgb([input[i], input[i + 1], input[i + 2]]);
    12445         rgbBuf[j++] = rgb[0];
    12446         rgbBuf[j++] = rgb[1];
    12447         rgbBuf[j++] = rgb[2];
    12448       }
    12449 
    12450       return rgbBuf;
     13549    getRgbItem: function LabCS_getRgbItem(src, srcOffset, dest, destOffset) {
     13550      convertToRgb(this, src, srcOffset, dest, destOffset);
    1245113551    },
     13552    getOutputLength: function LabCS_getOutputLength(inputLength) {
     13553      return inputLength;
     13554    },
     13555    isPassthrough: ColorSpace.prototype.isPassthrough,
    1245213556    isDefaultDecode: function LabCS_isDefaultDecode(decodeMap) {
    1245313557      // From Table 90 in Adobe's:
     
    1311314217
    1311414218var PartialEvaluator = (function PartialEvaluatorClosure() {
    13115   function PartialEvaluator(xref, handler, uniquePrefix) {
     14219  function PartialEvaluator(xref, handler, pageIndex, uniquePrefix) {
    1311614220    this.state = new EvalState();
    1311714221    this.stateStack = [];
     
    1311914223    this.xref = xref;
    1312014224    this.handler = handler;
     14225    this.pageIndex = pageIndex;
    1312114226    this.uniquePrefix = uniquePrefix;
    1312214227    this.objIdCounter = 0;
     
    1312414229  }
    1312514230
     14231  // Specifies properties for each command
     14232  //
     14233  // If variableArgs === true: [0, `numArgs`] expected
     14234  // If variableArgs === false: exactly `numArgs` expected
    1312614235  var OP_MAP = {
    13127     // Graphics state
    13128     w: 'setLineWidth',
    13129     J: 'setLineCap',
    13130     j: 'setLineJoin',
    13131     M: 'setMiterLimit',
    13132     d: 'setDash',
    13133     ri: 'setRenderingIntent',
    13134     i: 'setFlatness',
    13135     gs: 'setGState',
    13136     q: 'save',
    13137     Q: 'restore',
    13138     cm: 'transform',
     14236    // Graphic state
     14237    w: { fnName: 'setLineWidth', numArgs: 1, variableArgs: false },
     14238    J: { fnName: 'setLineCap', numArgs: 1, variableArgs: false },
     14239    j: { fnName: 'setLineJoin', numArgs: 1, variableArgs: false },
     14240    M: { fnName: 'setMiterLimit', numArgs: 1, variableArgs: false },
     14241    d: { fnName: 'setDash', numArgs: 2, variableArgs: false },
     14242    ri: { fnName: 'setRenderingIntent', numArgs: 1, variableArgs: false },
     14243    i: { fnName: 'setFlatness', numArgs: 1, variableArgs: false },
     14244    gs: { fnName: 'setGState', numArgs: 1, variableArgs: false },
     14245    q: { fnName: 'save', numArgs: 0, variableArgs: false },
     14246    Q: { fnName: 'restore', numArgs: 0, variableArgs: false },
     14247    cm: { fnName: 'transform', numArgs: 6, variableArgs: false },
    1313914248
    1314014249    // Path
    13141     m: 'moveTo',
    13142     l: 'lineTo',
    13143     c: 'curveTo',
    13144     v: 'curveTo2',
    13145     y: 'curveTo3',
    13146     h: 'closePath',
    13147     re: 'rectangle',
    13148     S: 'stroke',
    13149     s: 'closeStroke',
    13150     f: 'fill',
    13151     F: 'fill',
    13152     'f*': 'eoFill',
    13153     B: 'fillStroke',
    13154     'B*': 'eoFillStroke',
    13155     b: 'closeFillStroke',
    13156     'b*': 'closeEOFillStroke',
    13157     n: 'endPath',
     14250    m: { fnName: 'moveTo', numArgs: 2, variableArgs: false },
     14251    l: { fnName: 'lineTo', numArgs: 2, variableArgs: false },
     14252    c: { fnName: 'curveTo', numArgs: 6, variableArgs: false },
     14253    v: { fnName: 'curveTo2', numArgs: 4, variableArgs: false },
     14254    y: { fnName: 'curveTo3', numArgs: 4, variableArgs: false },
     14255    h: { fnName: 'closePath', numArgs: 0, variableArgs: false },
     14256    re: { fnName: 'rectangle', numArgs: 4, variableArgs: false },
     14257    S: { fnName: 'stroke', numArgs: 0, variableArgs: false },
     14258    s: { fnName: 'closeStroke', numArgs: 0, variableArgs: false },
     14259    f: { fnName: 'fill', numArgs: 0, variableArgs: false },
     14260    F: { fnName: 'fill', numArgs: 0, variableArgs: false },
     14261    'f*': { fnName: 'eoFill', numArgs: 0, variableArgs: false },
     14262    B: { fnName: 'fillStroke', numArgs: 0, variableArgs: false },
     14263    'B*': { fnName: 'eoFillStroke', numArgs: 0, variableArgs: false },
     14264    b: { fnName: 'closeFillStroke', numArgs: 0, variableArgs: false },
     14265    'b*': { fnName: 'closeEOFillStroke', numArgs: 0, variableArgs: false },
     14266    n: { fnName: 'endPath', numArgs: 0, variableArgs: false },
    1315814267
    1315914268    // Clipping
    13160     W: 'clip',
    13161     'W*': 'eoClip',
     14269    W: { fnName: 'clip', numArgs: 0, variableArgs: false },
     14270    'W*': { fnName: 'eoClip', numArgs: 0, variableArgs: false },
    1316214271
    1316314272    // Text
    13164     BT: 'beginText',
    13165     ET: 'endText',
    13166     Tc: 'setCharSpacing',
    13167     Tw: 'setWordSpacing',
    13168     Tz: 'setHScale',
    13169     TL: 'setLeading',
    13170     Tf: 'setFont',
    13171     Tr: 'setTextRenderingMode',
    13172     Ts: 'setTextRise',
    13173     Td: 'moveText',
    13174     TD: 'setLeadingMoveText',
    13175     Tm: 'setTextMatrix',
    13176     'T*': 'nextLine',
    13177     Tj: 'showText',
    13178     TJ: 'showSpacedText',
    13179     "'": 'nextLineShowText',
    13180     '"': 'nextLineSetSpacingShowText',
     14273    BT: { fnName: 'beginText', numArgs: 0, variableArgs: false },
     14274    ET: { fnName: 'endText', numArgs: 0, variableArgs: false },
     14275    Tc: { fnName: 'setCharSpacing', numArgs: 1, variableArgs: false },
     14276    Tw: { fnName: 'setWordSpacing', numArgs: 1, variableArgs: false },
     14277    Tz: { fnName: 'setHScale', numArgs: 1, variableArgs: false },
     14278    TL: { fnName: 'setLeading', numArgs: 1, variableArgs: false },
     14279    Tf: { fnName: 'setFont', numArgs: 2, variableArgs: false },
     14280    Tr: { fnName: 'setTextRenderingMode', numArgs: 1, variableArgs: false },
     14281    Ts: { fnName: 'setTextRise', numArgs: 1, variableArgs: false },
     14282    Td: { fnName: 'moveText', numArgs: 2, variableArgs: false },
     14283    TD: { fnName: 'setLeadingMoveText', numArgs: 2, variableArgs: false },
     14284    Tm: { fnName: 'setTextMatrix', numArgs: 6, variableArgs: false },
     14285    'T*': { fnName: 'nextLine', numArgs: 0, variableArgs: false },
     14286    Tj: { fnName: 'showText', numArgs: 1, variableArgs: false },
     14287    TJ: { fnName: 'showSpacedText', numArgs: 1, variableArgs: false },
     14288    '\'': { fnName: 'nextLineShowText', numArgs: 1, variableArgs: false },
     14289    '"': { fnName: 'nextLineSetSpacingShowText', numArgs: 3,
     14290      variableArgs: false },
    1318114291
    1318214292    // Type3 fonts
    13183     d0: 'setCharWidth',
    13184     d1: 'setCharWidthAndBounds',
     14293    d0: { fnName: 'setCharWidth', numArgs: 2, variableArgs: false },
     14294    d1: { fnName: 'setCharWidthAndBounds', numArgs: 6, variableArgs: false },
    1318514295
    1318614296    // Color
    13187     CS: 'setStrokeColorSpace',
    13188     cs: 'setFillColorSpace',
    13189     SC: 'setStrokeColor',
    13190     SCN: 'setStrokeColorN',
    13191     sc: 'setFillColor',
    13192     scn: 'setFillColorN',
    13193     G: 'setStrokeGray',
    13194     g: 'setFillGray',
    13195     RG: 'setStrokeRGBColor',
    13196     rg: 'setFillRGBColor',
    13197     K: 'setStrokeCMYKColor',
    13198     k: 'setFillCMYKColor',
     14297    CS: { fnName: 'setStrokeColorSpace', numArgs: 1, variableArgs: false },
     14298    cs: { fnName: 'setFillColorSpace', numArgs: 1, variableArgs: false },
     14299    SC: { fnName: 'setStrokeColor', numArgs: 4, variableArgs: true },
     14300    SCN: { fnName: 'setStrokeColorN', numArgs: 33, variableArgs: true },
     14301    sc: { fnName: 'setFillColor', numArgs: 4, variableArgs: true },
     14302    scn: { fnName: 'setFillColorN', numArgs: 33, variableArgs: true },
     14303    G: { fnName: 'setStrokeGray', numArgs: 1, variableArgs: false },
     14304    g: { fnName: 'setFillGray', numArgs: 1, variableArgs: false },
     14305    RG: { fnName: 'setStrokeRGBColor', numArgs: 3, variableArgs: false },
     14306    rg: { fnName: 'setFillRGBColor', numArgs: 3, variableArgs: false },
     14307    K: { fnName: 'setStrokeCMYKColor', numArgs: 4, variableArgs: false },
     14308    k: { fnName: 'setFillCMYKColor', numArgs: 4, variableArgs: false },
    1319914309
    1320014310    // Shading
    13201     sh: 'shadingFill',
     14311    sh: { fnName: 'shadingFill', numArgs: 1, variableArgs: false },
    1320214312
    1320314313    // Images
    13204     BI: 'beginInlineImage',
    13205     ID: 'beginImageData',
    13206     EI: 'endInlineImage',
     14314    BI: { fnName: 'beginInlineImage', numArgs: 0, variableArgs: false },
     14315    ID: { fnName: 'beginImageData', numArgs: 0, variableArgs: false },
     14316    EI: { fnName: 'endInlineImage', numArgs: 0, variableArgs: false },
    1320714317
    1320814318    // XObjects
    13209     Do: 'paintXObject',
    13210 
    13211     // Marked content
    13212     MP: 'markPoint',
    13213     DP: 'markPointProps',
    13214     BMC: 'beginMarkedContent',
    13215     BDC: 'beginMarkedContentProps',
    13216     EMC: 'endMarkedContent',
     14319    Do: { fnName: 'paintXObject', numArgs: 1, variableArgs: false },
     14320    MP: { fnName: 'markPoint', numArgs: 1, variableArgs: false },
     14321    DP: { fnName: 'markPointProps', numArgs: 2, variableArgs: false },
     14322    BMC: { fnName: 'beginMarkedContent', numArgs: 1, variableArgs: false },
     14323    BDC: { fnName: 'beginMarkedContentProps', numArgs: 2, variableArgs: false },
     14324    EMC: { fnName: 'endMarkedContent', numArgs: 0, variableArgs: false },
    1321714325
    1321814326    // Compatibility
    13219     BX: 'beginCompat',
    13220     EX: 'endCompat',
     14327    BX: { fnName: 'beginCompat', numArgs: 0, variableArgs: false },
     14328    EX: { fnName: 'endCompat', numArgs: 0, variableArgs: false },
    1322114329
    1322214330    // (reserved partial commands for the lexer)
     
    1324014348      assert(fontRes, 'fontRes not available');
    1324114349
     14350      ++this.fontIdCounter;
     14351
    1324214352      font = xref.fetchIfRef(font) || fontRes.get(fontName);
    13243       assertWellFormed(isDict(font));
    13244 
    13245       ++this.fontIdCounter;
     14353      if (!isDict(font)) {
     14354        return {
     14355          translated: new ErrorFont('Font ' + fontName + ' is not available'),
     14356          loadedName: 'g_font_' + this.uniquePrefix + this.fontIdCounter
     14357        };
     14358      }
     14359
    1324614360      var loadedName = font.loadedName;
    1324714361      if (!loadedName) {
    1324814362        // keep track of each font we translated so the caller can
    1324914363        // load them asynchronously before calling display on a page
    13250         loadedName = 'font_' + this.uniquePrefix + this.fontIdCounter;
     14364        loadedName = 'g_font_' + this.uniquePrefix + this.fontIdCounter;
    1325114365        font.loadedName = loadedName;
    1325214366
     
    1325614370                                          dependency);
    1325714371        } catch (e) {
    13258           translated = { error: e };
     14372          translated = new ErrorFont(e instanceof Error ? e.message : e);
    1325914373        }
    1326014374        font.translated = translated;
     
    1328614400      var xref = this.xref;
    1328714401      var handler = this.handler;
     14402      var pageIndex = this.pageIndex;
    1328814403      var uniquePrefix = this.uniquePrefix || '';
    1328914404
     
    1330414419        var loadedName = font.loadedName;
    1330514420        if (!font.sent) {
    13306           var data = font.translated;
    13307 
    13308           if (data instanceof Font)
    13309             data = data.exportData();
    13310 
    13311           handler.send('obj', [
     14421          var data = font.translated.exportData();
     14422
     14423          handler.send('commonobj', [
    1331214424              loadedName,
    1331314425              'Font',
     
    1335014462        }
    1335114463
     14464        var softMask = dict.get('SMask', 'SM') || false;
     14465        var mask = dict.get('Mask') || false;
     14466
     14467        var SMALL_IMAGE_DIMENSIONS = 200;
     14468        // Inlining small images into the queue as RGB data
     14469        if (inline && !softMask && !mask &&
     14470            !(image instanceof JpegStream) &&
     14471            (w + h) < SMALL_IMAGE_DIMENSIONS) {
     14472          var imageObj = new PDFImage(xref, resources, image,
     14473                                      inline, null, null);
     14474          var imgData = imageObj.getImageData();
     14475          fn = 'paintInlineImageXObject';
     14476          args = [imgData];
     14477          return;
     14478        }
     14479
    1335214480        // If there is no imageMask, create the PDFImage and a lot
    1335314481        // of image processing can be done here.
     
    1335614484        args = [objId, w, h];
    1335714485
    13358         var softMask = dict.get('SMask', 'SM') || false;
    13359         var mask = dict.get('Mask') || false;
    13360 
    1336114486        if (!softMask && !mask && image instanceof JpegStream &&
    1336214487            image.isNativelySupported(xref, resources)) {
    1336314488          // These JPEGs don't need any more processing so we can just send it.
    1336414489          fn = 'paintJpegXObject';
    13365           handler.send('obj', [objId, 'JpegStream', image.getIR()]);
     14490          handler.send('obj', [objId, pageIndex, 'JpegStream', image.getIR()]);
    1336614491          return;
    1336714492        }
     
    1337014495
    1337114496        PDFImage.buildImage(function(imageObj) {
    13372             var drawWidth = imageObj.drawWidth;
    13373             var drawHeight = imageObj.drawHeight;
    13374             var imgData = {
    13375               width: drawWidth,
    13376               height: drawHeight,
    13377               data: new Uint8Array(drawWidth * drawHeight * 4)
    13378             };
    13379             var pixels = imgData.data;
    13380             imageObj.fillRgbaBuffer(pixels, drawWidth, drawHeight);
    13381             handler.send('obj', [objId, 'Image', imgData]);
     14497            var imgData = imageObj.getImageData();
     14498            handler.send('obj', [objId, pageIndex, 'Image', imgData]);
    1338214499          }, handler, xref, resources, image, inline);
    1338314500      }
     
    1339914516      var xobjs = resources.get('XObject') || new Dict();
    1340014517      var patterns = resources.get('Pattern') || new Dict();
     14518      // TODO(mduan): pass array of knownCommands rather than OP_MAP
     14519      // dictionary
    1340114520      var parser = new Parser(new Lexer(stream, OP_MAP), false, xref);
    1340214521      var res = resources;
     
    1340614525      while (true) {
    1340714526        obj = parser.getObj();
    13408         if (isEOF(obj))
     14527        if (isEOF(obj)) {
    1340914528          break;
     14529        }
    1341014530
    1341114531        if (isCmd(obj)) {
    1341214532          var cmd = obj.cmd;
    13413           var fn = OP_MAP[cmd];
    13414           assertWellFormed(fn, 'Unknown command "' + cmd + '"');
     14533
     14534          // Check that the command is valid
     14535          var opSpec = OP_MAP[cmd];
     14536          if (!opSpec) {
     14537            warn('Unknown command "' + cmd + '"');
     14538            continue;
     14539          }
     14540
     14541          var fn = opSpec.fnName;
     14542
     14543          // Validate the number of arguments for the command
     14544          if (opSpec.variableArgs) {
     14545            if (args.length > opSpec.numArgs) {
     14546              info('Command ' + fn + ': expected [0,' + opSpec.numArgs +
     14547                  '] args, but received ' + args.length + ' args');
     14548            }
     14549          } else {
     14550            if (args.length < opSpec.numArgs) {
     14551              // If we receive too few args, it's not possible to possible
     14552              // to execute the command, so skip the command
     14553              info('Command ' + fn + ': because expected ' + opSpec.numArgs +
     14554                  ' args, but received ' + args.length + ' args; skipping');
     14555              args = [];
     14556              continue;
     14557            } else if (args.length > opSpec.numArgs) {
     14558              info('Command ' + fn + ': expected ' + opSpec.numArgs +
     14559                  ' args, but received ' + args.length + ' args');
     14560            }
     14561          }
     14562
    1341514563          // TODO figure out how to type-check vararg functions
    1341614564
     
    1359414742          args = [];
    1359514743        } else if (obj != null) {
     14744          args.push(obj instanceof Dict ? obj.getAll() : obj);
    1359614745          assertWellFormed(args.length <= 33, 'Too many arguments');
    13597           args.push(obj instanceof Dict ? obj.getAll() : obj);
    1359814746        }
    1359914747      }
     
    1360214750    },
    1360314751
    13604     getTextContent: function partialEvaluatorGetIRQueue(
     14752    optimizeQueue: function PartialEvaluator_optimizeQueue(queue) {
     14753      var fnArray = queue.fnArray, argsArray = queue.argsArray;
     14754      // grouping paintInlineImageXObject's into paintInlineImageXObjectGroup
     14755      // searching for (save, transform, paintInlineImageXObject, restore)+
     14756      var MIN_IMAGES_IN_INLINE_IMAGES_BLOCK = 10;
     14757      var MAX_IMAGES_IN_INLINE_IMAGES_BLOCK = 200;
     14758      var MAX_WIDTH = 1000;
     14759      var IMAGE_PADDING = 1;
     14760      for (var i = 0, ii = fnArray.length; i < ii; i++) {
     14761        if (fnArray[i] === 'paintInlineImageXObject' &&
     14762            fnArray[i - 2] === 'save' && fnArray[i - 1] === 'transform' &&
     14763            fnArray[i + 1] === 'restore') {
     14764          var j = i - 2;
     14765          for (i += 2; i < ii && fnArray[i - 4] === fnArray[i]; i++) {
     14766          }
     14767          var count = Math.min((i - j) >> 2,
     14768                               MAX_IMAGES_IN_INLINE_IMAGES_BLOCK);
     14769          if (count < MIN_IMAGES_IN_INLINE_IMAGES_BLOCK) {
     14770            continue;
     14771          }
     14772          // assuming that heights of those image is too small (~1 pixel)
     14773          // packing as much as possible by lines
     14774          var maxX = 0;
     14775          var map = [], maxLineHeight = 0;
     14776          var currentX = IMAGE_PADDING, currentY = IMAGE_PADDING;
     14777          for (var q = 0; q < count; q++) {
     14778            var transform = argsArray[j + (q << 2) + 1];
     14779            var img = argsArray[j + (q << 2) + 2][0];
     14780            if (currentX + img.width > MAX_WIDTH) {
     14781              // starting new line
     14782              maxX = Math.max(maxX, currentX);
     14783              currentY += maxLineHeight + 2 * IMAGE_PADDING;
     14784              currentX = 0;
     14785              maxLineHeight = 0;
     14786            }
     14787            map.push({
     14788              transform: transform,
     14789              x: currentX, y: currentY,
     14790              w: img.width, h: img.height
     14791            });
     14792            currentX += img.width + 2 * IMAGE_PADDING;
     14793            maxLineHeight = Math.max(maxLineHeight, img.height);
     14794          }
     14795          var imgWidth = Math.max(maxX, currentX) + IMAGE_PADDING;
     14796          var imgHeight = currentY + maxLineHeight + IMAGE_PADDING;
     14797          var imgData = new Uint8Array(imgWidth * imgHeight * 4);
     14798          var imgRowSize = imgWidth << 2;
     14799          for (var q = 0; q < count; q++) {
     14800            var data = argsArray[j + (q << 2) + 2][0].data;
     14801            // copy image by lines and extends pixels into padding
     14802            var rowSize = map[q].w << 2;
     14803            var dataOffset = 0;
     14804            var offset = (map[q].x + map[q].y * imgWidth) << 2;
     14805            imgData.set(
     14806              data.subarray(0, rowSize), offset - imgRowSize);
     14807            for (var k = 0, kk = map[q].h; k < kk; k++) {
     14808              imgData.set(
     14809                data.subarray(dataOffset, dataOffset + rowSize), offset);
     14810              dataOffset += rowSize;
     14811              offset += imgRowSize;
     14812            }
     14813            imgData.set(
     14814              data.subarray(dataOffset - rowSize, dataOffset), offset);
     14815            while (offset >= 0) {
     14816              data[offset - 4] = data[offset];
     14817              data[offset - 3] = data[offset + 1];
     14818              data[offset - 2] = data[offset + 2];
     14819              data[offset - 1] = data[offset + 3];
     14820              data[offset + rowSize] = data[offset + rowSize - 4];
     14821              data[offset + rowSize + 1] = data[offset + rowSize - 3];
     14822              data[offset + rowSize + 2] = data[offset + rowSize - 2];
     14823              data[offset + rowSize + 3] = data[offset + rowSize - 1];
     14824              offset -= imgRowSize;
     14825            }
     14826          }
     14827          // replacing queue items
     14828          fnArray.splice(j, count * 4, ['paintInlineImageXObjectGroup']);
     14829          argsArray.splice(j, count * 4,
     14830            [{width: imgWidth, height: imgHeight, data: imgData}, map]);
     14831          i = j;
     14832          ii = fnArray.length;
     14833        }
     14834      }
     14835      // grouping paintImageMaskXObject's into paintImageMaskXObjectGroup
     14836      // searching for (save, transform, paintImageMaskXObject, restore)+
     14837      var MIN_IMAGES_IN_MASKS_BLOCK = 10;
     14838      var MAX_IMAGES_IN_MASKS_BLOCK = 100;
     14839      for (var i = 0, ii = fnArray.length; i < ii; i++) {
     14840        if (fnArray[i] === 'paintImageMaskXObject' &&
     14841            fnArray[i - 2] === 'save' && fnArray[i - 1] === 'transform' &&
     14842            fnArray[i + 1] === 'restore') {
     14843          var j = i - 2;
     14844          for (i += 2; i < ii && fnArray[i - 4] === fnArray[i]; i++) {
     14845          }
     14846          var count = Math.min((i - j) >> 2,
     14847                               MAX_IMAGES_IN_MASKS_BLOCK);
     14848          if (count < MIN_IMAGES_IN_MASKS_BLOCK) {
     14849            continue;
     14850          }
     14851          var images = [];
     14852          for (var q = 0; q < count; q++) {
     14853            var transform = argsArray[j + (q << 2) + 1];
     14854            var maskParams = argsArray[j + (q << 2) + 2];
     14855            images.push({data: maskParams[0], width: maskParams[2],
     14856              height: maskParams[3], transform: transform,
     14857              inverseDecode: maskParams[1]});
     14858          }
     14859          // replacing queue items
     14860          fnArray.splice(j, count * 4, ['paintImageMaskXObjectGroup']);
     14861          argsArray.splice(j, count * 4, [images]);
     14862          i = j;
     14863          ii = fnArray.length;
     14864        }
     14865      }
     14866    },
     14867
     14868    getTextContent: function PartialEvaluator_getTextContent(
    1360514869                                                    stream, resources, state) {
    1360614870      var bidiTexts;
    13607       var kSpaceFactor = 0.35;
    13608       var kMultipleSpaceFactor = 1.5;
     14871      var SPACE_FACTOR = 0.35;
     14872      var MULTI_SPACE_FACTOR = 1.5;
    1360914873
    1361014874      if (!state) {
     
    1364914913                } else if (items[j] < 0 && font.spaceWidth > 0) {
    1365014914                  var fakeSpaces = -items[j] / font.spaceWidth;
    13651                   if (fakeSpaces > kMultipleSpaceFactor) {
     14915                  if (fakeSpaces > MULTI_SPACE_FACTOR) {
    1365214916                    fakeSpaces = Math.round(fakeSpaces);
    1365314917                    while (fakeSpaces--) {
    1365414918                      chunk += ' ';
    1365514919                    }
    13656                   } else if (fakeSpaces > kSpaceFactor) {
     14920                  } else if (fakeSpaces > SPACE_FACTOR) {
    1365714921                    chunk += ' ';
    1365814922                  }
     
    1375915023          };
    1376015024        }
     15025
     15026        var cidEncoding = baseDict.get('Encoding');
     15027        if (isName(cidEncoding))
     15028          properties.cidEncoding = cidEncoding.name;
    1376115029
    1376215030        var cidToGidMap = dict.get('CIDToGIDMap');
     
    1402015288    },
    1402115289
     15290    isSerifFont: function PartialEvaluator_isSerifFont(baseFontName) {
     15291
     15292      // Simulating descriptor flags attribute
     15293      var fontNameWoStyle = baseFontName.split('-')[0];
     15294      return (fontNameWoStyle in serifFonts) ||
     15295          (fontNameWoStyle.search(/serif/gi) !== -1);
     15296    },
     15297
    1402215298    getBaseFontMetrics: function PartialEvaluator_getBaseFontMetrics(name) {
    1402315299      var defaultWidth = 0, widths = [], monospace = false;
    14024       var glyphWidths = Metrics[stdFontMap[name] || name];
     15300
     15301      var lookupName = stdFontMap[name] || name;
     15302
     15303      if (!(lookupName in Metrics)) {
     15304        // Use default fonts for looking up font metrics if the passed
     15305        // font is not a base font
     15306        if (this.isSerifFont(name)) {
     15307          lookupName = 'Times-Roman';
     15308        } else {
     15309          lookupName = 'Helvetica';
     15310        }
     15311      }
     15312      var glyphWidths = Metrics[lookupName];
     15313
    1402515314      if (isNum(glyphWidths)) {
    1402615315        defaultWidth = glyphWidths;
     
    1408415373          // Simulating descriptor flags attribute
    1408515374          var fontNameWoStyle = baseFontName.split('-')[0];
    14086           var flags = (serifFonts[fontNameWoStyle] ||
    14087             (fontNameWoStyle.search(/serif/gi) != -1) ? FontFlags.Serif : 0) |
     15375          var flags = (
     15376            this.isSerifFont(fontNameWoStyle) ? FontFlags.Serif : 0) |
    1408815377            (metrics.monospace ? FontFlags.FixedPitch : 0) |
    1408915378            (symbolsFonts[fontNameWoStyle] ? FontFlags.Symbolic :
     
    1411115400      var firstChar = dict.get('FirstChar') || 0;
    1411215401      var lastChar = dict.get('LastChar') || maxCharIndex;
     15402
    1411315403      var fontName = descriptor.get('FontName');
     15404      var baseFont = baseDict.get('BaseFont');
    1411415405      // Some bad pdf's have a string as the font name.
    14115       if (isString(fontName))
     15406      if (isString(fontName)) {
    1411615407        fontName = new Name(fontName);
     15408      }
     15409      if (isString(baseFont)) {
     15410        baseFont = new Name(baseFont);
     15411      }
     15412
     15413      var fontNameStr = fontName && fontName.name;
     15414      // 9.7.6.1
     15415      if (type.name == 'CIDFontType0') {
     15416        var cidEncoding = baseDict.get('Encoding');
     15417        if (isName(cidEncoding)) {
     15418          fontNameStr = fontNameStr + '-' + cidEncoding.name;
     15419        }
     15420      }
     15421      var baseFontStr = baseFont && baseFont.name;
     15422      if (fontNameStr !== baseFontStr) {
     15423        warn('The FontDescriptor\'s FontName is "' + fontNameStr +
     15424            '" but should be the same as the Font\'s BaseFont "' +
     15425            baseFontStr + '"');
     15426      }
     15427      fontName = fontName || baseFont;
     15428
    1411715429      assertWellFormed(isName(fontName), 'invalid font name');
    1411815430
     
    1414015452        wideChars: composite,
    1414115453        fixedPitch: false,
    14142         fontMatrix: dict.get('FontMatrix') || IDENTITY_MATRIX,
     15454        fontMatrix: dict.get('FontMatrix') || FONT_IDENTITY_MATRIX,
    1414315455        firstChar: firstChar || 0,
    1414415456        lastChar: lastChar || maxCharIndex,
     
    1419115503
    1419215504
    14193 /**
    14194  * Maximum time to wait for a font to be loaded by font-face rules.
    14195  */
    14196 var kMaxWaitForFontFace = 1000;
    14197 
    1419815505// Unicode Private Use Area
    14199 var kCmapGlyphOffset = 0xE000;
    14200 var kSizeOfGlyphArea = 0x1900;
    14201 var kSymbolicFontGlyphOffset = 0xF000;
     15506var CMAP_GLYPH_OFFSET = 0xE000;
     15507var GLYPH_AREA_SIZE = 0x1900;
     15508var SYMBOLIC_FONT_GLYPH_OFFSET = 0xF000;
    1420215509
    1420315510// PDF Glyph Space Units are one Thousandth of a TextSpace Unit
    1420415511// except for Type 3 fonts
    14205 var kPDFGlyphSpaceUnits = 1000;
    14206 
    14207 // Until hinting is fully supported this constant can be used
    14208 var kHintingEnabled = false;
     15512var PDF_GLYPH_SPACE_UNITS = 1000;
     15513
     15514// Hinting is currently disabled due to unknown problems on windows
     15515// in tracemonkey and various other pdfs with type1 fonts.
     15516var HINTING_ENABLED = false;
     15517
     15518var FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0];
    1420915519
    1421015520var FontFlags = {
     
    1457815888};
    1457915889
     15890var CMapConverterList = {
     15891  'H': jis7ToUnicode,
     15892  'V': jis7ToUnicode,
     15893  'EUC-H': eucjpToUnicode,
     15894  'EUC-V': eucjpToUnicode,
     15895  '90ms-RKSJ-H': sjisToUnicode,
     15896  '90ms-RKSJ-V': sjisToUnicode,
     15897  '90msp-RKSJ-H': sjisToUnicode,
     15898  '90msp-RKSJ-V': sjisToUnicode,
     15899  'GBK-EUC-H': gbkToUnicode
     15900};
     15901
     15902// CMaps using Hankaku (Halfwidth) Latin glyphs instead of proportional one.
     15903// We need to distinguish them to get correct widths from CIDFont dicts.
     15904var HalfwidthCMaps = {
     15905  'H': true,
     15906  'V': true,
     15907  'EUC-H': true,
     15908  'EUC-V': true,
     15909  '90ms-RKSJ-H': true,
     15910  '90ms-RKSJ-V': true,
     15911  'UniJIS-UCS2-HW-H': true,
     15912  'UniJIS-UCS2-HW-V': true
     15913};
     15914
     15915var decodeBytes;
     15916if (typeof TextDecoder !== 'undefined') {
     15917  // The encodings supported by TextDecoder can be found at:
     15918  // http://encoding.spec.whatwg.org/#concept-encoding-get
     15919  decodeBytes = function(bytes, encoding) {
     15920    return new TextDecoder(encoding).decode(bytes);
     15921  };
     15922} else if (typeof FileReaderSync !== 'undefined') {
     15923  decodeBytes = function(bytes, encoding) {
     15924    return new FileReaderSync().readAsText(new Blob([bytes]), encoding);
     15925  };
     15926} else {
     15927  // Clear the list so that decodeBytes will never be called.
     15928  CMapConverterList = {};
     15929}
     15930
     15931function jis7ToUnicode(str) {
     15932  var bytes = stringToBytes(str);
     15933  var length = bytes.length;
     15934  for (var i = 0; i < length; ++i) {
     15935    bytes[i] |= 0x80;
     15936  }
     15937  return decodeBytes(bytes, 'euc-jp');
     15938}
     15939
     15940function eucjpToUnicode(str) {
     15941  return decodeBytes(stringToBytes(str), 'euc-jp');
     15942}
     15943
     15944function sjisToUnicode(str) {
     15945  return decodeBytes(stringToBytes(str), 'shift_jis');
     15946}
     15947
     15948function gbkToUnicode(str) {
     15949  return decodeBytes(stringToBytes(str), 'gbk');
     15950}
     15951
    1458015952// Some characters, e.g. copyrightserif, mapped to the private use area and
    1458115953// might not be displayed using standard fonts. Mapping/hacking well-known chars
     
    1496116333
    1496216334function isSpecialUnicode(unicode) {
    14963   return (unicode <= 0x1F || (unicode >= 127 && unicode < kSizeOfGlyphArea)) ||
    14964     (unicode >= kCmapGlyphOffset &&
    14965     unicode < kCmapGlyphOffset + kSizeOfGlyphArea);
     16335  return (unicode <= 0x1F || (unicode >= 127 && unicode < GLYPH_AREA_SIZE)) ||
     16336    (unicode >= CMAP_GLYPH_OFFSET &&
     16337    unicode < CMAP_GLYPH_OFFSET + GLYPH_AREA_SIZE);
    1496616338}
    1496716339
     
    1637617748}
    1637717749
     17750function adjustWidths(properties) {
     17751  if (properties.fontMatrix[0] === FONT_IDENTITY_MATRIX[0]) {
     17752    return;
     17753  }
     17754  // adjusting width to fontMatrix scale
     17755  var scale = 0.001 / properties.fontMatrix[0];
     17756  var glyphsWidths = properties.widths;
     17757  for (var glyph in glyphsWidths) {
     17758    glyphsWidths[glyph] *= scale;
     17759  }
     17760  properties.defaultWidth *= scale;
     17761}
     17762
    1637817763/**
    1637917764 * 'Font' is the class the outside world should use, it encapsulate all the font
     
    1642217807
    1642317808    this.fontMatrix = properties.fontMatrix;
    16424     this.widthMultiplier = 1.0;
    1642517809    if (properties.type == 'Type3') {
    1642617810      this.encoding = properties.baseEncoding;
     
    1643017814    // Trying to fix encoding using glyph CIDSystemInfo.
    1643117815    this.loadCidToUnicode(properties);
     17816    this.cidEncoding = properties.cidEncoding;
    1643217817
    1643317818    if (properties.toUnicode)
     
    1646517850    if (subtype == 'CIDFontType0C' && type != 'CIDFontType0')
    1646617851      type = 'CIDFontType0';
     17852    // XXX: Temporarily change the type for open type so we trigger a warning.
     17853    // This should be removed when we add support for open type.
     17854    if (subtype === 'OpenType') {
     17855      type = 'OpenType';
     17856    }
    1646717857
    1646817858    var data;
     
    1647517865          new CFFFont(file, properties) : new Type1Font(name, file, properties);
    1647617866
     17867        adjustWidths(properties);
     17868
    1647717869        // Wrap the CFF data inside an OTF font file
    1647817870        data = this.convert(name, cff, properties);
     
    1648917881
    1649017882      default:
    16491         warn('Font ' + properties.type + ' is not supported');
     17883        warn('Font ' + type + ' is not supported');
    1649217884        break;
    1649317885    }
    1649417886
    1649517887    this.data = data;
     17888
     17889    // Transfer some properties again that could change during font conversion
    1649617890    this.fontMatrix = properties.fontMatrix;
    16497     this.widthMultiplier = !properties.fontMatrix ? 1.0 :
    16498       1.0 / properties.fontMatrix[0];
     17891    this.widths = properties.widths;
     17892    this.defaultWidth = properties.defaultWidth;
    1649917893    this.encoding = properties.baseEncoding;
     17894
    1650017895    this.loading = true;
    1650117896  };
     
    1664518040  };
    1664618041
    16647   function createCMapTable(glyphs, deltas) {
     18042  function createCmapTable(glyphs, deltas) {
    1664818043    var ranges = getRanges(glyphs);
    1664918044
     
    1665518050               string32(4 + numTables * 8); // start of the table record
    1665618051
    16657     var segCount = ranges.length + 1;
     18052    var trailingRangesCount = ranges[ranges.length - 1][1] < 0xFFFF ? 1 : 0;
     18053    var segCount = ranges.length + trailingRangesCount;
    1665818054    var segCount2 = segCount * 2;
    1665918055    var searchRange = getMaxPower2(segCount) * 2;
     
    1667018066
    1667118067    if (deltas) {
    16672       for (var i = 0; i < segCount - 1; i++) {
     18068      for (var i = 0, ii = ranges.length; i < ii; i++) {
    1667318069        var range = ranges[i];
    1667418070        var start = range[0];
     
    1668718083      }
    1668818084    } else {
    16689       for (var i = 0; i < segCount - 1; i++) {
     18085      for (var i = 0, ii = ranges.length; i < ii; i++) {
    1669018086        var range = ranges[i];
    1669118087        var start = range[0];
     
    1670018096    }
    1670118097
    16702     endCount += '\xFF\xFF';
    16703     startCount += '\xFF\xFF';
    16704     idDeltas += '\x00\x01';
    16705     idRangeOffsets += '\x00\x00';
     18098    if (trailingRangesCount > 0) {
     18099      endCount += '\xFF\xFF';
     18100      startCount += '\xFF\xFF';
     18101      idDeltas += '\x00\x01';
     18102      idRangeOffsets += '\x00\x00';
     18103    }
    1670618104
    1670718105    var format314 = '\x00\x00' + // language
     
    1671818116                         format314);
    1671918117  };
     18118
     18119  function validateOS2Table(os2) {
     18120    var stream = new Stream(os2.data);
     18121    var version = int16(stream.getBytes(2));
     18122    // TODO verify all OS/2 tables fields, but currently we validate only those
     18123    // that give us issues
     18124    stream.getBytes(60); // skipping type, misc sizes, panose, unicode ranges
     18125    var selection = int16(stream.getBytes(2));
     18126    if (version < 4 && (selection & 0x0300)) {
     18127      return false;
     18128    }
     18129    var firstChar = int16(stream.getBytes(2));
     18130    var lastChar = int16(stream.getBytes(2));
     18131    if (firstChar > lastChar) {
     18132      return false;
     18133    }
     18134    return true;
     18135  }
    1672018136
    1672118137  function createOS2Table(properties, charstrings, override) {
     
    1676318179    }
    1676418180
    16765     var unitsPerEm = override.unitsPerEm || kPDFGlyphSpaceUnits;
    16766     var typoAscent = override.ascent || properties.ascent;
    16767     var typoDescent = override.descent || properties.descent;
     18181    var bbox = properties.bbox || [0, 0, 0, 0];
     18182    var unitsPerEm = override.unitsPerEm ||
     18183      1 / (properties.fontMatrix || FONT_IDENTITY_MATRIX)[0];
     18184
     18185    // if the font units differ to the PDF glyph space units
     18186    // then scale up the values
     18187    var scale = properties.ascentScaled ? 1.0 :
     18188      unitsPerEm / PDF_GLYPH_SPACE_UNITS;
     18189
     18190    var typoAscent = override.ascent || Math.round(scale *
     18191      (properties.ascent || bbox[3]));
     18192    var typoDescent = override.descent || Math.round(scale *
     18193      (properties.descent || bbox[1]));
     18194    if (typoDescent > 0 && properties.descent > 0 && bbox[1] < 0) {
     18195      typoDescent = -typoDescent; // fixing incorrect descent
     18196    }
    1676818197    var winAscent = override.yMax || typoAscent;
    1676918198    var winDescent = -override.yMin || -typoDescent;
    16770 
    16771     // if there is a units per em value but no other override
    16772     // then scale the calculated ascent
    16773     if (unitsPerEm != kPDFGlyphSpaceUnits &&
    16774         'undefined' == typeof(override.ascent)) {
    16775       // if the font units differ to the PDF glyph space units
    16776       // then scale up the values
    16777       typoAscent = Math.round(typoAscent * unitsPerEm / kPDFGlyphSpaceUnits);
    16778       typoDescent = Math.round(typoDescent * unitsPerEm / kPDFGlyphSpaceUnits);
    16779       winAscent = typoAscent;
    16780       winDescent = -typoDescent;
    16781     }
    1678218199
    1678318200    return '\x00\x03' + // version
     
    1683618253  };
    1683718254
    16838   function createNameTable(name) {
     18255  function createNameTable(name, proto) {
     18256    if (!proto) {
     18257      proto = [[], []]; // no strings and unicode strings
     18258    }
     18259
    1683918260    var strings = [
    16840       'Original licence',  // 0.Copyright
    16841       name,                // 1.Font family
    16842       'Unknown',           // 2.Font subfamily (font weight)
    16843       'uniqueID',          // 3.Unique ID
    16844       name,                // 4.Full font name
    16845       'Version 0.11',      // 5.Version
    16846       '',                  // 6.Postscript name
    16847       'Unknown',           // 7.Trademark
    16848       'Unknown',           // 8.Manufacturer
    16849       'Unknown'            // 9.Designer
     18261      proto[0][0] || 'Original licence',  // 0.Copyright
     18262      proto[0][1] || name,                // 1.Font family
     18263      proto[0][2] || 'Unknown',           // 2.Font subfamily (font weight)
     18264      proto[0][3] || 'uniqueID',          // 3.Unique ID
     18265      proto[0][4] || name,                // 4.Full font name
     18266      proto[0][5] || 'Version 0.11',      // 5.Version
     18267      proto[0][6] || '',                  // 6.Postscript name
     18268      proto[0][7] || 'Unknown',           // 7.Trademark
     18269      proto[0][8] || 'Unknown',           // 8.Manufacturer
     18270      proto[0][9] || 'Unknown'            // 9.Designer
    1685018271    ];
    1685118272
     
    1685418275    var stringsUnicode = [];
    1685518276    for (var i = 0, ii = strings.length; i < ii; i++) {
    16856       var str = strings[i];
     18277      var str = proto[1][i] || strings[i];
    1685718278
    1685818279      var strUnicode = '';
     
    1689418315    return nameTable;
    1689518316  }
     18317
     18318  // Normalize the charcodes in the cmap table into unicode values
     18319  // that will work with the (3, 1) cmap table we will write out.
     18320  function cmapCharcodeToUnicode(charcode, symbolic, platformId, encodingId) {
     18321    var unicode;
     18322    if (symbolic) {
     18323      // These codes will be shifted into the range
     18324      // SYMBOLIC_FONT_GLYPH_OFFSET to (SYMBOLIC_FONT_GLYPH_OFFSET + 0xFF)
     18325      // so that they are not in the control character range that could
     18326      // be displayed as spaces by browsers.
     18327      if (platformId === 3 && encodingId === 0 ||
     18328          platformId === 1 && encodingId === 0) {
     18329        unicode = SYMBOLIC_FONT_GLYPH_OFFSET | (charcode & 0xFF);
     18330      }
     18331    } else {
     18332      if (platformId === 3 && encodingId === 1) {
     18333        // A (3, 1) table is alredy unicode (Microsoft Unicode format)
     18334        unicode = charcode;
     18335      } else if (platformId === 1 && encodingId === 0) {
     18336        // TODO(mack): Should apply the changes to convert the
     18337        // MacRomanEncoding to Mac OS Roman encoding in 9.6.6.4
     18338        // table 115 of the pdf spec
     18339        var glyphName = Encodings.MacRomanEncoding[charcode];
     18340        if (glyphName) {
     18341          unicode = GlyphsUnicode[glyphName];
     18342        }
     18343      }
     18344    }
     18345    return unicode;
     18346  }
     18347
    1689618348
    1689718349  Font.prototype = {
     
    1697718429      }
    1697818430
    16979       function readCMapTable(cmap, font) {
     18431      /**
     18432       * Read the appropriate subtable from the cmap according to 9.6.6.4 from
     18433       * PDF spec
     18434       */
     18435      function readCmapTable(cmap, font, hasEncoding, isSymbolicFont) {
    1698018436        var start = (font.start ? font.start : 0) + cmap.offset;
    1698118437        font.pos = start;
    1698218438
    1698318439        var version = int16(font.getBytes(2));
    16984         var numRecords = int16(font.getBytes(2));
    16985 
    16986         var records = [];
    16987         for (var i = 0; i < numRecords; i++) {
    16988           records.push({
    16989             platformID: int16(font.getBytes(2)),
    16990             encodingID: int16(font.getBytes(2)),
    16991             offset: int32(font.getBytes(4))
    16992           });
     18440        var numTables = int16(font.getBytes(2));
     18441
     18442        var potentialTable;
     18443        var foundPreferredTable;
     18444        // There's an order of preference in terms of which cmap subtable we
     18445        // want to use. So scan through them to find our preferred table.
     18446        for (var i = 0; i < numTables; i++) {
     18447          var platformId = int16(font.getBytes(2));
     18448          var encodingId = int16(font.getBytes(2));
     18449          var offset = int32(font.getBytes(4));
     18450          var useTable = false;
     18451          var canBreak = false;
     18452
     18453          // The following block implements the following from the spec:
     18454          //
     18455          //   When the font has no Encoding entry, or the font descriptor’s
     18456          //   Symbolic flag is set (in which case the Encoding entry
     18457          //   is ignored), this shall occur:
     18458          //      - If the font contains a (3, 0) subtable, the range of
     18459          //      - Otherwise, the (1, 0) subtable will be used.
     18460          //   Otherwise, if the font does have an encoding:
     18461          //      - Use the (3, 1) cmap subtable
     18462          //      - Otherwise, use the (1, 0) subtable if present
     18463          //
     18464          // The following diverges slightly from the above spec in order
     18465          // to handle the case that hasEncoding and isSymbolicFont are both
     18466          // true. In this, based on the ordering of the rules in the spec,
     18467          // my interpretation is that we should be acting as if the font is
     18468          // symbolic.
     18469          //
     18470          // However, in this case, the test pdf 'preistabelle.pdf'
     18471          // is interpreting this case as a non-symbolic font. In this case
     18472          // though, 'presitabelle.pdf' does contain a (3, 1) table and does
     18473          // not contain a (3, 0) table which indicates it is non-symbolic.
     18474          //
     18475          // Thus, I am using this heurisitic of looking at which table is
     18476          // found to truly determine whether or not the font is symbolic.
     18477          // That is, if the specific symbolic/non-symbolic font specific
     18478          // tables (3, 0) or (3, 1) is found, that information is used for
     18479          // deciding if the font is symbolic or not.
     18480          //
     18481          // TODO(mack): This section needs some more thought on whether the
     18482          // heuristic is good enough. For now, it passes all the regression
     18483          // tests.
     18484          if (isSymbolicFont && platformId === 3 && encodingId === 0) {
     18485            useTable = true;
     18486            canBreak = true;
     18487            foundPreferredTable = true;
     18488          } else if (hasEncoding && platformId === 3 && encodingId === 1) {
     18489            useTable = true;
     18490            canBreak = true;
     18491            foundPreferredTable = true;
     18492            // Update the isSymbolicFont based on this heuristic
     18493            isSymbolicFont = false;
     18494          } else if (platformId === 1 && encodingId === 0 &&
     18495              !foundPreferredTable) {
     18496            useTable = true;
     18497            foundPreferredTable = true;
     18498          } else if (!potentialTable) {
     18499            // We will use an arbitrary table if we cannot find a preferred
     18500            // table
     18501            useTable = true;
     18502          }
     18503
     18504          if (useTable) {
     18505            potentialTable = {
     18506              platformId: platformId,
     18507              encodingId: encodingId,
     18508              offset: offset,
     18509              isSymbolicFont: isSymbolicFont
     18510            };
     18511          }
     18512          if (canBreak) {
     18513            break;
     18514          }
    1699318515        }
    1699418516
    16995         // Check that table are sorted by platformID then encodingID,
    16996         records.sort(function fontReadCMapTableSort(a, b) {
    16997           return ((a.platformID << 16) + a.encodingID) -
    16998                  ((b.platformID << 16) + b.encodingID);
    16999         });
    17000 
    17001         var tables = [records[0]];
    17002         for (var i = 1; i < numRecords; i++) {
    17003           // The sanitizer will drop the font if 2 tables have the same
    17004           // platformID and the same encodingID, this will be correct for
    17005           // most cases but if the font has been made for Mac it could
    17006           // exist a few platformID: 1, encodingID: 0 but with a different
    17007           // language field and that's correct. But the sanitizer does not
    17008           // seem to support this case.
    17009           var current = records[i];
    17010           var previous = records[i - 1];
    17011           if (((current.platformID << 16) + current.encodingID) <=
    17012              ((previous.platformID << 16) + previous.encodingID))
    17013                 continue;
    17014           tables.push(current);
     18517        if (!potentialTable) {
     18518          error('Could not find a cmap table');
     18519          return;
    1701518520        }
    1701618521
    17017         var missing = numRecords - tables.length;
    17018         if (missing) {
    17019           numRecords = tables.length;
    17020           var data = string16(version) + string16(numRecords);
    17021 
    17022           for (var i = 0; i < numRecords; i++) {
    17023             var table = tables[i];
    17024             data += string16(table.platformID) +
    17025                     string16(table.encodingID) +
    17026                     string32(table.offset);
     18522        if (!foundPreferredTable) {
     18523          warn('Did not find a cmap of suitable format. Interpreting (' +
     18524               potentialTable.platformId + ', ' + potentialTable.encodingId +
     18525               ') as (3, 1) table');
     18526          potentialTable.platformId = 3;
     18527          potentialTable.encodingId = 1;
     18528        }
     18529
     18530        font.pos = start + potentialTable.offset;
     18531        var format = int16(font.getBytes(2));
     18532        var length = int16(font.getBytes(2));
     18533        var language = int16(font.getBytes(2));
     18534
     18535        var hasShortCmap = false;
     18536        var mappings = [];
     18537
     18538        // TODO(mack): refactor this cmap subtable reading logic out
     18539        if (format === 0) {
     18540          for (var j = 0; j < 256; j++) {
     18541            var index = font.getByte();
     18542            if (!index) {
     18543              continue;
     18544            }
     18545            mappings.push({
     18546              charcode: j,
     18547              glyphId: index
     18548            });
    1702718549          }
    17028 
    17029           for (var i = 0, ii = data.length; i < ii; i++)
    17030             cmap.data[i] = data.charCodeAt(i);
    17031         }
    17032 
    17033         for (var i = 0; i < numRecords; i++) {
    17034           var table = tables[i];
    17035           font.pos = start + table.offset;
    17036 
    17037           var format = int16(font.getBytes(2));
    17038           var length = int16(font.getBytes(2));
    17039           var language = int16(font.getBytes(2));
    17040 
    17041           if (format == 0) {
    17042             // Characters below 0x20 are controls characters that are hardcoded
    17043             // into the platform so if some characters in the font are assigned
    17044             // under this limit they will not be displayed so let's rewrite the
    17045             // CMap.
    17046             var glyphs = [];
    17047             var ids = [];
    17048             for (var j = 0; j < 256; j++) {
    17049               var index = font.getByte();
    17050               if (index) {
    17051                 glyphs.push({ unicode: j, code: j });
    17052                 ids.push(index);
    17053               }
     18550          hasShortCmap = true;
     18551        } else if (format === 4) {
     18552          // re-creating the table in format 4 since the encoding
     18553          // might be changed
     18554          var segCount = (int16(font.getBytes(2)) >> 1);
     18555          font.getBytes(6); // skipping range fields
     18556          var segIndex, segments = [];
     18557          for (segIndex = 0; segIndex < segCount; segIndex++) {
     18558            segments.push({ end: int16(font.getBytes(2)) });
     18559          }
     18560          font.getBytes(2);
     18561          for (segIndex = 0; segIndex < segCount; segIndex++) {
     18562            segments[segIndex].start = int16(font.getBytes(2));
     18563          }
     18564
     18565          for (segIndex = 0; segIndex < segCount; segIndex++) {
     18566            segments[segIndex].delta = int16(font.getBytes(2));
     18567          }
     18568
     18569          var offsetsCount = 0;
     18570          for (segIndex = 0; segIndex < segCount; segIndex++) {
     18571            var segment = segments[segIndex];
     18572            var rangeOffset = int16(font.getBytes(2));
     18573            if (!rangeOffset) {
     18574              segment.offsetIndex = -1;
     18575              continue;
    1705418576            }
    17055             return {
    17056               glyphs: glyphs,
    17057               ids: ids,
    17058               hasShortCmap: true
    17059             };
    17060           } else if (format == 4) {
    17061             // re-creating the table in format 4 since the encoding
    17062             // might be changed
    17063             var segCount = (int16(font.getBytes(2)) >> 1);
    17064             font.getBytes(6); // skipping range fields
    17065             var segIndex, segments = [];
    17066             for (segIndex = 0; segIndex < segCount; segIndex++) {
    17067               segments.push({ end: int16(font.getBytes(2)) });
    17068             }
    17069             font.getBytes(2);
    17070             for (segIndex = 0; segIndex < segCount; segIndex++) {
    17071               segments[segIndex].start = int16(font.getBytes(2));
    17072             }
    17073 
    17074             for (segIndex = 0; segIndex < segCount; segIndex++) {
    17075               segments[segIndex].delta = int16(font.getBytes(2));
    17076             }
    17077 
    17078             var offsetsCount = 0;
    17079             for (segIndex = 0; segIndex < segCount; segIndex++) {
    17080               var segment = segments[segIndex];
    17081               var rangeOffset = int16(font.getBytes(2));
    17082               if (!rangeOffset) {
    17083                 segment.offsetIndex = -1;
     18577
     18578            var offsetIndex = (rangeOffset >> 1) - (segCount - segIndex);
     18579            segment.offsetIndex = offsetIndex;
     18580            offsetsCount = Math.max(offsetsCount, offsetIndex +
     18581              segment.end - segment.start + 1);
     18582          }
     18583
     18584          var offsets = [];
     18585          for (var j = 0; j < offsetsCount; j++) {
     18586            offsets.push(int16(font.getBytes(2)));
     18587          }
     18588
     18589          for (segIndex = 0; segIndex < segCount; segIndex++) {
     18590            var segment = segments[segIndex];
     18591            var start = segment.start, end = segment.end;
     18592            var delta = segment.delta, offsetIndex = segment.offsetIndex;
     18593
     18594            for (var j = start; j <= end; j++) {
     18595              if (j == 0xFFFF) {
    1708418596                continue;
    1708518597              }
    1708618598
    17087               var offsetIndex = (rangeOffset >> 1) - (segCount - segIndex);
    17088               segment.offsetIndex = offsetIndex;
    17089               offsetsCount = Math.max(offsetsCount, offsetIndex +
    17090                 segment.end - segment.start + 1);
     18599              var glyphId = offsetIndex < 0 ? j :
     18600                offsets[offsetIndex + j - start];
     18601              glyphId = (glyphId + delta) & 0xFFFF;
     18602              if (glyphId === 0) {
     18603                continue;
     18604              }
     18605              mappings.push({
     18606                charcode: j,
     18607                glyphId: glyphId
     18608              });
    1709118609            }
    17092 
    17093             var offsets = [];
    17094             for (var j = 0; j < offsetsCount; j++)
    17095               offsets.push(int16(font.getBytes(2)));
    17096 
    17097             var glyphs = [], ids = [];
    17098 
    17099             for (segIndex = 0; segIndex < segCount; segIndex++) {
    17100               var segment = segments[segIndex];
    17101               var start = segment.start, end = segment.end;
    17102               var delta = segment.delta, offsetIndex = segment.offsetIndex;
    17103 
    17104               for (var j = start; j <= end; j++) {
    17105                 if (j == 0xFFFF)
    17106                   continue;
    17107 
    17108                 var glyphCode = offsetIndex < 0 ? j :
    17109                   offsets[offsetIndex + j - start];
    17110                 glyphCode = (glyphCode + delta) & 0xFFFF;
    17111                 if (glyphCode == 0)
    17112                   continue;
    17113 
    17114                 glyphs.push({ unicode: j, code: j });
    17115                 ids.push(glyphCode);
    17116               }
    17117             }
    17118 
    17119             return {
    17120               glyphs: glyphs,
    17121               ids: ids
    17122             };
    17123           } else if (format == 6) {
    17124             // Format 6 is a 2-bytes dense mapping, which means the font data
    17125             // lives glue together even if they are pretty far in the unicode
    17126             // table. (This looks weird, so I can have missed something), this
    17127             // works on Linux but seems to fails on Mac so let's rewrite the
    17128             // cmap table to a 3-1-4 style
    17129             var firstCode = int16(font.getBytes(2));
    17130             var entryCount = int16(font.getBytes(2));
    17131 
    17132             var glyphs = [];
    17133             var ids = [];
    17134             for (var j = 0; j < entryCount; j++) {
    17135               var glyphCode = int16(font.getBytes(2));
    17136               var code = firstCode + j;
    17137 
    17138               glyphs.push({ unicode: code, code: code });
    17139               ids.push(glyphCode);
    17140             }
    17141 
    17142             return {
    17143               glyphs: glyphs,
    17144               ids: ids
    17145             };
    1714618610          }
     18611        } else if (format == 6) {
     18612          // Format 6 is a 2-bytes dense mapping, which means the font data
     18613          // lives glue together even if they are pretty far in the unicode
     18614          // table. (This looks weird, so I can have missed something), this
     18615          // works on Linux but seems to fails on Mac so let's rewrite the
     18616          // cmap table to a 3-1-4 style
     18617          var firstCode = int16(font.getBytes(2));
     18618          var entryCount = int16(font.getBytes(2));
     18619
     18620          var glyphs = [];
     18621          var ids = [];
     18622          for (var j = 0; j < entryCount; j++) {
     18623            var glyphId = int16(font.getBytes(2));
     18624            var charcode = firstCode + j;
     18625
     18626            mappings.push({
     18627              charcode: charcode,
     18628              glyphId: glyphId
     18629            });
     18630          }
     18631        } else {
     18632          error('cmap table has unsupported format: ' + format);
    1714718633        }
    17148         error('Unsupported cmap table format');
     18634
     18635        return {
     18636          platformId: potentialTable.platformId,
     18637          encodingId: potentialTable.encodingId,
     18638          isSymbolicFont: potentialTable.isSymbolicFont,
     18639          mappings: mappings,
     18640          hasShortCmap: hasShortCmap
     18641        };
    1714918642      };
    1715018643
    1715118644      function sanitizeMetrics(font, header, metrics, numGlyphs) {
    17152         if (!header && !metrics)
    17153           return;
    17154 
    17155         // The vhea/vmtx tables are not required, so it happens that
    17156         // some fonts embed a vmtx table without a vhea table. In this
    17157         // situation the sanitizer assume numOfLongVerMetrics = 1. As
    17158         // a result it tries to read numGlyphs - 1 SHORT from the vmtx
    17159         // table, and if it is not possible, the font is rejected.
    17160         // So remove the vmtx table if there is no vhea table.
    17161         if (!header && metrics) {
    17162           metrics.data = null;
     18645        if (!header) {
     18646          if (metrics) {
     18647            metrics.data = null;
     18648          }
    1716318649          return;
    1716418650        }
     
    1716818654        var numOfMetrics = int16(font.getBytes(2));
    1716918655
     18656        if (numOfMetrics > numGlyphs) {
     18657          info('The numOfMetrics (' + numOfMetrics + ') should not be ' +
     18658               'greater than the numGlyphs (' + numGlyphs + ')');
     18659          // Reduce numOfMetrics if it is greater than numGlyphs
     18660          numOfMetrics = numGlyphs;
     18661          header.data[34] = (numOfMetrics & 0xff00) >> 8;
     18662          header.data[35] = numOfMetrics & 0x00ff;
     18663        }
     18664
    1717018665        var numOfSidebearings = numGlyphs - numOfMetrics;
    1717118666        var numMissing = numOfSidebearings -
    17172           ((hmtx.length - numOfMetrics * 4) >> 1);
     18667          ((metrics.length - numOfMetrics * 4) >> 1);
     18668
    1717318669        if (numMissing > 0) {
    1717418670          font.pos = (font.start ? font.start : 0) + metrics.offset;
    1717518671          var entries = '';
    17176           for (var i = 0, ii = hmtx.length; i < ii; i++)
     18672          for (var i = 0, ii = metrics.length; i < ii; i++)
    1717718673            entries += String.fromCharCode(font.getByte());
    1717818674          for (var i = 0; i < numMissing; i++)
     
    1723518731        dest.set(glyf, destStart);
    1723618732        return glyf.length;
     18733      }
     18734
     18735      function sanitizeHead(head, numGlyphs, locaLength) {
     18736        var data = head.data;
     18737
     18738        // Validate version:
     18739        // Should always be 0x00010000
     18740        var version = int32([data[0], data[1], data[2], data[3]]);
     18741        if (version >> 16 !== 1) {
     18742          info('Attempting to fix invalid version in head table: ' + version);
     18743          data[0] = 0;
     18744          data[1] = 1;
     18745          data[2] = 0;
     18746          data[3] = 0;
     18747        }
     18748
     18749        var indexToLocFormat = int16([data[50], data[51]]);
     18750        if (indexToLocFormat < 0 || indexToLocFormat > 1) {
     18751          info('Attempting to fix invalid indexToLocFormat in head table: ' +
     18752               indexToLocFormat);
     18753
     18754          // The value of indexToLocFormat should be 0 if the loca table
     18755          // consists of short offsets, and should be 1 if the loca table
     18756          // consists of long offsets.
     18757          //
     18758          // The number of entries in the loca table should be numGlyphs + 1.
     18759          //
     18760          // Using this information, we can work backwards to deduce if the
     18761          // size of each offset in the loca table, and thus figure out the
     18762          // appropriate value for indexToLocFormat.
     18763
     18764          var numGlyphsPlusOne = numGlyphs + 1;
     18765          if (locaLength === numGlyphsPlusOne << 1) {
     18766            // 0x0000 indicates the loca table consists of short offsets
     18767            data[50] = 0;
     18768            data[51] = 0;
     18769          } else if (locaLength === numGlyphsPlusOne << 2) {
     18770            // 0x0001 indicates the loca table consists of long offsets
     18771            data[50] = 0;
     18772            data[51] = 1;
     18773          } else {
     18774            warn('Could not fix indexToLocFormat: ' + indexToLocFormat);
     18775          }
     18776        }
    1723718777      }
    1723818778
     
    1732418864      }
    1732518865
    17326       function readGlyphNameMap(post, properties) {
     18866      function readPostScriptTable(post, properties, maxpNumGlyphs) {
    1732718867        var start = (font.start ? font.start : 0) + post.offset;
    1732818868        font.pos = start;
     
    1733418874
    1733518875        var glyphNames;
     18876        var valid = true;
    1733618877        switch (version) {
    1733718878          case 0x00010000:
     
    1734018881          case 0x00020000:
    1734118882            var numGlyphs = int16(font.getBytes(2));
     18883            if (numGlyphs != maxpNumGlyphs) {
     18884              valid = false;
     18885              break;
     18886            }
    1734218887            var glyphNameIndexes = [];
    17343             for (var i = 0; i < numGlyphs; ++i)
    17344               glyphNameIndexes.push(int16(font.getBytes(2)));
     18888            for (var i = 0; i < numGlyphs; ++i) {
     18889              var index = int16(font.getBytes(2));
     18890              if (index >= 32768) {
     18891                valid = false;
     18892                break;
     18893              }
     18894              glyphNameIndexes.push(index);
     18895            }
     18896            if (!valid) {
     18897              break;
     18898            }
    1734518899            var customNames = [];
    1734618900            while (font.pos < end) {
     
    1736518919          default:
    1736618920            warn('Unknown/unsupported post table version ' + version);
     18921            valid = false;
    1736718922            break;
    1736818923        }
    1736918924        properties.glyphNames = glyphNames;
     18925        return valid;
     18926      }
     18927
     18928      function readNameTable(nameTable) {
     18929        var start = (font.start ? font.start : 0) + nameTable.offset;
     18930        font.pos = start;
     18931
     18932        var names = [[], []];
     18933        var length = nameTable.length, end = start + length;
     18934        var format = int16(font.getBytes(2));
     18935        var FORMAT_0_HEADER_LENGTH = 6;
     18936        if (format !== 0 || length < FORMAT_0_HEADER_LENGTH) {
     18937          // unsupported name table format or table "too" small
     18938          return names;
     18939        }
     18940        var numRecords = int16(font.getBytes(2));
     18941        var stringsStart = int16(font.getBytes(2));
     18942        var records = [];
     18943        var NAME_RECORD_LENGTH = 12;
     18944        for (var i = 0; i < numRecords &&
     18945                        font.pos + NAME_RECORD_LENGTH <= end; i++) {
     18946          var r = {
     18947            platform: int16(font.getBytes(2)),
     18948            encoding: int16(font.getBytes(2)),
     18949            language: int16(font.getBytes(2)),
     18950            name: int16(font.getBytes(2)),
     18951            length: int16(font.getBytes(2)),
     18952            offset: int16(font.getBytes(2))
     18953          };
     18954          // using only Macintosh and Windows platform/encoding names
     18955          if ((r.platform == 1 && r.encoding == 0 && r.language == 0) ||
     18956              (r.platform == 3 && r.encoding == 1 && r.language == 0x409)) {
     18957            records.push(r);
     18958          }
     18959        }
     18960        for (var i = 0, ii = records.length; i < ii; i++) {
     18961          var record = records[i];
     18962          var pos = start + stringsStart + record.offset;
     18963          if (pos + record.length > end) {
     18964            continue; // outside of name table, ignoring
     18965          }
     18966          font.pos = pos;
     18967          var nameIndex = record.name;
     18968          var encoding = record.encoding ? 1 : 0;
     18969          if (record.encoding) {
     18970            // unicode
     18971            var str = '';
     18972            for (var j = 0, jj = record.length; j < jj; j += 2) {
     18973              str += String.fromCharCode(int16(font.getBytes(2)));
     18974            }
     18975            names[1][nameIndex] = str;
     18976          } else {
     18977            names[0][nameIndex] = bytesToString(font.getBytes(record.length));
     18978          }
     18979        }
     18980        return names;
    1737018981      }
    1737118982
     
    1738018991      }
    1738118992
     18993      var TTOpsStackDeltas = [
     18994        0, 0, 0, 0, 0, 0, 0, 0, -2, -2, -2, -2, 0, 0, -2, -5,
     18995        -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1, 0, -1, -1, -1, -1,
     18996        1, -1, -999, 0, 1, 0, 0, -2, 0, -1, -2, -1, -999, -999, -1, -1,
     18997        0, 0, -999, -999, -1, -1, -1, -1, -2, -999, -2, -2, -2, 0, -2, -2,
     18998        0, 0, -2, 0, -2, 0, 0, 0, -2, -1, -1, 1, 1, 0, 0, -1,
     18999        -1, -1, -1, -1, -1, -1, 0, 0, -1, 0, -1, -1, 0, -999, -1, -1,
     19000        -1, -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0,
     19001        -2, -999, -999, -999, -999, -999, -1, -1, -2, -2, 0, 0, 0, 0, -1, -1,
     19002        -999, -2, -2, 0, 0, -1, -2, -2, 0, -999, 0, 0, 0, -1, -2];
     19003        // 0xC0-DF == -1 and 0xE0-FF == -2
     19004
     19005      function sanitizeTTProgram(table, ttContext) {
     19006        var data = table.data;
     19007        var i = 0, n, lastEndf = 0, lastDeff = 0;
     19008        var stack = [];
     19009        var tooComplexToFollowFunctions =
     19010          ttContext.tooComplexToFollowFunctions;
     19011        for (var ii = data.length; i < ii;) {
     19012          var op = data[i++];
     19013          // The TrueType instruction set docs can be found at
     19014          // https://developer.apple.com/fonts/TTRefMan/RM05/Chap5.html
     19015          if (op === 0x40) { // NPUSHB - pushes n bytes
     19016            n = data[i++];
     19017            for (var j = 0; j < n; j++) {
     19018              stack.push(data[i++]);
     19019            }
     19020          } else if (op === 0x41) { // NPUSHW - pushes n words
     19021            n = data[i++];
     19022            for (var j = 0; j < n; j++) {
     19023              var b = data[i++];
     19024              stack.push((b << 8) | data[i++]);
     19025            }
     19026          } else if ((op & 0xF8) === 0xB0) { // PUSHB - pushes bytes
     19027            n = op - 0xB0 + 1;
     19028            for (var j = 0; j < n; j++) {
     19029              stack.push(data[i++]);
     19030            }
     19031          } else if ((op & 0xF8) === 0xB8) { // PUSHW - pushes words
     19032            n = op - 0xB8 + 1;
     19033            for (var j = 0; j < n; j++) {
     19034              var b = data[i++];
     19035              stack.push((b << 8) | data[i++]);
     19036            }
     19037          } else if (op === 0x2B && !tooComplexToFollowFunctions) { // CALL
     19038            // collecting inforamtion about which functions are used
     19039            var funcId = stack[stack.length - 1];
     19040            ttContext.functionsUsed[funcId] = true;
     19041            if (i >= 2 && data[i - 2] === 0x2B) {
     19042              // all data in stack, calls are performed in sequence
     19043              tooComplexToFollowFunctions = true;
     19044            }
     19045          } else if (op === 0x2C && !tooComplexToFollowFunctions) { // FDEF
     19046            // collecting inforamtion about which functions are defined
     19047            lastDeff = i;
     19048            var funcId = stack[stack.length - 1];
     19049            ttContext.functionsDefined[funcId] = true;
     19050            if (i >= 2 && data[i - 2] === 0x2D) {
     19051              // all function ids in stack, FDEF/ENDF perfomed in sequence
     19052              tooComplexToFollowFunctions = true;
     19053            }
     19054          } else if (op === 0x2D) { // ENDF - end of function
     19055            lastEndf = i;
     19056          } else if (op === 0x89) { // IDEF - instruction definition
     19057            // recording it as a function to track ENDF
     19058            lastDeff = i;
     19059          }
     19060          // Adjusting stack not extactly, but just enough to get function id
     19061          var stackDelta = op <= 0x8E ? TTOpsStackDeltas[op] :
     19062            op >= 0xC0 && op <= 0xDF ? -1 : op >= 0xE0 ? -2 : 0;
     19063          while (stackDelta < 0 && stack.length > 0) {
     19064            stack.pop();
     19065            stackDelta++;
     19066          }
     19067          while (stackDelta > 0) {
     19068            stack.push(NaN); // pushing any number into stack
     19069            stackDelta--;
     19070          }
     19071        }
     19072        ttContext.tooComplexToFollowFunctions = tooComplexToFollowFunctions;
     19073        var content = [data];
     19074        if (i > data.length) {
     19075          content.push(new Uint8Array(i - data.length));
     19076        }
     19077        if (lastDeff > lastEndf) {
     19078          // new function definition started, but not finished
     19079          // complete function by [CLEAR, ENDF]
     19080          content.push(new Uint8Array([0x22, 0x2D]));
     19081        }
     19082        if (ttContext.defineMissingFunctions && !tooComplexToFollowFunctions) {
     19083          for (var j = 0, jj = ttContext.functionsUsed.length; j < jj; j++) {
     19084            if (!ttContext.functionsUsed[j] || ttContext.functionsDefined[j]) {
     19085              continue;
     19086            }
     19087            // function is used, but not defined
     19088            // creating empty one [PUSHB, function-id, FDEF, ENDF]
     19089            content.push(new Uint8Array([0xB0, j, 0x2C, 0x2D]));
     19090          }
     19091        }
     19092        if (content.length > 1) {
     19093          // concatenating the content items
     19094          var newLength = 0;
     19095          for (var j = 0, jj = content.length; j < jj; j++) {
     19096            newLength += content[j].length;
     19097          }
     19098          newLength = (newLength + 3) & ~3;
     19099          var result = new Uint8Array(newLength);
     19100          var pos = 0;
     19101          for (var j = 0, jj = content.length; j < jj; j++) {
     19102            result.set(content[j], pos);
     19103            pos += content[j].length;
     19104          }
     19105          table.data = result;
     19106          table.length = newLength;
     19107        }
     19108      }
     19109
     19110      function sanitizeTTPrograms(fpgm, prep) {
     19111        var ttContext = {
     19112          functionsDefined: [],
     19113          functionsUsed: [],
     19114          tooComplexToFollowFunctions: false
     19115        };
     19116        if (prep) {
     19117          // collecting prep functions info first
     19118          sanitizeTTProgram(prep, ttContext);
     19119        }
     19120        if (fpgm) {
     19121          ttContext.defineMissingFunctions = true;
     19122          sanitizeTTProgram(fpgm, ttContext);
     19123        }
     19124      }
     19125
    1738219126      // Check that required tables are present
    1738319127      var requiredTables = ['OS/2', 'cmap', 'head', 'hhea',
     
    1738719131      var numTables = header.numTables;
    1738819132
    17389       var cmap, post, maxp, hhea, hmtx, vhea, vmtx, head, loca, glyf, os2;
     19133      var cmap, post, maxp, hhea, hmtx, head, os2;
     19134      var glyf, fpgm, loca, prep, cvt;
    1739019135      var tables = [];
    1739119136      for (var i = 0; i < numTables; i++) {
     
    1741019155          requiredTables.splice(index, 1);
    1741119156        } else {
    17412           if (table.tag == 'vmtx')
    17413             vmtx = table;
    17414           else if (table.tag == 'vhea')
    17415             vhea = table;
    17416           else if (table.tag == 'loca')
     19157          if (table.tag == 'loca')
    1741719158            loca = table;
    1741819159          else if (table.tag == 'glyf')
    1741919160            glyf = table;
     19161          else if (table.tag == 'fpgm')
     19162            fpgm = table;
     19163          else if (table.tag == 'prep')
     19164            prep = table;
     19165          else if (table.tag == 'cvt ')
     19166            cvt = table;
     19167          else // skipping table if it's not a required or optional table
     19168            continue;
    1742019169        }
    1742119170        tables.push(table);
     
    1744219191      }
    1744319192
    17444       // Ensure the [h/v]mtx tables contains the advance width and
     19193      // Ensure the hmtx table contains the advance width and
    1744519194      // sidebearings information for numGlyphs in the maxp table
    1744619195      font.pos = (font.start || 0) + maxp.offset;
     
    1744919198
    1745019199      sanitizeMetrics(font, hhea, hmtx, numGlyphs);
    17451       sanitizeMetrics(font, vhea, vmtx, numGlyphs);
     19200
     19201      sanitizeTTPrograms(fpgm, prep);
     19202
     19203      if (head) {
     19204        sanitizeHead(head, numGlyphs, loca.length);
     19205      }
    1745219206
    1745319207      var isGlyphLocationsLong = int16([head.data[50], head.data[51]]);
     
    1746919223      // The 'post' table has glyphs names.
    1747019224      if (post) {
    17471         readGlyphNameMap(post, properties);
     19225        var valid = readPostScriptTable(post, properties, numGlyphs);
     19226        if (!valid) {
     19227          tables.splice(tables.indexOf(post), 1);
     19228          post = null;
     19229        }
    1747219230      }
    1747319231
     
    1752519283        // trying to fit as many unassigned symbols as we can
    1752619284        // in the range allocated for the user defined symbols
    17527         var unusedUnicode = kCmapGlyphOffset;
     19285        var unusedUnicode = CMAP_GLYPH_OFFSET;
    1752819286        for (var j = 0, jj = unassignedUnicodeItems.length; j < jj; j++) {
    1752919287          var i = unassignedUnicodeItems[j];
     
    1753119289          while (unusedUnicode in usedUnicodes)
    1753219290            unusedUnicode++;
    17533           if (unusedUnicode >= kCmapGlyphOffset + kSizeOfGlyphArea)
     19291          if (unusedUnicode >= CMAP_GLYPH_OFFSET + GLYPH_AREA_SIZE)
    1753419292            break;
    1753519293          var unicode = unusedUnicode++;
     
    1754019298        }
    1754119299      } else {
    17542         var cmapTable = readCMapTable(cmap, font);
    17543 
    17544         glyphs = cmapTable.glyphs;
    17545         ids = cmapTable.ids;
    17546 
    17547         var hasShortCmap = !!cmapTable.hasShortCmap;
     19300        this.useToFontChar = true;
     19301        // Most of the following logic in this code branch is based on the
     19302        // 9.6.6.4 of the PDF spec.
     19303
     19304        // TODO(mack):
     19305        // We are using this.hasEncoding to mean that the encoding is either
     19306        // MacRomanEncoding or WinAnsiEncoding (following spec in 9.6.6.4),
     19307        // but this.hasEncoding is currently true for any encodings on the
     19308        // Encodings object (e.g. MacExpertEncoding). So should consider using
     19309        // better check for this.
     19310        var cmapTable = readCmapTable(cmap, font, this.hasEncoding,
     19311            this.isSymbolicFont);
     19312
     19313        // TODO(mack): If the (3, 0) cmap table used, then the font is
     19314        // symbolic. The range of charcodes in the cmap table should be
     19315        // one of the following:
     19316        //   -> 0x0000 - 0x00FF
     19317        //   -> 0xF000 - 0xF0FF
     19318        //   -> 0xF100 - 0xF1FF
     19319        //   -> 0xF200 - 0xF2FF
     19320        // If it is not, we should change not consider this a symbolic font
     19321        this.isSymbolicFont = cmapTable.isSymbolicFont;
     19322
     19323        var cmapPlatformId = cmapTable.platformId;
     19324        var cmapEncodingId = cmapTable.encodingId;
     19325        var cmapMappings = cmapTable.mappings;
     19326        var cmapMappingsLength = cmapMappings.length;
     19327        var glyphs = [];
     19328        var ids = [];
     19329        for (var i = 0; i < cmapMappingsLength; ++i) {
     19330          var cmapMapping = cmapMappings[i];
     19331          var charcode = cmapMapping.charcode;
     19332          var unicode = cmapCharcodeToUnicode(charcode, this.isSymbolicFont,
     19333              cmapPlatformId, cmapEncodingId);
     19334
     19335          if (!unicode) {
     19336            // TODO(mack): gotta check if skipping mappings where we cannot find
     19337            // a unicode is the correct behaviour
     19338            continue;
     19339          }
     19340          glyphs.push({
     19341            code: charcode,
     19342            unicode: unicode
     19343          });
     19344          ids.push(cmapMapping.glyphId);
     19345        }
     19346
     19347        var hasShortCmap = cmapTable.hasShortCmap;
    1754819348        var toFontChar = this.toFontChar;
    1754919349
     
    1755119351          // Fixes the short cmap tables -- some generators use incorrect
    1755219352          // glyph id.
    17553           for (var i = 0, ii = ids.length; i < ii; i++)
     19353          for (var i = 0, ii = ids.length; i < ii; i++) {
    1755419354            ids[i] = i;
    17555         }
    17556 
    17557         var unusedUnicode = kCmapGlyphOffset;
    17558         var glyphNames = properties.glyphNames || [];
    17559         var encoding = properties.baseEncoding;
    17560         var differences = properties.differences;
    17561         if (toFontChar && toFontChar.length > 0) {
    17562           // checking if cmap is just identity map
    17563           var isIdentity = true;
    17564           for (var i = 0, ii = glyphs.length; i < ii; i++) {
    17565             if (glyphs[i].unicode != i + 1) {
    17566               isIdentity = false;
    17567               break;
    17568             }
    17569           }
    17570           // if it is, replacing with meaningful toUnicode values
    17571           if (isIdentity && !this.isSymbolicFont) {
    17572             var usedUnicodes = [], unassignedUnicodeItems = [];
    17573             for (var i = 0, ii = glyphs.length; i < ii; i++) {
    17574               var unicode = toFontChar[i + 1];
    17575               if (!unicode || typeof unicode !== 'number' ||
    17576                   unicode in usedUnicodes) {
    17577                 unassignedUnicodeItems.push(i);
    17578                 continue;
    17579               }
    17580               glyphs[i].unicode = unicode;
    17581               usedUnicodes[unicode] = true;
    17582             }
    17583             for (var j = 0, jj = unassignedUnicodeItems.length; j < jj; j++) {
    17584               var i = unassignedUnicodeItems[j];
    17585               while (unusedUnicode in usedUnicodes)
    17586                 unusedUnicode++;
    17587               var cid = i + 1;
    17588               // override only if unicode mapping is not specified
    17589               if (!(cid in toFontChar))
    17590                 toFontChar[cid] = unusedUnicode;
    17591               glyphs[i].unicode = unusedUnicode++;
    17592             }
    17593             this.useToFontChar = true;
    1759419355          }
    1759519356        }
    1759619357
    17597         // remove glyph references outside range of avaialable glyphs or empty
    17598         var glyphsRemoved = 0;
    17599         for (var i = ids.length - 1; i >= 0; i--) {
    17600           if (ids[i] < numGlyphs &&
    17601               (!emptyGlyphIds[ids[i]] || this.isSymbolicFont))
    17602             continue;
    17603           ids.splice(i, 1);
    17604           glyphs.splice(i, 1);
    17605           glyphsRemoved++;
    17606         }
    17607 
    17608         // checking if it's a "true" symbolic font
    17609         if (this.isSymbolicFont) {
    17610           var minUnicode = 0xFFFF, maxUnicode = 0;
    17611           for (var i = 0, ii = glyphs.length; i < ii; i++) {
    17612             var unicode = glyphs[i].unicode;
    17613             minUnicode = Math.min(minUnicode, unicode);
    17614             maxUnicode = Math.max(maxUnicode, unicode);
    17615           }
    17616           // high byte must be the same for min and max unicodes
    17617           if ((maxUnicode & 0xFF00) != (minUnicode & 0xFF00))
    17618             this.isSymbolicFont = false;
    17619         }
    17620 
    17621         // heuristics: if removed more than 10 glyphs encoding WinAnsiEncoding
    17622         // does not set properly (broken PDFs have about 100 removed glyphs)
    17623         if (glyphsRemoved > 10) {
    17624           warn('Switching TrueType encoding to MacRomanEncoding for ' +
    17625                this.name + ' font');
    17626           encoding = Encodings.MacRomanEncoding;
    17627         }
    17628 
    17629         if (hasShortCmap && this.hasEncoding && !this.isSymbolicFont) {
    17630           // Re-encode short map encoding to unicode -- that simplifies the
    17631           // resolution of MacRoman encoded glyphs logic for TrueType fonts:
    17632           // copying all characters to private use area, all mapping all known
    17633           // glyphs to the unicodes. The glyphs and ids arrays will grow.
    17634           var usedUnicodes = [];
    17635           for (var i = 0, ii = glyphs.length; i < ii; i++) {
    17636             var code = glyphs[i].unicode;
    17637             var gid = ids[i];
    17638             glyphs[i].unicode += kCmapGlyphOffset;
    17639             toFontChar[code] = glyphs[i].unicode;
    17640 
    17641             var glyphName = glyphNames[gid] || encoding[code];
    17642             if (glyphName in GlyphsUnicode) {
    17643               var unicode = GlyphsUnicode[glyphName];
    17644               if (unicode in usedUnicodes)
    17645                 continue;
    17646 
    17647               usedUnicodes[unicode] = true;
    17648               glyphs.push({
    17649                 unicode: unicode,
    17650                 code: glyphs[i].code
    17651               });
    17652               ids.push(gid);
    17653               toFontChar[code] = unicode;
    17654             }
    17655           }
    17656           this.useToFontChar = true;
    17657         } else if (!this.isSymbolicFont && (this.hasEncoding ||
    17658                     properties.glyphNames || differences.length > 0)) {
    17659           // Re-encode cmap encoding to unicode, based on the 'post' table data
    17660           // diffrence array or base encoding
    17661           var reverseMap = [];
    17662           for (var i = 0, ii = glyphs.length; i < ii; i++)
    17663             reverseMap[glyphs[i].unicode] = i;
    17664 
    17665           var newGlyphUnicodes = [];
    17666           for (var i = 0, ii = glyphs.length; i < ii; i++) {
    17667             var code = glyphs[i].unicode;
    17668             var changeCode = false;
    17669             var gid = ids[i];
    17670 
    17671             var glyphName = glyphNames[gid];
    17672             if (!glyphName) {
    17673               glyphName = differences[code] || encoding[code];
    17674               changeCode = true;
    17675             }
    17676             if (glyphName in GlyphsUnicode) {
    17677               var unicode = GlyphsUnicode[glyphName];
    17678               if (!unicode || reverseMap[unicode] === i)
    17679                 continue; // unknown glyph name or in its own place
    17680 
    17681               newGlyphUnicodes[i] = unicode;
    17682               if (changeCode)
    17683                 toFontChar[code] = unicode;
    17684               delete reverseMap[code];
    17685             }
    17686           }
    17687           for (var index in newGlyphUnicodes) {
    17688             if (newGlyphUnicodes.hasOwnProperty(index)) {
    17689               var unicode = newGlyphUnicodes[index];
    17690               if (reverseMap[unicode]) {
    17691                 // avoiding assigning to the same unicode
    17692                 glyphs[index].unicode = unusedUnicode++;
    17693                 continue;
    17694               }
    17695               glyphs[index].unicode = unicode;
    17696               reverseMap[unicode] = index;
    17697             }
    17698           }
    17699           this.useToFontChar = true;
    17700         }
    17701 
    17702         // Moving all symbolic font glyphs into 0xF000 - 0xF0FF range.
     19358        // Rewrite the whole toFontChar dictionary with a new one using the
     19359        // information from the mappings in the cmap table.
     19360        var newToFontChar = [];
    1770319361        if (this.isSymbolicFont) {
    1770419362          for (var i = 0, ii = glyphs.length; i < ii; i++) {
    17705             var code = glyphs[i].unicode & 0xFF;
    17706             var fontCharCode = kSymbolicFontGlyphOffset | code;
    17707             glyphs[i].unicode = toFontChar[code] = fontCharCode;
     19363            var glyph = glyphs[i];
     19364            // For (3, 0) cmap tables:
     19365            // The charcode key being stored in toFontChar is the lower byte
     19366            // of the two-byte charcodes of the cmap table since according to
     19367            // the spec: 'each byte from the string shall be prepended with the
     19368            // high byte of the range [of charcodes in the cmap table], to form
     19369            // a two-byte character, which shall be used to select the
     19370            // associated glyph description from the subtable'.
     19371            //
     19372            // For (1, 0) cmap tables:
     19373            // 'single bytes from the string shall be used to look up the
     19374            // associated glyph descriptions from the subtable'. This means
     19375            // charcodes in the cmap will be single bytes, so no-op since
     19376            // glyph.code & 0xFF === glyph.code
     19377            newToFontChar[glyph.code & 0xFF] = glyph.unicode;
    1770819378          }
    17709           this.useToFontChar = true;
     19379        } else {
     19380
     19381          var encoding = properties.baseEncoding;
     19382          var differences = properties.differences;
     19383
     19384          // TODO(mack): check if it is necessary to shift control characters
     19385          // for non-symbolic fonts so that browsers dont't render them using
     19386          // space characters
     19387
     19388          var glyphCodeMapping = cmapTable.glyphCodeMapping;
     19389          for (var charcode = 0; charcode < encoding.length; ++charcode) {
     19390            if (!encoding.hasOwnProperty(charcode)) {
     19391              continue;
     19392            }
     19393
     19394            // Since the cmap table that we will be writing out is a (3, 1)
     19395            // unicode table, in this section we will rewrites the charcodes
     19396            // in the pdf into unicodes
     19397
     19398            var glyphName = encoding[charcode];
     19399            // A nonsymbolic font should not have a Differences array, but
     19400            // if it does have one, we should still use it
     19401            if (charcode in differences) {
     19402              glyphName = differences[charcode];
     19403            }
     19404
     19405            // Finally, any undefined entries in the table shall be filled
     19406            // using StandardEncoding
     19407            if (!glyphName) {
     19408              glyphName = Encodings.StandardEncoding[charcode];
     19409            }
     19410
     19411            // TODO(mack): Handle the case that the glyph name cannot be
     19412            // mapped as specified, in which case the glyph name shall be
     19413            // looked up in the font program's 'post' table (if one is
     19414            // present) and the associated glyph id shall be used.
     19415            //
     19416            // For now, we're just using the '.notdef' glyph name in this
     19417            // case.
     19418            glyphName = glyphName || '.notdef';
     19419
     19420            var unicode = GlyphsUnicode[glyphName];
     19421            newToFontChar[charcode] = unicode;
     19422          }
    1771019423        }
     19424        this.toFontChar = toFontChar = newToFontChar;
    1771119425
    1771219426        createGlyphNameMap(glyphs, ids, properties);
     
    1771419428      }
    1771519429
     19430      if (glyphs.length === 0) {
     19431        // defines at least one glyph
     19432        glyphs.push({ unicode: 0xF000, code: 0xF000, glyph: '.notdef' });
     19433        ids.push(0);
     19434      }
     19435
    1771619436      // Converting glyphs and ids into font's cmap table
    17717       cmap.data = createCMapTable(glyphs, ids);
     19437      cmap.data = createCmapTable(glyphs, ids);
    1771819438      var unicodeIsEnabled = [];
    1771919439      for (var i = 0, ii = glyphs.length; i < ii; i++) {
     
    1772119441      }
    1772219442      this.unicodeIsEnabled = unicodeIsEnabled;
     19443
     19444      if (os2 && !validateOS2Table(os2)) {
     19445        tables.splice(tables.indexOf(os2), 1);
     19446        os2 = null;
     19447      }
    1772319448
    1772419449      if (!os2) {
     
    1774019465
    1774119466      // Rewrite the 'post' table if needed
    17742       if (requiredTables.indexOf('post') != -1) {
     19467      if (!post) {
    1774319468        tables.push({
    1774419469          tag: 'post',
     
    1774719472      }
    1774819473
    17749       // Rewrite the 'name' table if needed
     19474      // Re-creating 'name' table
    1775019475      if (requiredTables.indexOf('name') != -1) {
    1775119476        tables.push({
     
    1775319478          data: stringToArray(createNameTable(this.name))
    1775419479        });
     19480      } else {
     19481        // ... using existing 'name' table as prototype
     19482        for (var i = 0, ii = tables.length; i < ii; i++) {
     19483          var table = tables[i];
     19484          if (table.tag === 'name') {
     19485            var namePrototype = readNameTable(table);
     19486            table.data = stringToArray(createNameTable(name, namePrototype));
     19487            break;
     19488          }
     19489        }
    1775519490      }
    1775619491
     
    1779819533      // representing the offset where to draw the actual data of a particular
    1779919534      // table
    17800       var kRequiredTablesCount = 9;
     19535      var REQ_TABLES_CNT = 9;
    1780119536
    1780219537      var otf = {
     
    1783419569        this.toFontChar = toFontChar;
    1783519570      }
    17836       var unitsPerEm = properties.unitsPerEm || 1000; // defaulting to 1000
     19571      var unitsPerEm = 1 / (properties.fontMatrix || FONT_IDENTITY_MATRIX)[0];
    1783719572
    1783819573      var fields = {
     
    1784419579
    1784519580        // Character to glyphs mapping
    17846         'cmap': createCMapTable(charstrings.slice(),
     19581        'cmap': createCmapTable(charstrings.slice(),
    1784719582                                ('glyphIds' in font) ? font.glyphIds : null),
    1784819583
     
    1793019665    buildToFontChar: function Font_buildToFontChar(toUnicode) {
    1793119666      var result = [];
    17932       var unusedUnicode = kCmapGlyphOffset;
     19667      var unusedUnicode = CMAP_GLYPH_OFFSET;
    1793319668      for (var i = 0, ii = toUnicode.length; i < ii; i++) {
    1793419669        var unicode = toUnicode[i];
     
    1798119716        return; // identity encoding
    1798219717
     19718      var cidEncoding = properties.cidEncoding;
     19719      var overwrite = HalfwidthCMaps[cidEncoding];
    1798319720      var cid = 1, i, j, k, ii;
    1798419721      for (i = 0, ii = cidToUnicode.length; i < ii; ++i) {
     
    1798719724          var length = unicode.length;
    1798819725          for (j = 0; j < length; j++) {
    17989             cidToUnicodeMap[cid] = unicode[j];
    17990             unicodeToCIDMap[unicode[j]] = cid;
     19726            cidToUnicodeMap[cid] = k = unicode[j];
     19727            if (!unicodeToCIDMap[k] || overwrite) {
     19728              unicodeToCIDMap[k] = cid;
     19729            }
    1799119730          }
    1799219731          cid++;
     
    1799719736            for (j = 0; j < fillLength; ++j) {
    1799819737              cidToUnicodeMap[cid] = k;
    17999               unicodeToCIDMap[k] = cid;
     19738              if (!unicodeToCIDMap[k] || overwrite) {
     19739                unicodeToCIDMap[k] = cid;
     19740              }
    1800019741              cid++;
    1800119742              k++;
     
    1800519746        } else if (unicode) {
    1800619747          cidToUnicodeMap[cid] = unicode;
    18007           unicodeToCIDMap[unicode] = cid;
     19748          if (!unicodeToCIDMap[unicode] || overwrite) {
     19749            unicodeToCIDMap[unicode] = cid;
     19750          }
    1800819751          cid++;
    1800919752        } else
    1801019753          cid++;
     19754      }
     19755
     19756      if (!cidEncoding) {
     19757        return;
     19758      }
     19759      if (cidEncoding.indexOf('Identity-') !== 0) {
     19760        // input is already Unicode for non-Identity CMap encodings.
     19761        this.cidToUnicode = [];
     19762      } else {
     19763        // We don't have to do reverse conversions if the string is
     19764        // already CID.
     19765        this.unicodeToCID = [];
    1801119766      }
    1801219767    },
     
    1807319828          break; // the non-zero width found
    1807419829      }
    18075       width = (width || this.defaultWidth) * this.widthMultiplier;
     19830      width = width || this.defaultWidth;
    1807619831      // Do not shadow the property here. See discussion:
    1807719832      // https://github.com/mozilla/pdf.js/pull/2127#discussion_r1662280
     
    1808919844          if (this.noUnicodeAdaptation) {
    1809019845            width = this.widths[this.unicodeToCID[charcode] || charcode];
    18091             fontCharCode = mapPrivateUseChars(charcode);
    18092             break;
    1809319846          }
    1809419847          fontCharCode = this.toFontChar[charcode] || charcode;
     
    1809719850          if (this.noUnicodeAdaptation) {
    1809819851            width = this.widths[this.unicodeToCID[charcode] || charcode];
    18099             fontCharCode = mapPrivateUseChars(charcode);
    18100             break;
    1810119852          }
    1810219853          fontCharCode = this.toFontChar[charcode] || charcode;
     
    1815419905        unicodeChars = String.fromCharCode(unicodeChars);
    1815519906
    18156       width = (isNum(width) ? width : this.defaultWidth) * this.widthMultiplier;
     19907      width = isNum(width) ? width : this.defaultWidth;
    1815719908      disabled = this.unicodeIsEnabled ?
    1815819909        !this.unicodeIsEnabled[fontCharCode] : false;
     
    1818319934
    1818419935      glyphs = [];
    18185 
    18186       if (this.wideChars) {
     19936      var charsCacheKey = chars;
     19937
     19938      var converter;
     19939      var cidEncoding = this.cidEncoding;
     19940      if (cidEncoding) {
     19941        converter = CMapConverterList[cidEncoding];
     19942        if (converter) {
     19943          chars = converter(chars);
     19944        } else if (cidEncoding.indexOf('Uni') !== 0 &&
     19945                   cidEncoding.indexOf('Identity-') !== 0) {
     19946          warn('Unsupported CMap: ' + cidEncoding);
     19947        }
     19948      }
     19949      if (!converter && this.wideChars) {
    1818719950        // composite fonts have multi-byte strings convert the string from
    1818819951        // single-byte to multi-byte
     
    1821119974
    1821219975      // Enter the translated string into the cache
    18213       return (charsCache[chars] = glyphs);
     19976      return (charsCache[charsCacheKey] = glyphs);
    1821419977    }
    1821519978  };
     
    1822619989    charsToGlyphs: function ErrorFont_charsToGlyphs() {
    1822719990      return [];
     19991    },
     19992    exportData: function ErrorFont_exportData() {
     19993      return {error: this.error};
    1822819994    }
    1822919995  };
     
    1823219998})();
    1823319999
    18234 var CallothersubrCmd = (function CallothersubrCmdClosure() {
    18235   function CallothersubrCmd(index) {
    18236     this.index = index;
     20000/*
     20001 * CharStrings are encoded following the the CharString Encoding sequence
     20002 * describe in Chapter 6 of the "Adobe Type1 Font Format" specification.
     20003 * The value in a byte indicates a command, a number, or subsequent bytes
     20004 * that are to be interpreted in a special way.
     20005 *
     20006 * CharString Number Encoding:
     20007 *  A CharString byte containing the values from 32 through 255 inclusive
     20008 *  indicate an integer. These values are decoded in four ranges.
     20009 *
     20010 * 1. A CharString byte containing a value, v, between 32 and 246 inclusive,
     20011 * indicate the integer v - 139. Thus, the integer values from -107 through
     20012 * 107 inclusive may be encoded in single byte.
     20013 *
     20014 * 2. A CharString byte containing a value, v, between 247 and 250 inclusive,
     20015 * indicates an integer involving the next byte, w, according to the formula:
     20016 * [(v - 247) x 256] + w + 108
     20017 *
     20018 * 3. A CharString byte containing a value, v, between 251 and 254 inclusive,
     20019 * indicates an integer involving the next byte, w, according to the formula:
     20020 * -[(v - 251) * 256] - w - 108
     20021 *
     20022 * 4. A CharString containing the value 255 indicates that the next 4 bytes
     20023 * are a two complement signed integer. The first of these bytes contains the
     20024 * highest order bits, the second byte contains the next higher order bits
     20025 * and the fourth byte contain the lowest order bits.
     20026 *
     20027 *
     20028 * CharString Command Encoding:
     20029 *  CharStrings commands are encoded in 1 or 2 bytes.
     20030 *
     20031 *  Single byte commands are encoded in 1 byte that contains a value between
     20032 *  0 and 31 inclusive.
     20033 *  If a command byte contains the value 12, then the value in the next byte
     20034 *  indicates a command. This "escape" mechanism allows many extra commands
     20035 * to be encoded and this encoding technique helps to minimize the length of
     20036 * the charStrings.
     20037 */
     20038var Type1CharString = (function Type1CharStringClosure() {
     20039  var COMMAND_MAP = {
     20040    'hstem': [1],
     20041    'vstem': [3],
     20042    'vmoveto': [4],
     20043    'rlineto': [5],
     20044    'hlineto': [6],
     20045    'vlineto': [7],
     20046    'rrcurveto': [8],
     20047    'callsubr': [10],
     20048    'flex': [12, 35],
     20049    'drop' : [12, 18],
     20050    'endchar': [14],
     20051    'rmoveto': [21],
     20052    'hmoveto': [22],
     20053    'vhcurveto': [30],
     20054    'hvcurveto': [31]
     20055  };
     20056
     20057  function Type1CharString() {
     20058    this.width = 0;
     20059    this.lsb = 0;
     20060    this.flexing = false;
     20061    this.output = [];
     20062    this.stack = [];
    1823720063  }
    1823820064
    18239   return CallothersubrCmd;
     20065  Type1CharString.prototype = {
     20066    convert: function Type1CharString_convert(encoded, subrs) {
     20067      var count = encoded.length;
     20068      var error = false;
     20069      for (var i = 0; i < count; i++) {
     20070        var value = encoded[i];
     20071        if (value < 32) {
     20072          if (value === 12) {
     20073            value = (value << 8) + encoded[++i];
     20074          }
     20075          switch (value) {
     20076            case 1: // hstem
     20077              if (!HINTING_ENABLED) {
     20078                this.stack = [];
     20079                break;
     20080              }
     20081              error = this.executeCommand(2, COMMAND_MAP.hstem);
     20082              break;
     20083            case 3: // vstem
     20084              if (!HINTING_ENABLED) {
     20085                this.stack = [];
     20086                break;
     20087              }
     20088              error = this.executeCommand(2, COMMAND_MAP.vstem);
     20089              break;
     20090            case 4: // vmoveto
     20091              if (this.flexing) {
     20092                if (this.stack.length < 1) {
     20093                  error = true;
     20094                  break;
     20095                }
     20096                // Add the dx for flex and but also swap the values so they are
     20097                // the right order.
     20098                var dy = this.stack.pop();
     20099                this.stack.push(0, dy);
     20100                break;
     20101              }
     20102              error = this.executeCommand(1, COMMAND_MAP.vmoveto);
     20103              break;
     20104            case 5: // rlineto
     20105              error = this.executeCommand(2, COMMAND_MAP.rlineto);
     20106              break;
     20107            case 6: // hlineto
     20108              error = this.executeCommand(1, COMMAND_MAP.hlineto);
     20109              break;
     20110            case 7: // vlineto
     20111              error = this.executeCommand(1, COMMAND_MAP.vlineto);
     20112              break;
     20113            case 8: // rrcurveto
     20114              error = this.executeCommand(6, COMMAND_MAP.rrcurveto);
     20115              break;
     20116            case 9: // closepath
     20117              // closepath is a Type1 command that does not take argument and is
     20118              // useless in Type2 and it can simply be ignored.
     20119              this.stack = [];
     20120              break;
     20121            case 10: // callsubr
     20122              if (this.stack.length < 1) {
     20123                error = true;
     20124                break;
     20125              }
     20126              var subrNumber = this.stack.pop();
     20127              error = this.convert(subrs[subrNumber], subrs);
     20128              break;
     20129            case 11: // return
     20130              return error;
     20131              break;
     20132            case 13: // hsbw
     20133              if (this.stack.length < 2) {
     20134                error = true;
     20135                break;
     20136              }
     20137              // To convert to type2 we have to move the width value to the
     20138              // first part of the charstring and then use hmoveto with lsb.
     20139              var wx = this.stack.pop();
     20140              var sbx = this.stack.pop();
     20141              this.lsb = sbx;
     20142              this.width = wx;
     20143              this.stack.push(sbx);
     20144              error = this.executeCommand(1, COMMAND_MAP.hmoveto);
     20145              break;
     20146            case 14: // endchar
     20147              this.output.push(COMMAND_MAP.endchar[0]);
     20148              break;
     20149            case 21: // rmoveto
     20150              if (this.flexing) {
     20151                break;
     20152              }
     20153              error = this.executeCommand(2, COMMAND_MAP.rmoveto);
     20154              break;
     20155            case 22: // hmoveto
     20156              if (this.flexing) {
     20157                // Add the dy for flex.
     20158                this.stack.push(0);
     20159                break;
     20160              }
     20161              error = this.executeCommand(1, COMMAND_MAP.hmoveto);
     20162              break;
     20163            case 30: // vhcurveto
     20164              error = this.executeCommand(4, COMMAND_MAP.vhcurveto);
     20165              break;
     20166            case 31: // hvcurveto
     20167              error = this.executeCommand(4, COMMAND_MAP.hvcurveto);
     20168              break;
     20169            case (12 << 8) + 0: // dotsection
     20170              // dotsection is a Type1 command to specify some hinting feature
     20171              // for dots that do not take a parameter and it can safely be
     20172              // ignored for Type2.
     20173              this.stack = [];
     20174              break;
     20175            case (12 << 8) + 1: // vstem3
     20176              if (!HINTING_ENABLED) {
     20177                this.stack = [];
     20178                break;
     20179              }
     20180              // [vh]stem3 are Type1 only and Type2 supports [vh]stem with
     20181              // multiple parameters, so instead of returning [vh]stem3 take a
     20182              // shortcut and return [vhstem] instead.
     20183              error = this.executeCommand(2, COMMAND_MAP.vstem);
     20184              break;
     20185            case (12 << 8) + 2: // hstem3
     20186              if (!HINTING_ENABLED) {
     20187                 this.stack = [];
     20188                break;
     20189              }
     20190              // See vstem3.
     20191              error = this.executeCommand(2, COMMAND_MAP.hstem);
     20192              break;
     20193            case (12 << 8) + 6: // seac
     20194              // seac is like type 2's special endchar but it doesn't use the
     20195              // first argument asb, so remove it.
     20196              error = this.executeCommand(4, COMMAND_MAP.endchar);
     20197              break;
     20198            case (12 << 8) + 7: // sbw
     20199              if (this.stack.length < 4) {
     20200                error = true;
     20201                break;
     20202              }
     20203              // To convert to type2 we have to move the width value to the
     20204              // first part of the charstring and then use rmoveto with
     20205              // (dx, dy). The height argument will not be used for vmtx and
     20206              // vhea tables reconstruction -- ignoring it.
     20207              var wy = this.stack.pop();
     20208              var wx = this.stack.pop();
     20209              var sby = this.stack.pop();
     20210              var sbx = this.stack.pop();
     20211              this.lsb = sbx;
     20212              this.width = wx;
     20213              this.stack.push(sbx, sby);
     20214              error = this.executeCommand(2, COMMAND_MAP.rmoveto);
     20215              break;
     20216            case (12 << 8) + 12: // div
     20217              if (this.stack.length < 2) {
     20218                error = true;
     20219                break;
     20220              }
     20221              var num2 = this.stack.pop();
     20222              var num1 = this.stack.pop();
     20223              this.stack.push(num1 / num2);
     20224              break;
     20225            case (12 << 8) + 16: // callothersubr
     20226              if (this.stack.length < 2) {
     20227                error = true;
     20228                break;
     20229              }
     20230              var subrNumber = this.stack.pop();
     20231              var numArgs = this.stack.pop();
     20232              if (subrNumber === 0 && numArgs === 3) {
     20233                var flexArgs = this.stack.splice(this.stack.length - 17, 17);
     20234                this.stack.push(
     20235                  flexArgs[2] + flexArgs[0], // bcp1x + rpx
     20236                  flexArgs[3] + flexArgs[1], // bcp1y + rpy
     20237                  flexArgs[4], // bcp2x
     20238                  flexArgs[5], // bcp2y
     20239                  flexArgs[6], // p2x
     20240                  flexArgs[7], // p2y
     20241                  flexArgs[8], // bcp3x
     20242                  flexArgs[9], // bcp3y
     20243                  flexArgs[10], // bcp4x
     20244                  flexArgs[11], // bcp4y
     20245                  flexArgs[12], // p3x
     20246                  flexArgs[13], // p3y
     20247                  flexArgs[14] // flexDepth
     20248                  // 15 = finalx unused by flex
     20249                  // 16 = finaly unused by flex
     20250                );
     20251                error = this.executeCommand(13, COMMAND_MAP.flex, true);
     20252                this.flexing = false;
     20253                this.stack.push(flexArgs[15], flexArgs[16]);
     20254              } else if (subrNumber === 1 && numArgs === 0) {
     20255                this.flexing = true;
     20256              }
     20257              break;
     20258            case (12 << 8) + 17: // pop
     20259              // Ignore this since it is only used with othersubr.
     20260              break;
     20261            case (12 << 8) + 33: // setcurrentpoint
     20262              // Ignore for now.
     20263              this.stack = [];
     20264              break;
     20265            default:
     20266              warn('Unknown type 1 charstring command of "' + value + '"');
     20267              break;
     20268          }
     20269          if (error) {
     20270            break;
     20271          }
     20272          continue;
     20273        } else if (value <= 246) {
     20274          value = value - 139;
     20275        } else if (value <= 250) {
     20276          value = ((value - 247) * 256) + encoded[++i] + 108;
     20277        } else if (value <= 254) {
     20278          value = -((value - 251) * 256) - encoded[++i] - 108;
     20279        } else {
     20280          value = (encoded[++i] & 0xff) << 24 | (encoded[++i] & 0xff) << 16 |
     20281                  (encoded[++i] & 0xff) << 8 | (encoded[++i] & 0xff) << 0;
     20282        }
     20283        this.stack.push(value);
     20284      }
     20285      return error;
     20286    },
     20287
     20288    executeCommand: function(howManyArgs, command, keepStack) {
     20289      var stackLength = this.stack.length;
     20290      if (howManyArgs > stackLength) {
     20291        return true;
     20292      }
     20293      var start = stackLength - howManyArgs;
     20294      for (var i = start; i < stackLength; i++) {
     20295        var value = this.stack[i];
     20296        if (value === (value | 0)) { // int
     20297          this.output.push(28, (value >> 8) & 0xff, value & 0xff);
     20298        } else { // fixed point
     20299          value = (65536 * value) | 0;
     20300          this.output.push(255,
     20301                           (value >> 24) & 0xFF,
     20302                           (value >> 16) & 0xFF,
     20303                           (value >> 8) & 0xFF,
     20304                           value & 0xFF);
     20305        }
     20306      }
     20307      this.output.push.apply(this.output, command);
     20308      if (keepStack) {
     20309        this.stack.splice(start, howManyArgs);
     20310      } else {
     20311        this.stack = [];
     20312      }
     20313      return false;
     20314    }
     20315  };
     20316
     20317  return Type1CharString;
    1824020318})();
    1824120319
     
    1825120329   * for decrypting the eexec block of for decoding charStrings.
    1825220330   */
    18253   var kEexecEncryptionKey = 55665;
    18254   var kCharStringsEncryptionKey = 4330;
     20331  var EEXEC_ENCRYPT_KEY = 55665;
     20332  var CHAR_STRS_ENCRYPT_KEY = 4330;
    1825520333
    1825620334  function decrypt(stream, key, discardNumber) {
     
    1826920347
    1827020348  /*
    18271    * CharStrings are encoded following the the CharString Encoding sequence
    18272    * describe in Chapter 6 of the "Adobe Type1 Font Format" specification.
    18273    * The value in a byte indicates a command, a number, or subsequent bytes
    18274    * that are to be interpreted in a special way.
    18275    *
    18276    * CharString Number Encoding:
    18277    *  A CharString byte containing the values from 32 through 255 inclusive
    18278    *  indicate an integer. These values are decoded in four ranges.
    18279    *
    18280    * 1. A CharString byte containing a value, v, between 32 and 246 inclusive,
    18281    * indicate the integer v - 139. Thus, the integer values from -107 through
    18282    * 107 inclusive may be encoded in single byte.
    18283    *
    18284    * 2. A CharString byte containing a value, v, between 247 and 250 inclusive,
    18285    * indicates an integer involving the next byte, w, according to the formula:
    18286    * [(v - 247) x 256] + w + 108
    18287    *
    18288    * 3. A CharString byte containing a value, v, between 251 and 254 inclusive,
    18289    * indicates an integer involving the next byte, w, according to the formula:
    18290    * -[(v - 251) * 256] - w - 108
    18291    *
    18292    * 4. A CharString containing the value 255 indicates that the next 4 bytes
    18293    * are a two complement signed integer. The first of these bytes contains the
    18294    * highest order bits, the second byte contains the next higher order bits
    18295    * and the fourth byte contain the lowest order bits.
    18296    *
    18297    *
    18298    * CharString Command Encoding:
    18299    *  CharStrings commands are encoded in 1 or 2 bytes.
    18300    *
    18301    *  Single byte commands are encoded in 1 byte that contains a value between
    18302    *  0 and 31 inclusive.
    18303    *  If a command byte contains the value 12, then the value in the next byte
    18304    *  indicates a command. This "escape" mechanism allows many extra commands
    18305    * to be encoded and this encoding technique helps to minimize the length of
    18306    * the charStrings.
    18307    */
    18308   var charStringDictionary = {
    18309     '1': 'hstem',
    18310     '3': 'vstem',
    18311     '4': 'vmoveto',
    18312     '5': 'rlineto',
    18313     '6': 'hlineto',
    18314     '7': 'vlineto',
    18315     '8': 'rrcurveto',
    18316 
    18317     // closepath is a Type1 command that do not take argument and is useless
    18318     // in Type2 and it can simply be ignored.
    18319     '9': null, // closepath
    18320 
    18321     '10': 'callsubr',
    18322 
    18323     // return is normally used inside sub-routines to tells to the execution
    18324     // flow that it can be back to normal.
    18325     // During the translation process Type1 charstrings will be flattened and
    18326     // sub-routines will be embedded directly into the charstring directly, so
    18327     // this can be ignored safely.
    18328     '11': 'return',
    18329 
    18330     '12': {
    18331       // dotsection is a Type1 command to specify some hinting feature for dots
    18332       // that do not take a parameter and it can safely be ignored for Type2.
    18333       '0': null, // dotsection
    18334 
    18335       // [vh]stem3 are Type1 only and Type2 supports [vh]stem with multiple
    18336       // parameters, so instead of returning [vh]stem3 take a shortcut and
    18337       // return [vhstem] instead.
    18338       '1': 'vstem',
    18339       '2': 'hstem',
    18340 
    18341       '6': 'endchar', // seac
    18342       // Type1 only command with command not (yet) built-in ,throw an error
    18343       '7': -1, // sbw
    18344 
    18345       '11': 'sub',
    18346       '12': 'div',
    18347 
    18348       // callothersubr is a mechanism to make calls on the postscript
    18349       // interpreter, this is not supported by Type2 charstring but hopefully
    18350       // most of the default commands can be ignored safely.
    18351       '16': 'callothersubr',
    18352 
    18353       '17': 'pop',
    18354 
    18355       // setcurrentpoint sets the current point to x, y without performing a
    18356       // moveto (this is a one shot positionning command). This is used only
    18357       // with the return of an OtherSubrs call.
    18358       // TODO Implement the OtherSubrs charstring embedding and replace this
    18359       // call by a no-op, like 2 'pop' commands for example.
    18360       '33': null // setcurrentpoint
    18361     },
    18362     '13': 'hsbw',
    18363     '14': 'endchar',
    18364     '21': 'rmoveto',
    18365     '22': 'hmoveto',
    18366     '30': 'vhcurveto',
    18367     '31': 'hvcurveto'
    18368   };
    18369 
    18370   var kEscapeCommand = 12;
    18371 
    18372   // Breaks up the stack by arguments and also calculates the value.
    18373   function breakUpArgs(stack, numArgs) {
    18374     var args = [];
    18375     var index = stack.length - 1;
    18376     for (var i = 0; i < numArgs; i++) {
    18377       if (index < 0) {
    18378         args.unshift({ arg: [0],
    18379                        value: 0,
    18380                        offset: 0 });
    18381         warn('Malformed charstring stack: not enough values on stack.');
    18382         continue;
    18383       }
    18384       var token = stack[index];
    18385       if (token === 'div') {
    18386         var a = stack[index - 2];
    18387         var b = stack[index - 1];
    18388         if (!isInt(a) || !isInt(b)) {
    18389           warn('Malformed charsting stack: expected ints on stack for div.');
    18390           a = 0;
    18391           b = 1;
    18392         }
    18393         args.unshift({ arg: [a, b, 'div'],
    18394                        value: a / b,
    18395                        offset: index - 2 });
    18396         index -= 3;
    18397       } else if (isInt(token)) {
    18398         args.unshift({ arg: stack.slice(index, index + 1),
    18399                        value: token,
    18400                        offset: index });
    18401         index--;
    18402       } else {
    18403         warn('Malformed charsting stack: found bad token ' + token + '.');
    18404       }
    18405     }
    18406     return args;
    18407   }
    18408 
    18409   function decodeCharString(array) {
    18410     var charstring = [];
    18411     var lsb = 0;
    18412     var width = 0;
    18413     var flexState = 0;
    18414 
    18415     var value = '';
    18416     var count = array.length;
    18417     for (var i = 0; i < count; i++) {
    18418       value = array[i];
    18419 
    18420       if (value < 32) {
    18421         var command = null;
    18422         if (value == kEscapeCommand) {
    18423           var escape = array[++i];
    18424 
    18425           // TODO Clean this code
    18426           if (escape == 16) {
    18427             var index = charstring.pop();
    18428             var argc = charstring.pop();
    18429             for (var j = 0; j < argc; j++)
    18430               charstring.push('drop');
    18431 
    18432             // If the flex mechanism is not used in a font program, Adobe
    18433             // states that entries 0, 1 and 2 can simply be replaced by
    18434             // {}, which means that we can simply ignore them.
    18435             if (index < 3) {
    18436               continue;
    18437             }
    18438 
    18439             // This is the same things about hint replacement, if it is not used
    18440             // entry 3 can be replaced by {3}
    18441             // TODO support hint replacment
    18442             if (index == 3) {
    18443               charstring.push(3);
    18444               i++;
    18445               continue;
    18446