plugins/pdfviewer
Thomas Brüderli
bruederli at kolabsys.com
Mon Jan 20 16:41:52 CET 2014
plugins/pdfviewer/README | 3
plugins/pdfviewer/pdfjs-viewer.diff | 130
plugins/pdfviewer/viewer/compatibility.js | 12
plugins/pdfviewer/viewer/debugger.js | 10
plugins/pdfviewer/viewer/images/findbarButton-next-rtl.png |binary
plugins/pdfviewer/viewer/images/findbarButton-next.png |binary
plugins/pdfviewer/viewer/images/findbarButton-previous-rtl.png |binary
plugins/pdfviewer/viewer/images/findbarButton-previous.png |binary
plugins/pdfviewer/viewer/images/loading-small.png |binary
plugins/pdfviewer/viewer/images/secondaryToolbarButton-firstPage.png |binary
plugins/pdfviewer/viewer/images/secondaryToolbarButton-lastPage.png |binary
plugins/pdfviewer/viewer/images/secondaryToolbarButton-rotateCcw.png |binary
plugins/pdfviewer/viewer/images/secondaryToolbarButton-rotateCw.png |binary
plugins/pdfviewer/viewer/images/shadow.png |binary
plugins/pdfviewer/viewer/images/texture.png |binary
plugins/pdfviewer/viewer/images/toolbarButton-bookmark.png |binary
plugins/pdfviewer/viewer/images/toolbarButton-download.png |binary
plugins/pdfviewer/viewer/images/toolbarButton-menuArrows.png |binary
plugins/pdfviewer/viewer/images/toolbarButton-openFile.png |binary
plugins/pdfviewer/viewer/images/toolbarButton-pageDown-rtl.png |binary
plugins/pdfviewer/viewer/images/toolbarButton-pageDown.png |binary
plugins/pdfviewer/viewer/images/toolbarButton-pageUp-rtl.png |binary
plugins/pdfviewer/viewer/images/toolbarButton-pageUp.png |binary
plugins/pdfviewer/viewer/images/toolbarButton-presentationMode.png |binary
plugins/pdfviewer/viewer/images/toolbarButton-print.png |binary
plugins/pdfviewer/viewer/images/toolbarButton-search.png |binary
plugins/pdfviewer/viewer/images/toolbarButton-secondaryToolbarToggle-rtl.png |binary
plugins/pdfviewer/viewer/images/toolbarButton-secondaryToolbarToggle.png |binary
plugins/pdfviewer/viewer/images/toolbarButton-sidebarToggle-rtl.png |binary
plugins/pdfviewer/viewer/images/toolbarButton-sidebarToggle.png |binary
plugins/pdfviewer/viewer/images/toolbarButton-viewOutline-rtl.png |binary
plugins/pdfviewer/viewer/images/toolbarButton-viewOutline.png |binary
plugins/pdfviewer/viewer/images/toolbarButton-viewThumbnail.png |binary
plugins/pdfviewer/viewer/images/toolbarButton-zoomOut.png |binary
plugins/pdfviewer/viewer/locale/de/viewer.properties | 31
plugins/pdfviewer/viewer/locale/en-US/viewer.properties | 5
plugins/pdfviewer/viewer/locale/es/viewer.properties | 18
plugins/pdfviewer/viewer/locale/ja/viewer.properties | 13
plugins/pdfviewer/viewer/locale/locale.properties | 4
plugins/pdfviewer/viewer/locale/nl/viewer.properties | 5
plugins/pdfviewer/viewer/locale/zh-CN/viewer.properties | 14
plugins/pdfviewer/viewer/locale/zh-TW/viewer.properties | 11
plugins/pdfviewer/viewer/pdf.js | 7776 +++++++++-
plugins/pdfviewer/viewer/pdf.min.js | 178
plugins/pdfviewer/viewer/pdf.worker.js | 5664 ++++---
plugins/pdfviewer/viewer/viewer.css | 93
plugins/pdfviewer/viewer/viewer.html | 117
plugins/pdfviewer/viewer/viewer.js | 5542 +++++++
plugins/pdfviewer/viewer/viewer.min.js | 164
49 files changed, 16952 insertions(+), 2838 deletions(-)
New commits:
commit dcac898f7d9a5551c18a7aa1a28821e7c45f0304
Author: Thomas Bruederli <thomas at roundcube.net>
Date: Mon Jan 20 16:41:18 2014 +0100
Updated pdfviewer plugin to latest version of pdf.js
diff --git a/plugins/pdfviewer/README b/plugins/pdfviewer/README
index 8949ac8..ecba65e 100644
--- a/plugins/pdfviewer/README
+++ b/plugins/pdfviewer/README
@@ -44,6 +44,9 @@ or the YUI Compressor [2].
$ <roundcubedir>/bin/jsshrink.sh viewer/pdf.js ECMASCRIPT5
$ <roundcubedir>/bin/jsshrink.sh viewer/viewer.js ECMASCRIPT5
+This will create minimized versions in viewer/*.min.js which are
+linked by the viewer.html template.
+
[1] http://closure-compiler.googlecode.com/
[2] http://developer.yahoo.com/yui/compressor/
diff --git a/plugins/pdfviewer/pdfjs-viewer.diff b/plugins/pdfviewer/pdfjs-viewer.diff
index 52a65c6..91bc469 100644
--- a/plugins/pdfviewer/pdfjs-viewer.diff
+++ b/plugins/pdfviewer/pdfjs-viewer.diff
@@ -1,57 +1,69 @@
---- viewer/viewer.html.orig 2013-10-03 14:06:24.000000000 +0200
-+++ viewer/viewer.html 2013-10-03 13:53:17.000000000 +0200
-@@ -31,7 +31,7 @@
+--- viewer/viewer.html.orig 2014-01-20 16:22:49.000000000 +0100
++++ viewer/viewer.html 2014-01-20 16:38:37.000000000 +0100
+@@ -31,12 +31,12 @@
<!-- This snippet is used in production, see Makefile -->
<link rel="resource" type="application/l10n" href="locale/locale.properties"/>
<script type="text/javascript" src="l10n.js"></script>
-<script type="text/javascript" src="../build/pdf.js"></script>
-+<script type="text/javascript" src="pdf.js"></script>
++<script type="text/javascript" src="pdf.min.js"></script>
-@@ -88,18 +88,10 @@
+ <script type="text/javascript" src="debugger.js"></script>
+- <script type="text/javascript" src="viewer.js"></script>
++ <script type="text/javascript" src="viewer.min.js"></script>
+
+ </head>
+
+@@ -88,7 +88,7 @@
<span data-l10n-id="presentation_mode_label">Presentation Mode</span>
</button>
- <button id="secondaryOpenFile" class="secondaryToolbarButton openFile visibleLargeView" title="Open File" tabindex="19" data-l10n-id="open_file">
-- <span data-l10n-id="open_file_label">Open</span>
-- </button>
--
- <button id="secondaryPrint" class="secondaryToolbarButton print visibleMediumView" title="Print" tabindex="20" data-l10n-id="print">
++ <button id="secondaryOpenFile" class="secondaryToolbarButton openFile hidden" title="Open File" tabindex="19" data-l10n-id="open_file">
+ <span data-l10n-id="open_file_label">Open</span>
+ </button>
+
+@@ -96,11 +96,11 @@
<span data-l10n-id="print_label">Print</span>
</button>
- <button id="secondaryDownload" class="secondaryToolbarButton download visibleMediumView" title="Download" tabindex="21" data-l10n-id="download">
-- <span data-l10n-id="download_label">Download</span>
-- </button>
--
- <div class="horizontalToolbarSeparator visibleLargeView"></div>
++ <button id="secondaryDownload" class="secondaryToolbarButton download hidden" title="Download" tabindex="21" data-l10n-id="download">
+ <span data-l10n-id="download_label">Download</span>
+ </button>
+
+- <a href="#" id="secondaryViewBookmark" class="secondaryToolbarButton bookmark visibleSmallView" title="Current view (copy or open in new window)" tabindex="22" data-l10n-id="bookmark">
++ <a href="#" id="secondaryViewBookmark" class="secondaryToolbarButton bookmark hidden" title="Current view (copy or open in new window)" tabindex="22" data-l10n-id="bookmark">
+ <span data-l10n-id="bookmark_label">Current View</span>
+ </a>
- <button id="firstPage" class="secondaryToolbarButton firstPage" title="Go to First Page" tabindex="22" data-l10n-id="first_page">
-@@ -150,20 +142,10 @@
+@@ -159,7 +159,7 @@
<span data-l10n-id="presentation_mode_label">Presentation Mode</span>
</button>
- <button id="openFile" class="toolbarButton openFile hiddenLargeView" title="Open File" tabindex="13" data-l10n-id="open_file">
-- <span data-l10n-id="open_file_label">Open</span>
-- </button>
--
- <button id="print" class="toolbarButton print hiddenMediumView" title="Print" tabindex="14" data-l10n-id="print">
++ <button id="openFile" class="toolbarButton openFile hidden" title="Open File" tabindex="13" data-l10n-id="open_file">
+ <span data-l10n-id="open_file_label">Open</span>
+ </button>
+
+@@ -167,11 +167,11 @@
<span data-l10n-id="print_label">Print</span>
</button>
- <button id="download" class="toolbarButton download hiddenMediumView" title="Download" tabindex="15" data-l10n-id="download">
-- <span data-l10n-id="download_label">Download</span>
-- </button>
-- <!-- <div class="toolbarButtonSpacer"></div> -->
-- <a href="#" id="viewBookmark" class="toolbarButton bookmark hiddenSmallView" title="Current view (copy or open in new window)" tabindex="16" data-l10n-id="bookmark"><span data-l10n-id="bookmark_label">Current View</span></a>
--
- <div class="verticalToolbarSeparator hiddenSmallView"></div>
-
- <button id="secondaryToolbarToggle" class="toolbarButton" title="Tools" tabindex="17" data-l10n-id="tools">
---- viewer/viewer.js.orig 2013-10-03 14:06:30.000000000 +0200
-+++ viewer/viewer.js 2013-10-03 14:06:00.000000000 +0200
-@@ -22,7 +22,7 @@
++ <button id="download" class="toolbarButton download hidden" title="Download" tabindex="15" data-l10n-id="download">
+ <span data-l10n-id="download_label">Download</span>
+ </button>
+ <!-- <div class="toolbarButtonSpacer"></div> -->
+- <a href="#" id="viewBookmark" class="toolbarButton bookmark hiddenSmallView" title="Current view (copy or open in new window)" tabindex="16" data-l10n-id="bookmark">
++ <a href="#" id="viewBookmark" class="toolbarButton bookmark hidden" title="Current view (copy or open in new window)" tabindex="16" data-l10n-id="bookmark">
+ <span data-l10n-id="bookmark_label">Current View</span>
+ </a>
+
+--- viewer/viewer.js.orig 2014-01-20 16:22:49.000000000 +0100
++++ viewer/viewer.js 2014-01-20 16:32:24.000000000 +0100
+@@ -23,7 +23,7 @@
'use strict';
@@ -60,7 +72,7 @@
var DEFAULT_SCALE = 'auto';
var DEFAULT_SCALE_DELTA = 1.1;
var UNKNOWN_SCALE = 0;
-@@ -49,7 +49,7 @@
+@@ -55,7 +55,7 @@
};
PDFJS.imageResourcesPath = './images/';
@@ -69,19 +81,19 @@
var mozL10n = document.mozL10n || document.webL10n;
-@@ -1313,9 +1313,9 @@
-
- this.presentationMode.addEventListener('click',
- this.presentationModeClick.bind(this));
-- this.openFile.addEventListener('click', this.openFileClick.bind(this));
-+ //this.openFile.addEventListener('click', this.openFileClick.bind(this));
- this.print.addEventListener('click', this.printClick.bind(this));
-- this.download.addEventListener('click', this.downloadClick.bind(this));
-+ //this.download.addEventListener('click', this.downloadClick.bind(this));
-
- this.firstPage.addEventListener('click', this.firstPageClick.bind(this));
- this.lastPage.addEventListener('click', this.lastPageClick.bind(this));
-@@ -3991,8 +3991,8 @@
+@@ -1581,9 +1581,9 @@
+ // (except for toggleHandTool, hand_tool.js is responsible for it):
+ { element: this.presentationModeButton,
+ handler: this.presentationModeClick },
+- { element: this.openFile, handler: this.openFileClick },
++ //{ element: this.openFile, handler: this.openFileClick },
+ { element: this.print, handler: this.printClick },
+- { element: this.download, handler: this.downloadClick },
++ //{ element: this.download, handler: this.downloadClick },
+ { element: this.firstPage, handler: this.firstPageClick },
+ { element: this.lastPage, handler: this.lastPageClick },
+ { element: this.pageRotateCw, handler: this.pageRotateCwClick },
+@@ -4806,8 +4806,8 @@
document.body.appendChild(fileInput);
if (!window.File || !window.FileReader || !window.FileList || !window.Blob) {
@@ -92,7 +104,7 @@
} else {
document.getElementById('fileInput').value = null;
}
-@@ -4147,14 +4147,14 @@
+@@ -4970,14 +4970,14 @@
document.getElementById('presentationMode').addEventListener('click',
SecondaryToolbar.presentationModeClick.bind(SecondaryToolbar));
@@ -109,29 +121,5 @@
+// document.getElementById('download').addEventListener('click',
+// SecondaryToolbar.downloadClick.bind(SecondaryToolbar));
- document.getElementById('contextFirstPage').addEventListener('click',
- SecondaryToolbar.firstPageClick.bind(SecondaryToolbar));
-@@ -4229,8 +4229,8 @@
- store.set('scrollLeft', Math.round(topLeft[0]));
- store.set('scrollTop', Math.round(topLeft[1]));
- });
-- var href = PDFView.getAnchorUrl(pdfOpenParams);
-- document.getElementById('viewBookmark').href = href;
-+ //var href = PDFView.getAnchorUrl(pdfOpenParams);
-+ //document.getElementById('viewBookmark').href = href;
-
- // Update the current bookmark in the browsing history.
- PDFHistory.updateCurrentBookmark(pdfOpenParams, pageNumber);
-@@ -4273,9 +4273,9 @@
- PDFView.setTitleUsingUrl(file.name);
-
- // URL does not reflect proper document location - hiding some icons.
-- document.getElementById('viewBookmark').setAttribute('hidden', 'true');
-- document.getElementById('download').setAttribute('hidden', 'true');
-- document.getElementById('secondaryDownload').setAttribute('hidden', 'true');
-+ //document.getElementById('viewBookmark').setAttribute('hidden', 'true');
-+ //document.getElementById('download').setAttribute('hidden', 'true');
-+ //document.getElementById('secondaryDownload').setAttribute('hidden', 'true');
- }, true);
-
- function selectScaleOption(value) {
+
+ PDFView.open(file, 0);
diff --git a/plugins/pdfviewer/viewer/compatibility.js b/plugins/pdfviewer/viewer/compatibility.js
index 23ca69e..433e617 100644
--- a/plugins/pdfviewer/viewer/compatibility.js
+++ b/plugins/pdfviewer/viewer/compatibility.js
@@ -361,12 +361,16 @@ if (typeof PDFJS === 'undefined') {
if (index >= 0 && remove)
list.splice(index, 1);
element.className = list.join(' ');
+ return (index >= 0);
}
var classListPrototype = {
add: function(name) {
changeList(this.element, name, true, false);
},
+ contains: function(name) {
+ return changeList(this.element, name, false, false);
+ },
remove: function(name) {
changeList(this.element, name, false, true);
},
@@ -438,6 +442,14 @@ if (typeof PDFJS === 'undefined') {
}
})();
+// Checks if possible to use URL.createObjectURL()
+(function checkOnBlobSupport() {
+ // sometimes IE loosing the data created with createObjectURL(), see #3977
+ if (navigator.userAgent.indexOf('Trident') >= 0) {
+ PDFJS.disableCreateObjectURL = true;
+ }
+})();
+
// Checks if navigator.language is supported
(function checkNavigatorLanguage() {
if ('language' in navigator)
diff --git a/plugins/pdfviewer/viewer/debugger.js b/plugins/pdfviewer/viewer/debugger.js
index da57fc3..a70ad0c 100644
--- a/plugins/pdfviewer/viewer/debugger.js
+++ b/plugins/pdfviewer/viewer/debugger.js
@@ -240,6 +240,8 @@ var Stepper = (function StepperClosure() {
return out;
}
+ var opMap = null;
+
var glyphCommands = {
'showText': 0,
'showSpacedText': 0,
@@ -271,6 +273,12 @@ var Stepper = (function StepperClosure() {
headerRow.appendChild(c('th', 'args'));
panel.appendChild(content);
this.table = table;
+ if (!opMap) {
+ opMap = Object.create(null);
+ for (var key in PDFJS.OPS) {
+ opMap[PDFJS.OPS[key]] = key;
+ }
+ }
},
updateOperatorList: function updateOperatorList(operatorList) {
var self = this;
@@ -300,7 +308,7 @@ var Stepper = (function StepperClosure() {
breakCell.appendChild(cbox);
line.appendChild(breakCell);
line.appendChild(c('td', i.toString()));
- var fn = operatorList.fnArray[i];
+ var fn = opMap[operatorList.fnArray[i]];
var decArgs = args;
if (fn in glyphCommands) {
var glyphIndex = glyphCommands[fn];
diff --git a/plugins/pdfviewer/viewer/images/findbarButton-next-rtl.png b/plugins/pdfviewer/viewer/images/findbarButton-next-rtl.png
index 08a2c25..4b5551e 100644
Binary files a/plugins/pdfviewer/viewer/images/findbarButton-next-rtl.png and b/plugins/pdfviewer/viewer/images/findbarButton-next-rtl.png differ
diff --git a/plugins/pdfviewer/viewer/images/findbarButton-next.png b/plugins/pdfviewer/viewer/images/findbarButton-next.png
index beef8cc..f681e4e 100644
Binary files a/plugins/pdfviewer/viewer/images/findbarButton-next.png and b/plugins/pdfviewer/viewer/images/findbarButton-next.png differ
diff --git a/plugins/pdfviewer/viewer/images/findbarButton-previous-rtl.png b/plugins/pdfviewer/viewer/images/findbarButton-previous-rtl.png
index beef8cc..f681e4e 100644
Binary files a/plugins/pdfviewer/viewer/images/findbarButton-previous-rtl.png and b/plugins/pdfviewer/viewer/images/findbarButton-previous-rtl.png differ
diff --git a/plugins/pdfviewer/viewer/images/findbarButton-previous.png b/plugins/pdfviewer/viewer/images/findbarButton-previous.png
index 08a2c25..4b5551e 100644
Binary files a/plugins/pdfviewer/viewer/images/findbarButton-previous.png and b/plugins/pdfviewer/viewer/images/findbarButton-previous.png differ
diff --git a/plugins/pdfviewer/viewer/images/loading-small.png b/plugins/pdfviewer/viewer/images/loading-small.png
index 1b2df80..51848a7 100644
Binary files a/plugins/pdfviewer/viewer/images/loading-small.png and b/plugins/pdfviewer/viewer/images/loading-small.png differ
diff --git a/plugins/pdfviewer/viewer/images/secondaryToolbarButton-firstPage.png b/plugins/pdfviewer/viewer/images/secondaryToolbarButton-firstPage.png
index 59b3d34..2c1076d 100644
Binary files a/plugins/pdfviewer/viewer/images/secondaryToolbarButton-firstPage.png and b/plugins/pdfviewer/viewer/images/secondaryToolbarButton-firstPage.png differ
diff --git a/plugins/pdfviewer/viewer/images/secondaryToolbarButton-lastPage.png b/plugins/pdfviewer/viewer/images/secondaryToolbarButton-lastPage.png
index 3967cc6..55a9efe 100644
Binary files a/plugins/pdfviewer/viewer/images/secondaryToolbarButton-lastPage.png and b/plugins/pdfviewer/viewer/images/secondaryToolbarButton-lastPage.png differ
diff --git a/plugins/pdfviewer/viewer/images/secondaryToolbarButton-rotateCcw.png b/plugins/pdfviewer/viewer/images/secondaryToolbarButton-rotateCcw.png
index ffe6293..d23d84a 100644
Binary files a/plugins/pdfviewer/viewer/images/secondaryToolbarButton-rotateCcw.png and b/plugins/pdfviewer/viewer/images/secondaryToolbarButton-rotateCcw.png differ
diff --git a/plugins/pdfviewer/viewer/images/secondaryToolbarButton-rotateCw.png b/plugins/pdfviewer/viewer/images/secondaryToolbarButton-rotateCw.png
index 1fe2a8f..f36bba8 100644
Binary files a/plugins/pdfviewer/viewer/images/secondaryToolbarButton-rotateCw.png and b/plugins/pdfviewer/viewer/images/secondaryToolbarButton-rotateCw.png differ
diff --git a/plugins/pdfviewer/viewer/images/shadow.png b/plugins/pdfviewer/viewer/images/shadow.png
index dd009dc..31d3bdb 100644
Binary files a/plugins/pdfviewer/viewer/images/shadow.png and b/plugins/pdfviewer/viewer/images/shadow.png differ
diff --git a/plugins/pdfviewer/viewer/images/texture.png b/plugins/pdfviewer/viewer/images/texture.png
index df00864..eb5ccb5 100644
Binary files a/plugins/pdfviewer/viewer/images/texture.png and b/plugins/pdfviewer/viewer/images/texture.png differ
diff --git a/plugins/pdfviewer/viewer/images/toolbarButton-bookmark.png b/plugins/pdfviewer/viewer/images/toolbarButton-bookmark.png
index 1e5259a..b27050e 100644
Binary files a/plugins/pdfviewer/viewer/images/toolbarButton-bookmark.png and b/plugins/pdfviewer/viewer/images/toolbarButton-bookmark.png differ
diff --git a/plugins/pdfviewer/viewer/images/toolbarButton-download.png b/plugins/pdfviewer/viewer/images/toolbarButton-download.png
index 8676d8e..7755eee 100644
Binary files a/plugins/pdfviewer/viewer/images/toolbarButton-download.png and b/plugins/pdfviewer/viewer/images/toolbarButton-download.png differ
diff --git a/plugins/pdfviewer/viewer/images/toolbarButton-menuArrows.png b/plugins/pdfviewer/viewer/images/toolbarButton-menuArrows.png
index 31b06b5..63a7c32 100644
Binary files a/plugins/pdfviewer/viewer/images/toolbarButton-menuArrows.png and b/plugins/pdfviewer/viewer/images/toolbarButton-menuArrows.png differ
diff --git a/plugins/pdfviewer/viewer/images/toolbarButton-openFile.png b/plugins/pdfviewer/viewer/images/toolbarButton-openFile.png
index fc7023f..e139f30 100644
Binary files a/plugins/pdfviewer/viewer/images/toolbarButton-openFile.png and b/plugins/pdfviewer/viewer/images/toolbarButton-openFile.png differ
diff --git a/plugins/pdfviewer/viewer/images/toolbarButton-pageDown-rtl.png b/plugins/pdfviewer/viewer/images/toolbarButton-pageDown-rtl.png
index c0051f8..9ba3667 100644
Binary files a/plugins/pdfviewer/viewer/images/toolbarButton-pageDown-rtl.png and b/plugins/pdfviewer/viewer/images/toolbarButton-pageDown-rtl.png differ
diff --git a/plugins/pdfviewer/viewer/images/toolbarButton-pageDown.png b/plugins/pdfviewer/viewer/images/toolbarButton-pageDown.png
index 762ac43..272a3ca 100644
Binary files a/plugins/pdfviewer/viewer/images/toolbarButton-pageDown.png and b/plugins/pdfviewer/viewer/images/toolbarButton-pageDown.png differ
diff --git a/plugins/pdfviewer/viewer/images/toolbarButton-pageUp-rtl.png b/plugins/pdfviewer/viewer/images/toolbarButton-pageUp-rtl.png
index 0d49d8e..da02bc6 100644
Binary files a/plugins/pdfviewer/viewer/images/toolbarButton-pageUp-rtl.png and b/plugins/pdfviewer/viewer/images/toolbarButton-pageUp-rtl.png differ
diff --git a/plugins/pdfviewer/viewer/images/toolbarButton-pageUp.png b/plugins/pdfviewer/viewer/images/toolbarButton-pageUp.png
index 3155b8b..a4d6c8e 100644
Binary files a/plugins/pdfviewer/viewer/images/toolbarButton-pageUp.png and b/plugins/pdfviewer/viewer/images/toolbarButton-pageUp.png differ
diff --git a/plugins/pdfviewer/viewer/images/toolbarButton-presentationMode.png b/plugins/pdfviewer/viewer/images/toolbarButton-presentationMode.png
index fa73095..2bd1c1d 100644
Binary files a/plugins/pdfviewer/viewer/images/toolbarButton-presentationMode.png and b/plugins/pdfviewer/viewer/images/toolbarButton-presentationMode.png differ
diff --git a/plugins/pdfviewer/viewer/images/toolbarButton-print.png b/plugins/pdfviewer/viewer/images/toolbarButton-print.png
index fef84dd..ccc6208 100644
Binary files a/plugins/pdfviewer/viewer/images/toolbarButton-print.png and b/plugins/pdfviewer/viewer/images/toolbarButton-print.png differ
diff --git a/plugins/pdfviewer/viewer/images/toolbarButton-search.png b/plugins/pdfviewer/viewer/images/toolbarButton-search.png
index 604e652..e52370e 100644
Binary files a/plugins/pdfviewer/viewer/images/toolbarButton-search.png and b/plugins/pdfviewer/viewer/images/toolbarButton-search.png differ
diff --git a/plugins/pdfviewer/viewer/images/toolbarButton-secondaryToolbarToggle-rtl.png b/plugins/pdfviewer/viewer/images/toolbarButton-secondaryToolbarToggle-rtl.png
index 9793024..145316b 100644
Binary files a/plugins/pdfviewer/viewer/images/toolbarButton-secondaryToolbarToggle-rtl.png and b/plugins/pdfviewer/viewer/images/toolbarButton-secondaryToolbarToggle-rtl.png differ
diff --git a/plugins/pdfviewer/viewer/images/toolbarButton-secondaryToolbarToggle.png b/plugins/pdfviewer/viewer/images/toolbarButton-secondaryToolbarToggle.png
index ddd8a87..02ed6c6 100644
Binary files a/plugins/pdfviewer/viewer/images/toolbarButton-secondaryToolbarToggle.png and b/plugins/pdfviewer/viewer/images/toolbarButton-secondaryToolbarToggle.png differ
diff --git a/plugins/pdfviewer/viewer/images/toolbarButton-sidebarToggle-rtl.png b/plugins/pdfviewer/viewer/images/toolbarButton-sidebarToggle-rtl.png
index d9946fd..c308668 100644
Binary files a/plugins/pdfviewer/viewer/images/toolbarButton-sidebarToggle-rtl.png and b/plugins/pdfviewer/viewer/images/toolbarButton-sidebarToggle-rtl.png differ
diff --git a/plugins/pdfviewer/viewer/images/toolbarButton-sidebarToggle.png b/plugins/pdfviewer/viewer/images/toolbarButton-sidebarToggle.png
index 5a937c7..be9eceb 100644
Binary files a/plugins/pdfviewer/viewer/images/toolbarButton-sidebarToggle.png and b/plugins/pdfviewer/viewer/images/toolbarButton-sidebarToggle.png differ
diff --git a/plugins/pdfviewer/viewer/images/toolbarButton-viewOutline-rtl.png b/plugins/pdfviewer/viewer/images/toolbarButton-viewOutline-rtl.png
index d57a12c..21ceb3b 100644
Binary files a/plugins/pdfviewer/viewer/images/toolbarButton-viewOutline-rtl.png and b/plugins/pdfviewer/viewer/images/toolbarButton-viewOutline-rtl.png differ
diff --git a/plugins/pdfviewer/viewer/images/toolbarButton-viewOutline.png b/plugins/pdfviewer/viewer/images/toolbarButton-viewOutline.png
index cb3967b..9b2e2f5 100644
Binary files a/plugins/pdfviewer/viewer/images/toolbarButton-viewOutline.png and b/plugins/pdfviewer/viewer/images/toolbarButton-viewOutline.png differ
diff --git a/plugins/pdfviewer/viewer/images/toolbarButton-viewThumbnail.png b/plugins/pdfviewer/viewer/images/toolbarButton-viewThumbnail.png
index 3a27f04..d71dd27 100644
Binary files a/plugins/pdfviewer/viewer/images/toolbarButton-viewThumbnail.png and b/plugins/pdfviewer/viewer/images/toolbarButton-viewThumbnail.png differ
diff --git a/plugins/pdfviewer/viewer/images/toolbarButton-zoomOut.png b/plugins/pdfviewer/viewer/images/toolbarButton-zoomOut.png
index 810fbf9..7991ee7 100644
Binary files a/plugins/pdfviewer/viewer/images/toolbarButton-zoomOut.png and b/plugins/pdfviewer/viewer/images/toolbarButton-zoomOut.png differ
diff --git a/plugins/pdfviewer/viewer/locale/de/viewer.properties b/plugins/pdfviewer/viewer/locale/de/viewer.properties
index 5988c82..c9908b5 100644
--- a/plugins/pdfviewer/viewer/locale/de/viewer.properties
+++ b/plugins/pdfviewer/viewer/locale/de/viewer.properties
@@ -42,6 +42,8 @@ bookmark.title=Aktuelle Ansicht (Kopieren oder in einem neuen Fenster öffnen)
bookmark_label=Aktuelle Ansicht
# Secondary toolbar and context menu
+tools.title=Werkzeuge
+tools_label=Werkzeuge
first_page.title=Erste Seite
first_page.label=Erste Seite
first_page_label=Erste Seite
@@ -51,9 +53,14 @@ last_page_label=Letzte Seite
page_rotate_cw.title=Im Uhrzeigersinn drehen
page_rotate_cw.label=Im Uhrzeigersinn drehen
page_rotate_cw_label=Im Uhrzeigersinn drehen
-page_rotate_ccw.title=Entgegen dem Uhrzeigersinn drehen
-page_rotate_ccw.label=Entgegen dem Uhrzeigersinn drehen
-page_rotate_ccw_label=Entgegen dem Uhrzeigersinn drehen
+page_rotate_ccw.title=Gegen den Uhrzeigersinn drehen
+page_rotate_ccw.label=Gegen den Uhrzeigersinn drehen
+page_rotate_ccw_label=Gegen den Uhrzeigersinn drehen
+
+hand_tool_enable.title=Hand-Werkzeug aktivieren
+hand_tool_enable_label=Hand-Werkzeug aktivieren
+hand_tool_disable.title=Hand-Werkzeug deaktivieren
+hand_tool_disable_label=Hand-Werkzeug deaktivieren
# Tooltips and alt text for side panel toolbar buttons
# (the _label strings are alt text for the buttons, the .title strings are
@@ -91,9 +98,9 @@ find_not_found=Ausdruck nicht gefunden
error_more_info=Mehr Info
error_less_info=Weniger Info
error_close=SchlieÃen
-# LOCALIZATION NOTE (error_build): "{{build}}" will be replaced by the PDF.JS
-# build ID.
-error_build=PDF.JS Build: {{build}}
+# LOCALIZATION NOTE (error_version_info): "{{version}}" and "{{build}}" will be
+# replaced by the PDF.JS version and build ID.
+error_version_info=PDF.js v{{version}} (build: {{build}})
# LOCALIZATION NOTE (error_message): "{{message}}" will be replaced by an
# english string describing the error.
error_message=Nachricht: {{message}}
@@ -104,7 +111,7 @@ error_stack=Stack: {{stack}}
error_file=Datei: {{file}}
# LOCALIZATION NOTE (error_line): "{{line}}" will be replaced with a line number
error_line=Zeile: {{line}}
-rendering_error=Das PDF konnte nicht angezeigt werden.
+rendering_error=Die PDF-Datei konnte nicht angezeigt werden.
# Predefined zoom values
page_scale_width=Seitenbreite
@@ -114,15 +121,21 @@ page_scale_actual=OriginalgröÃe
# Loading indicator messages
loading_error_indicator=Fehler
-loading_error=Das PDF konnte nicht geladen werden.
+loading_error=Die PDF-Datei konnte nicht geladen werden.
invalid_file_error=Ungültige oder beschädigte PDF-Datei.
+missing_file_error=Fehlende PDF-Datei.
# LOCALIZATION NOTE (text_annotation_type.alt): This is used as a tooltip.
# "{{type}}" will be replaced with an annotation type from a list defined in
# the PDF spec (32000-1:2008 Table 169 â Annotation types).
# Some common types are e.g.: "Check", "Text", "Comment", "Note"
text_annotation_type.alt=[{{type}} Annotation]
-request_password=Das PDF ist passwortgeschützt:
+password_label=Geben Sie das Passwort ein, um diese Datei zu öffnen.
+password_invalid=Ungültiges Passwort. Versuchen Sie es erneut.
+password_ok=OK
+password_cancel=Abbrechen
printing_not_supported=Warnung: Drucken wird durch diesen Browser nicht vollständig unterstützt.
+printing_not_ready=Warnung: Die PDF-Datei ist zum Drucken noch nicht vollständig geladen.
web_fonts_disabled=Webfonts sind deaktiviert: Eingebundene PDF-Schriftarten können nicht verwendet werden.
+document_colors_disabled=PDF-Dateien können eigene Farben nicht verwenden: \'Seiten das Verwenden von eigenen Farben erlauben\' ist im Browser deaktiviert.
diff --git a/plugins/pdfviewer/viewer/locale/en-US/viewer.properties b/plugins/pdfviewer/viewer/locale/en-US/viewer.properties
index 629bfb2..2c893a4 100644
--- a/plugins/pdfviewer/viewer/locale/en-US/viewer.properties
+++ b/plugins/pdfviewer/viewer/locale/en-US/viewer.properties
@@ -57,6 +57,11 @@ page_rotate_ccw.title=Rotate Counterclockwise
page_rotate_ccw.label=Rotate Counterclockwise
page_rotate_ccw_label=Rotate Counterclockwise
+hand_tool_enable.title=Enable hand tool
+hand_tool_enable_label=Enable hand tool
+hand_tool_disable.title=Disable hand tool
+hand_tool_disable_label=Disable hand tool
+
# Tooltips and alt text for side panel toolbar buttons
# (the _label strings are alt text for the buttons, the .title strings are
# tooltips)
diff --git a/plugins/pdfviewer/viewer/locale/es/viewer.properties b/plugins/pdfviewer/viewer/locale/es/viewer.properties
index 188cbed..fc8848f 100644
--- a/plugins/pdfviewer/viewer/locale/es/viewer.properties
+++ b/plugins/pdfviewer/viewer/locale/es/viewer.properties
@@ -38,10 +38,12 @@ print.title=Imprimir
print_label=Imprimir
download.title=Descargar
download_label=Descargar
-bookmark.title=Vista actual (copie o abra en una ventana nueva)
+bookmark.title=Vista actual (para copiar o abrir en otra ventana)
bookmark_label=Vista actual
# Secondary toolbar and context menu
+tools.title=Herramientas
+tools_label=Herramientas
first_page.title=Ir a la primera página
first_page.label=Ir a la primera página
first_page_label=Ir a la primera página
@@ -55,6 +57,11 @@ page_rotate_ccw.title=Girar a la izquierda
page_rotate_ccw.label=Girar a la izquierda
page_rotate_ccw_label=Girar a la izquierda
+hand_tool_enable.title=Activar la herramienta Mano
+hand_tool_enable_label=Activar la herramienta Mano
+hand_tool_disable.title=Desactivar la herramienta Mano
+hand_tool_disable_label=Desactivar la herramienta Mano
+
# Tooltips and alt text for side panel toolbar buttons
# (the _label strings are alt text for the buttons, the .title strings are
# tooltips)
@@ -118,14 +125,17 @@ loading_error=Ocurrió un error al cargar el PDF.
invalid_file_error=El archivo PDF no es válido o está dañado.
missing_file_error=Falta el archivo PDF.
-# LOCALIZATION NOTE (text_annotation_type): This is used as a tooltip.
+# LOCALIZATION NOTE (text_annotation_type.alt): This is used as a tooltip.
# "{{type}}" will be replaced with an annotation type from a list defined in
# the PDF spec (32000-1:2008 Table 169 â Annotation types).
# Some common types are e.g.: "Check", "Text", "Comment", "Note"
text_annotation_type.alt=[Anotación {{type}}]
-request_password=El archivo PDF está protegido por una contraseña:
+password_label=Escriba la contraseña para abrir este archivo PDF.
+password_invalid=La contraseña no es válida. Inténtelo de nuevo.
+password_ok=Aceptar
+password_cancel=Cancelar
printing_not_supported=Aviso: Este navegador no es compatible completamente con la impresión.
printing_not_ready=Aviso: El PDF no se ha cargado completamente para su impresión.
web_fonts_disabled=Se han desactivado los tipos de letra web: no se pueden usar los tipos de letra incrustados en el PDF.
-web_colors_disabled=Se han desactivado los colores web.
+document_colors_disabled=No se permite que los documentos PDF usen sus propios colores: la opción «Permitir que las páginas elijan sus propios colores» está desactivada en el navegador.
diff --git a/plugins/pdfviewer/viewer/locale/ja/viewer.properties b/plugins/pdfviewer/viewer/locale/ja/viewer.properties
index dd024ca..3b35bbd 100644
--- a/plugins/pdfviewer/viewer/locale/ja/viewer.properties
+++ b/plugins/pdfviewer/viewer/locale/ja/viewer.properties
@@ -23,7 +23,7 @@ next_label=次ã¸
# Do not translate "{{pageCount}}", it will be substituted with a number
# representing the total number of pages.
page_label=ãã¼ã¸ï¼
-page_of=of {{pageCount}}
+page_of=/ {{pageCount}}
zoom_out.title=縮å°
zoom_out_label=縮å°
@@ -57,6 +57,11 @@ page_rotate_ccw.title=å·¦å転
page_rotate_ccw.label=å·¦å転
page_rotate_ccw_label=å·¦å転
+hand_tool_enable.title=æã®ã²ããã¼ã«ãæå¹ã«ãã
+hand_tool_enable_label=æã®ã²ããã¼ã«ãæå¹ã«ãã
+hand_tool_disable.title=æã®ã²ããã¼ã«ãç¡å¹ã«ãã
+hand_tool_disable_label=æã®ã²ããã¼ã«ãç¡å¹ã«ãã
+
# Tooltips and alt text for side panel toolbar buttons
# (the _label strings are alt text for the buttons, the .title strings are
# tooltips)
@@ -125,8 +130,10 @@ missing_file_error=PDF ãã¡ã¤ã«ãè¦ã¤ããã¾ããã
# the PDF spec (32000-1:2008 Table 169 â Annotation types).
# Some common types are e.g.: "Check", "Text", "Comment", "Note"
text_annotation_type.alt=[{{type}} 注é]
-request_password=PDF ã¯ãã¹ã¯ã¼ãã«ãã£ã¦ä¿è·ããã¦ãã¾ã
-invalid_password=ç¡å¹ãªãã¹ã¯ã¼ãã§ã
+password_label=ãã® PDF ãã¡ã¤ã«ãéãããã®ãã¹ã¯ã¼ããå
¥åãã¦ãã ããã
+password_invalid=ç¡å¹ãªãã¹ã¯ã¼ãã§ããããä¸åº¦ããç´ãã¦ãã ããã
+password_ok=OK
+password_cancel=ãã£ã³ã»ã«
printing_not_supported=è¦åï¼ãã®ãã©ã¦ã¶ã§ã¯å°å·ãå®å
¨ã«ãµãã¼ãããã¦ãã¾ãã
printing_not_ready=è¦åï¼PDF ãå°å·ããããã®èªã¿è¾¼ã¿ãçµäºãã¦ãã¾ãã
diff --git a/plugins/pdfviewer/viewer/locale/locale.properties b/plugins/pdfviewer/viewer/locale/locale.properties
index d706328..7e94bc6 100644
--- a/plugins/pdfviewer/viewer/locale/locale.properties
+++ b/plugins/pdfviewer/viewer/locale/locale.properties
@@ -70,8 +70,8 @@
[sr]
@import url(sr/viewer.properties)
-[sv]
- at import url(sv/viewer.properties)
+[sv-SE]
+ at import url(sv-SE/viewer.properties)
[tr]
@import url(tr/viewer.properties)
diff --git a/plugins/pdfviewer/viewer/locale/nl/viewer.properties b/plugins/pdfviewer/viewer/locale/nl/viewer.properties
index 9288af8..38f266d 100644
--- a/plugins/pdfviewer/viewer/locale/nl/viewer.properties
+++ b/plugins/pdfviewer/viewer/locale/nl/viewer.properties
@@ -57,6 +57,11 @@ page_rotate_ccw.title=Tegen de klok in roteren
page_rotate_ccw.label=Tegen de klok in roteren
page_rotate_ccw_label=Tegen de klok in roteren
+hand_tool_enable.title=Handcursor inschakelen
+hand_tool_enable_label=Handcursor inschakelen
+hand_tool_disable.title=Handcursor uitschakelen
+hand_tool_disable_label=Handcursor uitschakelen
+
# Tooltips and alt text for side panel toolbar buttons
# (the _label strings are alt text for the buttons, the .title strings are
# tooltips)
diff --git a/plugins/pdfviewer/viewer/locale/zh-CN/viewer.properties b/plugins/pdfviewer/viewer/locale/zh-CN/viewer.properties
index 28a9971..bbc77c2 100644
--- a/plugins/pdfviewer/viewer/locale/zh-CN/viewer.properties
+++ b/plugins/pdfviewer/viewer/locale/zh-CN/viewer.properties
@@ -42,6 +42,8 @@ bookmark.title=å½åè§å¾ï¼å¤å¶æå¨æ°çªå£ä¸æå¼ï¼
bookmark_label=å½åè§å¾
# Secondary toolbar and context menu
+tools.title=å·¥å
·
+tools_label=å·¥å
·
first_page.title=转å°ç¬¬ä¸é¡µ
first_page.label=转å°ç¬¬ä¸é¡µ
first_page_label=转å°ç¬¬ä¸é¡µ
@@ -55,6 +57,11 @@ page_rotate_ccw.title=éæ¶éæ转
page_rotate_ccw.label=éæ¶éæ转
page_rotate_ccw_label=éæ¶éæ转
+hand_tool_enable.title=å¯ç¨æåå·¥å
·
+hand_tool_enable_label=å¯ç¨æåå·¥å
·
+hand_tool_disable.title=ç¦ç¨æåå·¥å
·
+hand_tool_disable_label=ç¦ç¨æåå·¥å
·
+
# Tooltips and alt text for side panel toolbar buttons
# (the _label strings are alt text for the buttons, the .title strings are
# tooltips)
@@ -123,7 +130,12 @@ missing_file_error=缺失 PDF æ件ã
# the PDF spec (32000-1:2008 Table 169 â Annotation types).
# Some common types are e.g.: "Check", "Text", "Comment", "Note"
text_annotation_type.alt=[{{type}} 注解]
-request_password=该 PDF ææ¡£åå¯ç ä¿æ¤ï¼
+password_label=è¾å
¥ PDF æ件çå¯ç ã
+password_invalid=å¯ç æ æï¼è¯·éæ°è¾å
¥ã
+password_ok=ç¡®å®
+password_cancel=åæ¶
printing_not_supported=è¦åï¼è¯¥æµè§å¨ä¸è½å®å
¨æ¯ææå°ã
+printing_not_ready=è¦åï¼æ¤ PDF 没æå®å
¨è¢«è½½å
¥ä»¥ä¾æå°ã
web_fonts_disabled=Web 页é¢åä½å·²è¢«ç¦ç¨ï¼æ æ³ä½¿ç¨åµå
¥å° PDF ä¸çåä½ã
+document_colors_disabled=PDF æ件ä¸è¢«å
许使ç¨èªå·±çé¢è²ï¼\âå
许页é¢éæ©èªå·±çé¢è²â\没æå¨è¯¥æµè§å¨ä¸è¢«æ¿æ´»ã
diff --git a/plugins/pdfviewer/viewer/locale/zh-TW/viewer.properties b/plugins/pdfviewer/viewer/locale/zh-TW/viewer.properties
index 766ff14..3456495 100644
--- a/plugins/pdfviewer/viewer/locale/zh-TW/viewer.properties
+++ b/plugins/pdfviewer/viewer/locale/zh-TW/viewer.properties
@@ -57,6 +57,11 @@ page_rotate_ccw.title=éæéæè½
page_rotate_ccw.label=éæéæè½
page_rotate_ccw_label=éæéæè½
+hand_tool_enable.title=åç¨æåå·¥å
·
+hand_tool_enable_label=åç¨æåå·¥å
·
+hand_tool_disable.title=åç¨æåå·¥å
·
+hand_tool_disable_label=åç¨æåå·¥å
·
+
# Tooltips and alt text for side panel toolbar buttons
# (the _label strings are alt text for the buttons, the .title strings are
# tooltips)
@@ -125,8 +130,10 @@ missing_file_error=æ¾ä¸å° PDF æªæ¡ã
# the PDF spec (32000-1:2008 Table 169 â Annotation types).
# Some common types are e.g.: "Check", "Text", "Comment", "Note"
text_annotation_type.alt=[{{type}} 註解]
-request_password=PDF 已被å¯ç¢¼ä¿è·:
-invalid_password=å¯ç¢¼ç¡æã
+password_label=è«è¼¸å
¥ç¨ä¾éåæ¤ PDF æªæ¡çå¯ç¢¼ã
+password_invalid=å¯ç¢¼ä¸æ£ç¢ºï¼è«å試ä¸æ¬¡ã
+password_ok=確å®
+password_cancel=åæ¶
printing_not_supported=è¦å: æ¤ç覽å¨æªå®æ´æ¯æ´åå°åè½ã
printing_not_ready=è¦å: æ¤ PDF æªå®æä¸è¼ä»¥ä¾åå°ã
diff --git a/plugins/pdfviewer/viewer/pdf.js b/plugins/pdfviewer/viewer/pdf.js
index 0ff40a1..c3723f5 100644
--- a/plugins/pdfviewer/viewer/pdf.js
+++ b/plugins/pdfviewer/viewer/pdf.js
@@ -1,166 +1,7610 @@
-"undefined"===typeof PDFJS&&(("undefined"!==typeof window?window:this).PDFJS={});PDFJS.version="0.8.573";PDFJS.build="e97e003";
-(function(){var D,V;function S(b){ba>=na&&(J("Info: "+b),PDFJS.LogManager.notify("info",b))}function F(b){ba>=ca&&(J("Warning: "+b),PDFJS.LogManager.notify("warn",b))}function m(b){if(1<arguments.length){var a=["Error:"];a.push.apply(a,arguments);J.apply(null,a);b=[].join.call(arguments," ")}else J("Error: "+b);var a=J,c;try{throw Error();}catch(e){c=e.stack?e.stack.split("\n").slice(2).join("\n"):""}a(c);PDFJS.LogManager.notify("error",b);throw Error(b);}function K(b){F("TODO: "+b)}function oa(b,
-a){if(!a)return b;if(0<=a.indexOf(":"))return a;if("/"==a.charAt(0)){var c=b.indexOf("://"),c=b.indexOf("/",c+3);return b.substring(0,c)+a}var e=b.length,c=b.lastIndexOf("#"),e=0<=c?c:e,c=b.lastIndexOf("?",e),c=b.lastIndexOf("/",0<=c?c:e);return b.substring(0,c+1)+a}function Y(b,a){if(!b)return!1;var c=b.indexOf(":");if(0>c)return a;switch(b.substr(0,c)){case "http":case "https":case "ftp":case "mailto":return!0;default:return!1}}function W(b,a,c){Object.defineProperty(b,a,{value:c,enumerable:!0,
-configurable:!0,writable:!1});return c}function T(b){var a,c=b.length,e="";if("\u00fe"===b[0]&&"\u00ff"===b[1])for(a=2;a<c;a+=2)e+=String.fromCharCode(b.charCodeAt(a)<<8|b.charCodeAt(a+1));else for(a=0;a<c;++a)var d=pa[b.charCodeAt(a)],e=e+(d?String.fromCharCode(d):b.charAt(a));return e}function L(b){return"boolean"==typeof b}function M(b){return b instanceof Name}function O(b,a){if(!(b instanceof Dict))return!1;if(!a)return!0;var c=b.get("Type");return M(c)&&c.name==a}function B(b){return b instanceof
-Array}function X(b){return"object"==typeof b&&null!==b&&void 0!==b&&"getBytes"in b}function da(b){if("object"!=typeof b)return!1;if(!O(b))if(X(b))b=b.dict;else return!1;return b.has("FunctionType")}function Z(b,a){this.name=b;this.comObj=a;this.callbackIndex=1;var c=this.callbacks={},e=this.actionHandler={};e.console_log=[function(a){J.apply(null,a)}];e.console_error="console"in v?[function(a){v.console.error.apply(null,a)}]:[function(a){J.apply(null,a)}];e._warn=[function(a){F(a)}];a.onmessage=function(d){var b=
-d.data;if(b.isReply)if(d=b.callbackId,b.callbackId in c){var f=c[d];delete c[d];f(b.data)}else m("Cannot resolve callback "+d);else b.action in e?(d=e[b.action],b.callbackId?(f=new x,f.then(function(c){a.postMessage({isReply:!0,callbackId:b.callbackId,data:c})}),d[0].call(d[1],b.data,f)):d[0].call(d[1],b.data)):m("Unkown action from worker: "+b.action)}}function qa(b,a,c){var e=new Image;e.onload=function(){c.resolve(b,e)};e.src="data:image/jpeg;base64,"+window.btoa(a)}function ea(b,a){var c=document.createElement("canvas");
-c.width=b;c.height=a;return c}function fa(b){b.mozCurrentTransform||(b._scaleX=b._scaleX||1,b._scaleY=b._scaleY||1,b._originalSave=b.save,b._originalRestore=b.restore,b._originalRotate=b.rotate,b._originalScale=b.scale,b._originalTranslate=b.translate,b._originalTransform=b.transform,b._originalSetTransform=b.setTransform,b._transformMatrix=[b._scaleX,0,0,b._scaleY,0,0],b._transformStack=[],Object.defineProperty(b,"mozCurrentTransform",{get:function(){return this._transformMatrix}}),Object.defineProperty(b,
-"mozCurrentTransformInverse",{get:function(){var a=this._transformMatrix,c=a[0],e=a[1],d=a[2],b=a[3],f=a[4],a=a[5],k=c*b-e*d,h=e*d-c*b;return[b/k,e/h,d/h,c/k,(b*f-d*a)/h,(e*f-c*a)/k]}}),b.save=function(){var a=this._transformMatrix;this._transformStack.push(a);this._transformMatrix=a.slice(0,6);this._originalSave()},b.restore=function(){var a=this._transformStack.pop();a&&(this._transformMatrix=a,this._originalRestore())},b.translate=function(a,c){var e=this._transformMatrix;e[4]=e[0]*a+e[2]*c+e[4];
-e[5]=e[1]*a+e[3]*c+e[5];this._originalTranslate(a,c)},b.scale=function(a,c){var e=this._transformMatrix;e[0]*=a;e[1]*=a;e[2]*=c;e[3]*=c;this._originalScale(a,c)},b.transform=function(a,c,e,d,g,f){var k=this._transformMatrix;this._transformMatrix=[k[0]*a+k[2]*c,k[1]*a+k[3]*c,k[0]*e+k[2]*d,k[1]*e+k[3]*d,k[0]*g+k[2]*f+k[4],k[1]*g+k[3]*f+k[5]];b._originalTransform(a,c,e,d,g,f)},b.setTransform=function(a,c,e,d,g,f){this._transformMatrix=[a,c,e,d,g,f];b._originalSetTransform(a,c,e,d,g,f)},b.rotate=function(a){var c=
-Math.cos(a),e=Math.sin(a),d=this._transformMatrix;this._transformMatrix=[d[0]*c+d[2]*e,d[1]*c+d[3]*e,d[0]*-e+d[2]*c,d[1]*-e+d[3]*c,d[4],d[5]];this._originalRotate(a)})}function ra(b){var a=b.width,c=b.height,e,d,g=a+1,f=new Uint8Array(g*(c+1)),k=new Uint8Array([0,2,4,0,1,0,5,4,8,10,0,8,0,2,1,0]),h=3,l=b.data,n=4*a,t=0;0!==l[3]&&(f[0]=1,++t);for(e=1;e<a;e++)l[h]!==l[h+4]&&(f[e]=l[h]?2:1,++t),h+=4;0!==l[h]&&(f[e]=2,++t);h+=4;for(b=1;b<c;b++){d=b*g;l[h-n]!==l[h]&&(f[d]=l[h]?1:8,++t);var y=(l[h]?4:0)+
-(l[h-n]?8:0);for(e=1;e<a;e++)y=(y>>2)+(l[h+4]?4:0)+(l[h-n+4]?8:0),k[y]&&(f[d+e]=k[y],++t),h+=4;l[h-n]!==l[h]&&(f[d+e]=l[h]?2:4,++t);h+=4;if(1E3<t)return null}h-=n;d=b*g;0!==l[h]&&(f[d]=8,++t);for(e=1;e<a;e++)l[h]!==l[h+4]&&(f[d+e]=l[h]?4:8,++t),h+=4;0!==l[h]&&(f[d+e]=4,++t);if(1E3<t)return null;var k=new Int32Array([0,g,-1,0,-g,0,0,0,1]),q=[];for(b=0;t&&b<=c;b++){h=b*g;for(e=h+a;h<e&&!f[h];)h++;if(h!==e){e=[h%g,b];d=f[h];l=h;do{n=k[d];do h+=n;while(!f[h]);n=f[h];5!==n&&10!==n?(d=n,f[h]=0):(d=n&51*
-d>>4,f[h]&=d>>2|d<<2);e.push(h%g);e.push(h/g|0);--t}while(l!==h);q.push(e);--b}}return function(f){f.save();f.scale(1/a,-1/c);f.translate(0,-c);f.beginPath();for(var d=0,e=q.length;d<e;d++){var b=q[d];f.moveTo(b[0],b[1]);for(var k=2,h=b.length;k<h;k+=2)f.lineTo(b[k],b[k+1])}f.fill();f.beginPath();f.restore()}}var v="undefined"===typeof window?this:window,U="undefined"==typeof window,ca=1,na=5,ba=ca,$=[0.0010,0,0,0.0010,0,0];V=0;v.PDFJS||(v.PDFJS={});v.PDFJS.pdfBug=!1;var J=function(){return"console"in
-v&&"log"in v.console?v.console.log.bind(v.console):function(){}}();PDFJS.isValidUrl=Y;PDFJS.LogManager=function(){var b=[];return{addLogger:function(a){b.push(a)},notify:function(a,c){for(var e=0,d=b.length;e<d;e++){var g=b[e];if(g[a])g[a](c)}}}}();var ga=PDFJS.PasswordResponses={NEED_PASSWORD:1,INCORRECT_PASSWORD:2};(function(){function b(a,c){this.name="PasswordException";this.message=a;this.code=c}b.prototype=Error();return b.constructor=b})();(function(){function b(a,c){this.name="UnknownErrorException";
-this.message=a;this.details=c}b.prototype=Error();return b.constructor=b})();(function(){function b(a){this.name="InvalidPDFException";this.message=a}b.prototype=Error();return b.constructor=b})();(function(){function b(a){this.name="MissingPDFException";this.message=a}b.prototype=Error();return b.constructor=b})();var sa=function(){function b(a){this.message=a}b.prototype=Error();b.prototype.name="NotImplementedException";return b.constructor=b}();(function(){function b(a,c){this.begin=a;this.end=
-c;this.message="Missing data [begin, end)"}b.prototype=Error();b.prototype.name="MissingDataException";return b.constructor=b})();(function(){function b(a){this.message=a}b.prototype=Error();b.prototype.name="XRefParseException";return b.constructor=b})();var ha=[1,0,0,1,0,0],s=PDFJS.Util=function(){function b(){}b.makeCssRgb=function(a){return"rgb("+a[0]+","+a[1]+","+a[2]+")"};b.makeCssCmyk=function(a){a=p.singletons.cmyk.getRgb(a,0);return b.makeCssRgb(a)};b.transform=function(a,c){return[a[0]*
-c[0]+a[2]*c[1],a[1]*c[0]+a[3]*c[1],a[0]*c[2]+a[2]*c[3],a[1]*c[2]+a[3]*c[3],a[0]*c[4]+a[2]*c[5]+a[4],a[1]*c[4]+a[3]*c[5]+a[5]]};b.applyTransform=function(a,c){return[a[0]*c[0]+a[1]*c[2]+c[4],a[0]*c[1]+a[1]*c[3]+c[5]]};b.applyInverseTransform=function(a,c){var e=c[0]*c[3]-c[1]*c[2];return[(a[0]*c[3]-a[1]*c[2]+c[2]*c[5]-c[4]*c[3])/e,(-a[0]*c[1]+a[1]*c[0]+c[4]*c[1]-c[5]*c[0])/e]};b.getAxialAlignedBoundingBox=function(a,c){var e=b.applyTransform(a,c),d=b.applyTransform(a.slice(2,4),c),g=b.applyTransform([a[0],
-a[3]],c),f=b.applyTransform([a[2],a[1]],c);return[Math.min(e[0],d[0],g[0],f[0]),Math.min(e[1],d[1],g[1],f[1]),Math.max(e[0],d[0],g[0],f[0]),Math.max(e[1],d[1],g[1],f[1])]};b.inverseTransform=function(a){var c=a[0]*a[3]-a[1]*a[2];return[a[3]/c,-a[1]/c,-a[2]/c,a[0]/c,(a[2]*a[5]-a[4]*a[3])/c,(a[4]*a[1]-a[5]*a[0])/c]};b.apply3dTransform=function(a,c){return[a[0]*c[0]+a[1]*c[1]+a[2]*c[2],a[3]*c[0]+a[4]*c[1]+a[5]*c[2],a[6]*c[0]+a[7]*c[1]+a[8]*c[2]]};b.singularValueDecompose2dScale=function(a){var c=[a[0],
-a[2],a[1],a[3]],e=a[0]*c[0]+a[1]*c[2],d=a[2]*c[1]+a[3]*c[3],b=(e+d)/2;a=Math.sqrt((e+d)*(e+d)-4*(e*d-(a[2]*c[0]+a[3]*c[2])*(a[0]*c[1]+a[1]*c[3])))/2;c=b-a||1;return[Math.sqrt(b+a||1),Math.sqrt(c)]};b.normalizeRect=function(a){var c=a.slice(0);a[0]>a[2]&&(c[0]=a[2],c[2]=a[0]);a[1]>a[3]&&(c[1]=a[3],c[3]=a[1]);return c};b.intersect=function(a,c){function e(a,c){return a-c}var d=[a[0],a[2],c[0],c[2]].sort(e),g=[a[1],a[3],c[1],c[3]].sort(e),f=[];a=b.normalizeRect(a);c=b.normalizeRect(c);if(d[0]===a[0]&&
-d[1]===c[0]||d[0]===c[0]&&d[1]===a[0])f[0]=d[1],f[2]=d[2];else return!1;if(g[0]===a[1]&&g[1]===c[1]||g[0]===c[1]&&g[1]===a[1])f[1]=g[1],f[3]=g[2];else return!1;return f};b.sign=function(a){return 0>a?-1:1};b.concatenateToArray=function(a,c){Array.prototype.push.apply(a,c)};b.prependToArray=function(a,c){Array.prototype.unshift.apply(a,c)};b.extendObj=function(a,c){for(var e in c)a[e]=c[e]};b.getInheritableProperty=function(a,c){for(;a&&!a.has(c);)a=a.get("Parent");return a?a.get(c):null};b.inherit=
-function(a,c,e){a.prototype=Object.create(c.prototype);a.prototype.constructor=a;for(var d in e)a.prototype[d]=e[d]};b.loadScript=function(a,c){var e=document.createElement("script"),d=!1;e.setAttribute("src",a);c&&(e.onload=function(){d||c();d=!0});document.getElementsByTagName("head")[0].appendChild(e)};return b}();PDFJS.PageViewport=function(){function b(a,c,e,d,b,f){this.viewBox=a;this.scale=c;this.rotation=e;this.offsetX=d;this.offsetY=b;var k=(a[2]+a[0])/2,h=(a[3]+a[1])/2,l,n,t;e%=360;switch(0>
-e?e+360:e){case 180:e=-1;n=l=0;t=1;break;case 90:e=0;n=l=1;t=0;break;case 270:e=0;n=l=-1;t=0;break;default:e=1,n=l=0,t=-1}f&&(n=-n,t=-t);0===e?(d=Math.abs(h-a[1])*c+d,b=Math.abs(k-a[0])*c+b,f=Math.abs(a[3]-a[1])*c,a=Math.abs(a[2]-a[0])*c):(d=Math.abs(k-a[0])*c+d,b=Math.abs(h-a[1])*c+b,f=Math.abs(a[2]-a[0])*c,a=Math.abs(a[3]-a[1])*c);this.transform=[e*c,l*c,n*c,t*c,d-e*c*k-n*c*h,b-l*c*k-t*c*h];this.width=f;this.height=a;this.fontScale=c}b.prototype={clone:function(a){a=a||{};var c="scale"in a?a.scale:
-this.scale,e="rotation"in a?a.rotation:this.rotation;return new b(this.viewBox.slice(),c,e,this.offsetX,this.offsetY,a.dontFlip)},convertToViewportPoint:function(a,c){return s.applyTransform([a,c],this.transform)},convertToViewportRectangle:function(a){var c=s.applyTransform([a[0],a[1]],this.transform);a=s.applyTransform([a[2],a[3]],this.transform);return[c[0],c[1],a[0],a[1]]},convertToPdfPoint:function(a,c){return s.applyInverseTransform([a,c],this.transform)}};return b}();var pa=[0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,728,711,710,729,733,731,730,732,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8226,8224,8225,8230,8212,8211,402,8260,8249,8250,8722,8240,8222,8220,8221,8216,8217,8218,8482,64257,64258,321,338,352,376,381,305,322,339,353,382,0,8364],x=PDFJS.Promise=function(){function b(){this._status=a;this._handlers=[]}var a=0,c=2,e={handlers:[],
-running:!1,unhandledRejections:[],pendingRejectionCheck:!1,scheduleHandlers:function(c){c._status!=a&&(this.handlers=this.handlers.concat(c._handlers),c._handlers=[],this.running||(this.running=!0,setTimeout(this.runHandlers.bind(this),0)))},runHandlers:function(){for(;0<this.handlers.length;){var a=this.handlers.shift(),e=a.thisPromise._status,f=a.thisPromise._value;try{1===e?"function"==typeof a.onResolve&&(f=a.onResolve(f)):"function"===typeof a.onReject&&(f=a.onReject(f),e=1,a.thisPromise._unhandledRejection&&
-this.removeUnhandeledRejection(a.thisPromise))}catch(b){e=c,f=b}a.nextPromise._updateStatus(e,f)}this.running=!1},addUnhandledRejection:function(a){this.unhandledRejections.push({promise:a,time:Date.now()});this.scheduleRejectionCheck()},removeUnhandeledRejection:function(a){a._unhandledRejection=!1;for(var c=0;c<this.unhandledRejections.length;c++)this.unhandledRejections[c].promise===a&&(this.unhandledRejections.splice(c),c--)},scheduleRejectionCheck:function(){this.pendingRejectionCheck||(this.pendingRejectionCheck=
-!0,setTimeout(function(){this.pendingRejectionCheck=!1;for(var a=Date.now(),c=0;c<this.unhandledRejections.length;c++)if(500<a-this.unhandledRejections[c].time){var f=this.unhandledRejections[c].promise._value,e="Unhandled rejection: "+f;f.stack&&(e+="\n"+f.stack);F(e);this.unhandledRejections.splice(c);c--}this.unhandledRejections.length&&this.scheduleRejectionCheck()}.bind(this),500))}};b.all=function(a){function e(a){f._status!==c&&(h=[],f.reject(a))}var f=new b,k=a.length,h=[];if(0===k)return f.resolve(h),
-f;for(var l=0,n=a.length;l<n;++l)a[l].then(function(a){return function(e){f._status!==c&&(h[a]=e,k--,0===k&&f.resolve(h))}}(l),e);return f};b.prototype={_status:null,_value:null,_handlers:null,_unhandledRejection:null,_updateStatus:function(a,b){1!==this._status&&this._status!==c&&(1==a&&b&&"function"===typeof b.then?b.then(this._updateStatus.bind(this,1),this._updateStatus.bind(this,c)):(this._status=a,this._value=b,a===c&&0===this._handlers.length&&(this._unhandledRejection=!0,e.addUnhandledRejection(this)),
-e.scheduleHandlers(this)))},get isResolved(){return 1===this._status},get isRejected(){return this._status===c},resolve:function(a){this._updateStatus(1,a)},reject:function(a){this._updateStatus(c,a)},then:function(a,c){var f=new b;this._handlers.push({thisPromise:this,onResolve:a,onReject:c,nextPromise:f});e.scheduleHandlers(this);return f}};return b}(),ta=function(){function b(){this.started={};this.times=[];this.enabled=!0}b.prototype={time:function(a){this.enabled&&(a in this.started&&F("Timer is already running for "+
-a),this.started[a]=Date.now())},timeEnd:function(a){this.enabled&&(a in this.started||F("Timer has not been started for "+a),this.times.push({name:a,start:this.started[a],end:Date.now()}),delete this.started[a])},toString:function(){for(var a=this.times,c="",e=0,d=0,b=a.length;d<b;++d){var f=a[d].name;f.length>e&&(e=f.length)}d=0;for(b=a.length;d<b;++d){for(var k=a[d],f=k.end-k.start,k=k.name;k.length<e;)k+=" ";c+=k+" "+f+"ms\n"}return c}};return b}();PDFJS.createBlob=function(b,a){if("function"===
-typeof Blob)return new Blob([b],{type:a});var c=new MozBlobBuilder;c.append(b);return c.getBlob(a)};Z.prototype={on:function(b,a,c){var e=this.actionHandler;e[b]&&m('There is already an actionName called "'+b+'"');e[b]=[a,c]},send:function(b,a,c){b={action:b,data:a};c&&(a=this.callbackIndex++,this.callbacks[a]=c,b.callbackId=a);this.comObj.postMessage(b)}};var p=function(){function b(){m("should not call ColorSpace constructor")}b.prototype={getRgb:function(a,c){m("Should not call ColorSpace.getRgb")},
-getRgbItem:function(a,c,e,d){m("Should not call ColorSpace.getRgbItem")},getRgbBuffer:function(a,c,e,d,b,f){m("Should not call ColorSpace.getRgbBuffer")},getOutputLength:function(a){m("Should not call ColorSpace.getOutputLength")},isPassthrough:function(a){return!1},createRgbBuffer:function(a,c,e,d){if(this.isPassthrough(d))return a.subarray(c);var b=new Uint8Array(3*e),f=1<<d;if(1===this.numComps&&e>f&&"DeviceGray"!==this.name&&"DeviceRGB"!==this.name){for(var k=8>=d?new Uint8Array(f):new Uint16Array(f),
-h=0;h<f;h++)k[h]=h;var l=new Uint8Array(3*f);this.getRgbBuffer(k,0,f,l,0,d);for(h=d=0;h<e;++h)f=3*a[c++],b[d++]=l[f],b[d++]=l[f+1],b[d++]=l[f+2];return b}this.getRgbBuffer(a,c,e,b,0,d);return b},usesZeroToOneRange:!0};b.parse=function(a,c,e){a=b.parseToIR(a,c,e);return a instanceof ia?a:b.fromIR(a)};b.fromIR=function(a){var c=B(a)?a[0]:a;switch(c){case "DeviceGrayCS":return this.singletons.gray;case "DeviceRgbCS":return this.singletons.rgb;case "DeviceCmykCS":return this.singletons.cmyk;case "PatternCS":return(a=
-a[1])&&(a=b.fromIR(a)),new ua(a);case "IndexedCS":var c=a[2],e=a[3];return new va(b.fromIR(a[1]),c,e);case "AlternateCS":return c=a[3],new ia(a[1],b.fromIR(a[2]),P.fromIR(c));case "LabCS":return new wa(a[1].WhitePoint,a[1].BlackPoint,a[1].Range);default:m("Unkown name "+c)}return null};b.parseToIR=function(a,c,e){if(M(a)){var d=e.get("ColorSpace");O(d)&&(d=d.get(a.name))&&(a=d)}a=c.fetchIfRef(a);if(M(a))switch(this.mode=d=a.name,d){case "DeviceGray":case "G":return"DeviceGrayCS";case "DeviceRGB":case "RGB":return"DeviceRgbCS";
-case "DeviceCMYK":case "CMYK":return"DeviceCmykCS";case "Pattern":return["PatternCS",null];default:m("unrecognized colorspace "+d)}else if(B(a))switch(this.mode=d=a[0].name,d){case "DeviceGray":case "G":return"DeviceGrayCS";case "DeviceRGB":case "RGB":return"DeviceRgbCS";case "DeviceCMYK":case "CMYK":return"DeviceCmykCS";case "CalGray":return"DeviceGrayCS";case "CalRGB":return"DeviceRgbCS";case "ICCBased":d=c.fetchIfRef(a[1]).dict.get("N");if(1==d)return"DeviceGrayCS";if(3==d)return"DeviceRgbCS";
-if(4==d)return"DeviceCmykCS";break;case "Pattern":return(a=a[1])&&(a=b.parseToIR(a,c,e)),["PatternCS",a];case "Indexed":case "I":return e=b.parseToIR(a[1],c,e),d=a[2]+1,c=c.fetchIfRef(a[3]),X(c)&&(c=c.getBytes()),["IndexedCS",e,d,c];case "Separation":case "DeviceN":var g=a[1],d=1;M(g)?d=1:B(g)&&(d=g.length);e=b.parseToIR(a[2],c,e);c=P.getIR(c,c.fetchIfRef(a[3]));return["AlternateCS",d,e,c];case "Lab":return["LabCS",a[1].getAll()];default:m('unimplemented color space object "'+d+'"')}else m('unrecognized color space object: "'+
-a+'"');return null};b.isDefaultDecode=function(a,c){if(!a)return!0;if(2*c!==a.length)return F("The decode map is not the correct length"),!0;for(var e=0,d=a.length;e<d;e+=2)if(0!==a[e]||1!=a[e+1])return!1;return!0};b.singletons={get gray(){return W(this,"gray",new xa)},get rgb(){return W(this,"rgb",new ya)},get cmyk(){return W(this,"cmyk",new za)}};return b}(),ia=function(){function b(a,c,e){this.name="Alternate";this.numComps=a;this.defaultColor=new Float32Array(a);for(var d=0;d<a;++d)this.defaultColor[d]=
-1;this.base=c;this.tintFn=e}b.prototype={getRgb:function(a,c){var e=new Uint8Array(3);this.getRgbItem(a,c,e,0);return e},getRgbItem:function(a,c,e,d){a="subarray"in a?a.subarray(c,c+this.numComps):Array.prototype.slice.call(a,c,c+this.numComps);a=this.tintFn(a);this.base.getRgbItem(a,0,e,d)},getRgbBuffer:function(a,c,e,d,b,f){var k=this.tintFn,h=this.base;f=1/((1<<f)-1);for(var l=h.numComps,n=h.usesZeroToOneRange,t=h.isPassthrough(8)||!n,y=t?b:0,q=t?d:new Uint8Array(l*e),r=this.numComps,m=new Float32Array(r),
-u=0;u<e;u++){for(var w=0;w<r;w++)m[w]=a[c++]*f;var s=k(m);if(n)for(w=0;w<l;w++)q[y++]=255*s[w];else h.getRgbItem(s,0,q,y),y+=l}t||h.getRgbBuffer(q,0,e,d,b,8)},getOutputLength:function(a){return this.base.getOutputLength(a*this.base.numComps/this.numComps)},isPassthrough:p.prototype.isPassthrough,createRgbBuffer:p.prototype.createRgbBuffer,isDefaultDecode:function(a){return p.isDefaultDecode(a,this.numComps)},usesZeroToOneRange:!0};return b}(),ua=function(){function b(a){this.name="Pattern";this.base=
-a}b.prototype={};return b}(),va=function(){function b(a,c,e){this.name="Indexed";this.numComps=1;this.defaultColor=new Uint8Array([0]);this.base=a;this.highVal=c;a=a.numComps*c;var d;if(X(e))d=new Uint8Array(a),e=e.getBytes(a),d.set(e);else if("string"==typeof e)for(d=new Uint8Array(a),c=0;c<a;++c)d[c]=e.charCodeAt(c);else e instanceof Uint8Array||e instanceof Array?d=e:m("Unrecognized lookup table: "+e);this.lookup=d}b.prototype={getRgb:function(a,c){return this.base.getRgb(this.lookup,a[c]*this.base.numComps)},
-getRgbItem:function(a,c,e,d){this.base.getRgbItem(this.lookup,a[c]*this.base.numComps,e,d)},getRgbBuffer:function(a,c,e,d,b){for(var f=this.base,k=f.numComps,h=f.getOutputLength(k),l=this.lookup,n=0;n<e;++n){var t=a[c++]*k;f.getRgbBuffer(l,t,1,d,b,8);b+=h}},getOutputLength:function(a){return this.base.getOutputLength(a*this.base.numComps)},isPassthrough:p.prototype.isPassthrough,createRgbBuffer:p.prototype.createRgbBuffer,isDefaultDecode:function(a){return!0},usesZeroToOneRange:!0};return b}(),xa=
-function(){function b(){this.name="DeviceGray";this.numComps=1;this.defaultColor=new Float32Array([0])}b.prototype={getRgb:function(a,c){var e=new Uint8Array(3);this.getRgbItem(a,c,e,0);return e},getRgbItem:function(a,c,e,d){a=255*a[c]|0;e[d]=e[d+1]=e[d+2]=0>a?0:255<a?255:a},getRgbBuffer:function(a,c,e,d,b,f){f=255/((1<<f)-1);for(var k=0;k<e;++k){var h=f*a[c++]|0;d[b++]=h;d[b++]=h;d[b++]=h}},getOutputLength:function(a){return 3*a},isPassthrough:p.prototype.isPassthrough,createRgbBuffer:p.prototype.createRgbBuffer,
-isDefaultDecode:function(a){return p.isDefaultDecode(a,this.numComps)},usesZeroToOneRange:!0};return b}(),ya=function(){function b(){this.name="DeviceRGB";this.numComps=3;this.defaultColor=new Float32Array([0,0,0])}b.prototype={getRgb:function(a,c){var e=new Uint8Array(3);this.getRgbItem(a,c,e,0);return e},getRgbItem:function(a,c,e,d){var b=255*a[c]|0,f=255*a[c+1]|0;a=255*a[c+2]|0;e[d]=0>b?0:255<b?255:b;e[d+1]=0>f?0:255<f?255:f;e[d+2]=0>a?0:255<a?255:a},getRgbBuffer:function(a,c,e,d,b,f){e*=3;if(8==
-f)d.set(a.subarray(c,c+e),b);else{f=255/((1<<f)-1);for(var k=0;k<e;++k)d[b++]=f*a[c++]|0}},getOutputLength:function(a){return a},isPassthrough:function(a){return 8==a},createRgbBuffer:p.prototype.createRgbBuffer,isDefaultDecode:function(a){return p.isDefaultDecode(a,this.numComps)},usesZeroToOneRange:!0};return b}(),za=function(){function b(a,e,d,b,f){var k=a[e+0]*d,h=a[e+1]*d,l=a[e+2]*d;d*=a[e+3];a=k*(-4.387332384609988*k+54.48615194189176*h+18.82290502165302*l+212.25662451639585*d+-285.2331026137004)+
-h*(1.7149763477362134*h-5.6096736904047315*l+-17.873870861415444*d-5.497006427196366)+l*(-2.5217340131683033*l-21.248923337353073*d+17.5119270841813)+d*(-21.86122147463605*d-189.48180835922747)+255;e=k*(8.841041422036149*k+60.118027045597366*h+6.871425592049007*l+31.159100130055922*d+-79.2970844816548)+h*(-15.310361306967817*h+17.575251261109482*l+131.35250912493976*d-190.9453302588951)+l*(4.444339102852739*l+9.8632861493405*d-24.86741582555878)+d*(-20.737325471181034*d-187.80453709719578)+255;k=
-k*(0.8842522430003296*k+8.078677503112928*h+30.89978309703729*l-0.23883238689178934*d+-14.183576799673286)+h*(10.49593273432072*h+63.02378494754052*l+50.606957656360734*d-112.23884253719248)+l*(0.03296041114873217*l+115.60384449646641*d+-193.58209356861505)+d*(-22.33816807309886*d-180.12613974708367)+255;b[f]=255<a?255:0>a?0:a;b[f+1]=255<e?255:0>e?0:e;b[f+2]=255<k?255:0>k?0:k}function a(){this.name="DeviceCMYK";this.numComps=4;this.defaultColor=new Float32Array([0,0,0,1])}a.prototype={getRgb:function(a,
-e){var d=new Uint8Array(3);b(a,e,1,d,0);return d},getRgbItem:function(a,e,d,g){b(a,e,1,d,g)},getRgbBuffer:function(a,e,d,g,f,k){k=1/((1<<k)-1);for(var h=0;h<d;h++)b(a,e,k,g,f),e+=4,f+=3},getOutputLength:function(a){return 3*(a>>2)},isPassthrough:p.prototype.isPassthrough,createRgbBuffer:p.prototype.createRgbBuffer,isDefaultDecode:function(a){return p.isDefaultDecode(a,this.numComps)},usesZeroToOneRange:!0};return a}(),wa=function(){function b(a,c,b){this.name="Lab";this.numComps=3;this.defaultColor=
-new Float32Array([0,0,0]);a||m("WhitePoint missing - required for color space Lab");c=c||[0,0,0];b=b||[-100,100,-100,100];this.XW=a[0];this.YW=a[1];this.ZW=a[2];this.amin=b[0];this.amax=b[1];this.bmin=b[2];this.bmax=b[3];this.XB=c[0];this.YB=c[1];this.ZB=c[2];(0>this.XW||0>this.ZW||1!==this.YW)&&m("Invalid WhitePoint components, no fallback available");if(0>this.XB||0>this.YB||0>this.ZB)S("Invalid BlackPoint, falling back to default"),this.XB=this.YB=this.ZB=0;if(this.amin>this.amax||this.bmin>this.bmax)S("Invalid Range, falling back to defaults"),
-this.amin=-100,this.amax=100,this.bmin=-100,this.bmax=100}function a(a){return a>=6/29?a*a*a:108/841*(a-4/29)}function c(c,d,b,f,k,h){var l=d[b],n=d[b+1];d=d[b+2];!1!==f&&(l=0+100*l/f,n=c.amin+n*(c.amax-c.amin)/f,d=c.bmin+d*(c.bmax-c.bmin)/f);n=n>c.amax?c.amax:n<c.amin?c.amin:n;d=d>c.bmax?c.bmax:d<c.bmin?c.bmin:d;f=(l+16)/116;l=f-d/200;n=c.XW*a(f+n/500);f=c.YW*a(f);l=c.ZW*a(l);1>c.ZW?(c=3.1339*n+-1.617*f+-0.4906*l,d=-0.9785*n+1.916*f+0.0333*l,n=0.072*n+-0.229*f+1.4057*l):(c=3.2406*n+-1.5372*f+-0.4986*
-l,d=-0.9689*n+1.8758*f+0.0415*l,n=0.0557*n+-0.204*f+1.057*l);k[h]=255*Math.sqrt(0>c?0:1<c?1:c);k[h+1]=255*Math.sqrt(0>d?0:1<d?1:d);k[h+2]=255*Math.sqrt(0>n?0:1<n?1:n)}b.prototype={getRgb:function(a,d){var b=new Uint8Array(3);c(this,a,d,!1,b,0);return b},getRgbItem:function(a,b,g,f){c(this,a,b,!1,g,f)},getRgbBuffer:function(a,b,g,f,k,h){h=(1<<h)-1;for(var l=0;l<g;l++)c(this,a,b,h,f,k),b+=3,k+=3},getOutputLength:function(a){return a},isPassthrough:p.prototype.isPassthrough,isDefaultDecode:function(a){return!0},
-usesZeroToOneRange:!1};return b}();D=3;var ja=function(){function b(){m("should not call Pattern constructor")}b.prototype={getPattern:function(a){m("Should not call Pattern.getStyle: "+a)}};b.shadingFromIR=function(a){return N[a[0]].fromIR(a)};b.parseShading=function(a,c,b,d){a=X(a)?a.dict:a;var g=a.get("ShadingType");switch(g){case 2:case D:return new N.RadialAxial(a,c,b,d);default:return K("Unsupported shading type: "+g),new N.Dummy}};return b}(),N={SMALL_NUMBER:0.01};N.RadialAxial=function(){function b(a,
-c,b,d,g){this.matrix=c;this.coordsArr=a.get("Coords");this.shadingType=a.get("ShadingType");this.type="Pattern";this.ctx=g;c=a.get("ColorSpace","CS");this.cs=c=p.parse(c,b,d);d=0;var f=1;a.has("Domain")&&(g=a.get("Domain"),d=g[0],f=g[1]);var k=g=!1;a.has("Extend")&&(k=a.get("Extend"),g=k[0],k=k[1]);if(!(this.shadingType!==D||g&&k)){var h=this.coordsArr[0],l=this.coordsArr[1],n=this.coordsArr[2],t=this.coordsArr[3],y=this.coordsArr[4],q=this.coordsArr[5],h=Math.sqrt((h-t)*(h-t)+(l-y)*(l-y));n<=q+h&&
-q<=n+h&&F("Unsupported radial gradient.")}this.extendStart=g;this.extendEnd=k;n=a.get("Function");if(B(n)){for(var r=[],q=0,h=n.length;q<h;q++)l=b.fetchIfRef(n[q]),da(l)||m("Invalid function"),r.push(P.parse(b,l));n=function(a){for(var c=[],f=0,b=r.length;f<b;f++)c.push(r[f](a)[0]);return c}}else da(n)||m("Invalid function"),n=P.parse(b,n);q=f-d;h=q/10;b=this.colorStops=[];if(d>=f||0>=h)S("Bad shading domain.");else{for(l=d;l<=f;l+=h)t=c.getRgb(n([l]),0),t=s.makeCssRgb(t),b.push([(l-d)/q,t]);d="transparent";
-a.has("Background")&&(t=c.getRgb(a.get("Background"),0),d=s.makeCssRgb(t));g||(b.unshift([0,d]),b[1][0]+=N.SMALL_NUMBER);k||(b[b.length-1][0]-=N.SMALL_NUMBER,b.push([1,d]));this.colorStops=b}}b.fromIR=function(a){var c=a[1],b=a[2],d=a[3],g=a[4],f=a[5],k=a[6];return{type:"Pattern",getPattern:function(a){var l;2==c?l=a.createLinearGradient(d[0],d[1],g[0],g[1]):c==D&&(l=a.createRadialGradient(d[0],d[1],f,g[0],g[1],k));a=0;for(var n=b.length;a<n;++a){var t=b[a];l.addColorStop(t[0],t[1])}return l}}};b.prototype=
-{getIR:function(){var a=this.coordsArr,c=this.shadingType;if(2==c)var b=[a[0],a[1]],d=[a[2],a[3]],g=null,f=null;else c==D?(b=[a[0],a[1]],d=[a[3],a[4]],g=a[2],f=a[5]):m("getPattern type unknown: "+c);if(a=this.matrix)b=s.applyTransform(b,a),d=s.applyTransform(d,a);return["RadialAxial",c,this.colorStops,b,d,g,f]}};return b}();N.Dummy=function(){function b(){this.type="Pattern"}b.fromIR=function(){return{type:"Pattern",getPattern:function(){return"hotpink"}}};b.prototype={getIR:function(){return["Dummy"]}};
-return b}();var Aa=function(){function b(a,c,b,d,g,f){this.name=a[1][0].name;this.operatorList=a[2];this.matrix=a[3]||[1,0,0,1,0,0];this.bbox=a[4];this.xstep=a[5];this.ystep=a[6];this.paintType=a[7];this.tilingType=a[8];this.color=c;this.objs=d;this.commonObjs=g;this.baseTransform=f;this.type="Pattern";this.ctx=b}b.getIR=function(a,c,b){var d=c.get("Matrix"),g=c.get("BBox"),f=c.get("XStep"),k=c.get("YStep"),h=c.get("PaintType");c=c.get("TilingType");return["TilingPattern",b,a,d,g,f,k,h,c]};b.prototype=
-{createPatternCanvas:function(a){var c=this.operatorList,b=this.bbox,d=this.xstep,g=this.ystep,f=this.paintType,k=this.color,h=this.objs,l=this.commonObjs;K("TilingType: "+this.tilingType);var n=b[0],t=b[1],y=b[2],q=b[3],r=[n,t],m=[n+d,t+g],u=m[0]-r[0],m=m[1]-r[1],w=s.singularValueDecompose2dScale(this.matrix),p=s.singularValueDecompose2dScale(this.baseTransform),w=[w[0]*p[0],w[1]*p[1]],u=Math.min(Math.ceil(Math.abs(u*w[0])),3E3),m=Math.min(Math.ceil(Math.abs(m*w[1])),3E3),w=G.getCanvas("pattern",
-u,m,!0),p=w.context,h=new ka(p,l,h);h.groupLevel=a.groupLevel;this.setFillAndStrokeStyleToContext(p,f,k);this.setScale(u,m,d,g);this.transformToScale(h);h.transform.apply(h,[1,0,0,1,-r[0],-r[1]]);this.clipBbox(h,b,n,t,y,q);h.executeOperatorList(c);return w.canvas},setScale:function(a,c,b,d){this.scale=[a/b,c/d]},transformToScale:function(a){var c=this.scale;a.transform.apply(a,[c[0],0,0,c[1],0,0])},scaleToContext:function(){var a=this.scale;this.ctx.scale(1/a[0],1/a[1])},clipBbox:function(a,c,b,d,
-g,f){c&&B(c)&&4==c.length&&(a.rectangle(b,d,g-b,f-d),a.clip(),a.endPath())},setFillAndStrokeStyleToContext:function(a,c,b){switch(c){case 1:c=this.ctx;a.fillStyle=c.fillStyle;a.strokeStyle=c.strokeStyle;break;case 2:c=p.singletons.rgb.getRgb(b,0);c=s.makeCssRgb(c);a.fillStyle=c;a.strokeStyle=c;break;default:m("Unsupported paint type: "+c)}},getPattern:function(a,c){var b=this.createPatternCanvas(c);a=this.ctx;a.setTransform.apply(a,this.baseTransform);a.transform.apply(a,this.matrix);this.scaleToContext();
-return a.createPattern(b,"repeat")}};return b}(),P=function(){return{getSampleArray:function(b,a,c,e){for(var d=1,g=0,f=b.length;g<f;g++)d*=b[g];d*=a;b=[];var f=a=0,k=1/(Math.pow(2,c)-1);e=e.getBytes((d*c+7)/8);for(var h=0,g=0;g<d;g++){for(;a<c;)f<<=8,f|=e[h++],a+=8;a-=c;b.push((f>>a)*k);f&=(1<<a)-1}return b},getIR:function(b,a){var c=a.dict;c||(c=a);var e=[this.constructSampled,null,this.constructInterpolated,this.constructStiched,this.constructPostScript],d=c.get("FunctionType");(e=e[d])||m("Unknown type of function");
-return e.call(this,a,c,b)},fromIR:function(b){switch(b[0]){case 0:return this.constructSampledFromIR(b);case 2:return this.constructInterpolatedFromIR(b);case 3:return this.constructStichedFromIR(b);default:return this.constructPostScriptFromIR(b)}},parse:function(b,a){var c=this.getIR(b,a);return this.fromIR(c)},constructSampled:function(b,a){function c(a){for(var c=a.length,f=[],b=0,d=0;d<c;d+=2)f[b]=[a[d],a[d+1]],++b;return f}var e=a.get("Domain"),d=a.get("Range");e&&d||m("No domain or range");
-var g=e.length/2,f=d.length/2,e=c(e),d=c(d),k=a.get("Size"),h=a.get("BitsPerSample"),l=a.get("Order")||1;1!==l&&K("No support for cubic spline interpolation: "+l);l=a.get("Encode");if(!l)for(var l=[],n=0;n<g;++n)l.push(0),l.push(k[n]-1);var l=c(l),n=(n=a.get("Decode"))?c(n):d,t=this.getSampleArray(k,f,h,b);return[0,g,e,l,n,t,k,f,Math.pow(2,h)-1,d]},constructSampledFromIR:function(b){return function(a){var c=b[1],e=b[2],d=b[3],g=b[4],f=b[5],k=b[6],h=b[7],l=b[9];c!=a.length&&m("Incorrect number of arguments: "+
-c+" != "+a.length);for(var n=1<<c,t=new Float64Array(n),y=new Uint32Array(n),q=0;q<n;q++)t[q]=1;for(var r=h,s=1,u=0;u<c;++u){for(var q=e[u][0],w=e[u][1],p=Math.min(Math.max(a[u],q),w),E=d[u][0]+(p-q)*((d[u][1]-d[u][0])/(w-q)),w=k[u],E=Math.min(Math.max(E,0),w-1),q=E<w-1?Math.floor(E):E-1,p=q+1-E,E=E-q,z=q*r,v=z+r,q=0;q<n;q++)q&s?(t[q]*=E,y[q]+=v):(t[q]*=p,y[q]+=z);r*=w;s<<=1}a=new Float64Array(h);for(q=0;q<h;++q){for(u=c=0;u<n;u++)c+=f[y[u]+q]*t[u];c=g[q][0]+(c-0)*((g[q][1]-g[q][0])/1);a[q]=Math.min(Math.max(c,
-l[q][0]),l[q][1])}return a}},constructInterpolated:function(b,a){var c=a.get("C0")||[0],e=a.get("C1")||[1],d=a.get("N");B(c)&&B(e)||m("Illegal dictionary for interpolated function");for(var g=c.length,f=[],k=0;k<g;++k)f.push(e[k]-c[k]);return[2,c,f,d]},constructInterpolatedFromIR:function(b){var a=b[1],c=b[2],e=b[3],d=c.length;return function(b){b=1==e?b[0]:Math.pow(b[0],e);for(var f=[],k=0;k<d;++k)f.push(a[k]+b*c[k]);return f}},constructStiched:function(b,a,c){(b=a.get("Domain"))||m("No domain");
-1!=b.length/2&&m("Bad domain for stiched function");for(var e=a.get("Functions"),d=[],g=0,f=e.length;g<f;++g)d.push(P.getIR(c,c.fetchIfRef(e[g])));c=a.get("Bounds");a=a.get("Encode");return[3,b,c,a,d]},constructStichedFromIR:function(b){var a=b[1],c=b[2],e=b[3];b=b[4];for(var d=[],g=0,f=b.length;g<f;g++)d.push(P.fromIR(b[g]));return function(f){f=f[0];var b=a[0],l=a[1];f>l?f=l:f<b&&(f=b);b=0;for(l=c.length;b<l&&!(f<c[b]);++b);l=a[0];0<b&&(l=c[b-1]);var g=a[1];b<c.length&&(g=c[b]);var t=e[2*b];return d[b]([t+
-(f-l)*(e[2*b+1]-t)/(g-l)])}},constructPostScript:function(b,a,c){c=a.get("Domain");a=a.get("Range");c||m("No domain.");a||m("No range.");b=new Ba(b);b=(new Ca(b)).parse();return[4,c,a,b]},constructPostScriptFromIR:function(b){var a=b[1],c=b[2],e=c.length/2,d=new Da(b[3]),g=new Ea;return function(f){for(var b=[],h=0,l=a.length/2;h<l;++h)b.push(f[h]);f=b.join("_");if(g.has(f))return g.get(f);b=d.execute(b);l=[];for(h=e-1;0<=h;--h){var n=b.pop(),t=2*h;n<c[t]?n=c[t]:n>c[t+1]&&(n=c[t+1]);l[h]=n}g.set(f,
-l);return l}}}}(),Ea=function(){function b(){this.cache={};this.total=0}b.prototype={has:function(a){return a in this.cache},get:function(a){return this.cache[a]},set:function(a,c){1024>this.total&&(this.cache[a]=c,this.total++)}};return b}(),Fa=function(){function b(a){this.stack=a||[]}b.prototype={push:function(a){100<=this.stack.length&&m("PostScript function stack overflow.");this.stack.push(a)},pop:function(){0>=this.stack.length&&m("PostScript function stack underflow.");return this.stack.pop()},
-copy:function(a){100<=this.stack.length+a&&m("PostScript function stack overflow.");var c=this.stack,b=c.length-a;for(a-=1;0<=a;a--,b++)c.push(c[b])},index:function(a){this.push(this.stack[this.stack.length-a-1])},roll:function(a,c){var b=this.stack,d=b.length-a,g=b.length-1,f=d+(c-Math.floor(c/a)*a),k,h,l;k=d;for(h=g;k<h;k++,h--)l=b[k],b[k]=b[h],b[h]=l;k=d;for(h=f-1;k<h;k++,h--)l=b[k],b[k]=b[h],b[h]=l;k=f;for(h=g;k<h;k++,h--)l=b[k],b[k]=b[h],b[h]=l}};return b}(),Da=function(){function b(a,c){this.operators=
-a;this.operands=c}b.prototype={execute:function(a){a=new Fa(a);for(var c=0,b=this.operators,d=b.length,g,f;c<d;)if(g=b[c++],"number"==typeof g)a.push(g);else switch(g){case "jz":f=a.pop();(g=a.pop())||(c=f);break;case "j":c=g=a.pop();break;case "abs":g=a.pop();a.push(Math.abs(g));break;case "add":f=a.pop();g=a.pop();a.push(g+f);break;case "and":f=a.pop();g=a.pop();L(g)&&L(f)?a.push(g&&f):a.push(g&f);break;case "atan":g=a.pop();a.push(Math.atan(g));break;case "bitshift":f=a.pop();g=a.pop();0<g?a.push(g<<
-f):a.push(g>>f);break;case "ceiling":g=a.pop();a.push(Math.ceil(g));break;case "copy":g=a.pop();a.copy(g);break;case "cos":g=a.pop();a.push(Math.cos(g));break;case "cvi":g=a.pop()|0;a.push(g);break;case "cvr":break;case "div":f=a.pop();g=a.pop();a.push(g/f);break;case "dup":a.copy(1);break;case "eq":f=a.pop();g=a.pop();a.push(g==f);break;case "exch":a.roll(2,1);break;case "exp":f=a.pop();g=a.pop();a.push(Math.pow(g,f));break;case "false":a.push(!1);break;case "floor":g=a.pop();a.push(Math.floor(g));
-break;case "ge":f=a.pop();g=a.pop();a.push(g>=f);break;case "gt":f=a.pop();g=a.pop();a.push(g>f);break;case "idiv":f=a.pop();g=a.pop();a.push(g/f|0);break;case "index":g=a.pop();a.index(g);break;case "le":f=a.pop();g=a.pop();a.push(g<=f);break;case "ln":g=a.pop();a.push(Math.log(g));break;case "log":g=a.pop();a.push(Math.log(g)/Math.LN10);break;case "lt":f=a.pop();g=a.pop();a.push(g<f);break;case "mod":f=a.pop();g=a.pop();a.push(g%f);break;case "mul":f=a.pop();g=a.pop();a.push(g*f);break;case "ne":f=
-a.pop();g=a.pop();a.push(g!=f);break;case "neg":a.pop();a.push(-f);break;case "not":g=a.pop();L(g)&&L(f)?a.push(g&&f):a.push(g&f);break;case "or":f=a.pop();g=a.pop();L(g)&&L(f)?a.push(g||f):a.push(g|f);break;case "pop":a.pop();break;case "roll":f=a.pop();g=a.pop();a.roll(g,f);break;case "round":g=a.pop();a.push(Math.round(g));break;case "sin":g=a.pop();a.push(Math.sin(g));break;case "sqrt":g=a.pop();a.push(Math.sqrt(g));break;case "sub":f=a.pop();g=a.pop();a.push(g-f);break;case "true":a.push(!0);
-break;case "truncate":g=a.pop();g=0>g?Math.ceil(g):Math.floor(g);a.push(g);break;case "xor":f=a.pop();g=a.pop();L(g)&&L(f)?a.push(g!=f):a.push(g^f);break;default:m("Unknown operator "+g)}return a.stack}};return b}(),Ca=function(){function b(a){this.lexer=a;this.operators=[];this.prev=this.token=null}b.prototype={nextToken:function(){this.prev=this.token;this.token=this.lexer.getToken()},accept:function(a){return this.token.type==a?(this.nextToken(),!0):!1},expect:function(a){if(this.accept(a))return!0;
-m("Unexpected symbol: found "+this.token.type+" expected "+a+".")},parse:function(){this.nextToken();this.expect(A.LBRACE);this.parseBlock();this.expect(A.RBRACE);return this.operators},parseBlock:function(){for(;;)if(this.accept(A.NUMBER))this.operators.push(this.prev.value);else if(this.accept(A.OPERATOR))this.operators.push(this.prev.value);else if(this.accept(A.LBRACE))this.parseCondition();else break},parseCondition:function(){var a=this.operators.length;this.operators.push(null,null);this.parseBlock();
-this.expect(A.RBRACE);if(this.accept(A.IF))this.operators[a]=this.operators.length,this.operators[a+1]="jz";else if(this.accept(A.LBRACE)){var c=this.operators.length;this.operators.push(null,null);var b=this.operators.length;this.parseBlock();this.expect(A.RBRACE);this.expect(A.IFELSE);this.operators[c]=this.operators.length;this.operators[c+1]="j";this.operators[a]=b;this.operators[a+1]="jz"}else m("PS Function: error parsing conditional.")}};return b}(),A={LBRACE:0,RBRACE:1,NUMBER:2,OPERATOR:3,
-IF:4,IFELSE:5},Q=function(){function b(a,b){this.type=a;this.value=b}var a={};b.getOperator=function(c){var e=a[c];return e?e:a[c]=new b(A.OPERATOR,c)};b.LBRACE=new b(A.LBRACE,"{");b.RBRACE=new b(A.RBRACE,"}");b.IF=new b(A.IF,"IF");b.IFELSE=new b(A.IFELSE,"IFELSE");return b}(),Ba=function(){function b(a){this.stream=a;this.nextChar()}b.prototype={nextChar:function(){return this.currentChar=this.stream.getByte()},getToken:function(){for(var a=!1,c=this.currentChar;;){if(0>c)return EOF;if(a){if(10===
-c||13===c)a=!1}else if(37==c)a=!0;else if(!Lexer.isSpace(c))break;c=this.nextChar()}switch(c|0){case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:case 43:case 45:case 46:return new Q(A.NUMBER,this.getNumber());case 123:return this.nextChar(),Q.LBRACE;case 125:return this.nextChar(),Q.RBRACE}for(a=String.fromCharCode(c);0<=(c=this.nextChar())&&(65<=c&&90>=c||97<=c&&122>=c);)a+=String.fromCharCode(c);switch(a.toLowerCase()){case "if":return Q.IF;case "ifelse":return Q.IFELSE;
-default:return Q.getOperator(a)}},getNumber:function(){for(var a=this.currentChar,c=String.fromCharCode(a);0<=(a=this.nextChar());)if(48<=a&&57>=a||45===a||46===a)c+=String.fromCharCode(a);else break;a=parseFloat(c);isNaN(a)&&m("Invalid floating point number: "+a);return a}};return b}(),H=function(){function b(a,b,d){var g=s.getAxialAlignedBoundingBox(b,d);b=g[0];d=g[1];var f=g[2],g=g[3];if(b===f||d===g)return[1,0,0,1,a[0],a[1]];f=(a[2]-a[0])/(f-b);g=(a[3]-a[1])/(g-d);return[f,0,0,g,a[0]-b*f,a[1]-
-d*g]}function a(a){if(a.data)this.data=a.data;else{var b=a.dict;a=this.data={};a.subtype=b.get("Subtype").name;var d=b.get("Rect");a.rect=s.normalizeRect(d);a.annotationFlags=b.get("F");d=b.get("C");B(d)&&3===d.length?a.color=d:a.color=[0,0,0];b.has("BS")?(d=b.get("BS"),a.borderWidth=d.has("W")?d.get("W"):1):(d=b.get("Border")||[0,0,1],a.borderWidth=d[2]||0);var g;d=b.get("AP");O(d)?(d=d.get("N"),O(d)?(b=b.get("AS"))&&d.has(b.name)&&(g=d.get(b.name)):g=d):g=void 0;this.appearance=g;a.hasAppearance=
-!!this.appearance}}a.prototype={getData:function(){return this.data},hasHtml:function(){return!1},getHtmlElement:function(a){throw new sa("getHtmlElement() should be implemented in subclass");},getEmptyContainer:function(a,b){U&&m("getEmptyContainer() should be called from main thread");b=b||this.data.rect;var d=document.createElement(a);d.style.width=Math.ceil(b[2]-b[0])+"px";d.style.height=Math.ceil(b[3]-b[1])+"px";return d},isViewable:function(){var a=this.data;return!(!a||a.annotationFlags&&a.annotationFlags&
-34||!a.rect)},loadResources:function(a){var b=new x;this.appearance.dict.getAsync("Resources").then(function(d){d?(new ObjectLoader(d.map,a,d.xref)).load().then(function(){b.resolve(d)}):b.resolve()}.bind(this));return b},getOperatorList:function(a){var e=new x;if(!this.appearance)return e.resolve(new OperatorList),e;var d=this.data,g=this.appearance.dict,f=this.loadResources("ExtGState ColorSpace Pattern Shading XObject Font".split(" ")),k=g.get("BBox")||[0,0,1,1],h=g.get("Matrix")||[1,0,0,1,0,0],
-l=b(d.rect,k,h);f.then(function(b){var f=new OperatorList;f.addOp("beginAnnotation",[d.rect,l,h]);a.getOperatorList(this.appearance,b,f);f.addOp("endAnnotation",[]);e.resolve(f)}.bind(this));return e}};a.getConstructor=function(c,b){if(c){if("Link"===c)return Ga;if("Text"===c)return Ha;if("Widget"===c){if(b)return"Tx"===b?Ia:aa}else return a}};a.fromData=function(c){var b=a.getConstructor(c.subtype,c.fieldType);if(b)return new b({data:c})};a.fromRef=function(c,b){var d=c.fetchIfRef(b);if(O(d)){var g=
-d.get("Subtype");if(g=M(g)?g.name:""){var f=s.getInheritableProperty(d,"FT"),f=M(f)?f.name:"";if(f=a.getConstructor(g,f)){d=new f({dict:d,ref:b});if(d.isViewable())return d;K("unimplemented annotation type: "+g)}}}};a.appendToOperatorList=function(a,b,d,g){var f=new x;d=[];for(var k=0,h=a.length;k<h;++k)d.push(a[k].getOperatorList(g));x.all(d).then(function(a){b.addOp("beginAnnotations",[]);for(var c=0,d=a.length;c<d;++c)b.addOpList(a[c]);b.addOp("endAnnotations",[]);f.resolve()},function(a){f.reject(a)});
-return f};return a}();PDFJS.Annotation=H;var aa=function(){function b(a){H.call(this,a);if(!a.data){var b=a.dict,d=this.data;d.fieldValue=T(s.getInheritableProperty(b,"V")||"");d.alternativeText=T(b.get("TU")||"");d.defaultAppearance=s.getInheritableProperty(b,"DA")||"";var g=s.getInheritableProperty(b,"FT");d.fieldType=M(g)?g.name:"";d.fieldFlags=s.getInheritableProperty(b,"Ff")||0;this.fieldResources=s.getInheritableProperty(b,"DR")||new Dict;var g=[],f=b;for(a=a.ref;f;){var b=f.get("Parent"),k=
-f.getRaw("Parent");if(f=f.get("T"))g.unshift(T(f));else{var f=b.get("Kids"),h,l;h=0;for(l=f.length;h<l;h++){var n=f[h];if(n.num==a.num&&n.gen==a.gen)break}g.unshift("`"+h)}f=b;a=k}d.fullName=g.join(".")}}var a=H.prototype;s.inherit(b,H,{isViewable:function(){return"Sig"===this.data.fieldType?(K("unimplemented annotation type: Widget signature"),!1):a.isViewable.call(this)}});return b}(),Ia=function(){function b(a){aa.call(this,a);a.data||(this.data.textAlignment=s.getInheritableProperty(a.dict,"Q"))}
-s.inherit(b,aa,{hasHtml:function(){return!this.data.hasAppearance&&!!this.data.fieldValue},getHtmlElement:function(a){U&&m("getHtmlElement() shall be called from main thread");var c=this.data,b=this.getEmptyContainer("div");b.style.display="table";var d=document.createElement("div");d.textContent=c.fieldValue;d.style.textAlign=["left","center","right"][c.textAlignment];d.style.verticalAlign="middle";d.style.display="table-cell";a=c.fontRefName?a.getData(c.fontRefName):null;var g=d.style;g.fontSize=
-c.fontSize+"px";g.direction=0>c.fontDirection?"rtl":"ltr";a&&(g.fontWeight=a.black?a.bold?"bolder":"bold":a.bold?"bold":"normal",g.fontStyle=a.italic?"italic":"normal",c=a.loadedName,g.fontFamily=(c?'"'+c+'", ':"")+(a.fallbackName||"Helvetica, sans-serif"));b.appendChild(d);return b},getOperatorList:function(a){if(this.appearance)return H.prototype.getOperatorList.call(this,a);var c=new x,b=new OperatorList,d=this.data,g=d.defaultAppearance;if(!g)return c.resolve(b),c;for(var f=Stream,k=g.length,
-h=new Uint8Array(k),l=0;l<k;++l)h[l]=g.charCodeAt(l)&255;g=new f(h);a.getOperatorList(g,this.fieldResources,b);a=b.fnArray;g=b.argsArray;d.rgb=[0,0,0];for(f=0;0>f;++f)k=a[f],h=g[f],"setFont"===k?(d.fontRefName=h[0],k=h[1],0>k?(d.fontDirection=-1,d.fontSize=-k):(d.fontDirection=1,d.fontSize=k)):"setFillRGBColor"===k?d.rgb=h:"setFillGray"===k&&(k=255*h[0],d.rgb=[k,k,k]);c.resolve(b);return c}});return b}(),Ha=function(){function b(a){H.call(this,a);if(!a.data){a=a.dict;var c=this.data,b=a.get("Contents"),
-d=a.get("T");c.content=T(b||"");c.title=T(d||"");c.name=a.has("Name")?a.get("Name").name:"Note"}}s.inherit(b,H,{getOperatorList:function(a){a=new x;a.resolve(new OperatorList);return a},hasHtml:function(){return!0},getHtmlElement:function(a){U&&m("getHtmlElement() shall be called from main thread");var c=this.data,b=c.rect;10>b[3]-b[1]&&(b[3]=b[1]+10);10>b[2]-b[0]&&(b[2]=b[0]+(b[3]-b[1]));var d=this.getEmptyContainer("section",b);d.className="annotText";a=document.createElement("img");a.style.height=
-d.style.height;var g=c.name;a.src=PDFJS.imageResourcesPath+"annotation-"+g.toLowerCase()+".svg";a.alt="[{{type}} Annotation]";a.dataset.l10nId="text_annotation_type";a.dataset.l10nArgs=JSON.stringify({type:g});var f=document.createElement("div");f.setAttribute("hidden",!0);var g=document.createElement("h1"),k=document.createElement("p");f.style.left=Math.floor(b[2]-b[0])+"px";f.style.top="0px";g.textContent=c.title;if(c.content||c.title){for(var b=document.createElement("span"),c=c.content.split(/(?:\r\n?|\n)/),
-h=0,l=c.length;h<l;++h)b.appendChild(document.createTextNode(c[h])),h<l-1&&b.appendChild(document.createElement("br"));k.appendChild(b);b=function(){d.style.zIndex+=1;f.removeAttribute("hidden")};c=function(a){if(a.toElement||a.relatedTarget)d.style.zIndex-=1,f.setAttribute("hidden",!0)};f.addEventListener("mouseover",b,!1);f.addEventListener("mouseout",c,!1);a.addEventListener("mouseover",b,!1);a.addEventListener("mouseout",c,!1)}else f.setAttribute("hidden",!0);f.appendChild(g);f.appendChild(k);
-d.appendChild(a);d.appendChild(f);return d}});return b}(),Ga=function(){function b(a){H.call(this,a);if(!a.data){var b=a.dict;a=this.data;var e=b.get("A");if(e)if(b=e.get("S").name,"URI"===b){var d=e.get("URI");Y(d,!1)||(d="");a.url=d}else"GoTo"===b?a.dest=e.get("D"):"GoToR"===b?(b=e.get("F"),O(b)&&(d=b.get("F")||""),Y(d,!1)||(d=""),a.url=d,a.dest=e.get("D")):"Named"===b?a.action=e.get("N").name:K("unrecognized link type: "+b);else b.has("Dest")&&(d=b.get("Dest"),a.dest=M(d)?d.name:d)}}s.inherit(b,
-H,{hasOperatorList:function(){return!1},hasHtml:function(){return!0},getHtmlElement:function(a){a=this.data.rect;var b=document.createElement("a"),e=this.data.borderWidth;b.style.borderWidth=e+"px";for(var d=this.data.color,g=[],f=0;3>f;++f)g[f]=Math.round(255*d[f]);b.style.borderColor=s.makeCssRgb(g);b.style.borderStyle="solid";d=a[3]-a[1]-2*e;b.style.width=a[2]-a[0]-2*e+"px";b.style.height=d+"px";b.href=this.data.url||"";return b}});return b}();PDFJS.maxImageSize=void 0===PDFJS.maxImageSize?-1:
-PDFJS.maxImageSize;PDFJS.disableFontFace=void 0===PDFJS.disableFontFace?!1:PDFJS.disableFontFace;PDFJS.getDocument=function(b,a,c,e){var d,g;"string"===typeof b?b={url:b}:"object"==typeof b&&null!==b&&void 0!==b&&"byteLength"in b?b={data:b}:"object"!==typeof b&&m("Invalid parameter in getDocument, need either Uint8Array, string or a parameter object");b.url||b.data||m("Invalid parameter array, need either .data or .url");var f={};for(d in b)f[d]="url"===d&&"undefined"!==typeof window?oa(window.location.href,
-b[d]):b[d];b=new PDFJS.Promise;d=new PDFJS.Promise;g=new Ja(b,d,a,e);b.then(function(){g.passwordCallback=c;g.fetchDocument(f)});return d};var Ka=function(){function b(a,b){this.pdfInfo=a;this.transport=b}b.prototype={get numPages(){return this.pdfInfo.numPages},get fingerprint(){return this.pdfInfo.fingerprint},get embeddedFontsUsed(){return this.transport.embeddedFontsUsed},getPage:function(a){return this.transport.getPage(a)},getDestinations:function(){return this.transport.getDestinations()},
-getJavaScript:function(){var a=new PDFJS.Promise;a.resolve(this.pdfInfo.javaScript);return a},getOutline:function(){var a=new PDFJS.Promise;a.resolve(this.pdfInfo.outline);return a},getMetadata:function(){var a=new PDFJS.Promise,b=this.pdfInfo.metadata;a.resolve({info:this.pdfInfo.info,metadata:b?new PDFJS.Metadata(b):null});return a},isEncrypted:function(){var a=new PDFJS.Promise;a.resolve(this.pdfInfo.encrypted);return a},getData:function(){var a=new PDFJS.Promise;this.transport.getData(a);return a},
-dataLoaded:function(){return this.transport.dataLoaded()},destroy:function(){this.transport.destroy()}};return b}(),Na=function(){function b(a,b){this.pageInfo=a;this.transport=b;this.stats=new ta;this.stats.enabled=!!v.PDFJS.enableStats;this.commonObjs=b.commonObjs;this.objs=new la;this.pendingDestroy=this.cleanupAfterRender=this.receivingOperatorList=!1;this.renderTasks=[]}b.prototype={get pageNumber(){return this.pageInfo.pageIndex+1},get rotate(){return this.pageInfo.rotate},get ref(){return this.pageInfo.ref},
-get view(){return this.pageInfo.view},getViewport:function(a,b){2>arguments.length&&(b=this.rotate);return new PDFJS.PageViewport(this.view,a,b,0,0)},getAnnotations:function(){if(this.annotationsPromise)return this.annotationsPromise;var a=new PDFJS.Promise;this.annotationsPromise=a;this.transport.getAnnotations(this.pageInfo.pageIndex);return a},render:function(a){function b(a){var c=f.renderTasks.indexOf(d);0<=c&&f.renderTasks.splice(c,1);f.cleanupAfterRender&&(f.pendingDestroy=!0);f._tryDestroy();
-a?g.reject(a):g.resolve();e.timeEnd("Rendering");e.timeEnd("Overall")}var e=this.stats;e.time("Overall");this.pendingDestroy=!1;this.displayReadyPromise||(this.receivingOperatorList=!0,this.displayReadyPromise=new x,this.operatorList={fnArray:[],argsArray:[],lastChunk:!1},this.stats.time("Page Request"),this.transport.messageHandler.send("RenderPageRequest",{pageIndex:this.pageNumber-1}));var d=new La(b,a,this.objs,this.commonObjs,this.operatorList,this.pageNumber);this.renderTasks.push(d);var g=
-new Ma(d),f=this;this.displayReadyPromise.then(function(a){f.pendingDestroy?b():(e.time("Rendering"),d.initalizeGraphics(a),d.operatorListChanged())},function(a){b(a)});return g},getTextContent:function(){var a=new PDFJS.Promise;this.transport.messageHandler.send("GetTextContent",{pageIndex:this.pageNumber-1},function(b){a.resolve(b)});return a},getOperationList:function(){var a=new PDFJS.Promise;a.resolve({dependencyFontsID:null,operatorList:null});return a},destroy:function(){this.pendingDestroy=
-!0;this._tryDestroy()},_tryDestroy:function(){this.pendingDestroy&&0===this.renderTasks.length&&!this.receivingOperatorList&&(delete this.operatorList,delete this.displayReadyPromise,this.objs.clear(),this.pendingDestroy=!1)},_startRenderPage:function(a){this.displayReadyPromise.resolve(a)},_renderPageChunk:function(a){s.concatenateToArray(this.operatorList.fnArray,a.fnArray);s.concatenateToArray(this.operatorList.argsArray,a.argsArray);this.operatorList.lastChunk=a.lastChunk;for(var b=0;b<this.renderTasks.length;b++)this.renderTasks[b].operatorListChanged();
-a.lastChunk&&(this.receivingOperatorList=!1,this._tryDestroy())}};return b}(),Ja=function(){function b(a,b,e,d){this.pdfDataRangeTransport=e;this.workerReadyPromise=b;this.progressCallback=d;this.commonObjs=new la;this.pageCache=[];this.pagePromises=[];this.embeddedFontsUsed=!1;this.passwordCallback=null;if(!v.PDFJS.disableWorker&&"undefined"!==typeof Worker){b=PDFJS.workerSrc;"undefined"===typeof b&&m("No PDFJS.workerSrc specified");try{var g=new Worker(b),f=new Z("main",g);this.messageHandler=f;
-f.on("test",function(b){b?(this.worker=g,this.setupMessageHandler(f)):(v.PDFJS.disableWorker=!0,this.setupFakeWorker());a.resolve()}.bind(this));var k=new Uint8Array(1);f.send("test",k);return}catch(h){S("The worker has been disabled.")}}v.PDFJS.disableWorker=!0;this.loadFakeWorkerFiles().then(function(){this.setupFakeWorker();a.resolve()}.bind(this))}b.prototype={destroy:function(){this.pageCache=[];this.pagePromises=[];var a=this;this.messageHandler.send("Terminate",null,function(){a.worker&&a.worker.terminate()})},
-loadFakeWorkerFiles:function(){PDFJS.fakeWorkerFilesLoadedPromise||(PDFJS.fakeWorkerFilesLoadedPromise=new x,s.loadScript(PDFJS.workerSrc,function(){PDFJS.fakeWorkerFilesLoadedPromise.resolve()}));return PDFJS.fakeWorkerFilesLoadedPromise},setupFakeWorker:function(){F("Setting up fake worker.");var a={postMessage:function(b){a.onmessage({data:b})},terminate:function(){}},b=new Z("main",a);this.setupMessageHandler(b);PDFJS.WorkerMessageHandler.setup(b)},setupMessageHandler:function(a){function b(c){a.send("UpdatePassword",
-c)}this.messageHandler=a;var e=this.pdfDataRangeTransport;e&&(e.addRangeListener(function(b,c){a.send("OnDataRange",{begin:b,chunk:c})}),e.addProgressListener(function(b){a.send("OnDataProgress",{loaded:b})}),a.on("RequestDataRange",function(a){e.requestDataRange(a.begin,a.end)},this));a.on("GetDoc",function(a){this.pdfDocument=a=new Ka(a.pdfInfo,this);this.workerReadyPromise.resolve(a)},this);a.on("NeedPassword",function(a){if(this.passwordCallback)return this.passwordCallback(b,ga.NEED_PASSWORD);
-this.workerReadyPromise.reject(a.exception.message,a.exception)},this);a.on("IncorrectPassword",function(a){if(this.passwordCallback)return this.passwordCallback(b,ga.INCORRECT_PASSWORD);this.workerReadyPromise.reject(a.exception.message,a.exception)},this);a.on("InvalidPDF",function(a){this.workerReadyPromise.reject(a.exception.name,a.exception)},this);a.on("MissingPDF",function(a){this.workerReadyPromise.reject(a.exception.message,a.exception)},this);a.on("UnknownError",function(a){this.workerReadyPromise.reject(a.exception.message,
-a.exception)},this);a.on("GetPage",function(a){a=a.pageInfo;var b=new Na(a,this);this.pageCache[a.pageIndex]=b;this.pagePromises[a.pageIndex].resolve(b)},this);a.on("GetAnnotations",function(a){this.pageCache[a.pageIndex].annotationsPromise.resolve(a.annotations)},this);a.on("StartRenderPage",function(a){var b=this.pageCache[a.pageIndex];b.stats.timeEnd("Page Request");b._startRenderPage(a.transparency)},this);a.on("RenderPageChunk",function(a){this.pageCache[a.pageIndex]._renderPageChunk(a.operatorList)},
-this);a.on("commonobj",function(a){var b=a[0],c=a[1];if(!this.commonObjs.hasData(b))switch(c){case "Font":a=a[2];var k;if("error"in a){var h=a.error;F("Error during font loading: "+h);this.commonObjs.resolve(b,h);break}else k=new Oa(a);R.bind([k],function(a){this.commonObjs.resolve(b,k)}.bind(this));break;case "FontPath":this.commonObjs.resolve(b,a[2]);break;default:h("Got unknown common object type "+c)}},this);a.on("obj",function(a){var b=a[0],c=a[2],k=this.pageCache[a[1]];if(!k.objs.hasData(b))switch(c){case "JpegStream":a=
-a[3];qa(b,a,k.objs);break;case "Image":a=a[3];k.objs.resolve(b,a);"data"in a&&8E6<a.data.length&&(k.cleanupAfterRender=!0);break;default:m("Got unknown object type "+c)}},this);a.on("DocProgress",function(a){this.progressCallback&&this.progressCallback({loaded:a.loaded,total:a.total})},this);a.on("DocError",function(a){this.workerReadyPromise.reject(a)},this);a.on("PageError",function(a){var b=this.pageCache[a.pageNum-1];b.displayReadyPromise?b.displayReadyPromise.reject(a.error):m(a.error)},this);
-a.on("JpegDecode",function(a,b){var c=a[0],k=a[1];3!=k&&1!=k&&m("Only 3 component or 1 component can be returned");var h=new Image;h.onload=function(){var a=h.width,c=h.height,f=a*c,d=4*f,f=new Uint8Array(f*k),e=ea(a,c).getContext("2d");e.drawImage(h,0,0);e=e.getImageData(0,0,a,c).data;if(3==k)for(var r=0,m=0;r<d;r+=4,m+=3)f[m]=e[r],f[m+1]=e[r+1],f[m+2]=e[r+2];else if(1==k)for(m=r=0;r<d;r+=4,m++)f[m]=e[r];b.resolve({data:f,width:a,height:c})}.bind(this);c="data:image/jpeg;base64,"+window.btoa(c);
-h.src=c})},fetchDocument:function(a){a.disableAutoFetch=PDFJS.disableAutoFetch;a.chunkedViewerLoading=!!this.pdfDataRangeTransport;this.messageHandler.send("GetDocRequest",{source:a,disableRange:PDFJS.disableRange,maxImageSize:PDFJS.maxImageSize,disableFontFace:PDFJS.disableFontFace})},getData:function(a){this.messageHandler.send("GetData",null,function(b){a.resolve(b)})},dataLoaded:function(){var a=new PDFJS.Promise;this.messageHandler.send("DataLoaded",null,function(b){a.resolve(b)});return a},
-getPage:function(a,b){var e=a-1;if(e in this.pagePromises)return this.pagePromises[e];b=new PDFJS.Promise("Page "+a);this.pagePromises[e]=b;this.messageHandler.send("GetPageRequest",{pageIndex:e});return b},getAnnotations:function(a){this.messageHandler.send("GetAnnotationsRequest",{pageIndex:a})},getDestinations:function(){var a=new PDFJS.Promise;this.messageHandler.send("GetDestinations",null,function(b){a.resolve(b)});return a}};return b}(),la=function(){function b(){this.objs={}}b.prototype={ensureObj:function(a){if(this.objs[a])return this.objs[a];
-var b={promise:new x(a),data:null,resolved:!1};return this.objs[a]=b},get:function(a,b){if(b)return this.ensureObj(a).promise.then(b),null;var e=this.objs[a];e&&e.resolved||m("Requesting object that isn't resolved yet "+a);return e.data},resolve:function(a,b){var e=this.ensureObj(a);e.resolved=!0;e.data=b;e.promise.resolve(b)},isResolved:function(a){var b=this.objs;return b[a]?b[a].resolved:!1},hasData:function(a){return this.isResolved(a)},getData:function(a){var b=this.objs;return b[a]&&b[a].resolved?
-b[a].data:null},clear:function(){this.objs={}}};return b}(),Ma=function(){function b(a){this.internalRenderTask=a;x.call(this)}b.prototype=Object.create(x.prototype);b.prototype.cancel=function(){this.internalRenderTask.cancel()};return b}(),La=function(){function b(a,b,e,d,g,f){this.callback=a;this.params=b;this.objs=e;this.commonObjs=d;this.operatorListIdx=null;this.operatorList=g;this.pageNumber=f;this.running=!1;this.graphicsReadyCallback=null;this.cancelled=this.graphicsReady=!1}b.prototype=
-{initalizeGraphics:function(a){if(!this.cancelled){PDFJS.pdfBug&&"StepperManager"in v&&v.StepperManager.enabled&&(this.stepper=v.StepperManager.create(this.pageNumber-1),this.stepper.init(this.operatorList),this.stepper.nextBreakPoint=this.stepper.getNextBreakPoint());var b=this.params;this.gfx=new ka(b.canvasContext,this.commonObjs,this.objs,b.textLayer,b.imageLayer);this.gfx.beginDrawing(b.viewport,a);this.operatorListIdx=0;this.graphicsReady=!0;this.graphicsReadyCallback&&this.graphicsReadyCallback()}},
-cancel:function(){this.running=!1;this.cancelled=!0;this.callback("cancelled")},operatorListChanged:function(){this.graphicsReady?(this.stepper&&this.stepper.updateOperatorList(this.operatorList),this.running||this._continue()):this.graphicsReadyCallback||(this.graphicsReadyCallback=this._continue.bind(this))},_continue:function(){this.running=!0;this.cancelled||(this.params.continueCallback?this.params.continueCallback(this._next.bind(this)):this._next())},_next:function(){this.cancelled||(this.operatorListIdx=
-this.gfx.executeOperatorList(this.operatorList,this.operatorListIdx,this._continue.bind(this),this.stepper),this.operatorListIdx===this.operatorList.fnArray.length&&(this.running=!1,this.operatorList.lastChunk&&(this.gfx.endDrawing(),this.callback())))}};return b}();PDFJS.Metadata=function(){function b(a){return a.replace(/>\\376\\377([^<]+)/g,function(a,b){for(var c=b.replace(/\\([0-3])([0-7])([0-7])/g,function(a,b,c,f){return String.fromCharCode(64*b+8*c+1*f)}),f="",k=0;k<c.length;k+=2)var h=256*
-c.charCodeAt(k)+c.charCodeAt(k+1),f=f+("&#x"+(65536+h).toString(16).substring(1)+";");return">"+f})}function a(a){"string"===typeof a?(a=b(a),a=(new DOMParser).parseFromString(a,"application/xml")):a instanceof Document||m("Metadata: Invalid metadata object");this.metaDocument=a;this.metadata={};this.parse()}a.prototype={parse:function(){var a=this.metaDocument.documentElement;if("rdf:rdf"!==a.nodeName.toLowerCase())for(a=a.firstChild;a&&"rdf:rdf"!==a.nodeName.toLowerCase();)a=a.nextSibling;var b=
-a?a.nodeName.toLowerCase():null;if(a&&"rdf:rdf"===b&&a.hasChildNodes()){var a=a.childNodes,d,g,f,k,h,l;f=0;for(h=a.length;f<h;f++)if(b=a[f],"rdf:description"===b.nodeName.toLowerCase())for(k=0,l=b.childNodes.length;k<l;k++)"#text"!==b.childNodes[k].nodeName.toLowerCase()&&(d=b.childNodes[k],g=d.nodeName.toLowerCase(),this.metadata[g]=d.textContent.trim())}},get:function(a){return this.metadata[a]||null},has:function(a){return"undefined"!==typeof this.metadata[a]}};return a}();var G=function(){var b=
-{};return{getCanvas:function(a,c,e,d){a in b?(a=b[a],a.canvas.width=c,a.canvas.height=e,a.context.setTransform(1,0,0,1,0,0)):(c=ea(c,e),e=c.getContext("2d"),d&&fa(e),b[a]=a={canvas:c,context:e});return a},clear:function(){b={}}}}(),ma=function(){function b(a){this.alphaIsShape=!1;this.fontSize=0;this.fontSizeScale=1;this.textMatrix=ha;this.fontMatrix=$;this.wordSpacing=this.charSpacing=this.lineY=this.lineX=this.y=this.x=this.leading=0;this.textHScale=1;this.textRenderingMode=V;this.textRise=0;this.fillColorSpace=
-p.singletons.gray;this.fillColorSpaceObj=null;this.strokeColorSpace=p.singletons.gray;this.strokeColorObj=this.fillColorObj=this.strokeColorSpaceObj=null;this.strokeColor=this.fillColor="#000000";this.lineWidth=this.strokeAlpha=this.fillAlpha=1;this.paintFormXObjectDepth=0;this.old=a}b.prototype={clone:function(){return Object.create(this)},setCurrentPoint:function(a,b){this.x=a;this.y=b}};return b}(),ka=function(){function b(a,b,c,d,e){this.ctx=a;this.current=new ma;this.stateStack=[];this.pendingClip=
-null;this.pendingEOFill=!1;this.xobjs=this.res=null;this.commonObjs=b;this.objs=c;this.textLayer=d;this.imageLayer=e;this.groupStack=[];this.baseTransform=this.processingType3=null;this.baseTransformStack=[];this.groupLevel=0;a&&fa(a)}function a(a,b){if("undefined"!==typeof ImageData&&b instanceof ImageData)a.putImageData(b,0,0);else{var c=a.createImageData(b.width,b.height),d=b.data,e=c.data;if("set"in e)e.set(d);else for(var g=0,y=e.length;g<y;g++)e[g]=d[g];a.putImageData(c,0,0)}}var c=["butt",
-"round","square"],e=["miter","round","bevel"],d={},g={};b.prototype={slowCommands:{stroke:!0,closeStroke:!0,fill:!0,eoFill:!0,fillStroke:!0,eoFillStroke:!0,closeFillStroke:!0,closeEOFillStroke:!0,showText:!0,showSpacedText:!0,setStrokeColorSpace:!0,setFillColorSpace:!0,setStrokeColor:!0,setStrokeColorN:!0,setFillColor:!0,setFillColorN:!0,setStrokeGray:!0,setFillGray:!0,setStrokeRGBColor:!0,setFillRGBColor:!0,setStrokeCMYKColor:!0,setFillCMYKColor:!0,paintJpegXObject:!0,paintImageXObject:!0,paintInlineImageXObject:!0,
-paintInlineImageXObjectGroup:!0,paintImageMaskXObject:!0,paintImageMaskXObjectGroup:!0,shadingFill:!0},beginDrawing:function(a,b){var c=this.ctx.canvas.width,d=this.ctx.canvas.height;b?this.ctx.clearRect(0,0,c,d):(this.ctx.mozOpaque=!0,this.ctx.save(),this.ctx.fillStyle="rgb(255, 255, 255)",this.ctx.fillRect(0,0,c,d),this.ctx.restore());c=a.transform;this.baseTransform=c.slice();this.ctx.save();this.ctx.transform.apply(this.ctx,c);this.textLayer&&this.textLayer.beginLayout();this.imageLayer&&this.imageLayer.beginLayout()},
-executeOperatorList:function(a,b,c,d){var e=a.argsArray;a=a.fnArray;b=b||0;var g=e.length;if(g==b)return b;for(var y=Date.now()+15,q=this.commonObjs,r=this.objs,m,u=this.slowCommands;;){if(d&&b===d.nextBreakPoint)return d.breakIt(b,c),b;m=a[b];if("dependency"!==m)this[m].apply(this,e[b]);else for(var s=e[b],p=0,E=s.length;p<E;p++){var z=s[p],v="g_"==z.substring(0,2);if(!v&&!r.isResolved(z))return r.get(z,c),b;if(v&&!q.isResolved(z))return q.get(z,c),b}b++;if(b==g)return b;if(c&&u[m]&&Date.now()>y)return setTimeout(c,
-0),b}},endDrawing:function(){this.ctx.restore();G.clear();this.textLayer&&this.textLayer.endLayout();this.imageLayer&&this.imageLayer.endLayout()},setLineWidth:function(a){this.current.lineWidth=a;this.ctx.lineWidth=a},setLineCap:function(a){this.ctx.lineCap=c[a]},setLineJoin:function(a){this.ctx.lineJoin=e[a]},setMiterLimit:function(a){this.ctx.miterLimit=a},setDash:function(a,b){var c=this.ctx;"setLineDash"in c?(c.setLineDash(a),c.lineDashOffset=b):(c.mozDash=a,c.mozDashOffset=b)},setRenderingIntent:function(a){},
-setFlatness:function(a){},setGState:function(a){for(var b=0,c=a.length;b<c;b++){var d=a[b],e=d[1];switch(d[0]){case "LW":this.setLineWidth(e);break;case "LC":this.setLineCap(e);break;case "LJ":this.setLineJoin(e);break;case "ML":this.setMiterLimit(e);break;case "D":this.setDash(e[0],e[1]);break;case "RI":this.setRenderingIntent(e);break;case "FL":this.setFlatness(e);break;case "Font":this.setFont(e[0],e[1]);break;case "CA":this.current.strokeAlpha=d[1];break;case "ca":this.current.fillAlpha=d[1];
-this.ctx.globalAlpha=d[1];break;case "BM":e&&e.name&&"Normal"!==e.name?(d=e.name.replace(/([A-Z])/g,function(a){return"-"+a.toLowerCase()}).substring(1),this.ctx.globalCompositeOperation=d,this.ctx.globalCompositeOperation!==d&&F('globalCompositeOperation "'+d+'" is not supported')):this.ctx.globalCompositeOperation="source-over"}}},save:function(){this.ctx.save();var a=this.current;this.stateStack.push(a);this.current=a.clone()},restore:function(){var a=this.stateStack.pop();a&&(this.current=a,this.ctx.restore())},
-transform:function(a,b,c,d,e,g){this.ctx.transform(a,b,c,d,e,g)},moveTo:function(a,b){this.ctx.moveTo(a,b);this.current.setCurrentPoint(a,b)},lineTo:function(a,b){this.ctx.lineTo(a,b);this.current.setCurrentPoint(a,b)},curveTo:function(a,b,c,d,e,g){this.ctx.bezierCurveTo(a,b,c,d,e,g);this.current.setCurrentPoint(e,g)},curveTo2:function(a,b,c,d){var e=this.current;this.ctx.bezierCurveTo(e.x,e.y,a,b,c,d);e.setCurrentPoint(c,d)},curveTo3:function(a,b,c,d){this.curveTo(a,b,c,d,c,d);this.current.setCurrentPoint(c,
-d)},closePath:function(){this.ctx.closePath()},rectangle:function(a,b,c,d){this.ctx.rect(a,b,c,d)},stroke:function(a){a="undefined"!==typeof a?a:!0;var b=this.ctx,c=this.current.strokeColor;0===this.current.lineWidth&&(b.lineWidth=this.getSinglePixelWidth());b.globalAlpha=this.current.strokeAlpha;c&&c.hasOwnProperty("type")&&"Pattern"===c.type?(b.save(),b.strokeStyle=c.getPattern(b,this),b.stroke(),b.restore()):b.stroke();a&&this.consumePath();b.globalAlpha=this.current.fillAlpha},closeStroke:function(){this.closePath();
-this.stroke()},fill:function(a){a="undefined"!==typeof a?a:!0;var b=this.ctx,c=this.current.fillColor,d=!1;c&&c.hasOwnProperty("type")&&"Pattern"===c.type&&(b.save(),b.fillStyle=c.getPattern(b,this),d=!0);if(this.pendingEOFill){if("mozFillRule"in this.ctx)this.ctx.mozFillRule="evenodd",this.ctx.fill(),this.ctx.mozFillRule="nonzero";else try{this.ctx.fill("evenodd")}catch(e){this.ctx.fill()}this.pendingEOFill=!1}else this.ctx.fill();d&&b.restore();a&&this.consumePath()},eoFill:function(){this.pendingEOFill=
-!0;this.fill()},fillStroke:function(){this.fill(!1);this.stroke(!1);this.consumePath()},eoFillStroke:function(){this.pendingEOFill=!0;this.fillStroke()},closeFillStroke:function(){this.closePath();this.fillStroke()},closeEOFillStroke:function(){this.pendingEOFill=!0;this.closePath();this.fillStroke()},endPath:function(){this.consumePath()},clip:function(){this.pendingClip=d},eoClip:function(){this.pendingClip=g},beginText:function(){this.current.textMatrix=ha;this.current.x=this.current.lineX=0;this.current.y=
-this.current.lineY=0},endText:function(){if("pendingTextPaths"in this){var a=this.pendingTextPaths,b=this.ctx;b.save();b.beginPath();for(var c=0;c<a.length;c++){var d=a[c];b.setTransform.apply(b,d.transform);b.translate(d.x,d.y);d.addToPath(b,d.fontSize)}b.restore();b.clip();b.beginPath();delete this.pendingTextPaths}else this.ctx.beginPath()},setCharSpacing:function(a){this.current.charSpacing=a},setWordSpacing:function(a){this.current.wordSpacing=a},setHScale:function(a){this.current.textHScale=
-a/100},setLeading:function(a){this.current.leading=-a},setFont:function(a,b){var c=this.commonObjs.get(a),d=this.current;c||m("Can't find font for "+a);d.fontMatrix=c.fontMatrix?c.fontMatrix:$;0!==d.fontMatrix[0]&&0!==d.fontMatrix[3]||F("Invalid font matrix for font "+a);0>b?(b=-b,d.fontDirection=-1):d.fontDirection=1;this.current.font=c;this.current.fontSize=b;if(!c.coded){var d=c.black?c.bold?"bolder":"bold":c.bold?"bold":"normal",e=c.italic?"italic":"normal",c='"'+(c.loadedName||"sans-serif")+
-'", '+c.fallbackName,g=16<=b?b:16;this.current.fontSizeScale=16!=g?1:b/16;this.ctx.font=e+" "+d+" "+g+"px "+c}},setTextRenderingMode:function(a){this.current.textRenderingMode=a},setTextRise:function(a){this.current.textRise=a},moveText:function(a,b){this.current.x=this.current.lineX+=a;this.current.y=this.current.lineY+=b},setLeadingMoveText:function(a,b){this.setLeading(-b);this.moveText(a,b)},setTextMatrix:function(a,b,c,d,e,g){this.current.textMatrix=[a,b,c,d,e,g];this.current.x=this.current.lineX=
-0;this.current.y=this.current.lineY=0},nextLine:function(){this.moveText(0,this.current.leading)},applyTextTransforms:function(){var a=this.ctx,b=this.current;a.transform.apply(a,b.textMatrix);a.translate(b.x,b.y+b.textRise);0<b.fontDirection?a.scale(b.textHScale,-1):a.scale(-b.textHScale,1)},createTextGeometry:function(){var a={},b=this.current.font,c=this.ctx.mozCurrentTransform,d=c[0],e=c[1],g=c[2],m=c[3],q=c[4],c=c[5],r=0<=d?Math.sqrt(d*d+e*e):-Math.sqrt(d*d+e*e),g=0<=m?Math.sqrt(g*g+m*m):-Math.sqrt(g*
-g+m*m),d=Math.atan2(e,d);a.x=q;a.y=c;a.hScale=r;a.vScale=g;a.angle=d;a.spaceWidth=b.spaceWidth;a.fontName=b.loadedName;a.fontFamily=b.fallbackName;a.fontSize=this.current.fontSize;return a},paintChar:function(a,b,c){var d=this.ctx,e=this.current,g=e.font,m=e.fontSize/e.fontSizeScale,q=e.textRenderingMode,e=q&3,q=!!(q&4),r;if(g.disableFontFace||q)r=g.getPathGenerator(this.commonObjs,a);g.disableFontFace?(d.save(),d.translate(b,c),d.beginPath(),r(d,m),e!==V&&2!==e||d.fill(),1!==e&&2!==e||d.stroke(),
-d.restore()):(e!==V&&2!==e||d.fillText(a,b,c),1!==e&&2!==e||d.strokeText(a,b,c));q&&(this.pendingTextPaths||(this.pendingTextPaths=[])).push({transform:d.mozCurrentTransform,x:b,y:c,fontSize:m,addToPath:r})},showText:function(a,b){var c=this.ctx,d=this.current,e=d.font,g=d.fontSize,m=d.fontSizeScale,q=d.charSpacing,r=d.wordSpacing,p=d.textHScale*d.fontDirection,u=d.fontMatrix||$,w=a.length,v,E=this.textLayer&&!b?!0:!1,z=0,A=e.vertical,F=e.defaultVMetrics;if(e.coded){c.save();c.transform.apply(c,d.textMatrix);
-c.translate(d.x,d.y);c.scale(p,1);E&&(this.save(),c.scale(1,-1),v=this.createTextGeometry(),this.restore());for(var I=0;I<w;++I){var C=a[I];if(null===C)this.ctx.translate(r,0),d.x+=r*p;else{this.processingType3=C;this.save();c.scale(g,g);c.transform.apply(c,u);this.executeOperatorList(C.operatorList);this.restore();var x=(s.applyTransform([C.width,0],u)[0]*g+q)*d.fontDirection;c.translate(x,0);d.x+=x*p;z+=x}}c.restore();this.processingType3=null}else{c.save();this.applyTextTransforms();var I=d.lineWidth,
-u=d.textMatrix[0],B=d.textMatrix[1],u=Math.sqrt(u*u+B*B),I=0===u||0===I?this.getSinglePixelWidth():I/u;E&&(v=this.createTextGeometry());1!=m&&(c.scale(m,m),I/=m);c.lineWidth=I;for(I=u=0;I<w;++I)if(C=a[I],null===C)u+=d.fontDirection*r;else{var B=!1,H=C.fontChar,D=C.vmetric||F;if(A)var L=C.vmetric?D[1]:0.5*C.width,L=-L*g*d.fontMatrix[0],M=D[2]*g*d.fontMatrix[0];var x=D?-D[0]:C.width,D=x*g*d.fontMatrix[0]+q*d.fontDirection,G=C.accent,J,K;C.disabled||(A?(C=L/m,J=(u+M)/m):(C=u/m,J=0),e.remeasure&&0<x&&
-(B=1E3*c.measureText(H).width/d.fontSize*d.fontSizeScale,x/=B,B=!0,c.save(),c.scale(x,1),C/=x,G&&(K/=x)),this.paintChar(H,C,J),G&&(K=C+G.offset.x/m,H=J-G.offset.y/m,this.paintChar(G.fontChar,K,H)));u+=D;z+=D;B&&c.restore()}A?d.y-=u*p:d.x+=u*p;c.restore()}E&&(v.canvasWidth=z,A&&(v.angle+=Math.PI/2),this.textLayer.appendText(v));return z},showSpacedText:function(a){var b=this.ctx,c=this.current,d=c.fontSize,e=0.0010*c.textHScale*c.fontDirection,g=a.length,m,q=0,r=this.textLayer?!0:!1,s=c.font.vertical,
-u=0;r&&(b.save(),this.applyTextTransforms(),m=this.createTextGeometry(),b.restore());for(b=0;b<g;++b){var p=a[b];"number"==typeof p?(p=-p*d*e,s?c.y+=p:c.x+=p,r&&(u+=p)):(p=this.showText(p,!0),r&&(q+=u+p,u=0))}r&&(m.canvasWidth=q,s&&(m.angle+=Math.PI/2),this.textLayer.appendText(m))},nextLineShowText:function(a){this.nextLine();this.showText(a)},nextLineSetSpacingShowText:function(a,b,c){this.setWordSpacing(a);this.setCharSpacing(b);this.nextLineShowText(c)},setCharWidth:function(a,b){},setCharWidthAndBounds:function(a,
-b,c,d,e,g){this.rectangle(c,d,e-c,g-d);this.clip();this.endPath()},setStrokeColorSpace:function(a){this.current.strokeColorSpace=p.fromIR(a)},setFillColorSpace:function(a){this.current.fillColorSpace=p.fromIR(a)},setStrokeColor:function(){var a=this.current.strokeColorSpace.getRgb(arguments,0),a=s.makeCssRgb(a);this.ctx.strokeStyle=a;this.current.strokeColor=a},getColorN_Pattern:function(a,b){if("TilingPattern"==a[0]){var c=a[1],d=b.base,e;d&&(e=d.getRgb(c,0));c=new Aa(a,e,this.ctx,this.objs,this.commonObjs,
-this.baseTransform)}else"RadialAxial"==a[0]||"Dummy"==a[0]?c=ja.shadingFromIR(a):m("Unkown IR type "+a[0]);return c},setStrokeColorN:function(){var a=this.current.strokeColorSpace;"Pattern"==a.name?this.current.strokeColor=this.getColorN_Pattern(arguments,a):this.setStrokeColor.apply(this,arguments)},setFillColor:function(){var a=this.current.fillColorSpace.getRgb(arguments,0),a=s.makeCssRgb(a);this.ctx.fillStyle=a;this.current.fillColor=a},setFillColorN:function(){var a=this.current.fillColorSpace;
-"Pattern"==a.name?this.current.fillColor=this.getColorN_Pattern(arguments,a):this.setFillColor.apply(this,arguments)},setStrokeGray:function(a){this.current.strokeColorSpace=p.singletons.gray;var b=this.current.strokeColorSpace.getRgb(arguments,0),b=s.makeCssRgb(b);this.ctx.strokeStyle=b;this.current.strokeColor=b},setFillGray:function(a){this.current.fillColorSpace=p.singletons.gray;var b=this.current.fillColorSpace.getRgb(arguments,0),b=s.makeCssRgb(b);this.ctx.fillStyle=b;this.current.fillColor=
-b},setStrokeRGBColor:function(a,b,c){this.current.strokeColorSpace=p.singletons.rgb;var d=this.current.strokeColorSpace.getRgb(arguments,0),d=s.makeCssRgb(d);this.ctx.strokeStyle=d;this.current.strokeColor=d},setFillRGBColor:function(a,b,c){this.current.fillColorSpace=p.singletons.rgb;var d=this.current.fillColorSpace.getRgb(arguments,0),d=s.makeCssRgb(d);this.ctx.fillStyle=d;this.current.fillColor=d},setStrokeCMYKColor:function(a,b,c,d){this.current.strokeColorSpace=p.singletons.cmyk;var e=s.makeCssCmyk(arguments);
-this.ctx.strokeStyle=e;this.current.strokeColor=e},setFillCMYKColor:function(a,b,c,d){this.current.fillColorSpace=p.singletons.cmyk;var e=s.makeCssCmyk(arguments);this.ctx.fillStyle=e;this.current.fillColor=e},shadingFill:function(a){var b=this.ctx;this.save();a=ja.shadingFromIR(a);b.fillStyle=a.getPattern(b,this);var c=b.mozCurrentTransformInverse;if(c){var b=b.canvas,d=b.width,e=b.height,b=s.applyTransform([0,0],c);a=s.applyTransform([0,e],c);var g=s.applyTransform([d,0],c),m=s.applyTransform([d,
-e],c),c=Math.min(b[0],a[0],g[0],m[0]),d=Math.min(b[1],a[1],g[1],m[1]),e=Math.max(b[0],a[0],g[0],m[0]),b=Math.max(b[1],a[1],g[1],m[1]);this.ctx.fillRect(c,d,e-c,b-d)}else this.ctx.fillRect(-1E10,-1E10,2E10,2E10);this.restore()},beginInlineImage:function(){m("Should not call beginInlineImage")},beginImageData:function(){m("Should not call beginImageData")},paintFormXObjectBegin:function(a,b){this.save();this.current.paintFormXObjectDepth++;this.baseTransformStack.push(this.baseTransform);a&&B(a)&&6==
-a.length&&this.transform.apply(this,a);this.baseTransform=this.ctx.mozCurrentTransform;b&&B(b)&&4==b.length&&(this.rectangle(b[0],b[1],b[2]-b[0],b[3]-b[1]),this.clip(),this.endPath())},paintFormXObjectEnd:function(){var a=this.current.paintFormXObjectDepth;do this.restore();while(this.current.paintFormXObjectDepth>=a);this.baseTransform=this.baseTransformStack.pop()},beginGroup:function(a){this.save();var b=this.ctx;a.isolated||S("TODO: Support non-isolated groups.");a.knockout&&K("Support knockout groups.");
-var c=b.mozCurrentTransform;a.matrix&&b.transform.apply(b,a.matrix);a.bbox||m("Bounding box is required.");var d=s.getAxialAlignedBoundingBox(a.bbox,b.mozCurrentTransform);a=Math.max(Math.ceil(d[2]-d[0]),1);var e=Math.max(Math.ceil(d[3]-d[1]),1);a=G.getCanvas("groupAt"+this.groupLevel,a,e,!0).context;e=d[0];d=d[1];a.translate(-e,-d);a.transform.apply(a,c);b.setTransform(1,0,0,1,0,0);b.translate(e,d);c="strokeStyle fillStyle fillRule globalAlpha lineWidth lineCap lineJoin miterLimit globalCompositeOperation font".split(" ");
-d=0;for(e=c.length;d<e;d++){var g=c[d];g in b&&(a[g]=b[g])}"setLineDash"in b?(a.setLineDash(b.getLineDash()),a.lineDashOffset=b.lineDashOffset):"mozDash"in b&&(a.mozDash=b.mozDash,a.mozDashOffset=b.mozDashOffset);this.ctx=a;this.setGState([["SMask","None"],["BM","Normal"],["ca",1],["CA",1]]);this.groupStack.push(b);this.groupLevel++},endGroup:function(a){this.groupLevel--;a=this.ctx;this.ctx=this.groupStack.pop();"imageSmoothingEnabled"in this.ctx?this.ctx.imageSmoothingEnabled=!1:this.ctx.mozImageSmoothingEnabled=
-!1;this.ctx.drawImage(a.canvas,0,0);this.restore()},beginAnnotations:function(){this.save();this.current=new ma},endAnnotations:function(){this.restore()},beginAnnotation:function(a,b,c){this.save();a&&B(a)&&4==a.length&&(this.rectangle(a[0],a[1],a[2]-a[0],a[3]-a[1]),this.clip(),this.endPath());this.transform.apply(this,b);this.transform.apply(this,c)},endAnnotation:function(){this.restore()},paintJpegXObject:function(a,b,c){var d=this.objs.get(a);d||m("Dependent image isn't ready yet");this.save();
-var e=this.ctx;e.scale(1/b,-1/c);e.drawImage(d,0,0,d.width,d.height,0,-c,b,c);this.imageLayer&&(d=e.mozCurrentTransformInverse,e=this.getCanvasPosition(0,0),this.imageLayer.appendImage({objId:a,left:e[0],top:e[1],width:b/d[0],height:c/d[3]}));this.restore()},paintImageMaskXObject:function(b){var c=this.ctx,d=b.width,e=b.height,g=this.processingType3;!g||"compiled"in g||(g.compiled=1E3>=d&&1E3>=e?ra({data:b.data,width:d,height:e}):null);g&&g.compiled?g.compiled(c):(c=G.getCanvas("maskCanvas",d,e),
-g=c.context,g.save(),a(g,b),g.globalCompositeOperation="source-in",b=this.current.fillColor,g.fillStyle=b&&b.hasOwnProperty("type")&&"Pattern"===b.type?b.getPattern(g,this):b,g.fillRect(0,0,d,e),g.restore(),this.paintInlineImageXObject(c.canvas))},paintImageMaskXObjectGroup:function(b){for(var c=this.ctx,d=0,e=b.length;d<e;d++){var g=b[d],m=g.width,p=g.height,q=G.getCanvas("maskCanvas",m,p),r=q.context;r.save();a(r,g);r.globalCompositeOperation="source-in";var s=this.current.fillColor;r.fillStyle=
-s&&s.hasOwnProperty("type")&&"Pattern"===s.type?s.getPattern(r,this):s;r.fillRect(0,0,m,p);r.restore();c.save();c.transform.apply(c,g.transform);c.scale(1,-1);c.drawImage(q.canvas,0,0,m,p,0,-1,1,1);c.restore()}},paintImageXObject:function(a){(a=this.objs.get(a))||m("Dependent image isn't ready yet");this.paintInlineImageXObject(a)},paintInlineImageXObject:function(b){var c=b.width,d=b.height,e=this.ctx;this.save();e.scale(1/c,-1/d);var g=e.mozCurrentTransformInverse,m=g[0],p=g[1],m=Math.max(Math.sqrt(m*
-m+p*p),1),p=g[2],q=g[3],p=Math.max(Math.sqrt(p*p+q*q),1);if(b instanceof HTMLElement)q=b;else{var r=G.getCanvas("inlineImage",c,d),s=r.context;a(s,b);q=r.canvas}for(var u=c,w=d,v="prescale1";2<m&&1<u||2<p&&1<w;){var x=u,z=w;2<m&&1<u&&(x=Math.ceil(u/2),m/=u/x);2<p&&1<w&&(z=Math.ceil(w/2),p/=w/z);r=G.getCanvas(v,x,z);s=r.context;s.clearRect(0,0,x,z);s.drawImage(q,0,0,u,w,0,0,x,z);q=r.canvas;u=x;w=z;v="prescale1"===v?"prescale2":"prescale1"}e.drawImage(q,0,0,u,w,0,-d,c,d);this.imageLayer&&(e=this.getCanvasPosition(0,
--d),this.imageLayer.appendImage({imgData:b,left:e[0],top:e[1],width:c/g[0],height:d/g[3]}));this.restore()},paintInlineImageXObjectGroup:function(b,c){var d=this.ctx,e=b.width,g=b.height,m=G.getCanvas("inlineImage",e,g);a(m.context,b);for(var p=0,q=c.length;p<q;p++){var r=c[p];d.save();d.transform.apply(d,r.transform);d.scale(1,-1);d.drawImage(m.canvas,r.x,r.y,r.w,r.h,0,-1,1,1);this.imageLayer&&(r=this.getCanvasPosition(r.x,r.y),this.imageLayer.appendImage({imgData:b,left:r[0],top:r[1],width:e,height:g}));
-d.restore()}},markPoint:function(a){},markPointProps:function(a,b){},beginMarkedContent:function(a){},beginMarkedContentProps:function(a,b){},endMarkedContent:function(){},beginCompat:function(){},endCompat:function(){},consumePath:function(){if(this.pendingClip){if(this.pendingClip==g)if("mozFillRule"in this.ctx)this.ctx.mozFillRule="evenodd",this.ctx.clip(),this.ctx.mozFillRule="nonzero";else try{this.ctx.clip("evenodd")}catch(a){this.ctx.clip()}else this.ctx.clip();this.pendingClip=null}this.ctx.beginPath()},
-getSinglePixelWidth:function(a){a=this.ctx.mozCurrentTransformInverse;return Math.sqrt(Math.max(a[0]*a[0]+a[1]*a[1],a[2]*a[2]+a[3]*a[3]))},getCanvasPosition:function(a,b){var c=this.ctx.mozCurrentTransform;return[c[0]*a+c[2]*b+c[4],c[1]*a+c[3]*b+c[5]]}};return b}();PDFJS.disableFontFace=!1;var R={insertRule:function(b){var a=document.getElementById("PDFJS_FONT_STYLE_TAG");a||(a=document.createElement("style"),a.id="PDFJS_FONT_STYLE_TAG",document.documentElement.getElementsByTagName("head")[0].appendChild(a));
-a=a.sheet;a.insertRule(b,a.cssRules.length)},get loadTestFont(){return W(this,"loadTestFont",atob("T1RUTwALAIAAAwAwQ0ZGIDHtZg4AAAOYAAAAgUZGVE1lkzZwAAAEHAAAABxHREVGABQAFQAABDgAAAAeT1MvMlYNYwkAAAEgAAAAYGNtYXABDQLUAAACNAAAAUJoZWFk/xVFDQAAALwAAAA2aGhlYQdkA+oAAAD0AAAAJGhtdHgD6AAAAAAEWAAAAAZtYXhwAAJQAAAAARgAAAAGbmFtZVjmdH4AAAGAAAAAsXBvc3T/hgAzAAADeAAAACAAAQAAAAEAALZRFsRfDzz1AAsD6AAAAADOBOTLAAAAAM4KHDwAAAAAA+gDIQAAAAgAAgAAAAAAAAABAAADIQAAAFoD6AAAAAAD6AABAAAAAAAAAAAAAAAAAAAAAQAAUAAAAgAAAAQD6AH0AAUAAAKKArwAAACMAooCvAAAAeAAMQECAAACAAYJAAAAAAAAAAAAAQAAAAAAAAAAAAAAAFBmRWQAwAAuAC4DIP84AFoDIQAAAAAAAQAAAAAAAAAAACAAIAABAAAADgCuAAEAAAAAAAAAAQAAAAEAAAAAAAEAAQAAAAEAAAAAAAIAAQAAAAEAAAAAAAMAAQAAAAEAAAAAAAQAAQAAAAEAAAAAAAUAAQAAAAEAAAAAAAYAAQAAAAMAAQQJAAAAAgABAAMAAQQJAAEAAgABAAMAAQQJAAIAAgABAAMAAQQJAAMAAgABAAMAAQQJAAQAAgABAAMAAQQJAAUAAgABAAMAAQQJAAYAAgABWABYAAAAAAAAAwAAAAMAAAAcAAEAAAAAADwAAwABAAAAHAAEACAAAAAEAAQAAQAAAC7//wAAAC7////TAAEAAAAAAAABBgAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAD/gwAyAAAAAQAAAAAAAAAAAAAAAAAAAAABAAQEAAEBAQJYAAEBASH4DwD4GwHEAvgcA/gXBIwMAYuL+nz5tQXkD5j3CBLnEQACAQEBIVhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYAAABAQAADwACAQEEE/t3Dov6fAH6fAT+fPp8+nwHDosMCvm1Cvm1DAz6fBQAAAAAAAABAAAAAMmJbzEAAAAAzgTjFQAAAADOBOQpAAEAAAAAAAAADAAUAAQAAAABAAAAAgABAAAAAAAAAAAD6AAAAAAAAA=="))},
-loadTestFontId:0,loadingContext:{requests:[],nextRequestId:0},isSyncFontLoadingSupported:function(){if(U)return!1;var b=/Mozilla\/5.0.*?rv:(\d+).*? Gecko/.exec(window.navigator.userAgent);return b&&14<=b[1]?!0:!1}(),bind:function(b,a){U&&m("bind() shall be called from main thread");for(var c=[],e=[],d=0,g=b.length;d<g;d++){var f=b[d];if(!f.attached&&!1!==f.loading){f.attached=!0;var k=f.bindDOM();k&&(c.push(k),e.push(f))}}d=R.queueLoadingCallback(a);0<c.length&&!this.isSyncFontLoadingSupported?R.prepareFontLoadEvent(c,
-e,d):d.complete()},queueLoadingCallback:function(b){var a=R.loadingContext,c={id:"pdfjs-font-loading-"+a.nextRequestId++,complete:function(){c.end&&m("completeRequest() cannot be called twice");for(c.end=Date.now();0<a.requests.length&&a.requests[0].end;){var b=a.requests.shift();setTimeout(b.callback,0)}},callback:b,started:Date.now()};a.requests.push(c);return c},prepareFontLoadEvent:function(b,a,c){function e(a,b){return a.charCodeAt(b)<<24|a.charCodeAt(b+1)<<16|a.charCodeAt(b+2)<<8|a.charCodeAt(b+
-3)&255}function d(a,b,c,d){a=m.substr(0,b);b=m.substr(b+c);return a+d+b}function g(a,b){l++;30<l?(F("Load test font never loaded."),b()):(h.font="30px "+a,h.fillText(".",0,20),0<h.getImageData(0,0,1,1).data[3]?b():setTimeout(g.bind(null,a,b)))}var f,k;b=document.createElement("canvas");b.width=1;b.height=1;var h=b.getContext("2d"),l=0;b="lt"+Date.now()+this.loadTestFontId++;var m=this.loadTestFont,m=d(m,976,b.length,b),p=e(m,16);f=0;for(k=b.length-3;f<k;f+=4)p=p-1482184792+e(b,f)|0;f<b.length&&(p=
-p-1482184792+e(b+"XXX",f)|0);m=d(m,16,4,String.fromCharCode(p>>24&255)+String.fromCharCode(p>>16&255)+String.fromCharCode(p>>8&255)+String.fromCharCode(p&255));f="url(data:font/opentype;base64,"+btoa(m)+");";R.insertRule('@font-face { font-family:"'+b+'";src:'+f+"}");p=[];f=0;for(k=a.length;f<k;f++)p.push(a[f].loadedName);p.push(b);var s=document.createElement("div");s.setAttribute("style","visibility: hidden;width: 10px; height: 10px;position: absolute; top: 0px; left: 0px;");f=0;for(k=p.length;f<
-k;++f)a=document.createElement("span"),a.textContent="Hi",a.style.fontFamily=p[f],s.appendChild(a);document.body.appendChild(s);g(b,function(){document.body.removeChild(s);c.complete()})}},Oa=function(){function b(a,b,e){this.compiledGlyphs={};if(1===arguments.length){var d=arguments[0],g;for(g in d)this[g]=d[g]}}b.prototype={bindDOM:function(){if(!this.data)return null;if(PDFJS.disableFontFace)return this.disableFontFace=!0,null;for(var a=this.data,b="",e=a.length,d=0;d<e;++d)b+=String.fromCharCode(a[d]);
-a=this.loadedName;b="url(data:"+this.mimetype+";base64,"+window.btoa(b)+");";a='@font-face { font-family:"'+a+'";src:'+b+"}";R.insertRule(a);PDFJS.pdfBug&&"FontInspector"in v&&v.FontInspector.enabled&&v.FontInspector.fontAdded(this,b);return a},getPathGenerator:function(a,b){if(!(b in this.compiledGlyphs)){var e=a.get(this.loadedName+"_path_"+b);this.compiledGlyphs[b]=new Function("c","size",e)}return this.compiledGlyphs[b]}};return b}()}).call("undefined"===typeof window?this:window);
-PDFJS.workerSrc||"undefined"===typeof document||(PDFJS.workerSrc=function(){var D=(document.body||document.getElementsByTagName("head")[0]).lastChild.src;return D&&D.replace(/\.js$/i,".worker.js")}());
+/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
+/* Copyright 2012 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Initializing PDFJS global object (if still undefined)
+if (typeof PDFJS === 'undefined') {
+ (typeof window !== 'undefined' ? window : this).PDFJS = {};
+}
+
+PDFJS.version = '0.8.894';
+PDFJS.build = 'ac91047';
+
+(function pdfjsWrapper() {
+ // Use strict in our context only - users might not want it
+ 'use strict';
+
+/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
+/* Copyright 2012 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/* globals Cmd, ColorSpace, Dict, MozBlobBuilder, Name, PDFJS, Ref, URL,
+ Promise */
+
+'use strict';
+
+var globalScope = (typeof window === 'undefined') ? this : window;
+
+var isWorker = (typeof window == 'undefined');
+
+var FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0];
+
+var TextRenderingMode = {
+ FILL: 0,
+ STROKE: 1,
+ FILL_STROKE: 2,
+ INVISIBLE: 3,
+ FILL_ADD_TO_PATH: 4,
+ STROKE_ADD_TO_PATH: 5,
+ FILL_STROKE_ADD_TO_PATH: 6,
+ ADD_TO_PATH: 7,
+ FILL_STROKE_MASK: 3,
+ ADD_TO_PATH_FLAG: 4
+};
+
+// The global PDFJS object exposes the API
+// In production, it will be declared outside a global wrapper
+// In development, it will be declared here
+if (!globalScope.PDFJS) {
+ globalScope.PDFJS = {};
+}
+
+globalScope.PDFJS.pdfBug = false;
+
+PDFJS.VERBOSITY_LEVELS = {
+ errors: 0,
+ warnings: 1,
+ infos: 5
+};
+
+// All the possible operations for an operator list.
+var OPS = PDFJS.OPS = {
+ // Intentionally start from 1 so it is easy to spot bad operators that will be
+ // 0's.
+ dependency: 1,
+ setLineWidth: 2,
+ setLineCap: 3,
+ setLineJoin: 4,
+ setMiterLimit: 5,
+ setDash: 6,
+ setRenderingIntent: 7,
+ setFlatness: 8,
+ setGState: 9,
+ save: 10,
+ restore: 11,
+ transform: 12,
+ moveTo: 13,
+ lineTo: 14,
+ curveTo: 15,
+ curveTo2: 16,
+ curveTo3: 17,
+ closePath: 18,
+ rectangle: 19,
+ stroke: 20,
+ closeStroke: 21,
+ fill: 22,
+ eoFill: 23,
+ fillStroke: 24,
+ eoFillStroke: 25,
+ closeFillStroke: 26,
+ closeEOFillStroke: 27,
+ endPath: 28,
+ clip: 29,
+ eoClip: 30,
+ beginText: 31,
+ endText: 32,
+ setCharSpacing: 33,
+ setWordSpacing: 34,
+ setHScale: 35,
+ setLeading: 36,
+ setFont: 37,
+ setTextRenderingMode: 38,
+ setTextRise: 39,
+ moveText: 40,
+ setLeadingMoveText: 41,
+ setTextMatrix: 42,
+ nextLine: 43,
+ showText: 44,
+ showSpacedText: 45,
+ nextLineShowText: 46,
+ nextLineSetSpacingShowText: 47,
+ setCharWidth: 48,
+ setCharWidthAndBounds: 49,
+ setStrokeColorSpace: 50,
+ setFillColorSpace: 51,
+ setStrokeColor: 52,
+ setStrokeColorN: 53,
+ setFillColor: 54,
+ setFillColorN: 55,
+ setStrokeGray: 56,
+ setFillGray: 57,
+ setStrokeRGBColor: 58,
+ setFillRGBColor: 59,
+ setStrokeCMYKColor: 60,
+ setFillCMYKColor: 61,
+ shadingFill: 62,
+ beginInlineImage: 63,
+ beginImageData: 64,
+ endInlineImage: 65,
+ paintXObject: 66,
+ markPoint: 67,
+ markPointProps: 68,
+ beginMarkedContent: 69,
+ beginMarkedContentProps: 70,
+ endMarkedContent: 71,
+ beginCompat: 72,
+ endCompat: 73,
+ paintFormXObjectBegin: 74,
+ paintFormXObjectEnd: 75,
+ beginGroup: 76,
+ endGroup: 77,
+ beginAnnotations: 78,
+ endAnnotations: 79,
+ beginAnnotation: 80,
+ endAnnotation: 81,
+ paintJpegXObject: 82,
+ paintImageMaskXObject: 83,
+ paintImageMaskXObjectGroup: 84,
+ paintImageXObject: 85,
+ paintInlineImageXObject: 86,
+ paintInlineImageXObjectGroup: 87
+};
+
+// A notice for devs. These are good for things that are helpful to devs, such
+// as warning that Workers were disabled, which is important to devs but not
+// end users.
+function info(msg) {
+ if (PDFJS.verbosity >= PDFJS.VERBOSITY_LEVELS.infos) {
+ console.log('Info: ' + msg);
+ }
+}
+
+// Non-fatal warnings.
+function warn(msg) {
+ if (PDFJS.verbosity >= PDFJS.VERBOSITY_LEVELS.warnings) {
+ console.log('Warning: ' + msg);
+ }
+}
+
+// Fatal errors that should trigger the fallback UI and halt execution by
+// throwing an exception.
+function error(msg) {
+ // If multiple arguments were passed, pass them all to the log function.
+ if (arguments.length > 1) {
+ var logArguments = ['Error:'];
+ logArguments.push.apply(logArguments, arguments);
+ console.log.apply(console, logArguments);
+ // Join the arguments into a single string for the lines below.
+ msg = [].join.call(arguments, ' ');
+ } else {
+ console.log('Error: ' + msg);
+ }
+ console.log(backtrace());
+ UnsupportedManager.notify(UNSUPPORTED_FEATURES.unknown);
+ throw new Error(msg);
+}
+
+function backtrace() {
+ try {
+ throw new Error();
+ } catch (e) {
+ return e.stack ? e.stack.split('\n').slice(2).join('\n') : '';
+ }
+}
+
+function assert(cond, msg) {
+ if (!cond)
+ error(msg);
+}
+
+var UNSUPPORTED_FEATURES = PDFJS.UNSUPPORTED_FEATURES = {
+ unknown: 'unknown',
+ forms: 'forms',
+ javaScript: 'javaScript',
+ smask: 'smask',
+ shadingPattern: 'shadingPattern',
+ font: 'font'
+};
+
+var UnsupportedManager = PDFJS.UnsupportedManager =
+ (function UnsupportedManagerClosure() {
+ var listeners = [];
+ return {
+ listen: function (cb) {
+ listeners.push(cb);
+ },
+ notify: function (featureId) {
+ warn('Unsupported feature "' + featureId + '"');
+ for (var i = 0, ii = listeners.length; i < ii; i++) {
+ listeners[i](featureId);
+ }
+ }
+ };
+})();
+
+// Combines two URLs. The baseUrl shall be absolute URL. If the url is an
+// absolute URL, it will be returned as is.
+function combineUrl(baseUrl, url) {
+ if (!url)
+ return baseUrl;
+ if (url.indexOf(':') >= 0)
+ return url;
+ if (url.charAt(0) == '/') {
+ // absolute path
+ var i = baseUrl.indexOf('://');
+ i = baseUrl.indexOf('/', i + 3);
+ return baseUrl.substring(0, i) + url;
+ } else {
+ // relative path
+ var pathLength = baseUrl.length, i;
+ i = baseUrl.lastIndexOf('#');
+ pathLength = i >= 0 ? i : pathLength;
+ i = baseUrl.lastIndexOf('?', pathLength);
+ pathLength = i >= 0 ? i : pathLength;
+ var prefixLength = baseUrl.lastIndexOf('/', pathLength);
+ return baseUrl.substring(0, prefixLength + 1) + url;
+ }
+}
+
+// Validates if URL is safe and allowed, e.g. to avoid XSS.
+function isValidUrl(url, allowRelative) {
+ if (!url) {
+ return false;
+ }
+ var colon = url.indexOf(':');
+ if (colon < 0) {
+ return allowRelative;
+ }
+ var protocol = url.substr(0, colon);
+ switch (protocol) {
+ case 'http':
+ case 'https':
+ case 'ftp':
+ case 'mailto':
+ return true;
+ default:
+ return false;
+ }
+}
+PDFJS.isValidUrl = isValidUrl;
+
+// In a well-formed PDF, |cond| holds. If it doesn't, subsequent
+// behavior is undefined.
+function assertWellFormed(cond, msg) {
+ if (!cond)
+ error(msg);
+}
+
+function shadow(obj, prop, value) {
+ Object.defineProperty(obj, prop, { value: value,
+ enumerable: true,
+ configurable: true,
+ writable: false });
+ return value;
+}
+
+var PasswordResponses = PDFJS.PasswordResponses = {
+ NEED_PASSWORD: 1,
+ INCORRECT_PASSWORD: 2
+};
+
+var PasswordException = (function PasswordExceptionClosure() {
+ function PasswordException(msg, code) {
+ this.name = 'PasswordException';
+ this.message = msg;
+ this.code = code;
+ }
+
+ PasswordException.prototype = new Error();
+ PasswordException.constructor = PasswordException;
+
+ return PasswordException;
+})();
+
+var UnknownErrorException = (function UnknownErrorExceptionClosure() {
+ function UnknownErrorException(msg, details) {
+ this.name = 'UnknownErrorException';
+ this.message = msg;
+ this.details = details;
+ }
+
+ UnknownErrorException.prototype = new Error();
+ UnknownErrorException.constructor = UnknownErrorException;
+
+ return UnknownErrorException;
+})();
+
+var InvalidPDFException = (function InvalidPDFExceptionClosure() {
+ function InvalidPDFException(msg) {
+ this.name = 'InvalidPDFException';
+ this.message = msg;
+ }
+
+ InvalidPDFException.prototype = new Error();
+ InvalidPDFException.constructor = InvalidPDFException;
+
+ return InvalidPDFException;
+})();
+
+var MissingPDFException = (function MissingPDFExceptionClosure() {
+ function MissingPDFException(msg) {
+ this.name = 'MissingPDFException';
+ this.message = msg;
+ }
+
+ MissingPDFException.prototype = new Error();
+ MissingPDFException.constructor = MissingPDFException;
+
+ return MissingPDFException;
+})();
+
+var NotImplementedException = (function NotImplementedExceptionClosure() {
+ function NotImplementedException(msg) {
+ this.message = msg;
+ }
+
+ NotImplementedException.prototype = new Error();
+ NotImplementedException.prototype.name = 'NotImplementedException';
+ NotImplementedException.constructor = NotImplementedException;
+
+ return NotImplementedException;
+})();
+
+var MissingDataException = (function MissingDataExceptionClosure() {
+ function MissingDataException(begin, end) {
+ this.begin = begin;
+ this.end = end;
+ this.message = 'Missing data [' + begin + ', ' + end + ')';
+ }
+
+ MissingDataException.prototype = new Error();
+ MissingDataException.prototype.name = 'MissingDataException';
+ MissingDataException.constructor = MissingDataException;
+
+ return MissingDataException;
+})();
+
+var XRefParseException = (function XRefParseExceptionClosure() {
+ function XRefParseException(msg) {
+ this.message = msg;
+ }
+
+ XRefParseException.prototype = new Error();
+ XRefParseException.prototype.name = 'XRefParseException';
+ XRefParseException.constructor = XRefParseException;
+
+ return XRefParseException;
+})();
+
+
+function bytesToString(bytes) {
+ var str = '';
+ var length = bytes.length;
+ for (var n = 0; n < length; ++n)
+ str += String.fromCharCode(bytes[n]);
+ return str;
+}
+
+function stringToBytes(str) {
+ var length = str.length;
+ var bytes = new Uint8Array(length);
+ for (var n = 0; n < length; ++n)
+ bytes[n] = str.charCodeAt(n) & 0xFF;
+ return bytes;
+}
+
+var IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0];
+
+var Util = PDFJS.Util = (function UtilClosure() {
+ function Util() {}
+
+ Util.makeCssRgb = function Util_makeCssRgb(rgb) {
+ return 'rgb(' + rgb[0] + ',' + rgb[1] + ',' + rgb[2] + ')';
+ };
+
+ Util.makeCssCmyk = function Util_makeCssCmyk(cmyk) {
+ var rgb = ColorSpace.singletons.cmyk.getRgb(cmyk, 0);
+ return Util.makeCssRgb(rgb);
+ };
+
+ // Concatenates two transformation matrices together and returns the result.
+ Util.transform = function Util_transform(m1, m2) {
+ return [
+ m1[0] * m2[0] + m1[2] * m2[1],
+ m1[1] * m2[0] + m1[3] * m2[1],
+ m1[0] * m2[2] + m1[2] * m2[3],
+ m1[1] * m2[2] + m1[3] * m2[3],
+ m1[0] * m2[4] + m1[2] * m2[5] + m1[4],
+ m1[1] * m2[4] + m1[3] * m2[5] + m1[5]
+ ];
+ };
+
+ // For 2d affine transforms
+ Util.applyTransform = function Util_applyTransform(p, m) {
+ var xt = p[0] * m[0] + p[1] * m[2] + m[4];
+ var yt = p[0] * m[1] + p[1] * m[3] + m[5];
+ return [xt, yt];
+ };
+
+ Util.applyInverseTransform = function Util_applyInverseTransform(p, m) {
+ var d = m[0] * m[3] - m[1] * m[2];
+ var xt = (p[0] * m[3] - p[1] * m[2] + m[2] * m[5] - m[4] * m[3]) / d;
+ var yt = (-p[0] * m[1] + p[1] * m[0] + m[4] * m[1] - m[5] * m[0]) / d;
+ return [xt, yt];
+ };
+
+ // Applies the transform to the rectangle and finds the minimum axially
+ // aligned bounding box.
+ Util.getAxialAlignedBoundingBox =
+ function Util_getAxialAlignedBoundingBox(r, m) {
+
+ var p1 = Util.applyTransform(r, m);
+ var p2 = Util.applyTransform(r.slice(2, 4), m);
+ var p3 = Util.applyTransform([r[0], r[3]], m);
+ var p4 = Util.applyTransform([r[2], r[1]], m);
+ return [
+ Math.min(p1[0], p2[0], p3[0], p4[0]),
+ Math.min(p1[1], p2[1], p3[1], p4[1]),
+ Math.max(p1[0], p2[0], p3[0], p4[0]),
+ Math.max(p1[1], p2[1], p3[1], p4[1])
+ ];
+ };
+
+ Util.inverseTransform = function Util_inverseTransform(m) {
+ var d = m[0] * m[3] - m[1] * m[2];
+ return [m[3] / d, -m[1] / d, -m[2] / d, m[0] / d,
+ (m[2] * m[5] - m[4] * m[3]) / d, (m[4] * m[1] - m[5] * m[0]) / d];
+ };
+
+ // Apply a generic 3d matrix M on a 3-vector v:
+ // | a b c | | X |
+ // | d e f | x | Y |
+ // | g h i | | Z |
+ // M is assumed to be serialized as [a,b,c,d,e,f,g,h,i],
+ // with v as [X,Y,Z]
+ Util.apply3dTransform = function Util_apply3dTransform(m, v) {
+ return [
+ m[0] * v[0] + m[1] * v[1] + m[2] * v[2],
+ m[3] * v[0] + m[4] * v[1] + m[5] * v[2],
+ m[6] * v[0] + m[7] * v[1] + m[8] * v[2]
+ ];
+ };
+
+ // This calculation uses Singular Value Decomposition.
+ // The SVD can be represented with formula A = USV. We are interested in the
+ // matrix S here because it represents the scale values.
+ Util.singularValueDecompose2dScale =
+ function Util_singularValueDecompose2dScale(m) {
+
+ var transpose = [m[0], m[2], m[1], m[3]];
+
+ // Multiply matrix m with its transpose.
+ var a = m[0] * transpose[0] + m[1] * transpose[2];
+ var b = m[0] * transpose[1] + m[1] * transpose[3];
+ var c = m[2] * transpose[0] + m[3] * transpose[2];
+ var d = m[2] * transpose[1] + m[3] * transpose[3];
+
+ // Solve the second degree polynomial to get roots.
+ var first = (a + d) / 2;
+ var second = Math.sqrt((a + d) * (a + d) - 4 * (a * d - c * b)) / 2;
+ var sx = first + second || 1;
+ var sy = first - second || 1;
+
+ // Scale values are the square roots of the eigenvalues.
+ return [Math.sqrt(sx), Math.sqrt(sy)];
+ };
+
+ // Normalize rectangle rect=[x1, y1, x2, y2] so that (x1,y1) < (x2,y2)
+ // For coordinate systems whose origin lies in the bottom-left, this
+ // means normalization to (BL,TR) ordering. For systems with origin in the
+ // top-left, this means (TL,BR) ordering.
+ Util.normalizeRect = function Util_normalizeRect(rect) {
+ var r = rect.slice(0); // clone rect
+ if (rect[0] > rect[2]) {
+ r[0] = rect[2];
+ r[2] = rect[0];
+ }
+ if (rect[1] > rect[3]) {
+ r[1] = rect[3];
+ r[3] = rect[1];
+ }
+ return r;
+ };
+
+ // Returns a rectangle [x1, y1, x2, y2] corresponding to the
+ // intersection of rect1 and rect2. If no intersection, returns 'false'
+ // The rectangle coordinates of rect1, rect2 should be [x1, y1, x2, y2]
+ Util.intersect = function Util_intersect(rect1, rect2) {
+ function compare(a, b) {
+ return a - b;
+ }
+
+ // Order points along the axes
+ var orderedX = [rect1[0], rect1[2], rect2[0], rect2[2]].sort(compare),
+ orderedY = [rect1[1], rect1[3], rect2[1], rect2[3]].sort(compare),
+ result = [];
+
+ rect1 = Util.normalizeRect(rect1);
+ rect2 = Util.normalizeRect(rect2);
+
+ // X: first and second points belong to different rectangles?
+ if ((orderedX[0] === rect1[0] && orderedX[1] === rect2[0]) ||
+ (orderedX[0] === rect2[0] && orderedX[1] === rect1[0])) {
+ // Intersection must be between second and third points
+ result[0] = orderedX[1];
+ result[2] = orderedX[2];
+ } else {
+ return false;
+ }
+
+ // Y: first and second points belong to different rectangles?
+ if ((orderedY[0] === rect1[1] && orderedY[1] === rect2[1]) ||
+ (orderedY[0] === rect2[1] && orderedY[1] === rect1[1])) {
+ // Intersection must be between second and third points
+ result[1] = orderedY[1];
+ result[3] = orderedY[2];
+ } else {
+ return false;
+ }
+
+ return result;
+ };
+
+ Util.sign = function Util_sign(num) {
+ return num < 0 ? -1 : 1;
+ };
+
+ // TODO(mack): Rename appendToArray
+ Util.concatenateToArray = function concatenateToArray(arr1, arr2) {
+ Array.prototype.push.apply(arr1, arr2);
+ };
+
+ Util.prependToArray = function concatenateToArray(arr1, arr2) {
+ Array.prototype.unshift.apply(arr1, arr2);
+ };
+
+ Util.extendObj = function extendObj(obj1, obj2) {
+ for (var key in obj2) {
+ obj1[key] = obj2[key];
+ }
+ };
+
+ Util.getInheritableProperty = function Util_getInheritableProperty(dict,
+ name) {
+ while (dict && !dict.has(name)) {
+ dict = dict.get('Parent');
+ }
+ if (!dict) {
+ return null;
+ }
+ return dict.get(name);
+ };
+
+ Util.inherit = function Util_inherit(sub, base, prototype) {
+ sub.prototype = Object.create(base.prototype);
+ sub.prototype.constructor = sub;
+ for (var prop in prototype) {
+ sub.prototype[prop] = prototype[prop];
+ }
+ };
+
+ Util.loadScript = function Util_loadScript(src, callback) {
+ var script = document.createElement('script');
+ var loaded = false;
+ script.setAttribute('src', src);
+ if (callback) {
+ script.onload = function() {
+ if (!loaded) {
+ callback();
+ }
+ loaded = true;
+ };
+ }
+ document.getElementsByTagName('head')[0].appendChild(script);
+ };
+
+ return Util;
+})();
+
+var PageViewport = PDFJS.PageViewport = (function PageViewportClosure() {
+ function PageViewport(viewBox, scale, rotation, offsetX, offsetY, dontFlip) {
+ this.viewBox = viewBox;
+ this.scale = scale;
+ this.rotation = rotation;
+ this.offsetX = offsetX;
+ this.offsetY = offsetY;
+
+ // creating transform to convert pdf coordinate system to the normal
+ // canvas like coordinates taking in account scale and rotation
+ var centerX = (viewBox[2] + viewBox[0]) / 2;
+ var centerY = (viewBox[3] + viewBox[1]) / 2;
+ var rotateA, rotateB, rotateC, rotateD;
+ rotation = rotation % 360;
+ rotation = rotation < 0 ? rotation + 360 : rotation;
+ switch (rotation) {
+ case 180:
+ rotateA = -1; rotateB = 0; rotateC = 0; rotateD = 1;
+ break;
+ case 90:
+ rotateA = 0; rotateB = 1; rotateC = 1; rotateD = 0;
+ break;
+ case 270:
+ rotateA = 0; rotateB = -1; rotateC = -1; rotateD = 0;
+ break;
+ //case 0:
+ default:
+ rotateA = 1; rotateB = 0; rotateC = 0; rotateD = -1;
+ break;
+ }
+
+ if (dontFlip) {
+ rotateC = -rotateC; rotateD = -rotateD;
+ }
+
+ var offsetCanvasX, offsetCanvasY;
+ var width, height;
+ if (rotateA === 0) {
+ offsetCanvasX = Math.abs(centerY - viewBox[1]) * scale + offsetX;
+ offsetCanvasY = Math.abs(centerX - viewBox[0]) * scale + offsetY;
+ width = Math.abs(viewBox[3] - viewBox[1]) * scale;
+ height = Math.abs(viewBox[2] - viewBox[0]) * scale;
+ } else {
+ offsetCanvasX = Math.abs(centerX - viewBox[0]) * scale + offsetX;
+ offsetCanvasY = Math.abs(centerY - viewBox[1]) * scale + offsetY;
+ width = Math.abs(viewBox[2] - viewBox[0]) * scale;
+ height = Math.abs(viewBox[3] - viewBox[1]) * scale;
+ }
+ // creating transform for the following operations:
+ // translate(-centerX, -centerY), rotate and flip vertically,
+ // scale, and translate(offsetCanvasX, offsetCanvasY)
+ this.transform = [
+ rotateA * scale,
+ rotateB * scale,
+ rotateC * scale,
+ rotateD * scale,
+ offsetCanvasX - rotateA * scale * centerX - rotateC * scale * centerY,
+ offsetCanvasY - rotateB * scale * centerX - rotateD * scale * centerY
+ ];
+
+ this.width = width;
+ this.height = height;
+ this.fontScale = scale;
+ }
+ PageViewport.prototype = {
+ clone: function PageViewPort_clone(args) {
+ args = args || {};
+ var scale = 'scale' in args ? args.scale : this.scale;
+ var rotation = 'rotation' in args ? args.rotation : this.rotation;
+ return new PageViewport(this.viewBox.slice(), scale, rotation,
+ this.offsetX, this.offsetY, args.dontFlip);
+ },
+ convertToViewportPoint: function PageViewport_convertToViewportPoint(x, y) {
+ return Util.applyTransform([x, y], this.transform);
+ },
+ convertToViewportRectangle:
+ function PageViewport_convertToViewportRectangle(rect) {
+ var tl = Util.applyTransform([rect[0], rect[1]], this.transform);
+ var br = Util.applyTransform([rect[2], rect[3]], this.transform);
+ return [tl[0], tl[1], br[0], br[1]];
+ },
+ convertToPdfPoint: function PageViewport_convertToPdfPoint(x, y) {
+ return Util.applyInverseTransform([x, y], this.transform);
+ }
+ };
+ return PageViewport;
+})();
+
+var PDFStringTranslateTable = [
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0x2D8, 0x2C7, 0x2C6, 0x2D9, 0x2DD, 0x2DB, 0x2DA, 0x2DC, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2022, 0x2020, 0x2021, 0x2026, 0x2014,
+ 0x2013, 0x192, 0x2044, 0x2039, 0x203A, 0x2212, 0x2030, 0x201E, 0x201C,
+ 0x201D, 0x2018, 0x2019, 0x201A, 0x2122, 0xFB01, 0xFB02, 0x141, 0x152, 0x160,
+ 0x178, 0x17D, 0x131, 0x142, 0x153, 0x161, 0x17E, 0, 0x20AC
+];
+
+function stringToPDFString(str) {
+ var i, n = str.length, str2 = '';
+ if (str[0] === '\xFE' && str[1] === '\xFF') {
+ // UTF16BE BOM
+ for (i = 2; i < n; i += 2)
+ str2 += String.fromCharCode(
+ (str.charCodeAt(i) << 8) | str.charCodeAt(i + 1));
+ } else {
+ for (i = 0; i < n; ++i) {
+ var code = PDFStringTranslateTable[str.charCodeAt(i)];
+ str2 += code ? String.fromCharCode(code) : str.charAt(i);
+ }
+ }
+ return str2;
+}
+
+function stringToUTF8String(str) {
+ return decodeURIComponent(escape(str));
+}
+
+function isEmptyObj(obj) {
+ for (var key in obj) {
+ return false;
+ }
+ return true;
+}
+
+function isBool(v) {
+ return typeof v == 'boolean';
+}
+
+function isInt(v) {
+ return typeof v == 'number' && ((v | 0) == v);
+}
+
+function isNum(v) {
+ return typeof v == 'number';
+}
+
+function isString(v) {
+ return typeof v == 'string';
+}
+
+function isNull(v) {
+ return v === null;
+}
+
+function isName(v) {
+ return v instanceof Name;
+}
+
+function isCmd(v, cmd) {
+ return v instanceof Cmd && (!cmd || v.cmd == cmd);
+}
+
+function isDict(v, type) {
+ if (!(v instanceof Dict)) {
+ return false;
+ }
+ if (!type) {
+ return true;
+ }
+ var dictType = v.get('Type');
+ return isName(dictType) && dictType.name == type;
+}
+
+function isArray(v) {
+ return v instanceof Array;
+}
+
+function isStream(v) {
+ return typeof v == 'object' && v !== null && v !== undefined &&
+ ('getBytes' in v);
+}
+
+function isArrayBuffer(v) {
+ return typeof v == 'object' && v !== null && v !== undefined &&
+ ('byteLength' in v);
+}
+
+function isRef(v) {
+ return v instanceof Ref;
+}
+
+function isPDFFunction(v) {
+ var fnDict;
+ if (typeof v != 'object')
+ return false;
+ else if (isDict(v))
+ fnDict = v;
+ else if (isStream(v))
+ fnDict = v.dict;
+ else
+ return false;
+ return fnDict.has('FunctionType');
+}
+
+/**
+ * Legacy support for PDFJS Promise implementation.
+ * TODO remove eventually
+ */
+var LegacyPromise = PDFJS.LegacyPromise = (function LegacyPromiseClosure() {
+ return function LegacyPromise() {
+ var resolve, reject;
+ var promise = new Promise(function (resolve_, reject_) {
+ resolve = resolve_;
+ reject = reject_;
+ });
+ promise.resolve = resolve;
+ promise.reject = reject;
+ return promise;
+ };
+})();
+
+/**
+ * Polyfill for Promises:
+ * The following promise implementation tries to generally implment the
+ * Promise/A+ spec. Some notable differences from other promise libaries are:
+ * - There currently isn't a seperate deferred and promise object.
+ * - Unhandled rejections eventually show an error if they aren't handled.
+ *
+ * Based off of the work in:
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=810490
+ */
+(function PromiseClosure() {
+ if (globalScope.Promise) {
+ // Promises existing in the DOM/Worker, checking presence of all/resolve
+ if (typeof globalScope.Promise.all !== 'function') {
+ globalScope.Promise.all = function (iterable) {
+ var count = 0, results = [], resolve, reject;
+ var promise = new globalScope.Promise(function (resolve_, reject_) {
+ resolve = resolve_;
+ reject = reject_;
+ });
+ iterable.forEach(function (p, i) {
+ count++;
+ p.then(function (result) {
+ results[i] = result;
+ count--;
+ if (count === 0) {
+ resolve(results);
+ }
+ }, reject);
+ });
+ if (count === 0) {
+ resolve(results);
+ }
+ return promise;
+ };
+ }
+ if (typeof globalScope.Promise.resolve !== 'function') {
+ globalScope.Promise.resolve = function (x) {
+ return new globalScope.Promise(function (resolve) { resolve(x); });
+ };
+ }
+ return;
+ }
+ var STATUS_PENDING = 0;
+ var STATUS_RESOLVED = 1;
+ var STATUS_REJECTED = 2;
+
+ // In an attempt to avoid silent exceptions, unhandled rejections are
+ // tracked and if they aren't handled in a certain amount of time an
+ // error is logged.
+ var REJECTION_TIMEOUT = 500;
+
+ var HandlerManager = {
+ handlers: [],
+ running: false,
+ unhandledRejections: [],
+ pendingRejectionCheck: false,
+
+ scheduleHandlers: function scheduleHandlers(promise) {
+ if (promise._status == STATUS_PENDING) {
+ return;
+ }
+
+ this.handlers = this.handlers.concat(promise._handlers);
+ promise._handlers = [];
+
+ if (this.running) {
+ return;
+ }
+ this.running = true;
+
+ setTimeout(this.runHandlers.bind(this), 0);
+ },
+
+ runHandlers: function runHandlers() {
+ var RUN_TIMEOUT = 1; // ms
+ var timeoutAt = Date.now() + RUN_TIMEOUT;
+ while (this.handlers.length > 0) {
+ var handler = this.handlers.shift();
+
+ var nextStatus = handler.thisPromise._status;
+ var nextValue = handler.thisPromise._value;
+
+ try {
+ if (nextStatus === STATUS_RESOLVED) {
+ if (typeof(handler.onResolve) == 'function') {
+ nextValue = handler.onResolve(nextValue);
+ }
+ } else if (typeof(handler.onReject) === 'function') {
+ nextValue = handler.onReject(nextValue);
+ nextStatus = STATUS_RESOLVED;
+
+ if (handler.thisPromise._unhandledRejection) {
+ this.removeUnhandeledRejection(handler.thisPromise);
+ }
+ }
+ } catch (ex) {
+ nextStatus = STATUS_REJECTED;
+ nextValue = ex;
+ }
+
+ handler.nextPromise._updateStatus(nextStatus, nextValue);
+ if (Date.now() >= timeoutAt) {
+ break;
+ }
+ }
+
+ if (this.handlers.length > 0) {
+ setTimeout(this.runHandlers.bind(this), 0);
+ return;
+ }
+
+ this.running = false;
+ },
+
+ addUnhandledRejection: function addUnhandledRejection(promise) {
+ this.unhandledRejections.push({
+ promise: promise,
+ time: Date.now()
+ });
+ this.scheduleRejectionCheck();
+ },
+
+ removeUnhandeledRejection: function removeUnhandeledRejection(promise) {
+ promise._unhandledRejection = false;
+ for (var i = 0; i < this.unhandledRejections.length; i++) {
+ if (this.unhandledRejections[i].promise === promise) {
+ this.unhandledRejections.splice(i);
+ i--;
+ }
+ }
+ },
+
+ scheduleRejectionCheck: function scheduleRejectionCheck() {
+ if (this.pendingRejectionCheck) {
+ return;
+ }
+ this.pendingRejectionCheck = true;
+ setTimeout(function rejectionCheck() {
+ this.pendingRejectionCheck = false;
+ var now = Date.now();
+ for (var i = 0; i < this.unhandledRejections.length; i++) {
+ if (now - this.unhandledRejections[i].time > REJECTION_TIMEOUT) {
+ var unhandled = this.unhandledRejections[i].promise._value;
+ var msg = 'Unhandled rejection: ' + unhandled;
+ if (unhandled.stack) {
+ msg += '\n' + unhandled.stack;
+ }
+ warn(msg);
+ this.unhandledRejections.splice(i);
+ i--;
+ }
+ }
+ if (this.unhandledRejections.length) {
+ this.scheduleRejectionCheck();
+ }
+ }.bind(this), REJECTION_TIMEOUT);
+ }
+ };
+
+ function Promise(resolver) {
+ this._status = STATUS_PENDING;
+ this._handlers = [];
+ resolver.call(this, this._resolve.bind(this), this._reject.bind(this));
+ }
+ /**
+ * Builds a promise that is resolved when all the passed in promises are
+ * resolved.
+ * @param {array} array of data and/or promises to wait for.
+ * @return {Promise} New dependant promise.
+ */
+ Promise.all = function Promise_all(promises) {
+ var resolveAll, rejectAll;
+ var deferred = new Promise(function (resolve, reject) {
+ resolveAll = resolve;
+ rejectAll = reject;
+ });
+ var unresolved = promises.length;
+ var results = [];
+ if (unresolved === 0) {
+ resolveAll(results);
+ return deferred;
+ }
+ function reject(reason) {
+ if (deferred._status === STATUS_REJECTED) {
+ return;
+ }
+ results = [];
+ rejectAll(reason);
+ }
+ for (var i = 0, ii = promises.length; i < ii; ++i) {
+ var promise = promises[i];
+ var resolve = (function(i) {
+ return function(value) {
+ if (deferred._status === STATUS_REJECTED) {
+ return;
+ }
+ results[i] = value;
+ unresolved--;
+ if (unresolved === 0)
+ resolveAll(results);
+ };
+ })(i);
+ if (Promise.isPromise(promise)) {
+ promise.then(resolve, reject);
+ } else {
+ resolve(promise);
+ }
+ }
+ return deferred;
+ };
+
+ /**
+ * Checks if the value is likely a promise (has a 'then' function).
+ * @return {boolean} true if x is thenable
+ */
+ Promise.isPromise = function Promise_isPromise(value) {
+ return value && typeof value.then === 'function';
+ };
+ /**
+ * Creates resolved promise
+ * @param x resolve value
+ * @returns {Promise}
+ */
+ Promise.resolve = function Promise_resolve(x) {
+ return new Promise(function (resolve) { resolve(x); });
+ };
+
+ Promise.prototype = {
+ _status: null,
+ _value: null,
+ _handlers: null,
+ _unhandledRejection: null,
+
+ _updateStatus: function Promise__updateStatus(status, value) {
+ if (this._status === STATUS_RESOLVED ||
+ this._status === STATUS_REJECTED) {
+ return;
+ }
+
+ if (status == STATUS_RESOLVED &&
+ Promise.isPromise(value)) {
+ value.then(this._updateStatus.bind(this, STATUS_RESOLVED),
+ this._updateStatus.bind(this, STATUS_REJECTED));
+ return;
+ }
+
+ this._status = status;
+ this._value = value;
+
+ if (status === STATUS_REJECTED && this._handlers.length === 0) {
+ this._unhandledRejection = true;
+ HandlerManager.addUnhandledRejection(this);
+ }
+
+ HandlerManager.scheduleHandlers(this);
+ },
+
+ _resolve: function Promise_resolve(value) {
+ this._updateStatus(STATUS_RESOLVED, value);
+ },
+
+ _reject: function Promise_reject(reason) {
+ this._updateStatus(STATUS_REJECTED, reason);
+ },
+
+ then: function Promise_then(onResolve, onReject) {
+ var nextPromise = new Promise(function (resolve, reject) {
+ this.resolve = reject;
+ this.reject = reject;
+ });
+ this._handlers.push({
+ thisPromise: this,
+ onResolve: onResolve,
+ onReject: onReject,
+ nextPromise: nextPromise
+ });
+ HandlerManager.scheduleHandlers(this);
+ return nextPromise;
+ }
+ };
+
+ globalScope.Promise = Promise;
+})();
+
+var StatTimer = (function StatTimerClosure() {
+ function rpad(str, pad, length) {
+ while (str.length < length)
+ str += pad;
+ return str;
+ }
+ function StatTimer() {
+ this.started = {};
+ this.times = [];
+ this.enabled = true;
+ }
+ StatTimer.prototype = {
+ time: function StatTimer_time(name) {
+ if (!this.enabled)
+ return;
+ if (name in this.started)
+ warn('Timer is already running for ' + name);
+ this.started[name] = Date.now();
+ },
+ timeEnd: function StatTimer_timeEnd(name) {
+ if (!this.enabled)
+ return;
+ if (!(name in this.started))
+ warn('Timer has not been started for ' + name);
+ this.times.push({
+ 'name': name,
+ 'start': this.started[name],
+ 'end': Date.now()
+ });
+ // Remove timer from started so it can be called again.
+ delete this.started[name];
+ },
+ toString: function StatTimer_toString() {
+ var times = this.times;
+ var out = '';
+ // Find the longest name for padding purposes.
+ var longest = 0;
+ for (var i = 0, ii = times.length; i < ii; ++i) {
+ var name = times[i]['name'];
+ if (name.length > longest)
+ longest = name.length;
+ }
+ for (var i = 0, ii = times.length; i < ii; ++i) {
+ var span = times[i];
+ var duration = span.end - span.start;
+ out += rpad(span['name'], ' ', longest) + ' ' + duration + 'ms\n';
+ }
+ return out;
+ }
+ };
+ return StatTimer;
+})();
+
+PDFJS.createBlob = function createBlob(data, contentType) {
+ if (typeof Blob !== 'undefined')
+ return new Blob([data], { type: contentType });
+ // Blob builder is deprecated in FF14 and removed in FF18.
+ var bb = new MozBlobBuilder();
+ bb.append(data);
+ return bb.getBlob(contentType);
+};
+
+PDFJS.createObjectURL = (function createObjectURLClosure() {
+ // Blob/createObjectURL is not available, falling back to data schema.
+ var digits =
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
+
+ return function createObjectURL(data, contentType) {
+ if (!PDFJS.disableCreateObjectURL &&
+ typeof URL !== 'undefined' && URL.createObjectURL) {
+ var blob = PDFJS.createBlob(data, contentType);
+ return URL.createObjectURL(blob);
+ }
+
+ var buffer = 'data:' + contentType + ';base64,';
+ for (var i = 0, ii = data.length; i < ii; i += 3) {
+ var b1 = data[i] & 0xFF;
+ var b2 = data[i + 1] & 0xFF;
+ var b3 = data[i + 2] & 0xFF;
+ var d1 = b1 >> 2, d2 = ((b1 & 3) << 4) | (b2 >> 4);
+ var d3 = i + 1 < ii ? ((b2 & 0xF) << 2) | (b3 >> 6) : 64;
+ var d4 = i + 2 < ii ? (b3 & 0x3F) : 64;
+ buffer += digits[d1] + digits[d2] + digits[d3] + digits[d4];
+ }
+ return buffer;
+ };
+})();
+
+function MessageHandler(name, comObj) {
+ this.name = name;
+ this.comObj = comObj;
+ this.callbackIndex = 1;
+ this.postMessageTransfers = true;
+ var callbacks = this.callbacks = {};
+ var ah = this.actionHandler = {};
+
+ ah['console_log'] = [function ahConsoleLog(data) {
+ console.log.apply(console, data);
+ }];
+ ah['console_error'] = [function ahConsoleError(data) {
+ console.error.apply(console, data);
+ }];
+ ah['_unsupported_feature'] = [function ah_unsupportedFeature(data) {
+ UnsupportedManager.notify(data);
+ }];
+
+ comObj.onmessage = function messageHandlerComObjOnMessage(event) {
+ var data = event.data;
+ if (data.isReply) {
+ var callbackId = data.callbackId;
+ if (data.callbackId in callbacks) {
+ var callback = callbacks[callbackId];
+ delete callbacks[callbackId];
+ callback(data.data);
+ } else {
+ error('Cannot resolve callback ' + callbackId);
+ }
+ } else if (data.action in ah) {
+ var action = ah[data.action];
+ if (data.callbackId) {
+ var deferred = {};
+ var promise = new Promise(function (resolve, reject) {
+ deferred.resolve = resolve;
+ deferred.reject = reject;
+ });
+ deferred.promise = promise;
+ promise.then(function(resolvedData) {
+ comObj.postMessage({
+ isReply: true,
+ callbackId: data.callbackId,
+ data: resolvedData
+ });
+ });
+ action[0].call(action[1], data.data, deferred);
+ } else {
+ action[0].call(action[1], data.data);
+ }
+ } else {
+ error('Unkown action from worker: ' + data.action);
+ }
+ };
+}
+
+MessageHandler.prototype = {
+ on: function messageHandlerOn(actionName, handler, scope) {
+ var ah = this.actionHandler;
+ if (ah[actionName]) {
+ error('There is already an actionName called "' + actionName + '"');
+ }
+ ah[actionName] = [handler, scope];
+ },
+ /**
+ * Sends a message to the comObj to invoke the action with the supplied data.
+ * @param {String} actionName Action to call.
+ * @param {JSON} data JSON data to send.
+ * @param {function} [callback] Optional callback that will handle a reply.
+ * @param {Array} [transfers] Optional list of transfers/ArrayBuffers
+ */
+ send: function messageHandlerSend(actionName, data, callback, transfers) {
+ var message = {
+ action: actionName,
+ data: data
+ };
+ if (callback) {
+ var callbackId = this.callbackIndex++;
+ this.callbacks[callbackId] = callback;
+ message.callbackId = callbackId;
+ }
+ if (transfers && this.postMessageTransfers) {
+ this.comObj.postMessage(message, transfers);
+ } else {
+ this.comObj.postMessage(message);
+ }
+ }
+};
+
+function loadJpegStream(id, imageUrl, objs) {
+ var img = new Image();
+ img.onload = (function loadJpegStream_onloadClosure() {
+ objs.resolve(id, img);
+ });
+ img.src = imageUrl;
+}
+
+
+var ColorSpace = (function ColorSpaceClosure() {
+ // Constructor should define this.numComps, this.defaultColor, this.name
+ function ColorSpace() {
+ error('should not call ColorSpace constructor');
+ }
+
+ ColorSpace.prototype = {
+ /**
+ * Converts the color value to the RGB color. The color components are
+ * located in the src array starting from the srcOffset. Returns the array
+ * of the rgb components, each value ranging from [0,255].
+ */
+ getRgb: function ColorSpace_getRgb(src, srcOffset) {
+ error('Should not call ColorSpace.getRgb');
+ },
+ /**
+ * Converts the color value to the RGB color, similar to the getRgb method.
+ * The result placed into the dest array starting from the destOffset.
+ */
+ getRgbItem: function ColorSpace_getRgb(src, srcOffset, dest, destOffset) {
+ error('Should not call ColorSpace.getRgbItem');
+ },
+ /**
+ * Converts the specified number of the color values to the RGB colors.
+ * The colors are located in the src array starting from the srcOffset.
+ * The result is placed into the dest array starting from the destOffset.
+ * The src array items shall be in [0,2^bits) range, the dest array items
+ * will be in [0,255] range.
+ */
+ getRgbBuffer: function ColorSpace_getRgbBuffer(src, srcOffset, count,
+ dest, destOffset, bits) {
+ error('Should not call ColorSpace.getRgbBuffer');
+ },
+ /**
+ * Determines amount of the bytes is required to store the reslut of the
+ * conversion that done by the getRgbBuffer method.
+ */
+ getOutputLength: function ColorSpace_getOutputLength(inputLength) {
+ error('Should not call ColorSpace.getOutputLength');
+ },
+ /**
+ * Returns true if source data will be equal the result/output data.
+ */
+ isPassthrough: function ColorSpace_isPassthrough(bits) {
+ return false;
+ },
+ /**
+ * Creates the output buffer and converts the specified number of the color
+ * values to the RGB colors, similar to the getRgbBuffer.
+ */
+ createRgbBuffer: function ColorSpace_createRgbBuffer(src, srcOffset,
+ count, bits) {
+ if (this.isPassthrough(bits)) {
+ return src.subarray(srcOffset);
+ }
+ var dest = new Uint8Array(count * 3);
+ var numComponentColors = 1 << bits;
+ // Optimization: create a color map when there is just one component and
+ // we are converting more colors than the size of the color map. We
+ // don't build the map if the colorspace is gray or rgb since those
+ // methods are faster than building a map. This mainly offers big speed
+ // ups for indexed and alternate colorspaces.
+ if (this.numComps === 1 && count > numComponentColors &&
+ this.name !== 'DeviceGray' && this.name !== 'DeviceRGB') {
+ // TODO it may be worth while to cache the color map. While running
+ // testing I never hit a cache so I will leave that out for now (perhaps
+ // we are reparsing colorspaces too much?).
+ var allColors = bits <= 8 ? new Uint8Array(numComponentColors) :
+ new Uint16Array(numComponentColors);
+ for (var i = 0; i < numComponentColors; i++) {
+ allColors[i] = i;
+ }
+ var colorMap = new Uint8Array(numComponentColors * 3);
+ this.getRgbBuffer(allColors, 0, numComponentColors, colorMap, 0, bits);
+
+ var destOffset = 0;
+ for (var i = 0; i < count; ++i) {
+ var key = src[srcOffset++] * 3;
+ dest[destOffset++] = colorMap[key];
+ dest[destOffset++] = colorMap[key + 1];
+ dest[destOffset++] = colorMap[key + 2];
+ }
+ return dest;
+ }
+ this.getRgbBuffer(src, srcOffset, count, dest, 0, bits);
+ return dest;
+ },
+ /**
+ * True if the colorspace has components in the default range of [0, 1].
+ * This should be true for all colorspaces except for lab color spaces
+ * which are [0,100], [-128, 127], [-128, 127].
+ */
+ usesZeroToOneRange: true
+ };
+
+ ColorSpace.parse = function ColorSpace_parse(cs, xref, res) {
+ var IR = ColorSpace.parseToIR(cs, xref, res);
+ if (IR instanceof AlternateCS)
+ return IR;
+
+ return ColorSpace.fromIR(IR);
+ };
+
+ ColorSpace.fromIR = function ColorSpace_fromIR(IR) {
+ var name = isArray(IR) ? IR[0] : IR;
+
+ switch (name) {
+ case 'DeviceGrayCS':
+ return this.singletons.gray;
+ case 'DeviceRgbCS':
+ return this.singletons.rgb;
+ case 'DeviceCmykCS':
+ return this.singletons.cmyk;
+ case 'CalGrayCS':
+ var whitePoint = IR[1].WhitePoint;
+ var blackPoint = IR[1].BlackPoint;
+ var gamma = IR[1].Gamma;
+ return new CalGrayCS(whitePoint, blackPoint, gamma);
+ case 'PatternCS':
+ var basePatternCS = IR[1];
+ if (basePatternCS)
+ basePatternCS = ColorSpace.fromIR(basePatternCS);
+ return new PatternCS(basePatternCS);
+ case 'IndexedCS':
+ var baseIndexedCS = IR[1];
+ var hiVal = IR[2];
+ var lookup = IR[3];
+ return new IndexedCS(ColorSpace.fromIR(baseIndexedCS), hiVal, lookup);
+ case 'AlternateCS':
+ var numComps = IR[1];
+ var alt = IR[2];
+ var tintFnIR = IR[3];
+
+ return new AlternateCS(numComps, ColorSpace.fromIR(alt),
+ PDFFunction.fromIR(tintFnIR));
+ case 'LabCS':
+ var whitePoint = IR[1].WhitePoint;
+ var blackPoint = IR[1].BlackPoint;
+ var range = IR[1].Range;
+ return new LabCS(whitePoint, blackPoint, range);
+ default:
+ error('Unkown name ' + name);
+ }
+ return null;
+ };
+
+ ColorSpace.parseToIR = function ColorSpace_parseToIR(cs, xref, res) {
+ if (isName(cs)) {
+ var colorSpaces = res.get('ColorSpace');
+ if (isDict(colorSpaces)) {
+ var refcs = colorSpaces.get(cs.name);
+ if (refcs)
+ cs = refcs;
+ }
+ }
+
+ cs = xref.fetchIfRef(cs);
+ var mode;
+
+ if (isName(cs)) {
+ mode = cs.name;
+ this.mode = mode;
+
+ switch (mode) {
+ case 'DeviceGray':
+ case 'G':
+ return 'DeviceGrayCS';
+ case 'DeviceRGB':
+ case 'RGB':
+ return 'DeviceRgbCS';
+ case 'DeviceCMYK':
+ case 'CMYK':
+ return 'DeviceCmykCS';
+ case 'Pattern':
+ return ['PatternCS', null];
+ default:
+ error('unrecognized colorspace ' + mode);
+ }
+ } else if (isArray(cs)) {
+ mode = cs[0].name;
+ this.mode = mode;
+
+ switch (mode) {
+ case 'DeviceGray':
+ case 'G':
+ return 'DeviceGrayCS';
+ case 'DeviceRGB':
+ case 'RGB':
+ return 'DeviceRgbCS';
+ case 'DeviceCMYK':
+ case 'CMYK':
+ return 'DeviceCmykCS';
+ case 'CalGray':
+ var params = cs[1].getAll();
+ return ['CalGrayCS', params];
+ case 'CalRGB':
+ return 'DeviceRgbCS';
+ case 'ICCBased':
+ var stream = xref.fetchIfRef(cs[1]);
+ var dict = stream.dict;
+ var numComps = dict.get('N');
+ if (numComps == 1)
+ return 'DeviceGrayCS';
+ if (numComps == 3)
+ return 'DeviceRgbCS';
+ if (numComps == 4)
+ return 'DeviceCmykCS';
+ break;
+ case 'Pattern':
+ var basePatternCS = cs[1];
+ if (basePatternCS)
+ basePatternCS = ColorSpace.parseToIR(basePatternCS, xref, res);
+ return ['PatternCS', basePatternCS];
+ case 'Indexed':
+ case 'I':
+ var baseIndexedCS = ColorSpace.parseToIR(cs[1], xref, res);
+ var hiVal = cs[2] + 1;
+ var lookup = xref.fetchIfRef(cs[3]);
+ if (isStream(lookup)) {
+ lookup = lookup.getBytes();
+ }
+ return ['IndexedCS', baseIndexedCS, hiVal, lookup];
+ case 'Separation':
+ case 'DeviceN':
+ var name = cs[1];
+ var numComps = 1;
+ if (isName(name))
+ numComps = 1;
+ else if (isArray(name))
+ numComps = name.length;
+ var alt = ColorSpace.parseToIR(cs[2], xref, res);
+ var tintFnIR = PDFFunction.getIR(xref, xref.fetchIfRef(cs[3]));
+ return ['AlternateCS', numComps, alt, tintFnIR];
+ case 'Lab':
+ var params = cs[1].getAll();
+ return ['LabCS', params];
+ default:
+ error('unimplemented color space object "' + mode + '"');
+ }
+ } else {
+ error('unrecognized color space object: "' + cs + '"');
+ }
+ return null;
+ };
+ /**
+ * Checks if a decode map matches the default decode map for a color space.
+ * This handles the general decode maps where there are two values per
+ * component. e.g. [0, 1, 0, 1, 0, 1] for a RGB color.
+ * This does not handle Lab, Indexed, or Pattern decode maps since they are
+ * slightly different.
+ * @param {Array} decode Decode map (usually from an image).
+ * @param {Number} n Number of components the color space has.
+ */
+ ColorSpace.isDefaultDecode = function ColorSpace_isDefaultDecode(decode, n) {
+ if (!decode)
+ return true;
+
+ if (n * 2 !== decode.length) {
+ warn('The decode map is not the correct length');
+ return true;
+ }
+ for (var i = 0, ii = decode.length; i < ii; i += 2) {
+ if (decode[i] !== 0 || decode[i + 1] != 1)
+ return false;
+ }
+ return true;
+ };
+
+ ColorSpace.singletons = {
+ get gray() {
+ return shadow(this, 'gray', new DeviceGrayCS());
+ },
+ get rgb() {
+ return shadow(this, 'rgb', new DeviceRgbCS());
+ },
+ get cmyk() {
+ return shadow(this, 'cmyk', new DeviceCmykCS());
+ }
+ };
+
+ return ColorSpace;
+})();
+
+/**
+ * Alternate color space handles both Separation and DeviceN color spaces. A
+ * Separation color space is actually just a DeviceN with one color component.
+ * Both color spaces use a tinting function to convert colors to a base color
+ * space.
+ */
+var AlternateCS = (function AlternateCSClosure() {
+ function AlternateCS(numComps, base, tintFn) {
+ this.name = 'Alternate';
+ this.numComps = numComps;
+ this.defaultColor = new Float32Array(numComps);
+ for (var i = 0; i < numComps; ++i) {
+ this.defaultColor[i] = 1;
+ }
+ this.base = base;
+ this.tintFn = tintFn;
+ }
+
+ AlternateCS.prototype = {
+ getRgb: function AlternateCS_getRgb(src, srcOffset) {
+ var rgb = new Uint8Array(3);
+ this.getRgbItem(src, srcOffset, rgb, 0);
+ return rgb;
+ },
+ getRgbItem: function AlternateCS_getRgbItem(src, srcOffset,
+ dest, destOffset) {
+ var baseNumComps = this.base.numComps;
+ var input = 'subarray' in src ?
+ src.subarray(srcOffset, srcOffset + this.numComps) :
+ Array.prototype.slice.call(src, srcOffset, srcOffset + this.numComps);
+ var tinted = this.tintFn(input);
+ this.base.getRgbItem(tinted, 0, dest, destOffset);
+ },
+ getRgbBuffer: function AlternateCS_getRgbBuffer(src, srcOffset, count,
+ dest, destOffset, bits) {
+ var tintFn = this.tintFn;
+ var base = this.base;
+ var scale = 1 / ((1 << bits) - 1);
+ var baseNumComps = base.numComps;
+ var usesZeroToOneRange = base.usesZeroToOneRange;
+ var isPassthrough = base.isPassthrough(8) || !usesZeroToOneRange;
+ var pos = isPassthrough ? destOffset : 0;
+ var baseBuf = isPassthrough ? dest : new Uint8Array(baseNumComps * count);
+ var numComps = this.numComps;
+
+ var scaled = new Float32Array(numComps);
+ for (var i = 0; i < count; i++) {
+ for (var j = 0; j < numComps; j++) {
+ scaled[j] = src[srcOffset++] * scale;
+ }
+ var tinted = tintFn(scaled);
+ if (usesZeroToOneRange) {
+ for (var j = 0; j < baseNumComps; j++) {
+ baseBuf[pos++] = tinted[j] * 255;
+ }
+ } else {
+ base.getRgbItem(tinted, 0, baseBuf, pos);
+ pos += baseNumComps;
+ }
+ }
+ if (!isPassthrough) {
+ base.getRgbBuffer(baseBuf, 0, count, dest, destOffset, 8);
+ }
+ },
+ getOutputLength: function AlternateCS_getOutputLength(inputLength) {
+ return this.base.getOutputLength(inputLength *
+ this.base.numComps / this.numComps);
+ },
+ isPassthrough: ColorSpace.prototype.isPassthrough,
+ createRgbBuffer: ColorSpace.prototype.createRgbBuffer,
+ isDefaultDecode: function AlternateCS_isDefaultDecode(decodeMap) {
+ return ColorSpace.isDefaultDecode(decodeMap, this.numComps);
+ },
+ usesZeroToOneRange: true
+ };
+
+ return AlternateCS;
+})();
+
+var PatternCS = (function PatternCSClosure() {
+ function PatternCS(baseCS) {
+ this.name = 'Pattern';
+ this.base = baseCS;
+ }
+ PatternCS.prototype = {};
+
+ return PatternCS;
+})();
+
+var IndexedCS = (function IndexedCSClosure() {
+ function IndexedCS(base, highVal, lookup) {
+ this.name = 'Indexed';
+ this.numComps = 1;
+ this.defaultColor = new Uint8Array([0]);
+ this.base = base;
+ this.highVal = highVal;
+
+ var baseNumComps = base.numComps;
+ var length = baseNumComps * highVal;
+ var lookupArray;
+
+ if (isStream(lookup)) {
+ lookupArray = new Uint8Array(length);
+ var bytes = lookup.getBytes(length);
+ lookupArray.set(bytes);
+ } else if (isString(lookup)) {
+ lookupArray = new Uint8Array(length);
+ for (var i = 0; i < length; ++i)
+ lookupArray[i] = lookup.charCodeAt(i);
+ } else if (lookup instanceof Uint8Array || lookup instanceof Array) {
+ lookupArray = lookup;
+ } else {
+ error('Unrecognized lookup table: ' + lookup);
+ }
+ this.lookup = lookupArray;
+ }
+
+ IndexedCS.prototype = {
+ getRgb: function IndexedCS_getRgb(src, srcOffset) {
+ var numComps = this.base.numComps;
+ var start = src[srcOffset] * numComps;
+ return this.base.getRgb(this.lookup, start);
+ },
+ getRgbItem: function IndexedCS_getRgbItem(src, srcOffset,
+ dest, destOffset) {
+ var numComps = this.base.numComps;
+ var start = src[srcOffset] * numComps;
+ this.base.getRgbItem(this.lookup, start, dest, destOffset);
+ },
+ getRgbBuffer: function IndexedCS_getRgbBuffer(src, srcOffset, count,
+ dest, destOffset) {
+ var base = this.base;
+ var numComps = base.numComps;
+ var outputDelta = base.getOutputLength(numComps);
+ var lookup = this.lookup;
+
+ for (var i = 0; i < count; ++i) {
+ var lookupPos = src[srcOffset++] * numComps;
+ base.getRgbBuffer(lookup, lookupPos, 1, dest, destOffset, 8);
+ destOffset += outputDelta;
+ }
+ },
+ getOutputLength: function IndexedCS_getOutputLength(inputLength) {
+ return this.base.getOutputLength(inputLength * this.base.numComps);
+ },
+ isPassthrough: ColorSpace.prototype.isPassthrough,
+ createRgbBuffer: ColorSpace.prototype.createRgbBuffer,
+ isDefaultDecode: function IndexedCS_isDefaultDecode(decodeMap) {
+ // indexed color maps shouldn't be changed
+ return true;
+ },
+ usesZeroToOneRange: true
+ };
+ return IndexedCS;
+})();
+
+var DeviceGrayCS = (function DeviceGrayCSClosure() {
+ function DeviceGrayCS() {
+ this.name = 'DeviceGray';
+ this.numComps = 1;
+ this.defaultColor = new Float32Array([0]);
+ }
+
+ DeviceGrayCS.prototype = {
+ getRgb: function DeviceGrayCS_getRgb(src, srcOffset) {
+ var rgb = new Uint8Array(3);
+ this.getRgbItem(src, srcOffset, rgb, 0);
+ return rgb;
+ },
+ getRgbItem: function DeviceGrayCS_getRgbItem(src, srcOffset,
+ dest, destOffset) {
+ var c = (src[srcOffset] * 255) | 0;
+ c = c < 0 ? 0 : c > 255 ? 255 : c;
+ dest[destOffset] = dest[destOffset + 1] = dest[destOffset + 2] = c;
+ },
+ getRgbBuffer: function DeviceGrayCS_getRgbBuffer(src, srcOffset, count,
+ dest, destOffset, bits) {
+ var scale = 255 / ((1 << bits) - 1);
+ var j = srcOffset, q = destOffset;
+ for (var i = 0; i < count; ++i) {
+ var c = (scale * src[j++]) | 0;
+ dest[q++] = c;
+ dest[q++] = c;
+ dest[q++] = c;
+ }
+ },
+ getOutputLength: function DeviceGrayCS_getOutputLength(inputLength) {
+ return inputLength * 3;
+ },
+ isPassthrough: ColorSpace.prototype.isPassthrough,
+ createRgbBuffer: ColorSpace.prototype.createRgbBuffer,
+ isDefaultDecode: function DeviceGrayCS_isDefaultDecode(decodeMap) {
+ return ColorSpace.isDefaultDecode(decodeMap, this.numComps);
+ },
+ usesZeroToOneRange: true
+ };
+ return DeviceGrayCS;
+})();
+
+var DeviceRgbCS = (function DeviceRgbCSClosure() {
+ function DeviceRgbCS() {
+ this.name = 'DeviceRGB';
+ this.numComps = 3;
+ this.defaultColor = new Float32Array([0, 0, 0]);
+ }
+ DeviceRgbCS.prototype = {
+ getRgb: function DeviceRgbCS_getRgb(src, srcOffset) {
+ var rgb = new Uint8Array(3);
+ this.getRgbItem(src, srcOffset, rgb, 0);
+ return rgb;
+ },
+ getRgbItem: function DeviceRgbCS_getRgbItem(src, srcOffset,
+ dest, destOffset) {
+ var r = (src[srcOffset] * 255) | 0;
+ var g = (src[srcOffset + 1] * 255) | 0;
+ var b = (src[srcOffset + 2] * 255) | 0;
+ dest[destOffset] = r < 0 ? 0 : r > 255 ? 255 : r;
+ dest[destOffset + 1] = g < 0 ? 0 : g > 255 ? 255 : g;
+ dest[destOffset + 2] = b < 0 ? 0 : b > 255 ? 255 : b;
+ },
+ getRgbBuffer: function DeviceRgbCS_getRgbBuffer(src, srcOffset, count,
+ dest, destOffset, bits) {
+ var length = count * 3;
+ if (bits == 8) {
+ dest.set(src.subarray(srcOffset, srcOffset + length), destOffset);
+ return;
+ }
+ var scale = 255 / ((1 << bits) - 1);
+ var j = srcOffset, q = destOffset;
+ for (var i = 0; i < length; ++i) {
+ dest[q++] = (scale * src[j++]) | 0;
+ }
+ },
+ getOutputLength: function DeviceRgbCS_getOutputLength(inputLength) {
+ return inputLength;
+ },
+ isPassthrough: function DeviceRgbCS_isPassthrough(bits) {
+ return bits == 8;
+ },
+ createRgbBuffer: ColorSpace.prototype.createRgbBuffer,
+ isDefaultDecode: function DeviceRgbCS_isDefaultDecode(decodeMap) {
+ return ColorSpace.isDefaultDecode(decodeMap, this.numComps);
+ },
+ usesZeroToOneRange: true
+ };
+ return DeviceRgbCS;
+})();
+
+var DeviceCmykCS = (function DeviceCmykCSClosure() {
+ // The coefficients below was found using numerical analysis: the method of
+ // steepest descent for the sum((f_i - color_value_i)^2) for r/g/b colors,
+ // where color_value is the tabular value from the table of sampled RGB colors
+ // from CMYK US Web Coated (SWOP) colorspace, and f_i is the corresponding
+ // CMYK color conversion using the estimation below:
+ // f(A, B,.. N) = Acc+Bcm+Ccy+Dck+c+Fmm+Gmy+Hmk+Im+Jyy+Kyk+Ly+Mkk+Nk+255
+ function convertToRgb(src, srcOffset, srcScale, dest, destOffset) {
+ var c = src[srcOffset + 0] * srcScale;
+ var m = src[srcOffset + 1] * srcScale;
+ var y = src[srcOffset + 2] * srcScale;
+ var k = src[srcOffset + 3] * srcScale;
+
+ var r =
+ c * (-4.387332384609988 * c + 54.48615194189176 * m +
+ 18.82290502165302 * y + 212.25662451639585 * k +
+ -285.2331026137004) +
+ m * (1.7149763477362134 * m - 5.6096736904047315 * y +
+ -17.873870861415444 * k - 5.497006427196366) +
+ y * (-2.5217340131683033 * y - 21.248923337353073 * k +
+ 17.5119270841813) +
+ k * (-21.86122147463605 * k - 189.48180835922747) + 255;
+ var g =
+ c * (8.841041422036149 * c + 60.118027045597366 * m +
+ 6.871425592049007 * y + 31.159100130055922 * k +
+ -79.2970844816548) +
+ m * (-15.310361306967817 * m + 17.575251261109482 * y +
+ 131.35250912493976 * k - 190.9453302588951) +
+ y * (4.444339102852739 * y + 9.8632861493405 * k - 24.86741582555878) +
+ k * (-20.737325471181034 * k - 187.80453709719578) + 255;
+ var b =
+ c * (0.8842522430003296 * c + 8.078677503112928 * m +
+ 30.89978309703729 * y - 0.23883238689178934 * k +
+ -14.183576799673286) +
+ m * (10.49593273432072 * m + 63.02378494754052 * y +
+ 50.606957656360734 * k - 112.23884253719248) +
+ y * (0.03296041114873217 * y + 115.60384449646641 * k +
+ -193.58209356861505) +
+ k * (-22.33816807309886 * k - 180.12613974708367) + 255;
+
+ dest[destOffset] = r > 255 ? 255 : r < 0 ? 0 : r;
+ dest[destOffset + 1] = g > 255 ? 255 : g < 0 ? 0 : g;
+ dest[destOffset + 2] = b > 255 ? 255 : b < 0 ? 0 : b;
+ }
+
+ function DeviceCmykCS() {
+ this.name = 'DeviceCMYK';
+ this.numComps = 4;
+ this.defaultColor = new Float32Array([0, 0, 0, 1]);
+ }
+ DeviceCmykCS.prototype = {
+ getRgb: function DeviceCmykCS_getRgb(src, srcOffset) {
+ var rgb = new Uint8Array(3);
+ convertToRgb(src, srcOffset, 1, rgb, 0);
+ return rgb;
+ },
+ getRgbItem: function DeviceCmykCS_getRgbItem(src, srcOffset,
+ dest, destOffset) {
+ convertToRgb(src, srcOffset, 1, dest, destOffset);
+ },
+ getRgbBuffer: function DeviceCmykCS_getRgbBuffer(src, srcOffset, count,
+ dest, destOffset, bits) {
+ var scale = 1 / ((1 << bits) - 1);
+ for (var i = 0; i < count; i++) {
+ convertToRgb(src, srcOffset, scale, dest, destOffset);
+ srcOffset += 4;
+ destOffset += 3;
+ }
+ },
+ getOutputLength: function DeviceCmykCS_getOutputLength(inputLength) {
+ return (inputLength >> 2) * 3;
+ },
+ isPassthrough: ColorSpace.prototype.isPassthrough,
+ createRgbBuffer: ColorSpace.prototype.createRgbBuffer,
+ isDefaultDecode: function DeviceCmykCS_isDefaultDecode(decodeMap) {
+ return ColorSpace.isDefaultDecode(decodeMap, this.numComps);
+ },
+ usesZeroToOneRange: true
+ };
+
+ return DeviceCmykCS;
+})();
+
+//
+// CalGrayCS: Based on "PDF Reference, Sixth Ed", p.245
+//
+var CalGrayCS = (function CalGrayCSClosure() {
+ function CalGrayCS(whitePoint, blackPoint, gamma) {
+ this.name = 'CalGray';
+ this.numComps = 1;
+ this.defaultColor = new Float32Array([0]);
+
+ if (!whitePoint) {
+ error('WhitePoint missing - required for color space CalGray');
+ }
+ blackPoint = blackPoint || [0, 0, 0];
+ gamma = gamma || 1;
+
+ // Translate arguments to spec variables.
+ this.XW = whitePoint[0];
+ this.YW = whitePoint[1];
+ this.ZW = whitePoint[2];
+
+ this.XB = blackPoint[0];
+ this.YB = blackPoint[1];
+ this.ZB = blackPoint[2];
+
+ this.G = gamma;
+
+ // Validate variables as per spec.
+ if (this.XW < 0 || this.ZW < 0 || this.YW !== 1) {
+ error('Invalid WhitePoint components for ' + this.name +
+ ', no fallback available');
+ }
+
+ if (this.XB < 0 || this.YB < 0 || this.ZB < 0) {
+ info('Invalid BlackPoint for ' + this.name + ', falling back to default');
+ this.XB = this.YB = this.ZB = 0;
+ }
+
+ if (this.XB !== 0 || this.YB !== 0 || this.ZB !== 0) {
+ warn(this.name + ', BlackPoint: XB: ' + this.XB + ', YB: ' + this.YB +
+ ', ZB: ' + this.ZB + ', only default values are supported.');
+ }
+
+ if (this.G < 1) {
+ info('Invalid Gamma: ' + this.G + ' for ' + this.name +
+ ', falling back to default');
+ this.G = 1;
+ }
+ }
+
+ function convertToRgb(cs, src, srcOffset, dest, destOffset, scale) {
+ // A represents a gray component of a calibrated gray space.
+ // A <---> AG in the spec
+ var A = src[srcOffset] * scale;
+ var AG = Math.pow(A, cs.G);
+
+ // Computes intermediate variables M, L, N as per spec.
+ // Except if other than default BlackPoint values are used.
+ var M = cs.XW * AG;
+ var L = cs.YW * AG;
+ var N = cs.ZW * AG;
+
+ // Decode XYZ, as per spec.
+ var X = M;
+ var Y = L;
+ var Z = N;
+
+ // http://www.poynton.com/notes/colour_and_gamma/ColorFAQ.html, Ch 4.
+ // This yields values in range [0, 100].
+ var Lstar = Math.max(116 * Math.pow(Y, 1 / 3) - 16, 0);
+
+ // Convert values to rgb range [0, 255].
+ dest[destOffset] = Lstar * 255 / 100;
+ dest[destOffset + 1] = Lstar * 255 / 100;
+ dest[destOffset + 2] = Lstar * 255 / 100;
+ }
+
+ CalGrayCS.prototype = {
+ getRgb: function CalGrayCS_getRgb(src, srcOffset) {
+ var rgb = new Uint8Array(3);
+ this.getRgbItem(src, srcOffset, rgb, 0);
+ return rgb;
+ },
+ getRgbItem: function CalGrayCS_getRgbItem(src, srcOffset,
+ dest, destOffset) {
+ convertToRgb(this, src, srcOffset, dest, destOffset, 1);
+ },
+ getRgbBuffer: function CalGrayCS_getRgbBuffer(src, srcOffset, count,
+ dest, destOffset, bits) {
+ var scale = 1 / ((1 << bits) - 1);
+
+ for (var i = 0; i < count; ++i) {
+ convertToRgb(this, src, srcOffset, dest, destOffset, scale);
+ srcOffset += 1;
+ destOffset += 3;
+ }
+ },
+ getOutputLength: function CalGrayCS_getOutputLength(inputLength) {
+ return inputLength * 3;
+ },
+ isPassthrough: ColorSpace.prototype.isPassthrough,
+ createRgbBuffer: ColorSpace.prototype.createRgbBuffer,
+ isDefaultDecode: function CalGrayCS_isDefaultDecode(decodeMap) {
+ return ColorSpace.isDefaultDecode(decodeMap, this.numComps);
+ },
+ usesZeroToOneRange: true
+ };
+ return CalGrayCS;
+})();
+
+//
+// LabCS: Based on "PDF Reference, Sixth Ed", p.250
+//
+var LabCS = (function LabCSClosure() {
+ function LabCS(whitePoint, blackPoint, range) {
+ this.name = 'Lab';
+ this.numComps = 3;
+ this.defaultColor = new Float32Array([0, 0, 0]);
+
+ if (!whitePoint)
+ error('WhitePoint missing - required for color space Lab');
+ blackPoint = blackPoint || [0, 0, 0];
+ range = range || [-100, 100, -100, 100];
+
+ // Translate args to spec variables
+ this.XW = whitePoint[0];
+ this.YW = whitePoint[1];
+ this.ZW = whitePoint[2];
+ this.amin = range[0];
+ this.amax = range[1];
+ this.bmin = range[2];
+ this.bmax = range[3];
+
+ // These are here just for completeness - the spec doesn't offer any
+ // formulas that use BlackPoint in Lab
+ this.XB = blackPoint[0];
+ this.YB = blackPoint[1];
+ this.ZB = blackPoint[2];
+
+ // Validate vars as per spec
+ if (this.XW < 0 || this.ZW < 0 || this.YW !== 1)
+ error('Invalid WhitePoint components, no fallback available');
+
+ if (this.XB < 0 || this.YB < 0 || this.ZB < 0) {
+ info('Invalid BlackPoint, falling back to default');
+ this.XB = this.YB = this.ZB = 0;
+ }
+
+ if (this.amin > this.amax || this.bmin > this.bmax) {
+ info('Invalid Range, falling back to defaults');
+ this.amin = -100;
+ this.amax = 100;
+ this.bmin = -100;
+ this.bmax = 100;
+ }
+ }
+
+ // Function g(x) from spec
+ function fn_g(x) {
+ if (x >= 6 / 29)
+ return x * x * x;
+ else
+ return (108 / 841) * (x - 4 / 29);
+ }
+
+ function decode(value, high1, low2, high2) {
+ return low2 + (value) * (high2 - low2) / (high1);
+ }
+
+ // If decoding is needed maxVal should be 2^bits per component - 1.
+ function convertToRgb(cs, src, srcOffset, maxVal, dest, destOffset) {
+ // XXX: Lab input is in the range of [0, 100], [amin, amax], [bmin, bmax]
+ // not the usual [0, 1]. If a command like setFillColor is used the src
+ // values will already be within the correct range. However, if we are
+ // converting an image we have to map the values to the correct range given
+ // above.
+ // Ls,as,bs <---> L*,a*,b* in the spec
+ var Ls = src[srcOffset];
+ var as = src[srcOffset + 1];
+ var bs = src[srcOffset + 2];
+ if (maxVal !== false) {
+ Ls = decode(Ls, maxVal, 0, 100);
+ as = decode(as, maxVal, cs.amin, cs.amax);
+ bs = decode(bs, maxVal, cs.bmin, cs.bmax);
+ }
+
+ // Adjust limits of 'as' and 'bs'
+ as = as > cs.amax ? cs.amax : as < cs.amin ? cs.amin : as;
+ bs = bs > cs.bmax ? cs.bmax : bs < cs.bmin ? cs.bmin : bs;
+
+ // Computes intermediate variables X,Y,Z as per spec
+ var M = (Ls + 16) / 116;
+ var L = M + (as / 500);
+ var N = M - (bs / 200);
+
+ var X = cs.XW * fn_g(L);
+ var Y = cs.YW * fn_g(M);
+ var Z = cs.ZW * fn_g(N);
+
+ var r, g, b;
+ // Using different conversions for D50 and D65 white points,
+ // per http://www.color.org/srgb.pdf
+ if (cs.ZW < 1) {
+ // Assuming D50 (X=0.9642, Y=1.00, Z=0.8249)
+ r = X * 3.1339 + Y * -1.6170 + Z * -0.4906;
+ g = X * -0.9785 + Y * 1.9160 + Z * 0.0333;
+ b = X * 0.0720 + Y * -0.2290 + Z * 1.4057;
+ } else {
+ // Assuming D65 (X=0.9505, Y=1.00, Z=1.0888)
+ r = X * 3.2406 + Y * -1.5372 + Z * -0.4986;
+ g = X * -0.9689 + Y * 1.8758 + Z * 0.0415;
+ b = X * 0.0557 + Y * -0.2040 + Z * 1.0570;
+ }
+ // clamp color values to [0,1] range then convert to [0,255] range.
+ dest[destOffset] = Math.sqrt(r < 0 ? 0 : r > 1 ? 1 : r) * 255;
+ dest[destOffset + 1] = Math.sqrt(g < 0 ? 0 : g > 1 ? 1 : g) * 255;
+ dest[destOffset + 2] = Math.sqrt(b < 0 ? 0 : b > 1 ? 1 : b) * 255;
+ }
+
+ LabCS.prototype = {
+ getRgb: function LabCS_getRgb(src, srcOffset) {
+ var rgb = new Uint8Array(3);
+ convertToRgb(this, src, srcOffset, false, rgb, 0);
+ return rgb;
+ },
+ getRgbItem: function LabCS_getRgbItem(src, srcOffset, dest, destOffset) {
+ convertToRgb(this, src, srcOffset, false, dest, destOffset);
+ },
+ getRgbBuffer: function LabCS_getRgbBuffer(src, srcOffset, count,
+ dest, destOffset, bits) {
+ var maxVal = (1 << bits) - 1;
+ for (var i = 0; i < count; i++) {
+ convertToRgb(this, src, srcOffset, maxVal, dest, destOffset);
+ srcOffset += 3;
+ destOffset += 3;
+ }
+ },
+ getOutputLength: function LabCS_getOutputLength(inputLength) {
+ return inputLength;
+ },
+ isPassthrough: ColorSpace.prototype.isPassthrough,
+ isDefaultDecode: function LabCS_isDefaultDecode(decodeMap) {
+ // XXX: Decoding is handled with the lab conversion because of the strange
+ // ranges that are used.
+ return true;
+ },
+ usesZeroToOneRange: false
+ };
+ return LabCS;
+})();
+
+
+
+var PatternType = {
+ AXIAL: 2,
+ RADIAL: 3
+};
+
+var Pattern = (function PatternClosure() {
+ // Constructor should define this.getPattern
+ function Pattern() {
+ error('should not call Pattern constructor');
+ }
+
+ Pattern.prototype = {
+ // Input: current Canvas context
+ // Output: the appropriate fillStyle or strokeStyle
+ getPattern: function Pattern_getPattern(ctx) {
+ error('Should not call Pattern.getStyle: ' + ctx);
+ }
+ };
+
+ Pattern.shadingFromIR = function Pattern_shadingFromIR(raw) {
+ return Shadings[raw[0]].fromIR(raw);
+ };
+
+ Pattern.parseShading = function Pattern_parseShading(shading, matrix, xref,
+ res) {
+
+ var dict = isStream(shading) ? shading.dict : shading;
+ var type = dict.get('ShadingType');
+
+ switch (type) {
+ case PatternType.AXIAL:
+ case PatternType.RADIAL:
+ // Both radial and axial shadings are handled by RadialAxial shading.
+ return new Shadings.RadialAxial(dict, matrix, xref, res);
+ default:
+ UnsupportedManager.notify(UNSUPPORTED_FEATURES.shadingPattern);
+ return new Shadings.Dummy();
+ }
+ };
+ return Pattern;
+})();
+
+var Shadings = {};
+
+// A small number to offset the first/last color stops so we can insert ones to
+// support extend. Number.MIN_VALUE appears to be too small and breaks the
+// extend. 1e-7 works in FF but chrome seems to use an even smaller sized number
+// internally so we have to go bigger.
+Shadings.SMALL_NUMBER = 1e-2;
+
+// Radial and axial shading have very similar implementations
+// If needed, the implementations can be broken into two classes
+Shadings.RadialAxial = (function RadialAxialClosure() {
+ function RadialAxial(dict, matrix, xref, res, ctx) {
+ this.matrix = matrix;
+ this.coordsArr = dict.get('Coords');
+ this.shadingType = dict.get('ShadingType');
+ this.type = 'Pattern';
+ this.ctx = ctx;
+ var cs = dict.get('ColorSpace', 'CS');
+ cs = ColorSpace.parse(cs, xref, res);
+ this.cs = cs;
+
+ var t0 = 0.0, t1 = 1.0;
+ if (dict.has('Domain')) {
+ var domainArr = dict.get('Domain');
+ t0 = domainArr[0];
+ t1 = domainArr[1];
+ }
+
+ var extendStart = false, extendEnd = false;
+ if (dict.has('Extend')) {
+ var extendArr = dict.get('Extend');
+ extendStart = extendArr[0];
+ extendEnd = extendArr[1];
+ }
+
+ if (this.shadingType === PatternType.RADIAL &&
+ (!extendStart || !extendEnd)) {
+ // Radial gradient only currently works if either circle is fully within
+ // the other circle.
+ var x1 = this.coordsArr[0];
+ var y1 = this.coordsArr[1];
+ var r1 = this.coordsArr[2];
+ var x2 = this.coordsArr[3];
+ var y2 = this.coordsArr[4];
+ var r2 = this.coordsArr[5];
+ var distance = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
+ if (r1 <= r2 + distance &&
+ r2 <= r1 + distance) {
+ warn('Unsupported radial gradient.');
+ }
+ }
+
+ this.extendStart = extendStart;
+ this.extendEnd = extendEnd;
+
+ var fnObj = dict.get('Function');
+ var fn;
+ if (isArray(fnObj)) {
+ var fnArray = [];
+ for (var j = 0, jj = fnObj.length; j < jj; j++) {
+ var obj = xref.fetchIfRef(fnObj[j]);
+ if (!isPDFFunction(obj)) {
+ error('Invalid function');
+ }
+ fnArray.push(PDFFunction.parse(xref, obj));
+ }
+ fn = function radialAxialColorFunction(arg) {
+ var out = [];
+ for (var i = 0, ii = fnArray.length; i < ii; i++) {
+ out.push(fnArray[i](arg)[0]);
+ }
+ return out;
+ };
+ } else {
+ if (!isPDFFunction(fnObj)) {
+ error('Invalid function');
+ }
+ fn = PDFFunction.parse(xref, fnObj);
+ }
+
+ // 10 samples seems good enough for now, but probably won't work
+ // if there are sharp color changes. Ideally, we would implement
+ // the spec faithfully and add lossless optimizations.
+ var diff = t1 - t0;
+ var step = diff / 10;
+
+ var colorStops = this.colorStops = [];
+
+ // Protect against bad domains so we don't end up in an infinte loop below.
+ if (t0 >= t1 || step <= 0) {
+ // Acrobat doesn't seem to handle these cases so we'll ignore for
+ // now.
+ info('Bad shading domain.');
+ return;
+ }
+
+ for (var i = t0; i <= t1; i += step) {
+ var rgbColor = cs.getRgb(fn([i]), 0);
+ var cssColor = Util.makeCssRgb(rgbColor);
+ colorStops.push([(i - t0) / diff, cssColor]);
+ }
+
+ var background = 'transparent';
+ if (dict.has('Background')) {
+ var rgbColor = cs.getRgb(dict.get('Background'), 0);
+ background = Util.makeCssRgb(rgbColor);
+ }
+
+ if (!extendStart) {
+ // Insert a color stop at the front and offset the first real color stop
+ // so it doesn't conflict with the one we insert.
+ colorStops.unshift([0, background]);
+ colorStops[1][0] += Shadings.SMALL_NUMBER;
+ }
+ if (!extendEnd) {
+ // Same idea as above in extendStart but for the end.
+ colorStops[colorStops.length - 1][0] -= Shadings.SMALL_NUMBER;
+ colorStops.push([1, background]);
+ }
+
+ this.colorStops = colorStops;
+ }
+
+ RadialAxial.fromIR = function RadialAxial_fromIR(raw) {
+ var type = raw[1];
+ var colorStops = raw[2];
+ var p0 = raw[3];
+ var p1 = raw[4];
+ var r0 = raw[5];
+ var r1 = raw[6];
+ return {
+ type: 'Pattern',
+ getPattern: function RadialAxial_getPattern(ctx) {
+ var grad;
+ if (type == PatternType.AXIAL)
+ grad = ctx.createLinearGradient(p0[0], p0[1], p1[0], p1[1]);
+ else if (type == PatternType.RADIAL)
+ grad = ctx.createRadialGradient(p0[0], p0[1], r0, p1[0], p1[1], r1);
+
+ for (var i = 0, ii = colorStops.length; i < ii; ++i) {
+ var c = colorStops[i];
+ grad.addColorStop(c[0], c[1]);
+ }
+ return grad;
+ }
+ };
+ };
+
+ RadialAxial.prototype = {
+ getIR: function RadialAxial_getIR() {
+ var coordsArr = this.coordsArr;
+ var type = this.shadingType;
+ if (type == PatternType.AXIAL) {
+ var p0 = [coordsArr[0], coordsArr[1]];
+ var p1 = [coordsArr[2], coordsArr[3]];
+ var r0 = null;
+ var r1 = null;
+ } else if (type == PatternType.RADIAL) {
+ var p0 = [coordsArr[0], coordsArr[1]];
+ var p1 = [coordsArr[3], coordsArr[4]];
+ var r0 = coordsArr[2];
+ var r1 = coordsArr[5];
+ } else {
+ error('getPattern type unknown: ' + type);
+ }
+
+ var matrix = this.matrix;
+ if (matrix) {
+ p0 = Util.applyTransform(p0, matrix);
+ p1 = Util.applyTransform(p1, matrix);
+ }
+
+ return ['RadialAxial', type, this.colorStops, p0, p1, r0, r1];
+ }
+ };
+
+ return RadialAxial;
+})();
+
+Shadings.Dummy = (function DummyClosure() {
+ function Dummy() {
+ this.type = 'Pattern';
+ }
+
+ Dummy.fromIR = function Dummy_fromIR() {
+ return {
+ type: 'Pattern',
+ getPattern: function Dummy_fromIR_getPattern() {
+ return 'hotpink';
+ }
+ };
+ };
+
+ Dummy.prototype = {
+ getIR: function Dummy_getIR() {
+ return ['Dummy'];
+ }
+ };
+ return Dummy;
+})();
+
+var TilingPattern = (function TilingPatternClosure() {
+ var PaintType = {
+ COLORED: 1,
+ UNCOLORED: 2
+ };
+
+ var MAX_PATTERN_SIZE = 3000; // 10in @ 300dpi shall be enough
+
+ function TilingPattern(IR, color, ctx, objs, commonObjs, baseTransform) {
+ this.name = IR[1][0].name;
+ this.operatorList = IR[2];
+ this.matrix = IR[3] || [1, 0, 0, 1, 0, 0];
+ this.bbox = IR[4];
+ this.xstep = IR[5];
+ this.ystep = IR[6];
+ this.paintType = IR[7];
+ this.tilingType = IR[8];
+ this.color = color;
+ this.objs = objs;
+ this.commonObjs = commonObjs;
+ this.baseTransform = baseTransform;
+ this.type = 'Pattern';
+ this.ctx = ctx;
+ }
+
+ TilingPattern.getIR = function TilingPattern_getIR(operatorList, dict, args) {
+ var matrix = dict.get('Matrix');
+ var bbox = dict.get('BBox');
+ var xstep = dict.get('XStep');
+ var ystep = dict.get('YStep');
+ var paintType = dict.get('PaintType');
+ var tilingType = dict.get('TilingType');
+
+ return [
+ 'TilingPattern', args, operatorList, matrix, bbox, xstep, ystep,
+ paintType, tilingType
+ ];
+ };
+
+ TilingPattern.prototype = {
+ createPatternCanvas: function TilinPattern_createPatternCanvas(owner) {
+ var operatorList = this.operatorList;
+ var bbox = this.bbox;
+ var xstep = this.xstep;
+ var ystep = this.ystep;
+ var paintType = this.paintType;
+ var tilingType = this.tilingType;
+ var color = this.color;
+ var objs = this.objs;
+ var commonObjs = this.commonObjs;
+ var ctx = this.ctx;
+
+ info('TilingType: ' + tilingType);
+
+ var x0 = bbox[0], y0 = bbox[1], x1 = bbox[2], y1 = bbox[3];
+
+ var topLeft = [x0, y0];
+ // we want the canvas to be as large as the step size
+ var botRight = [x0 + xstep, y0 + ystep];
+
+ var width = botRight[0] - topLeft[0];
+ var height = botRight[1] - topLeft[1];
+
+ // Obtain scale from matrix and current transformation matrix.
+ var matrixScale = Util.singularValueDecompose2dScale(this.matrix);
+ var curMatrixScale = Util.singularValueDecompose2dScale(
+ this.baseTransform);
+ var combinedScale = [matrixScale[0] * curMatrixScale[0],
+ matrixScale[1] * curMatrixScale[1]];
+
+ // MAX_PATTERN_SIZE is used to avoid OOM situation.
+ // Use width and height values that are as close as possible to the end
+ // result when the pattern is used. Too low value makes the pattern look
+ // blurry. Too large value makes it look too crispy.
+ width = Math.min(Math.ceil(Math.abs(width * combinedScale[0])),
+ MAX_PATTERN_SIZE);
+
+ height = Math.min(Math.ceil(Math.abs(height * combinedScale[1])),
+ MAX_PATTERN_SIZE);
+
+ var tmpCanvas = CachedCanvases.getCanvas('pattern', width, height, true);
+ var tmpCtx = tmpCanvas.context;
+ var graphics = new CanvasGraphics(tmpCtx, commonObjs, objs);
+ graphics.groupLevel = owner.groupLevel;
+
+ this.setFillAndStrokeStyleToContext(tmpCtx, paintType, color);
+
+ this.setScale(width, height, xstep, ystep);
+ this.transformToScale(graphics);
+
+ // transform coordinates to pattern space
+ var tmpTranslate = [1, 0, 0, 1, -topLeft[0], -topLeft[1]];
+ graphics.transform.apply(graphics, tmpTranslate);
+
+ this.clipBbox(graphics, bbox, x0, y0, x1, y1);
+
+ graphics.executeOperatorList(operatorList);
+ return tmpCanvas.canvas;
+ },
+
+ setScale: function TilingPattern_setScale(width, height, xstep, ystep) {
+ this.scale = [width / xstep, height / ystep];
+ },
+
+ transformToScale: function TilingPattern_transformToScale(graphics) {
+ var scale = this.scale;
+ var tmpScale = [scale[0], 0, 0, scale[1], 0, 0];
+ graphics.transform.apply(graphics, tmpScale);
+ },
+
+ scaleToContext: function TilingPattern_scaleToContext() {
+ var scale = this.scale;
+ this.ctx.scale(1 / scale[0], 1 / scale[1]);
+ },
+
+ clipBbox: function clipBbox(graphics, bbox, x0, y0, x1, y1) {
+ if (bbox && isArray(bbox) && 4 == bbox.length) {
+ var bboxWidth = x1 - x0;
+ var bboxHeight = y1 - y0;
+ graphics.rectangle(x0, y0, bboxWidth, bboxHeight);
+ graphics.clip();
+ graphics.endPath();
+ }
+ },
+
+ setFillAndStrokeStyleToContext:
+ function setFillAndStrokeStyleToContext(context, paintType, color) {
+ switch (paintType) {
+ case PaintType.COLORED:
+ var ctx = this.ctx;
+ context.fillStyle = ctx.fillStyle;
+ context.strokeStyle = ctx.strokeStyle;
+ break;
+ case PaintType.UNCOLORED:
+ var rgbColor = ColorSpace.singletons.rgb.getRgb(color, 0);
+ var cssColor = Util.makeCssRgb(rgbColor);
+ context.fillStyle = cssColor;
+ context.strokeStyle = cssColor;
+ break;
+ default:
+ error('Unsupported paint type: ' + paintType);
+ }
+ },
+
+ getPattern: function TilingPattern_getPattern(ctx, owner) {
+ var temporaryPatternCanvas = this.createPatternCanvas(owner);
+
+ var ctx = this.ctx;
+ ctx.setTransform.apply(ctx, this.baseTransform);
+ ctx.transform.apply(ctx, this.matrix);
+ this.scaleToContext();
+
+ return ctx.createPattern(temporaryPatternCanvas, 'repeat');
+ }
+ };
+
+ return TilingPattern;
+})();
+
+
+
+var PDFFunction = (function PDFFunctionClosure() {
+ var CONSTRUCT_SAMPLED = 0;
+ var CONSTRUCT_INTERPOLATED = 2;
+ var CONSTRUCT_STICHED = 3;
+ var CONSTRUCT_POSTSCRIPT = 4;
+
+ return {
+ getSampleArray: function PDFFunction_getSampleArray(size, outputSize, bps,
+ str) {
+ var length = 1;
+ for (var i = 0, ii = size.length; i < ii; i++)
+ length *= size[i];
+ length *= outputSize;
+
+ var array = [];
+ var codeSize = 0;
+ var codeBuf = 0;
+ // 32 is a valid bps so shifting won't work
+ var sampleMul = 1.0 / (Math.pow(2.0, bps) - 1);
+
+ var strBytes = str.getBytes((length * bps + 7) / 8);
+ var strIdx = 0;
+ for (var i = 0; i < length; i++) {
+ while (codeSize < bps) {
+ codeBuf <<= 8;
+ codeBuf |= strBytes[strIdx++];
+ codeSize += 8;
+ }
+ codeSize -= bps;
+ array.push((codeBuf >> codeSize) * sampleMul);
+ codeBuf &= (1 << codeSize) - 1;
+ }
+ return array;
+ },
+
+ getIR: function PDFFunction_getIR(xref, fn) {
+ var dict = fn.dict;
+ if (!dict)
+ dict = fn;
+
+ var types = [this.constructSampled,
+ null,
+ this.constructInterpolated,
+ this.constructStiched,
+ this.constructPostScript];
+
+ var typeNum = dict.get('FunctionType');
+ var typeFn = types[typeNum];
+ if (!typeFn)
+ error('Unknown type of function');
+
+ return typeFn.call(this, fn, dict, xref);
+ },
+
+ fromIR: function PDFFunction_fromIR(IR) {
+ var type = IR[0];
+ switch (type) {
+ case CONSTRUCT_SAMPLED:
+ return this.constructSampledFromIR(IR);
+ case CONSTRUCT_INTERPOLATED:
+ return this.constructInterpolatedFromIR(IR);
+ case CONSTRUCT_STICHED:
+ return this.constructStichedFromIR(IR);
+ //case CONSTRUCT_POSTSCRIPT:
+ default:
+ return this.constructPostScriptFromIR(IR);
+ }
+ },
+
+ parse: function PDFFunction_parse(xref, fn) {
+ var IR = this.getIR(xref, fn);
+ return this.fromIR(IR);
+ },
+
+ constructSampled: function PDFFunction_constructSampled(str, dict) {
+ function toMultiArray(arr) {
+ var inputLength = arr.length;
+ var outputLength = arr.length / 2;
+ var out = [];
+ var index = 0;
+ for (var i = 0; i < inputLength; i += 2) {
+ out[index] = [arr[i], arr[i + 1]];
+ ++index;
+ }
+ return out;
+ }
+ var domain = dict.get('Domain');
+ var range = dict.get('Range');
+
+ if (!domain || !range)
+ error('No domain or range');
+
+ var inputSize = domain.length / 2;
+ var outputSize = range.length / 2;
+
+ domain = toMultiArray(domain);
+ range = toMultiArray(range);
+
+ var size = dict.get('Size');
+ var bps = dict.get('BitsPerSample');
+ var order = dict.get('Order') || 1;
+ if (order !== 1) {
+ // No description how cubic spline interpolation works in PDF32000:2008
+ // As in poppler, ignoring order, linear interpolation may work as good
+ info('No support for cubic spline interpolation: ' + order);
+ }
+
+ var encode = dict.get('Encode');
+ if (!encode) {
+ encode = [];
+ for (var i = 0; i < inputSize; ++i) {
+ encode.push(0);
+ encode.push(size[i] - 1);
+ }
+ }
+ encode = toMultiArray(encode);
+
+ var decode = dict.get('Decode');
+ if (!decode)
+ decode = range;
+ else
+ decode = toMultiArray(decode);
+
+ var samples = this.getSampleArray(size, outputSize, bps, str);
+
+ return [
+ CONSTRUCT_SAMPLED, inputSize, domain, encode, decode, samples, size,
+ outputSize, Math.pow(2, bps) - 1, range
+ ];
+ },
+
+ constructSampledFromIR: function PDFFunction_constructSampledFromIR(IR) {
+ // See chapter 3, page 109 of the PDF reference
+ function interpolate(x, xmin, xmax, ymin, ymax) {
+ return ymin + ((x - xmin) * ((ymax - ymin) / (xmax - xmin)));
+ }
+
+ return function constructSampledFromIRResult(args) {
+ // See chapter 3, page 110 of the PDF reference.
+ var m = IR[1];
+ var domain = IR[2];
+ var encode = IR[3];
+ var decode = IR[4];
+ var samples = IR[5];
+ var size = IR[6];
+ var n = IR[7];
+ var mask = IR[8];
+ var range = IR[9];
+
+ if (m != args.length)
+ error('Incorrect number of arguments: ' + m + ' != ' +
+ args.length);
+
+ var x = args;
+
+ // Building the cube vertices: its part and sample index
+ // http://rjwagner49.com/Mathematics/Interpolation.pdf
+ var cubeVertices = 1 << m;
+ var cubeN = new Float64Array(cubeVertices);
+ var cubeVertex = new Uint32Array(cubeVertices);
+ for (var j = 0; j < cubeVertices; j++)
+ cubeN[j] = 1;
+
+ var k = n, pos = 1;
+ // Map x_i to y_j for 0 <= i < m using the sampled function.
+ for (var i = 0; i < m; ++i) {
+ // x_i' = min(max(x_i, Domain_2i), Domain_2i+1)
+ var domain_2i = domain[i][0];
+ var domain_2i_1 = domain[i][1];
+ var xi = Math.min(Math.max(x[i], domain_2i), domain_2i_1);
+
+ // e_i = Interpolate(x_i', Domain_2i, Domain_2i+1,
+ // Encode_2i, Encode_2i+1)
+ var e = interpolate(xi, domain_2i, domain_2i_1,
+ encode[i][0], encode[i][1]);
+
+ // e_i' = min(max(e_i, 0), Size_i - 1)
+ var size_i = size[i];
+ e = Math.min(Math.max(e, 0), size_i - 1);
+
+ // Adjusting the cube: N and vertex sample index
+ var e0 = e < size_i - 1 ? Math.floor(e) : e - 1; // e1 = e0 + 1;
+ var n0 = e0 + 1 - e; // (e1 - e) / (e1 - e0);
+ var n1 = e - e0; // (e - e0) / (e1 - e0);
+ var offset0 = e0 * k;
+ var offset1 = offset0 + k; // e1 * k
+ for (var j = 0; j < cubeVertices; j++) {
+ if (j & pos) {
+ cubeN[j] *= n1;
+ cubeVertex[j] += offset1;
+ } else {
+ cubeN[j] *= n0;
+ cubeVertex[j] += offset0;
+ }
+ }
+
+ k *= size_i;
+ pos <<= 1;
+ }
+
+ var y = new Float64Array(n);
+ for (var j = 0; j < n; ++j) {
+ // Sum all cube vertices' samples portions
+ var rj = 0;
+ for (var i = 0; i < cubeVertices; i++)
+ rj += samples[cubeVertex[i] + j] * cubeN[i];
+
+ // r_j' = Interpolate(r_j, 0, 2^BitsPerSample - 1,
+ // Decode_2j, Decode_2j+1)
+ rj = interpolate(rj, 0, 1, decode[j][0], decode[j][1]);
+
+ // y_j = min(max(r_j, range_2j), range_2j+1)
+ y[j] = Math.min(Math.max(rj, range[j][0]), range[j][1]);
+ }
+
+ return y;
+ };
+ },
+
+ constructInterpolated: function PDFFunction_constructInterpolated(str,
+ dict) {
+ var c0 = dict.get('C0') || [0];
+ var c1 = dict.get('C1') || [1];
+ var n = dict.get('N');
+
+ if (!isArray(c0) || !isArray(c1))
+ error('Illegal dictionary for interpolated function');
+
+ var length = c0.length;
+ var diff = [];
+ for (var i = 0; i < length; ++i)
+ diff.push(c1[i] - c0[i]);
+
+ return [CONSTRUCT_INTERPOLATED, c0, diff, n];
+ },
+
+ constructInterpolatedFromIR:
+ function PDFFunction_constructInterpolatedFromIR(IR) {
+ var c0 = IR[1];
+ var diff = IR[2];
+ var n = IR[3];
+
+ var length = diff.length;
+
+ return function constructInterpolatedFromIRResult(args) {
+ var x = n == 1 ? args[0] : Math.pow(args[0], n);
+
+ var out = [];
+ for (var j = 0; j < length; ++j)
+ out.push(c0[j] + (x * diff[j]));
+
+ return out;
+
+ };
+ },
+
+ constructStiched: function PDFFunction_constructStiched(fn, dict, xref) {
+ var domain = dict.get('Domain');
+
+ if (!domain)
+ error('No domain');
+
+ var inputSize = domain.length / 2;
+ if (inputSize != 1)
+ error('Bad domain for stiched function');
+
+ var fnRefs = dict.get('Functions');
+ var fns = [];
+ for (var i = 0, ii = fnRefs.length; i < ii; ++i)
+ fns.push(PDFFunction.getIR(xref, xref.fetchIfRef(fnRefs[i])));
+
+ var bounds = dict.get('Bounds');
+ var encode = dict.get('Encode');
+
+ return [CONSTRUCT_STICHED, domain, bounds, encode, fns];
+ },
+
+ constructStichedFromIR: function PDFFunction_constructStichedFromIR(IR) {
+ var domain = IR[1];
+ var bounds = IR[2];
+ var encode = IR[3];
+ var fnsIR = IR[4];
+ var fns = [];
+
+ for (var i = 0, ii = fnsIR.length; i < ii; i++) {
+ fns.push(PDFFunction.fromIR(fnsIR[i]));
+ }
+
+ return function constructStichedFromIRResult(args) {
+ var clip = function constructStichedFromIRClip(v, min, max) {
+ if (v > max)
+ v = max;
+ else if (v < min)
+ v = min;
+ return v;
+ };
+
+ // clip to domain
+ var v = clip(args[0], domain[0], domain[1]);
+ // calulate which bound the value is in
+ for (var i = 0, ii = bounds.length; i < ii; ++i) {
+ if (v < bounds[i])
+ break;
+ }
+
+ // encode value into domain of function
+ var dmin = domain[0];
+ if (i > 0)
+ dmin = bounds[i - 1];
+ var dmax = domain[1];
+ if (i < bounds.length)
+ dmax = bounds[i];
+
+ var rmin = encode[2 * i];
+ var rmax = encode[2 * i + 1];
+
+ var v2 = rmin + (v - dmin) * (rmax - rmin) / (dmax - dmin);
+
+ // call the appropropriate function
+ return fns[i]([v2]);
+ };
+ },
+
+ constructPostScript: function PDFFunction_constructPostScript(fn, dict,
+ xref) {
+ var domain = dict.get('Domain');
+ var range = dict.get('Range');
+
+ if (!domain)
+ error('No domain.');
+
+ if (!range)
+ error('No range.');
+
+ var lexer = new PostScriptLexer(fn);
+ var parser = new PostScriptParser(lexer);
+ var code = parser.parse();
+
+ return [CONSTRUCT_POSTSCRIPT, domain, range, code];
+ },
+
+ constructPostScriptFromIR: function PDFFunction_constructPostScriptFromIR(
+ IR) {
+ var domain = IR[1];
+ var range = IR[2];
+ var code = IR[3];
+ var numOutputs = range.length / 2;
+ var evaluator = new PostScriptEvaluator(code);
+ // Cache the values for a big speed up, the cache size is limited though
+ // since the number of possible values can be huge from a PS function.
+ var cache = new FunctionCache();
+ return function constructPostScriptFromIRResult(args) {
+ var initialStack = [];
+ for (var i = 0, ii = (domain.length / 2); i < ii; ++i) {
+ initialStack.push(args[i]);
+ }
+
+ var key = initialStack.join('_');
+ if (cache.has(key))
+ return cache.get(key);
+
+ var stack = evaluator.execute(initialStack);
+ var transformed = [];
+ for (i = numOutputs - 1; i >= 0; --i) {
+ var out = stack.pop();
+ var rangeIndex = 2 * i;
+ if (out < range[rangeIndex])
+ out = range[rangeIndex];
+ else if (out > range[rangeIndex + 1])
+ out = range[rangeIndex + 1];
+ transformed[i] = out;
+ }
+ cache.set(key, transformed);
+ return transformed;
+ };
+ }
+ };
+})();
+
+var FunctionCache = (function FunctionCacheClosure() {
+ // Of 10 PDF's with type4 functions the maxium number of distinct values seen
+ // was 256. This still may need some tweaking in the future though.
+ var MAX_CACHE_SIZE = 1024;
+ function FunctionCache() {
+ this.cache = {};
+ this.total = 0;
+ }
+ FunctionCache.prototype = {
+ has: function FunctionCache_has(key) {
+ return key in this.cache;
+ },
+ get: function FunctionCache_get(key) {
+ return this.cache[key];
+ },
+ set: function FunctionCache_set(key, value) {
+ if (this.total < MAX_CACHE_SIZE) {
+ this.cache[key] = value;
+ this.total++;
+ }
+ }
+ };
+ return FunctionCache;
+})();
+
+var PostScriptStack = (function PostScriptStackClosure() {
+ var MAX_STACK_SIZE = 100;
+ function PostScriptStack(initialStack) {
+ this.stack = initialStack || [];
+ }
+
+ PostScriptStack.prototype = {
+ push: function PostScriptStack_push(value) {
+ if (this.stack.length >= MAX_STACK_SIZE)
+ error('PostScript function stack overflow.');
+ this.stack.push(value);
+ },
+ pop: function PostScriptStack_pop() {
+ if (this.stack.length <= 0)
+ error('PostScript function stack underflow.');
+ return this.stack.pop();
+ },
+ copy: function PostScriptStack_copy(n) {
+ if (this.stack.length + n >= MAX_STACK_SIZE)
+ error('PostScript function stack overflow.');
+ var stack = this.stack;
+ for (var i = stack.length - n, j = n - 1; j >= 0; j--, i++)
+ stack.push(stack[i]);
+ },
+ index: function PostScriptStack_index(n) {
+ this.push(this.stack[this.stack.length - n - 1]);
+ },
+ // rotate the last n stack elements p times
+ roll: function PostScriptStack_roll(n, p) {
+ var stack = this.stack;
+ var l = stack.length - n;
+ var r = stack.length - 1, c = l + (p - Math.floor(p / n) * n), i, j, t;
+ for (i = l, j = r; i < j; i++, j--) {
+ t = stack[i]; stack[i] = stack[j]; stack[j] = t;
+ }
+ for (i = l, j = c - 1; i < j; i++, j--) {
+ t = stack[i]; stack[i] = stack[j]; stack[j] = t;
+ }
+ for (i = c, j = r; i < j; i++, j--) {
+ t = stack[i]; stack[i] = stack[j]; stack[j] = t;
+ }
+ }
+ };
+ return PostScriptStack;
+})();
+var PostScriptEvaluator = (function PostScriptEvaluatorClosure() {
+ function PostScriptEvaluator(operators, operands) {
+ this.operators = operators;
+ this.operands = operands;
+ }
+ PostScriptEvaluator.prototype = {
+ execute: function PostScriptEvaluator_execute(initialStack) {
+ var stack = new PostScriptStack(initialStack);
+ var counter = 0;
+ var operators = this.operators;
+ var length = operators.length;
+ var operator, a, b;
+ while (counter < length) {
+ operator = operators[counter++];
+ if (typeof operator == 'number') {
+ // Operator is really an operand and should be pushed to the stack.
+ stack.push(operator);
+ continue;
+ }
+ switch (operator) {
+ // non standard ps operators
+ case 'jz': // jump if false
+ b = stack.pop();
+ a = stack.pop();
+ if (!a)
+ counter = b;
+ break;
+ case 'j': // jump
+ a = stack.pop();
+ counter = a;
+ break;
+
+ // all ps operators in alphabetical order (excluding if/ifelse)
+ case 'abs':
+ a = stack.pop();
+ stack.push(Math.abs(a));
+ break;
+ case 'add':
+ b = stack.pop();
+ a = stack.pop();
+ stack.push(a + b);
+ break;
+ case 'and':
+ b = stack.pop();
+ a = stack.pop();
+ if (isBool(a) && isBool(b))
+ stack.push(a && b);
+ else
+ stack.push(a & b);
+ break;
+ case 'atan':
+ a = stack.pop();
+ stack.push(Math.atan(a));
+ break;
+ case 'bitshift':
+ b = stack.pop();
+ a = stack.pop();
+ if (a > 0)
+ stack.push(a << b);
+ else
+ stack.push(a >> b);
+ break;
+ case 'ceiling':
+ a = stack.pop();
+ stack.push(Math.ceil(a));
+ break;
+ case 'copy':
+ a = stack.pop();
+ stack.copy(a);
+ break;
+ case 'cos':
+ a = stack.pop();
+ stack.push(Math.cos(a));
+ break;
+ case 'cvi':
+ a = stack.pop() | 0;
+ stack.push(a);
+ break;
+ case 'cvr':
+ // noop
+ break;
+ case 'div':
+ b = stack.pop();
+ a = stack.pop();
+ stack.push(a / b);
+ break;
+ case 'dup':
+ stack.copy(1);
+ break;
+ case 'eq':
+ b = stack.pop();
+ a = stack.pop();
+ stack.push(a == b);
+ break;
+ case 'exch':
+ stack.roll(2, 1);
+ break;
+ case 'exp':
+ b = stack.pop();
+ a = stack.pop();
+ stack.push(Math.pow(a, b));
+ break;
+ case 'false':
+ stack.push(false);
+ break;
+ case 'floor':
+ a = stack.pop();
+ stack.push(Math.floor(a));
+ break;
+ case 'ge':
+ b = stack.pop();
+ a = stack.pop();
+ stack.push(a >= b);
+ break;
+ case 'gt':
+ b = stack.pop();
+ a = stack.pop();
+ stack.push(a > b);
+ break;
+ case 'idiv':
+ b = stack.pop();
+ a = stack.pop();
+ stack.push((a / b) | 0);
+ break;
+ case 'index':
+ a = stack.pop();
+ stack.index(a);
+ break;
+ case 'le':
+ b = stack.pop();
+ a = stack.pop();
+ stack.push(a <= b);
+ break;
+ case 'ln':
+ a = stack.pop();
+ stack.push(Math.log(a));
+ break;
+ case 'log':
+ a = stack.pop();
+ stack.push(Math.log(a) / Math.LN10);
+ break;
+ case 'lt':
+ b = stack.pop();
+ a = stack.pop();
+ stack.push(a < b);
+ break;
+ case 'mod':
+ b = stack.pop();
+ a = stack.pop();
+ stack.push(a % b);
+ break;
+ case 'mul':
+ b = stack.pop();
+ a = stack.pop();
+ stack.push(a * b);
+ break;
+ case 'ne':
+ b = stack.pop();
+ a = stack.pop();
+ stack.push(a != b);
+ break;
+ case 'neg':
+ a = stack.pop();
+ stack.push(-b);
+ break;
+ case 'not':
+ a = stack.pop();
+ if (isBool(a) && isBool(b))
+ stack.push(a && b);
+ else
+ stack.push(a & b);
+ break;
+ case 'or':
+ b = stack.pop();
+ a = stack.pop();
+ if (isBool(a) && isBool(b))
+ stack.push(a || b);
+ else
+ stack.push(a | b);
+ break;
+ case 'pop':
+ stack.pop();
+ break;
+ case 'roll':
+ b = stack.pop();
+ a = stack.pop();
+ stack.roll(a, b);
+ break;
+ case 'round':
+ a = stack.pop();
+ stack.push(Math.round(a));
+ break;
+ case 'sin':
+ a = stack.pop();
+ stack.push(Math.sin(a));
+ break;
+ case 'sqrt':
+ a = stack.pop();
+ stack.push(Math.sqrt(a));
+ break;
+ case 'sub':
+ b = stack.pop();
+ a = stack.pop();
+ stack.push(a - b);
+ break;
+ case 'true':
+ stack.push(true);
+ break;
+ case 'truncate':
+ a = stack.pop();
+ a = a < 0 ? Math.ceil(a) : Math.floor(a);
+ stack.push(a);
+ break;
+ case 'xor':
+ b = stack.pop();
+ a = stack.pop();
+ if (isBool(a) && isBool(b))
+ stack.push(a != b);
+ else
+ stack.push(a ^ b);
+ break;
+ default:
+ error('Unknown operator ' + operator);
+ break;
+ }
+ }
+ return stack.stack;
+ }
+ };
+ return PostScriptEvaluator;
+})();
+
+var PostScriptParser = (function PostScriptParserClosure() {
+ function PostScriptParser(lexer) {
+ this.lexer = lexer;
+ this.operators = [];
+ this.token = null;
+ this.prev = null;
+ }
+ PostScriptParser.prototype = {
+ nextToken: function PostScriptParser_nextToken() {
+ this.prev = this.token;
+ this.token = this.lexer.getToken();
+ },
+ accept: function PostScriptParser_accept(type) {
+ if (this.token.type == type) {
+ this.nextToken();
+ return true;
+ }
+ return false;
+ },
+ expect: function PostScriptParser_expect(type) {
+ if (this.accept(type))
+ return true;
+ error('Unexpected symbol: found ' + this.token.type + ' expected ' +
+ type + '.');
+ },
+ parse: function PostScriptParser_parse() {
+ this.nextToken();
+ this.expect(PostScriptTokenTypes.LBRACE);
+ this.parseBlock();
+ this.expect(PostScriptTokenTypes.RBRACE);
+ return this.operators;
+ },
+ parseBlock: function PostScriptParser_parseBlock() {
+ while (true) {
+ if (this.accept(PostScriptTokenTypes.NUMBER)) {
+ this.operators.push(this.prev.value);
+ } else if (this.accept(PostScriptTokenTypes.OPERATOR)) {
+ this.operators.push(this.prev.value);
+ } else if (this.accept(PostScriptTokenTypes.LBRACE)) {
+ this.parseCondition();
+ } else {
+ return;
+ }
+ }
+ },
+ parseCondition: function PostScriptParser_parseCondition() {
+ // Add two place holders that will be updated later
+ var conditionLocation = this.operators.length;
+ this.operators.push(null, null);
+
+ this.parseBlock();
+ this.expect(PostScriptTokenTypes.RBRACE);
+ if (this.accept(PostScriptTokenTypes.IF)) {
+ // The true block is right after the 'if' so it just falls through on
+ // true else it jumps and skips the true block.
+ this.operators[conditionLocation] = this.operators.length;
+ this.operators[conditionLocation + 1] = 'jz';
+ } else if (this.accept(PostScriptTokenTypes.LBRACE)) {
+ var jumpLocation = this.operators.length;
+ this.operators.push(null, null);
+ var endOfTrue = this.operators.length;
+ this.parseBlock();
+ this.expect(PostScriptTokenTypes.RBRACE);
+ this.expect(PostScriptTokenTypes.IFELSE);
+ // The jump is added at the end of the true block to skip the false
+ // block.
+ this.operators[jumpLocation] = this.operators.length;
+ this.operators[jumpLocation + 1] = 'j';
+
+ this.operators[conditionLocation] = endOfTrue;
+ this.operators[conditionLocation + 1] = 'jz';
+ } else {
+ error('PS Function: error parsing conditional.');
+ }
+ }
+ };
+ return PostScriptParser;
+})();
+
+var PostScriptTokenTypes = {
+ LBRACE: 0,
+ RBRACE: 1,
+ NUMBER: 2,
+ OPERATOR: 3,
+ IF: 4,
+ IFELSE: 5
+};
+
+var PostScriptToken = (function PostScriptTokenClosure() {
+ function PostScriptToken(type, value) {
+ this.type = type;
+ this.value = value;
+ }
+
+ var opCache = {};
+
+ PostScriptToken.getOperator = function PostScriptToken_getOperator(op) {
+ var opValue = opCache[op];
+ if (opValue)
+ return opValue;
+
+ return opCache[op] = new PostScriptToken(PostScriptTokenTypes.OPERATOR, op);
+ };
+
+ PostScriptToken.LBRACE = new PostScriptToken(PostScriptTokenTypes.LBRACE,
+ '{');
+ PostScriptToken.RBRACE = new PostScriptToken(PostScriptTokenTypes.RBRACE,
+ '}');
+ PostScriptToken.IF = new PostScriptToken(PostScriptTokenTypes.IF, 'IF');
+ PostScriptToken.IFELSE = new PostScriptToken(PostScriptTokenTypes.IFELSE,
+ 'IFELSE');
+ return PostScriptToken;
+})();
+
+var PostScriptLexer = (function PostScriptLexerClosure() {
+ function PostScriptLexer(stream) {
+ this.stream = stream;
+ this.nextChar();
+ }
+ PostScriptLexer.prototype = {
+ nextChar: function PostScriptLexer_nextChar() {
+ return (this.currentChar = this.stream.getByte());
+ },
+ getToken: function PostScriptLexer_getToken() {
+ var s = '';
+ var comment = false;
+ var ch = this.currentChar;
+
+ // skip comments
+ while (true) {
+ if (ch < 0) {
+ return EOF;
+ }
+
+ if (comment) {
+ if (ch === 0x0A || ch === 0x0D) {
+ comment = false;
+ }
+ } else if (ch == 0x25) { // '%'
+ comment = true;
+ } else if (!Lexer.isSpace(ch)) {
+ break;
+ }
+ ch = this.nextChar();
+ }
+ switch (ch | 0) {
+ case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: // '0'-'4'
+ case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: // '5'-'9'
+ case 0x2B: case 0x2D: case 0x2E: // '+', '-', '.'
+ return new PostScriptToken(PostScriptTokenTypes.NUMBER,
+ this.getNumber());
+ case 0x7B: // '{'
+ this.nextChar();
+ return PostScriptToken.LBRACE;
+ case 0x7D: // '}'
+ this.nextChar();
+ return PostScriptToken.RBRACE;
+ }
+ // operator
+ var str = String.fromCharCode(ch);
+ while ((ch = this.nextChar()) >= 0 && // and 'A'-'Z', 'a'-'z'
+ ((ch >= 0x41 && ch <= 0x5A) || (ch >= 0x61 && ch <= 0x7A))) {
+ str += String.fromCharCode(ch);
+ }
+ switch (str.toLowerCase()) {
+ case 'if':
+ return PostScriptToken.IF;
+ case 'ifelse':
+ return PostScriptToken.IFELSE;
+ default:
+ return PostScriptToken.getOperator(str);
+ }
+ },
+ getNumber: function PostScriptLexer_getNumber() {
+ var ch = this.currentChar;
+ var str = String.fromCharCode(ch);
+ while ((ch = this.nextChar()) >= 0) {
+ if ((ch >= 0x30 && ch <= 0x39) || // '0'-'9'
+ ch === 0x2D || ch === 0x2E) { // '-', '.'
+ str += String.fromCharCode(ch);
+ } else {
+ break;
+ }
+ }
+ var value = parseFloat(str);
+ if (isNaN(value))
+ error('Invalid floating point number: ' + value);
+ return value;
+ }
+ };
+ return PostScriptLexer;
+})();
+
+
+
+var Annotation = (function AnnotationClosure() {
+ // 12.5.5: Algorithm: Appearance streams
+ function getTransformMatrix(rect, bbox, matrix) {
+ var bounds = Util.getAxialAlignedBoundingBox(bbox, matrix);
+ var minX = bounds[0];
+ var minY = bounds[1];
+ var maxX = bounds[2];
+ var maxY = bounds[3];
+
+ if (minX === maxX || minY === maxY) {
+ // From real-life file, bbox was [0, 0, 0, 0]. In this case,
+ // just apply the transform for rect
+ return [1, 0, 0, 1, rect[0], rect[1]];
+ }
+
+ var xRatio = (rect[2] - rect[0]) / (maxX - minX);
+ var yRatio = (rect[3] - rect[1]) / (maxY - minY);
+ return [
+ xRatio,
+ 0,
+ 0,
+ yRatio,
+ rect[0] - minX * xRatio,
+ rect[1] - minY * yRatio
+ ];
+ }
+
+ function getDefaultAppearance(dict) {
+ var appearanceState = dict.get('AP');
+ if (!isDict(appearanceState)) {
+ return;
+ }
+
+ var appearance;
+ var appearances = appearanceState.get('N');
+ if (isDict(appearances)) {
+ var as = dict.get('AS');
+ if (as && appearances.has(as.name)) {
+ appearance = appearances.get(as.name);
+ }
+ } else {
+ appearance = appearances;
+ }
+ return appearance;
+ }
+
+ function Annotation(params) {
+ if (params.data) {
+ this.data = params.data;
+ return;
+ }
+
+ var dict = params.dict;
+ var data = this.data = {};
+
+ data.subtype = dict.get('Subtype').name;
+ var rect = dict.get('Rect');
+ data.rect = Util.normalizeRect(rect);
+ data.annotationFlags = dict.get('F');
+
+ var color = dict.get('C');
+ if (isArray(color) && color.length === 3) {
+ // TODO(mack): currently only supporting rgb; need support different
+ // colorspaces
+ data.color = color;
+ } else {
+ data.color = [0, 0, 0];
+ }
+
+ // Some types of annotations have border style dict which has more
+ // info than the border array
+ if (dict.has('BS')) {
+ var borderStyle = dict.get('BS');
+ data.borderWidth = borderStyle.has('W') ? borderStyle.get('W') : 1;
+ } else {
+ var borderArray = dict.get('Border') || [0, 0, 1];
+ data.borderWidth = borderArray[2] || 0;
+
+ // TODO: implement proper support for annotations with line dash patterns.
+ var dashArray = borderArray[3];
+ if (dashArray && isArray(dashArray)) {
+ var dashArrayLength = dashArray.length;
+ if (dashArrayLength > 0) {
+ // According to the PDF specification: the elements in a dashArray
+ // shall be numbers that are nonnegative and not all equal to zero.
+ var isInvalid = false;
+ var numPositive = 0;
+ for (var i = 0; i < dashArrayLength; i++) {
+ if (!(+dashArray[i] >= 0)) {
+ isInvalid = true;
+ break;
+ } else if (dashArray[i] > 0) {
+ numPositive++;
+ }
+ }
+ if (isInvalid || numPositive === 0) {
+ data.borderWidth = 0;
+ }
+ }
+ }
+ }
+
+ this.appearance = getDefaultAppearance(dict);
+ data.hasAppearance = !!this.appearance;
+ }
+
+ Annotation.prototype = {
+
+ getData: function Annotation_getData() {
+ return this.data;
+ },
+
+ hasHtml: function Annotation_hasHtml() {
+ return false;
+ },
+
+ getHtmlElement: function Annotation_getHtmlElement(commonObjs) {
+ throw new NotImplementedException(
+ 'getHtmlElement() should be implemented in subclass');
+ },
+
+ // TODO(mack): Remove this, it's not really that helpful.
+ getEmptyContainer: function Annotation_getEmptyContainer(tagName, rect) {
+ assert(!isWorker,
+ 'getEmptyContainer() should be called from main thread');
+
+ rect = rect || this.data.rect;
+ var element = document.createElement(tagName);
+ element.style.width = Math.ceil(rect[2] - rect[0]) + 'px';
+ element.style.height = Math.ceil(rect[3] - rect[1]) + 'px';
+ return element;
+ },
+
+ isViewable: function Annotation_isViewable() {
+ var data = this.data;
+ return !!(
+ data &&
+ (!data.annotationFlags ||
+ !(data.annotationFlags & 0x22)) && // Hidden or NoView
+ data.rect // rectangle is nessessary
+ );
+ },
+
+ loadResources: function(keys) {
+ var promise = new LegacyPromise();
+ this.appearance.dict.getAsync('Resources').then(function(resources) {
+ if (!resources) {
+ promise.resolve();
+ return;
+ }
+ var objectLoader = new ObjectLoader(resources.map,
+ keys,
+ resources.xref);
+ objectLoader.load().then(function() {
+ promise.resolve(resources);
+ });
+ }.bind(this));
+
+ return promise;
+ },
+
+ getOperatorList: function Annotation_getToOperatorList(evaluator) {
+
+ var promise = new LegacyPromise();
+
+ if (!this.appearance) {
+ promise.resolve(new OperatorList());
+ return promise;
+ }
+
+ var data = this.data;
+
+ var appearanceDict = this.appearance.dict;
+ var resourcesPromise = this.loadResources([
+ 'ExtGState',
+ 'ColorSpace',
+ 'Pattern',
+ 'Shading',
+ 'XObject',
+ 'Font'
+ // ProcSet
+ // Properties
+ ]);
+ var bbox = appearanceDict.get('BBox') || [0, 0, 1, 1];
+ var matrix = appearanceDict.get('Matrix') || [1, 0, 0, 1, 0 ,0];
+ var transform = getTransformMatrix(data.rect, bbox, matrix);
+
+ var border = data.border;
+
+ resourcesPromise.then(function(resources) {
+ var opList = new OperatorList();
+ opList.addOp(OPS.beginAnnotation, [data.rect, transform, matrix]);
+ evaluator.getOperatorList(this.appearance, resources, opList);
+ opList.addOp(OPS.endAnnotation, []);
+ promise.resolve(opList);
+ }.bind(this));
+
+ return promise;
+ }
+ };
+
+ Annotation.getConstructor =
+ function Annotation_getConstructor(subtype, fieldType) {
+
+ if (!subtype) {
+ return;
+ }
+
+ // TODO(mack): Implement FreeText annotations
+ if (subtype === 'Link') {
+ return LinkAnnotation;
+ } else if (subtype === 'Text') {
+ return TextAnnotation;
+ } else if (subtype === 'Widget') {
+ if (!fieldType) {
+ return;
+ }
+
+ if (fieldType === 'Tx') {
+ return TextWidgetAnnotation;
+ } else {
+ return WidgetAnnotation;
+ }
+ } else {
+ return Annotation;
+ }
+ };
+
+ // TODO(mack): Support loading annotation from data
+ Annotation.fromData = function Annotation_fromData(data) {
+ var subtype = data.subtype;
+ var fieldType = data.fieldType;
+ var Constructor = Annotation.getConstructor(subtype, fieldType);
+ if (Constructor) {
+ return new Constructor({ data: data });
+ }
+ };
+
+ Annotation.fromRef = function Annotation_fromRef(xref, ref) {
+
+ var dict = xref.fetchIfRef(ref);
+ if (!isDict(dict)) {
+ return;
+ }
+
+ var subtype = dict.get('Subtype');
+ subtype = isName(subtype) ? subtype.name : '';
+ if (!subtype) {
+ return;
+ }
+
+ var fieldType = Util.getInheritableProperty(dict, 'FT');
+ fieldType = isName(fieldType) ? fieldType.name : '';
+
+ var Constructor = Annotation.getConstructor(subtype, fieldType);
+ if (!Constructor) {
+ return;
+ }
+
+ var params = {
+ dict: dict,
+ ref: ref,
+ };
+
+ var annotation = new Constructor(params);
+
+ if (annotation.isViewable()) {
+ return annotation;
+ } else {
+ warn('unimplemented annotation type: ' + subtype);
+ }
+ };
+
+ Annotation.appendToOperatorList = function Annotation_appendToOperatorList(
+ annotations, opList, pdfManager, partialEvaluator) {
+
+ function reject(e) {
+ annotationsReadyPromise.reject(e);
+ }
+
+ var annotationsReadyPromise = new LegacyPromise();
+
+ var annotationPromises = [];
+ for (var i = 0, n = annotations.length; i < n; ++i) {
+ annotationPromises.push(annotations[i].getOperatorList(partialEvaluator));
+ }
+ Promise.all(annotationPromises).then(function(datas) {
+ opList.addOp(OPS.beginAnnotations, []);
+ for (var i = 0, n = datas.length; i < n; ++i) {
+ var annotOpList = datas[i];
+ opList.addOpList(annotOpList);
+ }
+ opList.addOp(OPS.endAnnotations, []);
+ annotationsReadyPromise.resolve();
+ }, reject);
+
+ return annotationsReadyPromise;
+ };
+
+ return Annotation;
+})();
+PDFJS.Annotation = Annotation;
+
+
+var WidgetAnnotation = (function WidgetAnnotationClosure() {
+
+ function WidgetAnnotation(params) {
+ Annotation.call(this, params);
+
+ if (params.data) {
+ return;
+ }
+
+ var dict = params.dict;
+ var data = this.data;
+
+ data.fieldValue = stringToPDFString(
+ Util.getInheritableProperty(dict, 'V') || '');
+ data.alternativeText = stringToPDFString(dict.get('TU') || '');
+ data.defaultAppearance = Util.getInheritableProperty(dict, 'DA') || '';
+ var fieldType = Util.getInheritableProperty(dict, 'FT');
+ data.fieldType = isName(fieldType) ? fieldType.name : '';
+ data.fieldFlags = Util.getInheritableProperty(dict, 'Ff') || 0;
+ this.fieldResources = Util.getInheritableProperty(dict, 'DR') || new Dict();
+
+ // Building the full field name by collecting the field and
+ // its ancestors 'T' data and joining them using '.'.
+ var fieldName = [];
+ var namedItem = dict;
+ var ref = params.ref;
+ while (namedItem) {
+ var parent = namedItem.get('Parent');
+ var parentRef = namedItem.getRaw('Parent');
+ var name = namedItem.get('T');
+ if (name) {
+ fieldName.unshift(stringToPDFString(name));
+ } else {
+ // The field name is absent, that means more than one field
+ // with the same name may exist. Replacing the empty name
+ // with the '`' plus index in the parent's 'Kids' array.
+ // This is not in the PDF spec but necessary to id the
+ // the input controls.
+ var kids = parent.get('Kids');
+ var j, jj;
+ for (j = 0, jj = kids.length; j < jj; j++) {
+ var kidRef = kids[j];
+ if (kidRef.num == ref.num && kidRef.gen == ref.gen)
+ break;
+ }
+ fieldName.unshift('`' + j);
+ }
+ namedItem = parent;
+ ref = parentRef;
+ }
+ data.fullName = fieldName.join('.');
+ }
+
+ var parent = Annotation.prototype;
+ Util.inherit(WidgetAnnotation, Annotation, {
+ isViewable: function WidgetAnnotation_isViewable() {
+ if (this.data.fieldType === 'Sig') {
+ warn('unimplemented annotation type: Widget signature');
+ return false;
+ }
+
+ return parent.isViewable.call(this);
+ }
+ });
+
+ return WidgetAnnotation;
+})();
+
+var TextWidgetAnnotation = (function TextWidgetAnnotationClosure() {
+ function TextWidgetAnnotation(params) {
+ WidgetAnnotation.call(this, params);
+
+ if (params.data) {
+ return;
+ }
+
+ this.data.textAlignment = Util.getInheritableProperty(params.dict, 'Q');
+ }
+
+ // TODO(mack): This dupes some of the logic in CanvasGraphics.setFont()
+ function setTextStyles(element, item, fontObj) {
+
+ var style = element.style;
+ style.fontSize = item.fontSize + 'px';
+ style.direction = item.fontDirection < 0 ? 'rtl': 'ltr';
+
+ if (!fontObj) {
+ return;
+ }
+
+ style.fontWeight = fontObj.black ?
+ (fontObj.bold ? 'bolder' : 'bold') :
+ (fontObj.bold ? 'bold' : 'normal');
+ style.fontStyle = fontObj.italic ? 'italic' : 'normal';
+
+ var fontName = fontObj.loadedName;
+ var fontFamily = fontName ? '"' + fontName + '", ' : '';
+ // Use a reasonable default font if the font doesn't specify a fallback
+ var fallbackName = fontObj.fallbackName || 'Helvetica, sans-serif';
+ style.fontFamily = fontFamily + fallbackName;
+ }
+
+
+ var parent = WidgetAnnotation.prototype;
+ Util.inherit(TextWidgetAnnotation, WidgetAnnotation, {
+ hasHtml: function TextWidgetAnnotation_hasHtml() {
+ return !this.data.hasAppearance && !!this.data.fieldValue;
+ },
+
+ getHtmlElement: function TextWidgetAnnotation_getHtmlElement(commonObjs) {
+ assert(!isWorker, 'getHtmlElement() shall be called from main thread');
+
+ var item = this.data;
+
+ var element = this.getEmptyContainer('div');
+ element.style.display = 'table';
+
+ var content = document.createElement('div');
+ content.textContent = item.fieldValue;
+ var textAlignment = item.textAlignment;
+ content.style.textAlign = ['left', 'center', 'right'][textAlignment];
+ content.style.verticalAlign = 'middle';
+ content.style.display = 'table-cell';
+
+ var fontObj = item.fontRefName ?
+ commonObjs.getData(item.fontRefName) : null;
+ var cssRules = setTextStyles(content, item, fontObj);
+
+ element.appendChild(content);
+
+ return element;
+ },
+
+ getOperatorList: function TextWidgetAnnotation_getOperatorList(evaluator) {
+ if (this.appearance) {
+ return Annotation.prototype.getOperatorList.call(this, evaluator);
+ }
+
+ var promise = new LegacyPromise();
+ var opList = new OperatorList();
+ var data = this.data;
+
+ // Even if there is an appearance stream, ignore it. This is the
+ // behaviour used by Adobe Reader.
+
+ var defaultAppearance = data.defaultAppearance;
+ if (!defaultAppearance) {
+ promise.resolve(opList);
+ return promise;
+ }
+
+ // Include any font resources found in the default appearance
+
+ var stream = new Stream(stringToBytes(defaultAppearance));
+ evaluator.getOperatorList(stream, this.fieldResources, opList);
+ var appearanceFnArray = opList.fnArray;
+ var appearanceArgsArray = opList.argsArray;
+ var fnArray = [];
+ var argsArray = [];
+
+ // TODO(mack): Add support for stroke color
+ data.rgb = [0, 0, 0];
+ // TODO THIS DOESN'T MAKE ANY SENSE SINCE THE fnArray IS EMPTY!
+ for (var i = 0, n = fnArray.length; i < n; ++i) {
+ var fnId = appearanceFnArray[i];
+ var args = appearanceArgsArray[i];
+
+ if (fnId === OPS.setFont) {
+ data.fontRefName = args[0];
+ var size = args[1];
+ if (size < 0) {
+ data.fontDirection = -1;
+ data.fontSize = -size;
+ } else {
+ data.fontDirection = 1;
+ data.fontSize = size;
+ }
+ } else if (fnId === OPS.setFillRGBColor) {
+ data.rgb = args;
+ } else if (fnId === OPS.setFillGray) {
+ var rgbValue = args[0] * 255;
+ data.rgb = [rgbValue, rgbValue, rgbValue];
+ }
+ }
+ promise.resolve(opList);
+ return promise;
+ }
+ });
+
+ return TextWidgetAnnotation;
+})();
+
+var TextAnnotation = (function TextAnnotationClosure() {
+ function TextAnnotation(params) {
+ Annotation.call(this, params);
+
+ if (params.data) {
+ return;
+ }
+
+ var dict = params.dict;
+ var data = this.data;
+
+ var content = dict.get('Contents');
+ var title = dict.get('T');
+ data.content = stringToPDFString(content || '');
+ data.title = stringToPDFString(title || '');
+ data.name = !dict.has('Name') ? 'Note' : dict.get('Name').name;
+ }
+
+ var ANNOT_MIN_SIZE = 10;
+
+ Util.inherit(TextAnnotation, Annotation, {
+
+ getOperatorList: function TextAnnotation_getOperatorList(evaluator) {
+ var promise = new LegacyPromise();
+ promise.resolve(new OperatorList());
+ return promise;
+ },
+
+ hasHtml: function TextAnnotation_hasHtml() {
+ return true;
+ },
+
+ getHtmlElement: function TextAnnotation_getHtmlElement(commonObjs) {
+ assert(!isWorker, 'getHtmlElement() shall be called from main thread');
+
+ var item = this.data;
+ var rect = item.rect;
+
+ // sanity check because of OOo-generated PDFs
+ if ((rect[3] - rect[1]) < ANNOT_MIN_SIZE) {
+ rect[3] = rect[1] + ANNOT_MIN_SIZE;
+ }
+ if ((rect[2] - rect[0]) < ANNOT_MIN_SIZE) {
+ rect[2] = rect[0] + (rect[3] - rect[1]); // make it square
+ }
+
+ var container = this.getEmptyContainer('section', rect);
+ container.className = 'annotText';
+
+ var image = document.createElement('img');
+ image.style.height = container.style.height;
+ var iconName = item.name;
+ image.src = PDFJS.imageResourcesPath + 'annotation-' +
+ iconName.toLowerCase() + '.svg';
+ image.alt = '[{{type}} Annotation]';
+ image.dataset.l10nId = 'text_annotation_type';
+ image.dataset.l10nArgs = JSON.stringify({type: iconName});
+ var content = document.createElement('div');
+ content.setAttribute('hidden', true);
+ var title = document.createElement('h1');
+ var text = document.createElement('p');
+ content.style.left = Math.floor(rect[2] - rect[0]) + 'px';
+ content.style.top = '0px';
+ title.textContent = item.title;
+
+ if (!item.content && !item.title) {
+ content.setAttribute('hidden', true);
+ } else {
+ var e = document.createElement('span');
+ var lines = item.content.split(/(?:\r\n?|\n)/);
+ for (var i = 0, ii = lines.length; i < ii; ++i) {
+ var line = lines[i];
+ e.appendChild(document.createTextNode(line));
+ if (i < (ii - 1))
+ e.appendChild(document.createElement('br'));
+ }
+ text.appendChild(e);
+
+ var showAnnotation = function showAnnotation() {
+ container.style.zIndex += 1;
+ content.removeAttribute('hidden');
+ };
+
+ var hideAnnotation = function hideAnnotation(e) {
+ if (e.toElement || e.relatedTarget) { // No context menu is used
+ container.style.zIndex -= 1;
+ content.setAttribute('hidden', true);
+ }
+ };
+
+ content.addEventListener('mouseover', showAnnotation, false);
+ content.addEventListener('mouseout', hideAnnotation, false);
+ image.addEventListener('mouseover', showAnnotation, false);
+ image.addEventListener('mouseout', hideAnnotation, false);
+ }
+
+ content.appendChild(title);
+ content.appendChild(text);
+ container.appendChild(image);
+ container.appendChild(content);
+
+ return container;
+ }
+ });
+
+ return TextAnnotation;
+})();
+
+var LinkAnnotation = (function LinkAnnotationClosure() {
+ function LinkAnnotation(params) {
+ Annotation.call(this, params);
+
+ if (params.data) {
+ return;
+ }
+
+ var dict = params.dict;
+ var data = this.data;
+
+ var action = dict.get('A');
+ if (action) {
+ var linkType = action.get('S').name;
+ if (linkType === 'URI') {
+ var url = addDefaultProtocolToUrl(action.get('URI'));
+ // TODO: pdf spec mentions urls can be relative to a Base
+ // entry in the dictionary.
+ if (!isValidUrl(url, false)) {
+ url = '';
+ }
+ data.url = url;
+ } else if (linkType === 'GoTo') {
+ data.dest = action.get('D');
+ } else if (linkType === 'GoToR') {
+ var urlDict = action.get('F');
+ if (isDict(urlDict)) {
+ // We assume that the 'url' is a Filspec dictionary
+ // and fetch the url without checking any further
+ url = urlDict.get('F') || '';
+ }
+
+ // TODO: pdf reference says that GoToR
+ // can also have 'NewWindow' attribute
+ if (!isValidUrl(url, false)) {
+ url = '';
+ }
+ data.url = url;
+ data.dest = action.get('D');
+ } else if (linkType === 'Named') {
+ data.action = action.get('N').name;
+ } else {
+ warn('unrecognized link type: ' + linkType);
+ }
+ } else if (dict.has('Dest')) {
+ // simple destination link
+ var dest = dict.get('Dest');
+ data.dest = isName(dest) ? dest.name : dest;
+ }
+ }
+
+ // Lets URLs beginning with 'www.' default to using the 'http://' protocol.
+ function addDefaultProtocolToUrl(url) {
+ if (url.indexOf('www.') === 0) {
+ return ('http://' + url);
+ }
+ return url;
+ }
+
+ Util.inherit(LinkAnnotation, Annotation, {
+ hasOperatorList: function LinkAnnotation_hasOperatorList() {
+ return false;
+ },
+
+ hasHtml: function LinkAnnotation_hasHtml() {
+ return true;
+ },
+
+ getHtmlElement: function LinkAnnotation_getHtmlElement(commonObjs) {
+ var rect = this.data.rect;
+ var element = document.createElement('a');
+ var borderWidth = this.data.borderWidth;
+
+ element.style.borderWidth = borderWidth + 'px';
+ var color = this.data.color;
+ var rgb = [];
+ for (var i = 0; i < 3; ++i) {
+ rgb[i] = Math.round(color[i] * 255);
+ }
+ element.style.borderColor = Util.makeCssRgb(rgb);
+ element.style.borderStyle = 'solid';
+
+ var width = rect[2] - rect[0] - 2 * borderWidth;
+ var height = rect[3] - rect[1] - 2 * borderWidth;
+ element.style.width = width + 'px';
+ element.style.height = height + 'px';
+
+ element.href = this.data.url || '';
+ return element;
+ }
+ });
+
+ return LinkAnnotation;
+})();
+
+
+/**
+ * The maximum allowed image size in total pixels e.g. width * height. Images
+ * above this value will not be drawn. Use -1 for no limit.
+ * @var {Number}
+ */
+PDFJS.maxImageSize = PDFJS.maxImageSize === undefined ? -1 : PDFJS.maxImageSize;
+
+/**
+ * By default fonts are converted to OpenType fonts and loaded via font face
+ * rules. If disabled, the font will be rendered using a built in font renderer
+ * that constructs the glyphs with primitive path commands.
+ * @var {Boolean}
+ */
+PDFJS.disableFontFace = PDFJS.disableFontFace === undefined ?
+ false : PDFJS.disableFontFace;
+
+/**
+ * Path for image resources, mainly for annotation icons. Include trailing
+ * slash.
+ * @var {String}
+ */
+PDFJS.imageResourcesPath = PDFJS.imageResourcesPath === undefined ?
+ '' : PDFJS.imageResourcesPath;
+
+/**
+ * Disable the web worker and run all code on the main thread. This will happen
+ * automatically if the browser doesn't support workers or sending typed arrays
+ * to workers.
+ * @var {Boolean}
+ */
+PDFJS.disableWorker = PDFJS.disableWorker === undefined ?
+ false : PDFJS.disableWorker;
+
+/**
+ * Path and filename of the worker file. Required when the worker is enabled in
+ * development mode. If unspecified in the production build, the worker will be
+ * loaded based on the location of the pdf.js file.
+ * @var {String}
+ */
+PDFJS.workerSrc = PDFJS.workerSrc === undefined ? null : PDFJS.workerSrc;
+
+/**
+ * Disable range request loading of PDF files. When enabled and if the server
+ * supports partial content requests then the PDF will be fetched in chunks.
+ * Enabled (false) by default.
+ * @var {Boolean}
+ */
+PDFJS.disableRange = PDFJS.disableRange === undefined ?
+ false : PDFJS.disableRange;
+
+/**
+ * Disable pre-fetching of PDF file data. When range requests are enabled PDF.js
+ * will automatically keep fetching more data even if it isn't needed to display
+ * the current page. This default behavior can be disabled.
+ * @var {Boolean}
+ */
+PDFJS.disableAutoFetch = PDFJS.disableAutoFetch === undefined ?
+ false : PDFJS.disableAutoFetch;
+
+/**
+ * Enables special hooks for debugging PDF.js.
+ * @var {Boolean}
+ */
+PDFJS.pdfBug = PDFJS.pdfBug === undefined ? false : PDFJS.pdfBug;
+
+/**
+ * Enables transfer usage in postMessage for ArrayBuffers.
+ * @var {boolean}
+ */
+PDFJS.postMessageTransfers = PDFJS.postMessageTransfers === undefined ?
+ true : PDFJS.postMessageTransfers;
+
+/**
+ * Disables URL.createObjectURL usage.
+ * @var {boolean}
+ */
+PDFJS.disableCreateObjectURL = PDFJS.disableCreateObjectURL === undefined ?
+ false : PDFJS.disableCreateObjectURL;
+
+/**
+ * Controls the logging level.
+ * The constants from PDFJS.VERBOSITY_LEVELS should be used:
+ * - errors
+ * - warnings [default]
+ * - infos
+ * @var {Number}
+ */
+PDFJS.verbosity = PDFJS.verbosity === undefined ?
+ PDFJS.VERBOSITY_LEVELS.warnings : PDFJS.verbosity;
+
+/**
+ * This is the main entry point for loading a PDF and interacting with it.
+ * NOTE: If a URL is used to fetch the PDF data a standard XMLHttpRequest(XHR)
+ * is used, which means it must follow the same origin rules that any XHR does
+ * e.g. No cross domain requests without CORS.
+ *
+ * @param {string|TypedAray|object} source Can be an url to where a PDF is
+ * located, a typed array (Uint8Array) already populated with data or
+ * and parameter object with the following possible fields:
+ * - url - The URL of the PDF.
+ * - data - A typed array with PDF data.
+ * - httpHeaders - Basic authentication headers.
+ * - withCredentials - Indicates whether or not cross-site Access-Control
+ * requests should be made using credentials such as
+ * cookies or authorization headers. The default is false.
+ * - password - For decrypting password-protected PDFs.
+ * - initialData - A typed array with the first portion or all of the pdf data.
+ * Used by the extension since some data is already loaded
+ * before the switch to range requests.
+ *
+ * @param {object} pdfDataRangeTransport is optional. It is used if you want
+ * to manually serve range requests for data in the PDF. See viewer.js for
+ * an example of pdfDataRangeTransport's interface.
+ *
+ * @param {function} passwordCallback is optional. It is used to request a
+ * password if wrong or no password was provided. The callback receives two
+ * parameters: function that needs to be called with new password and reason
+ * (see {PasswordResponses}).
+ *
+ * @return {Promise} A promise that is resolved with {PDFDocumentProxy} object.
+ */
+PDFJS.getDocument = function getDocument(source,
+ pdfDataRangeTransport,
+ passwordCallback,
+ progressCallback) {
+ var workerInitializedPromise, workerReadyPromise, transport;
+
+ if (typeof source === 'string') {
+ source = { url: source };
+ } else if (isArrayBuffer(source)) {
+ source = { data: source };
+ } else if (typeof source !== 'object') {
+ error('Invalid parameter in getDocument, need either Uint8Array, ' +
+ 'string or a parameter object');
+ }
+
+ if (!source.url && !source.data)
+ error('Invalid parameter array, need either .data or .url');
+
+ // copy/use all keys as is except 'url' -- full path is required
+ var params = {};
+ for (var key in source) {
+ if (key === 'url' && typeof window !== 'undefined') {
+ params[key] = combineUrl(window.location.href, source[key]);
+ continue;
+ }
+ params[key] = source[key];
+ }
+
+ workerInitializedPromise = new PDFJS.LegacyPromise();
+ workerReadyPromise = new PDFJS.LegacyPromise();
+ transport = new WorkerTransport(workerInitializedPromise,
+ workerReadyPromise, pdfDataRangeTransport, progressCallback);
+ workerInitializedPromise.then(function transportInitialized() {
+ transport.passwordCallback = passwordCallback;
+ transport.fetchDocument(params);
+ });
+ return workerReadyPromise;
+};
+
+/**
+ * Proxy to a PDFDocument in the worker thread. Also, contains commonly used
+ * properties that can be read synchronously.
+ */
+var PDFDocumentProxy = (function PDFDocumentProxyClosure() {
+ function PDFDocumentProxy(pdfInfo, transport) {
+ this.pdfInfo = pdfInfo;
+ this.transport = transport;
+ }
+ PDFDocumentProxy.prototype = {
+ /**
+ * @return {number} Total number of pages the PDF contains.
+ */
+ get numPages() {
+ return this.pdfInfo.numPages;
+ },
+ /**
+ * @return {string} A unique ID to identify a PDF. Not guaranteed to be
+ * unique.
+ */
+ get fingerprint() {
+ return this.pdfInfo.fingerprint;
+ },
+ /**
+ * @return {boolean} true if embedded document fonts are in use. Will be
+ * set during rendering of the pages.
+ */
+ get embeddedFontsUsed() {
+ return this.transport.embeddedFontsUsed;
+ },
+ /**
+ * @param {number} The page number to get. The first page is 1.
+ * @return {Promise} A promise that is resolved with a {PDFPageProxy}
+ * object.
+ */
+ getPage: function PDFDocumentProxy_getPage(number) {
+ return this.transport.getPage(number);
+ },
+ /**
+ * @param {object} Must have 'num' and 'gen' properties.
+ * @return {Promise} A promise that is resolved with the page index that is
+ * associated with the reference.
+ */
+ getPageIndex: function PDFDocumentProxy_getPageIndex(ref) {
+ return this.transport.getPageIndex(ref);
+ },
+ /**
+ * @return {Promise} A promise that is resolved with a lookup table for
+ * mapping named destinations to reference numbers.
+ */
+ getDestinations: function PDFDocumentProxy_getDestinations() {
+ return this.transport.getDestinations();
+ },
+ /**
+ * @return {Promise} A promise that is resolved with an array of all the
+ * JavaScript strings in the name tree.
+ */
+ getJavaScript: function PDFDocumentProxy_getJavaScript() {
+ var promise = new PDFJS.LegacyPromise();
+ var js = this.pdfInfo.javaScript;
+ promise.resolve(js);
+ return promise;
+ },
+ /**
+ * @return {Promise} A promise that is resolved with an {array} that is a
+ * tree outline (if it has one) of the PDF. The tree is in the format of:
+ * [
+ * {
+ * title: string,
+ * bold: boolean,
+ * italic: boolean,
+ * color: rgb array,
+ * dest: dest obj,
+ * items: array of more items like this
+ * },
+ * ...
+ * ].
+ */
+ getOutline: function PDFDocumentProxy_getOutline() {
+ var promise = new PDFJS.LegacyPromise();
+ var outline = this.pdfInfo.outline;
+ promise.resolve(outline);
+ return promise;
+ },
+ /**
+ * @return {Promise} A promise that is resolved with an {object} that has
+ * info and metadata properties. Info is an {object} filled with anything
+ * available in the information dictionary and similarly metadata is a
+ * {Metadata} object with information from the metadata section of the PDF.
+ */
+ getMetadata: function PDFDocumentProxy_getMetadata() {
+ var promise = new PDFJS.LegacyPromise();
+ var info = this.pdfInfo.info;
+ var metadata = this.pdfInfo.metadata;
+ promise.resolve({
+ info: info,
+ metadata: metadata ? new PDFJS.Metadata(metadata) : null
+ });
+ return promise;
+ },
+ isEncrypted: function PDFDocumentProxy_isEncrypted() {
+ var promise = new PDFJS.LegacyPromise();
+ promise.resolve(this.pdfInfo.encrypted);
+ return promise;
+ },
+ /**
+ * @return {Promise} A promise that is resolved with a TypedArray that has
+ * the raw data from the PDF.
+ */
+ getData: function PDFDocumentProxy_getData() {
+ var promise = new PDFJS.LegacyPromise();
+ this.transport.getData(promise);
+ return promise;
+ },
+ /**
+ * @return {Promise} A promise that is resolved when the document's data
+ * is loaded
+ */
+ dataLoaded: function PDFDocumentProxy_dataLoaded() {
+ return this.transport.dataLoaded();
+ },
+ cleanup: function PDFDocumentProxy_cleanup() {
+ this.transport.startCleanup();
+ },
+ destroy: function PDFDocumentProxy_destroy() {
+ this.transport.destroy();
+ }
+ };
+ return PDFDocumentProxy;
+})();
+
+var PDFPageProxy = (function PDFPageProxyClosure() {
+ function PDFPageProxy(pageInfo, transport) {
+ this.pageInfo = pageInfo;
+ this.transport = transport;
+ this.stats = new StatTimer();
+ this.stats.enabled = !!globalScope.PDFJS.enableStats;
+ this.commonObjs = transport.commonObjs;
+ this.objs = new PDFObjects();
+ this.receivingOperatorList = false;
+ this.cleanupAfterRender = false;
+ this.pendingDestroy = false;
+ this.renderTasks = [];
+ }
+ PDFPageProxy.prototype = {
+ /**
+ * @return {number} Page number of the page. First page is 1.
+ */
+ get pageNumber() {
+ return this.pageInfo.pageIndex + 1;
+ },
+ /**
+ * @return {number} The number of degrees the page is rotated clockwise.
+ */
+ get rotate() {
+ return this.pageInfo.rotate;
+ },
+ /**
+ * @return {object} The reference that points to this page. It has 'num' and
+ * 'gen' properties.
+ */
+ get ref() {
+ return this.pageInfo.ref;
+ },
+ /**
+ * @return {array} An array of the visible portion of the PDF page in the
+ * user space units - [x1, y1, x2, y2].
+ */
+ get view() {
+ return this.pageInfo.view;
+ },
+ /**
+ * @param {number} scale The desired scale of the viewport.
+ * @param {number} rotate Degrees to rotate the viewport. If omitted this
+ * defaults to the page rotation.
+ * @return {PageViewport} Contains 'width' and 'height' properties along
+ * with transforms required for rendering.
+ */
+ getViewport: function PDFPageProxy_getViewport(scale, rotate) {
+ if (arguments.length < 2)
+ rotate = this.rotate;
+ return new PDFJS.PageViewport(this.view, scale, rotate, 0, 0);
+ },
+ /**
+ * @return {Promise} A promise that is resolved with an {array} of the
+ * annotation objects.
+ */
+ getAnnotations: function PDFPageProxy_getAnnotations() {
+ if (this.annotationsPromise)
+ return this.annotationsPromise;
+
+ var promise = new PDFJS.LegacyPromise();
+ this.annotationsPromise = promise;
+ this.transport.getAnnotations(this.pageInfo.pageIndex);
+ return promise;
+ },
+ /**
+ * Begins the process of rendering a page to the desired context.
+ * @param {object} params A parameter object that supports:
+ * {
+ * canvasContext(required): A 2D context of a DOM Canvas object.,
+ * textLayer(optional): An object that has beginLayout, endLayout, and
+ * appendText functions.,
+ * imageLayer(optional): An object that has beginLayout, endLayout and
+ * appendImage functions.,
+ * continueCallback(optional): A function that will be called each time
+ * the rendering is paused. To continue
+ * rendering call the function that is the
+ * first argument to the callback.
+ * }.
+ * @return {RenderTask} An extended promise that is resolved when the page
+ * finishes rendering (see RenderTask).
+ */
+ render: function PDFPageProxy_render(params) {
+ var stats = this.stats;
+ stats.time('Overall');
+
+ // If there was a pending destroy cancel it so no cleanup happens during
+ // this call to render.
+ this.pendingDestroy = false;
+
+ // If there is no displayReadyPromise yet, then the operatorList was never
+ // requested before. Make the request and create the promise.
+ if (!this.displayReadyPromise) {
+ this.receivingOperatorList = true;
+ this.displayReadyPromise = new LegacyPromise();
+ this.operatorList = {
+ fnArray: [],
+ argsArray: [],
+ lastChunk: false
+ };
+
+ this.stats.time('Page Request');
+ this.transport.messageHandler.send('RenderPageRequest', {
+ pageIndex: this.pageNumber - 1
+ });
+ }
+
+ var internalRenderTask = new InternalRenderTask(complete, params,
+ this.objs, this.commonObjs,
+ this.operatorList, this.pageNumber);
+ this.renderTasks.push(internalRenderTask);
+ var renderTask = new RenderTask(internalRenderTask);
+
+ var self = this;
+ this.displayReadyPromise.then(
+ function pageDisplayReadyPromise(transparency) {
+ if (self.pendingDestroy) {
+ complete();
+ return;
+ }
+ stats.time('Rendering');
+ internalRenderTask.initalizeGraphics(transparency);
+ internalRenderTask.operatorListChanged();
+ },
+ function pageDisplayReadPromiseError(reason) {
+ complete(reason);
+ }
+ );
+
+ function complete(error) {
+ var i = self.renderTasks.indexOf(internalRenderTask);
+ if (i >= 0) {
+ self.renderTasks.splice(i, 1);
+ }
+
+ if (self.cleanupAfterRender) {
+ self.pendingDestroy = true;
+ }
+ self._tryDestroy();
+
+ if (error) {
+ renderTask.promise.reject(error);
+ } else {
+ renderTask.promise.resolve();
+ }
+ stats.timeEnd('Rendering');
+ stats.timeEnd('Overall');
+ }
+
+ return renderTask;
+ },
+ /**
+ * @return {Promise} That is resolved with the a {string} that is the text
+ * content from the page.
+ */
+ getTextContent: function PDFPageProxy_getTextContent() {
+ var promise = new PDFJS.LegacyPromise();
+ this.transport.messageHandler.send('GetTextContent', {
+ pageIndex: this.pageNumber - 1
+ },
+ function textContentCallback(textContent) {
+ promise.resolve(textContent);
+ }
+ );
+ return promise;
+ },
+ /**
+ * Stub for future feature.
+ */
+ getOperationList: function PDFPageProxy_getOperationList() {
+ var promise = new PDFJS.LegacyPromise();
+ var operationList = { // not implemented
+ dependencyFontsID: null,
+ operatorList: null
+ };
+ promise.resolve(operationList);
+ return promise;
+ },
+ /**
+ * Destroys resources allocated by the page.
+ */
+ destroy: function PDFPageProxy_destroy() {
+ this.pendingDestroy = true;
+ this._tryDestroy();
+ },
+ /**
+ * For internal use only. Attempts to clean up if rendering is in a state
+ * where that's possible.
+ */
+ _tryDestroy: function PDFPageProxy__destroy() {
+ if (!this.pendingDestroy ||
+ this.renderTasks.length !== 0 ||
+ this.receivingOperatorList) {
+ return;
+ }
+
+ delete this.operatorList;
+ delete this.displayReadyPromise;
+ this.objs.clear();
+ this.pendingDestroy = false;
+ },
+ /**
+ * For internal use only.
+ */
+ _startRenderPage: function PDFPageProxy_startRenderPage(transparency) {
+ this.displayReadyPromise.resolve(transparency);
+ },
+ /**
+ * For internal use only.
+ */
+ _renderPageChunk: function PDFPageProxy_renderPageChunk(operatorListChunk) {
+ // Add the new chunk to the current operator list.
+ for (var i = 0, ii = operatorListChunk.length; i < ii; i++) {
+ this.operatorList.fnArray.push(operatorListChunk.fnArray[i]);
+ this.operatorList.argsArray.push(operatorListChunk.argsArray[i]);
+ }
+ this.operatorList.lastChunk = operatorListChunk.lastChunk;
+
+ // Notify all the rendering tasks there are more operators to be consumed.
+ for (var i = 0; i < this.renderTasks.length; i++) {
+ this.renderTasks[i].operatorListChanged();
+ }
+
+ if (operatorListChunk.lastChunk) {
+ this.receivingOperatorList = false;
+ this._tryDestroy();
+ }
+ }
+ };
+ return PDFPageProxy;
+})();
+/**
+ * For internal use only.
+ */
+var WorkerTransport = (function WorkerTransportClosure() {
+ function WorkerTransport(workerInitializedPromise, workerReadyPromise,
+ pdfDataRangeTransport, progressCallback) {
+ this.pdfDataRangeTransport = pdfDataRangeTransport;
+
+ this.workerReadyPromise = workerReadyPromise;
+ this.progressCallback = progressCallback;
+ this.commonObjs = new PDFObjects();
+
+ this.pageCache = [];
+ this.pagePromises = [];
+ this.embeddedFontsUsed = false;
+
+ this.passwordCallback = null;
+
+ // If worker support isn't disabled explicit and the browser has worker
+ // support, create a new web worker and test if it/the browser fullfills
+ // all requirements to run parts of pdf.js in a web worker.
+ // Right now, the requirement is, that an Uint8Array is still an Uint8Array
+ // as it arrives on the worker. Chrome added this with version 15.
+ if (!globalScope.PDFJS.disableWorker && typeof Worker !== 'undefined') {
+ var workerSrc = PDFJS.workerSrc;
+ if (!workerSrc) {
+ error('No PDFJS.workerSrc specified');
+ }
+
+ try {
+ // Some versions of FF can't create a worker on localhost, see:
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=683280
+ var worker = new Worker(workerSrc);
+ var messageHandler = new MessageHandler('main', worker);
+ this.messageHandler = messageHandler;
+
+ messageHandler.on('test', function transportTest(data) {
+ var supportTypedArray = data && data.supportTypedArray;
+ if (supportTypedArray) {
+ this.worker = worker;
+ if (!data.supportTransfers) {
+ PDFJS.postMessageTransfers = false;
+ }
+ this.setupMessageHandler(messageHandler);
+ workerInitializedPromise.resolve();
+ } else {
+ globalScope.PDFJS.disableWorker = true;
+ this.loadFakeWorkerFiles().then(function() {
+ this.setupFakeWorker();
+ workerInitializedPromise.resolve();
+ }.bind(this));
+ }
+ }.bind(this));
+
+ var testObj = new Uint8Array([PDFJS.postMessageTransfers ? 255 : 0]);
+ // Some versions of Opera throw a DATA_CLONE_ERR on serializing the
+ // typed array. Also, checking if we can use transfers.
+ try {
+ messageHandler.send('test', testObj, null, [testObj.buffer]);
+ } catch (ex) {
+ info('Cannot use postMessage transfers');
+ testObj[0] = 0;
+ messageHandler.send('test', testObj);
+ }
+ return;
+ } catch (e) {
+ info('The worker has been disabled.');
+ }
+ }
+ // Either workers are disabled, not supported or have thrown an exception.
+ // Thus, we fallback to a faked worker.
+ globalScope.PDFJS.disableWorker = true;
+ this.loadFakeWorkerFiles().then(function() {
+ this.setupFakeWorker();
+ workerInitializedPromise.resolve();
+ }.bind(this));
+ }
+ WorkerTransport.prototype = {
+ destroy: function WorkerTransport_destroy() {
+ this.pageCache = [];
+ this.pagePromises = [];
+ var self = this;
+ this.messageHandler.send('Terminate', null, function () {
+ if (self.worker) {
+ self.worker.terminate();
+ }
+ });
+ },
+
+ loadFakeWorkerFiles: function WorkerTransport_loadFakeWorkerFiles() {
+ if (!PDFJS.fakeWorkerFilesLoadedPromise) {
+ PDFJS.fakeWorkerFilesLoadedPromise = new LegacyPromise();
+ // In the developer build load worker_loader which in turn loads all the
+ // other files and resolves the promise. In production only the
+ // pdf.worker.js file is needed.
+ Util.loadScript(PDFJS.workerSrc, function() {
+ PDFJS.fakeWorkerFilesLoadedPromise.resolve();
+ });
+ }
+ return PDFJS.fakeWorkerFilesLoadedPromise;
+ },
+
+ setupFakeWorker: function WorkerTransport_setupFakeWorker() {
+ warn('Setting up fake worker.');
+ // If we don't use a worker, just post/sendMessage to the main thread.
+ var fakeWorker = {
+ postMessage: function WorkerTransport_postMessage(obj) {
+ fakeWorker.onmessage({data: obj});
+ },
+ terminate: function WorkerTransport_terminate() {}
+ };
+
+ var messageHandler = new MessageHandler('main', fakeWorker);
+ this.setupMessageHandler(messageHandler);
+
+ // If the main thread is our worker, setup the handling for the messages
+ // the main thread sends to it self.
+ PDFJS.WorkerMessageHandler.setup(messageHandler);
+ },
+
+ setupMessageHandler:
+ function WorkerTransport_setupMessageHandler(messageHandler) {
+ this.messageHandler = messageHandler;
+
+ function updatePassword(password) {
+ messageHandler.send('UpdatePassword', password);
+ }
+
+ var pdfDataRangeTransport = this.pdfDataRangeTransport;
+ if (pdfDataRangeTransport) {
+ pdfDataRangeTransport.addRangeListener(function(begin, chunk) {
+ messageHandler.send('OnDataRange', {
+ begin: begin,
+ chunk: chunk
+ });
+ });
+
+ pdfDataRangeTransport.addProgressListener(function(loaded) {
+ messageHandler.send('OnDataProgress', {
+ loaded: loaded
+ });
+ });
+
+ messageHandler.on('RequestDataRange',
+ function transportDataRange(data) {
+ pdfDataRangeTransport.requestDataRange(data.begin, data.end);
+ }, this);
+ }
+
+ messageHandler.on('GetDoc', function transportDoc(data) {
+ var pdfInfo = data.pdfInfo;
+ var pdfDocument = new PDFDocumentProxy(pdfInfo, this);
+ this.pdfDocument = pdfDocument;
+ this.workerReadyPromise.resolve(pdfDocument);
+ }, this);
+
+ messageHandler.on('NeedPassword', function transportPassword(data) {
+ if (this.passwordCallback) {
+ return this.passwordCallback(updatePassword,
+ PasswordResponses.NEED_PASSWORD);
+ }
+ this.workerReadyPromise.reject(data.exception.message, data.exception);
+ }, this);
+
+ messageHandler.on('IncorrectPassword', function transportBadPass(data) {
+ if (this.passwordCallback) {
+ return this.passwordCallback(updatePassword,
+ PasswordResponses.INCORRECT_PASSWORD);
+ }
+ this.workerReadyPromise.reject(data.exception.message, data.exception);
+ }, this);
+
+ messageHandler.on('InvalidPDF', function transportInvalidPDF(data) {
+ this.workerReadyPromise.reject(data.exception.name, data.exception);
+ }, this);
+
+ messageHandler.on('MissingPDF', function transportMissingPDF(data) {
+ this.workerReadyPromise.reject(data.exception.message, data.exception);
+ }, this);
+
+ messageHandler.on('UnknownError', function transportUnknownError(data) {
+ this.workerReadyPromise.reject(data.exception.message, data.exception);
+ }, this);
+
+ messageHandler.on('GetPage', function transportPage(data) {
+ var pageInfo = data.pageInfo;
+ var page = new PDFPageProxy(pageInfo, this);
+ this.pageCache[pageInfo.pageIndex] = page;
+ var promise = this.pagePromises[pageInfo.pageIndex];
+ promise.resolve(page);
+ }, this);
+
+ messageHandler.on('GetAnnotations', function transportAnnotations(data) {
+ var annotations = data.annotations;
+ var promise = this.pageCache[data.pageIndex].annotationsPromise;
+ promise.resolve(annotations);
+ }, this);
+
+ messageHandler.on('StartRenderPage', function transportRender(data) {
+ var page = this.pageCache[data.pageIndex];
+
+ page.stats.timeEnd('Page Request');
+ page._startRenderPage(data.transparency);
+ }, this);
+
+ messageHandler.on('RenderPageChunk', function transportRender(data) {
+ var page = this.pageCache[data.pageIndex];
+
+ page._renderPageChunk(data.operatorList);
+ }, this);
+
+ messageHandler.on('commonobj', function transportObj(data) {
+ var id = data[0];
+ var type = data[1];
+ if (this.commonObjs.hasData(id))
+ return;
+
+ switch (type) {
+ case 'Font':
+ var exportedData = data[2];
+
+ var font;
+ if ('error' in exportedData) {
+ var error = exportedData.error;
+ warn('Error during font loading: ' + error);
+ this.commonObjs.resolve(id, error);
+ break;
+ } else {
+ font = new FontFace(exportedData);
+ }
+
+ FontLoader.bind(
+ [font],
+ function fontReady(fontObjs) {
+ this.commonObjs.resolve(id, font);
+ }.bind(this)
+ );
+ break;
+ case 'FontPath':
+ this.commonObjs.resolve(id, data[2]);
+ break;
+ default:
+ error('Got unknown common object type ' + type);
+ }
+ }, this);
+
+ messageHandler.on('obj', function transportObj(data) {
+ var id = data[0];
+ var pageIndex = data[1];
+ var type = data[2];
+ var pageProxy = this.pageCache[pageIndex];
+ if (pageProxy.objs.hasData(id))
+ return;
+
+ switch (type) {
+ case 'JpegStream':
+ var imageData = data[3];
+ loadJpegStream(id, imageData, pageProxy.objs);
+ break;
+ case 'Image':
+ var imageData = data[3];
+ pageProxy.objs.resolve(id, imageData);
+
+ // heuristics that will allow not to store large data
+ var MAX_IMAGE_SIZE_TO_STORE = 8000000;
+ if ('data' in imageData &&
+ imageData.data.length > MAX_IMAGE_SIZE_TO_STORE) {
+ pageProxy.cleanupAfterRender = true;
+ }
+ break;
+ default:
+ error('Got unknown object type ' + type);
+ }
+ }, this);
+
+ messageHandler.on('DocProgress', function transportDocProgress(data) {
+ if (this.progressCallback) {
+ this.progressCallback({
+ loaded: data.loaded,
+ total: data.total
+ });
+ }
+ }, this);
+
+ messageHandler.on('DocError', function transportDocError(data) {
+ this.workerReadyPromise.reject(data);
+ }, this);
+
+ messageHandler.on('PageError', function transportError(data) {
+ var page = this.pageCache[data.pageNum - 1];
+ if (page.displayReadyPromise)
+ page.displayReadyPromise.reject(data.error);
+ else
+ error(data.error);
+ }, this);
+
+ messageHandler.on('JpegDecode', function(data, deferred) {
+ var imageUrl = data[0];
+ var components = data[1];
+ if (components != 3 && components != 1)
+ error('Only 3 component or 1 component can be returned');
+
+ var img = new Image();
+ img.onload = (function messageHandler_onloadClosure() {
+ var width = img.width;
+ var height = img.height;
+ var size = width * height;
+ var rgbaLength = size * 4;
+ var buf = new Uint8Array(size * components);
+ var tmpCanvas = createScratchCanvas(width, height);
+ var tmpCtx = tmpCanvas.getContext('2d');
+ tmpCtx.drawImage(img, 0, 0);
+ var data = tmpCtx.getImageData(0, 0, width, height).data;
+
+ if (components == 3) {
+ for (var i = 0, j = 0; i < rgbaLength; i += 4, j += 3) {
+ buf[j] = data[i];
+ buf[j + 1] = data[i + 1];
+ buf[j + 2] = data[i + 2];
+ }
+ } else if (components == 1) {
+ for (var i = 0, j = 0; i < rgbaLength; i += 4, j++) {
+ buf[j] = data[i];
+ }
+ }
+ deferred.resolve({ data: buf, width: width, height: height});
+ }).bind(this);
+ img.src = imageUrl;
+ });
+ },
+
+ fetchDocument: function WorkerTransport_fetchDocument(source) {
+ source.disableAutoFetch = PDFJS.disableAutoFetch;
+ source.chunkedViewerLoading = !!this.pdfDataRangeTransport;
+ this.messageHandler.send('GetDocRequest', {
+ source: source,
+ disableRange: PDFJS.disableRange,
+ maxImageSize: PDFJS.maxImageSize,
+ disableFontFace: PDFJS.disableFontFace,
+ disableCreateObjectURL: PDFJS.disableCreateObjectURL,
+ verbosity: PDFJS.verbosity
+ });
+ },
+
+ getData: function WorkerTransport_getData(promise) {
+ this.messageHandler.send('GetData', null, function(data) {
+ promise.resolve(data);
+ });
+ },
+
+ dataLoaded: function WorkerTransport_dataLoaded() {
+ var promise = new PDFJS.LegacyPromise();
+ this.messageHandler.send('DataLoaded', null, function(args) {
+ promise.resolve(args);
+ });
+ return promise;
+ },
+
+ getPage: function WorkerTransport_getPage(pageNumber, promise) {
+ var pageIndex = pageNumber - 1;
+ if (pageIndex in this.pagePromises)
+ return this.pagePromises[pageIndex];
+ var promise = new PDFJS.LegacyPromise();
+ this.pagePromises[pageIndex] = promise;
+ this.messageHandler.send('GetPageRequest', { pageIndex: pageIndex });
+ return promise;
+ },
+
+ getPageIndex: function WorkerTransport_getPageIndexByRef(ref) {
+ var promise = new PDFJS.LegacyPromise();
+ this.messageHandler.send('GetPageIndex', { ref: ref },
+ function (pageIndex) {
+ promise.resolve(pageIndex);
+ }
+ );
+ return promise;
+ },
+
+ getAnnotations: function WorkerTransport_getAnnotations(pageIndex) {
+ this.messageHandler.send('GetAnnotationsRequest',
+ { pageIndex: pageIndex });
+ },
+
+ getDestinations: function WorkerTransport_getDestinations() {
+ var promise = new PDFJS.LegacyPromise();
+ this.messageHandler.send('GetDestinations', null,
+ function transportDestinations(destinations) {
+ promise.resolve(destinations);
+ }
+ );
+ return promise;
+ },
+
+ startCleanup: function WorkerTransport_startCleanup() {
+ this.messageHandler.send('Cleanup', null,
+ function endCleanup() {
+ for (var i = 0, ii = this.pageCache.length; i < ii; i++) {
+ var page = this.pageCache[i];
+ if (page) {
+ page.destroy();
+ }
+ }
+ this.commonObjs.clear();
+ FontLoader.clear();
+ }.bind(this)
+ );
+ }
+ };
+ return WorkerTransport;
+
+})();
+
+/**
+ * A PDF document and page is built of many objects. E.g. there are objects
+ * for fonts, images, rendering code and such. These objects might get processed
+ * inside of a worker. The `PDFObjects` implements some basic functions to
+ * manage these objects.
+ */
+var PDFObjects = (function PDFObjectsClosure() {
+ function PDFObjects() {
+ this.objs = {};
+ }
+
+ PDFObjects.prototype = {
+ /**
+ * Internal function.
+ * Ensures there is an object defined for `objId`.
+ */
+ ensureObj: function PDFObjects_ensureObj(objId) {
+ if (this.objs[objId])
+ return this.objs[objId];
+
+ var obj = {
+ promise: new LegacyPromise(),
+ data: null,
+ resolved: false
+ };
+ this.objs[objId] = obj;
+
+ return obj;
+ },
+
+ /**
+ * If called *without* callback, this returns the data of `objId` but the
+ * object needs to be resolved. If it isn't, this function throws.
+ *
+ * If called *with* a callback, the callback is called with the data of the
+ * object once the object is resolved. That means, if you call this
+ * function and the object is already resolved, the callback gets called
+ * right away.
+ */
+ get: function PDFObjects_get(objId, callback) {
+ // If there is a callback, then the get can be async and the object is
+ // not required to be resolved right now
+ if (callback) {
+ this.ensureObj(objId).promise.then(callback);
+ return null;
+ }
+
+ // If there isn't a callback, the user expects to get the resolved data
+ // directly.
+ var obj = this.objs[objId];
+
+ // If there isn't an object yet or the object isn't resolved, then the
+ // data isn't ready yet!
+ if (!obj || !obj.resolved)
+ error('Requesting object that isn\'t resolved yet ' + objId);
+
+ return obj.data;
+ },
+
+ /**
+ * Resolves the object `objId` with optional `data`.
+ */
+ resolve: function PDFObjects_resolve(objId, data) {
+ var obj = this.ensureObj(objId);
+
+ obj.resolved = true;
+ obj.data = data;
+ obj.promise.resolve(data);
+ },
+
+ isResolved: function PDFObjects_isResolved(objId) {
+ var objs = this.objs;
+
+ if (!objs[objId]) {
+ return false;
+ } else {
+ return objs[objId].resolved;
+ }
+ },
+
+ hasData: function PDFObjects_hasData(objId) {
+ return this.isResolved(objId);
+ },
+
+ /**
+ * Returns the data of `objId` if object exists, null otherwise.
+ */
+ getData: function PDFObjects_getData(objId) {
+ var objs = this.objs;
+ if (!objs[objId] || !objs[objId].resolved) {
+ return null;
+ } else {
+ return objs[objId].data;
+ }
+ },
+
+ clear: function PDFObjects_clear() {
+ this.objs = {};
+ }
+ };
+ return PDFObjects;
+})();
+
+var RenderTask = (function RenderTaskClosure() {
+ function RenderTask(internalRenderTask) {
+ this.internalRenderTask = internalRenderTask;
+ this.promise = new PDFJS.LegacyPromise();
+ }
+
+ /**
+ * Cancel the rendering task. If the task is curently rendering it will not be
+ * cancelled until graphics pauses with a timeout. The promise that this
+ * object extends will resolved when cancelled.
+ */
+ RenderTask.prototype.cancel = function RenderTask_cancel() {
+ this.internalRenderTask.cancel();
+ };
+
+ return RenderTask;
+})();
+
+var InternalRenderTask = (function InternalRenderTaskClosure() {
+
+ function InternalRenderTask(callback, params, objs, commonObjs, operatorList,
+ pageNumber) {
+ this.callback = callback;
+ this.params = params;
+ this.objs = objs;
+ this.commonObjs = commonObjs;
+ this.operatorListIdx = null;
+ this.operatorList = operatorList;
+ this.pageNumber = pageNumber;
+ this.running = false;
+ this.graphicsReadyCallback = null;
+ this.graphicsReady = false;
+ this.cancelled = false;
+ }
+
+ InternalRenderTask.prototype = {
+
+ initalizeGraphics:
+ function InternalRenderTask_initalizeGraphics(transparency) {
+
+ if (this.cancelled) {
+ return;
+ }
+ if (PDFJS.pdfBug && 'StepperManager' in globalScope &&
+ globalScope.StepperManager.enabled) {
+ this.stepper = globalScope.StepperManager.create(this.pageNumber - 1);
+ this.stepper.init(this.operatorList);
+ this.stepper.nextBreakPoint = this.stepper.getNextBreakPoint();
+ }
+
+ var params = this.params;
+ this.gfx = new CanvasGraphics(params.canvasContext, this.commonObjs,
+ this.objs, params.textLayer,
+ params.imageLayer);
+
+ this.gfx.beginDrawing(params.viewport, transparency);
+ this.operatorListIdx = 0;
+ this.graphicsReady = true;
+ if (this.graphicsReadyCallback) {
+ this.graphicsReadyCallback();
+ }
+ },
+
+ cancel: function InternalRenderTask_cancel() {
+ this.running = false;
+ this.cancelled = true;
+ this.callback('cancelled');
+ },
+
+ operatorListChanged: function InternalRenderTask_operatorListChanged() {
+ if (!this.graphicsReady) {
+ if (!this.graphicsReadyCallback) {
+ this.graphicsReadyCallback = this._continue.bind(this);
+ }
+ return;
+ }
+
+ if (this.stepper) {
+ this.stepper.updateOperatorList(this.operatorList);
+ }
+
+ if (this.running) {
+ return;
+ }
+ this._continue();
+ },
+
+ _continue: function InternalRenderTask__continue() {
+ this.running = true;
+ if (this.cancelled) {
+ return;
+ }
+ if (this.params.continueCallback) {
+ this.params.continueCallback(this._next.bind(this));
+ } else {
+ this._next();
+ }
+ },
+
+ _next: function InternalRenderTask__next() {
+ if (this.cancelled) {
+ return;
+ }
+ this.operatorListIdx = this.gfx.executeOperatorList(this.operatorList,
+ this.operatorListIdx,
+ this._continue.bind(this),
+ this.stepper);
+ if (this.operatorListIdx === this.operatorList.argsArray.length) {
+ this.running = false;
+ if (this.operatorList.lastChunk) {
+ this.gfx.endDrawing();
+ this.callback();
+ }
+ }
+ }
+
+ };
+
+ return InternalRenderTask;
+})();
+
+
+var Metadata = PDFJS.Metadata = (function MetadataClosure() {
+ function fixMetadata(meta) {
+ return meta.replace(/>\\376\\377([^<]+)/g, function(all, codes) {
+ var bytes = codes.replace(/\\([0-3])([0-7])([0-7])/g,
+ function(code, d1, d2, d3) {
+ return String.fromCharCode(d1 * 64 + d2 * 8 + d3 * 1);
+ });
+ var chars = '';
+ for (var i = 0; i < bytes.length; i += 2) {
+ var code = bytes.charCodeAt(i) * 256 + bytes.charCodeAt(i + 1);
+ chars += code >= 32 && code < 127 && code != 60 && code != 62 &&
+ code != 38 && false ? String.fromCharCode(code) :
+ '&#x' + (0x10000 + code).toString(16).substring(1) + ';';
+ }
+ return '>' + chars;
+ });
+ }
+
+ function Metadata(meta) {
+ if (typeof meta === 'string') {
+ // Ghostscript produces invalid metadata
+ meta = fixMetadata(meta);
+
+ var parser = new DOMParser();
+ meta = parser.parseFromString(meta, 'application/xml');
+ } else if (!(meta instanceof Document)) {
+ error('Metadata: Invalid metadata object');
+ }
+
+ this.metaDocument = meta;
+ this.metadata = {};
+ this.parse();
+ }
+
+ Metadata.prototype = {
+ parse: function Metadata_parse() {
+ var doc = this.metaDocument;
+ var rdf = doc.documentElement;
+
+ if (rdf.nodeName.toLowerCase() !== 'rdf:rdf') { // Wrapped in <xmpmeta>
+ rdf = rdf.firstChild;
+ while (rdf && rdf.nodeName.toLowerCase() !== 'rdf:rdf')
+ rdf = rdf.nextSibling;
+ }
+
+ var nodeName = (rdf) ? rdf.nodeName.toLowerCase() : null;
+ if (!rdf || nodeName !== 'rdf:rdf' || !rdf.hasChildNodes())
+ return;
+
+ var children = rdf.childNodes, desc, entry, name, i, ii, length, iLength;
+
+ for (i = 0, length = children.length; i < length; i++) {
+ desc = children[i];
+ if (desc.nodeName.toLowerCase() !== 'rdf:description')
+ continue;
+
+ for (ii = 0, iLength = desc.childNodes.length; ii < iLength; ii++) {
+ if (desc.childNodes[ii].nodeName.toLowerCase() !== '#text') {
+ entry = desc.childNodes[ii];
+ name = entry.nodeName.toLowerCase();
+ this.metadata[name] = entry.textContent.trim();
+ }
+ }
+ }
+ },
+
+ get: function Metadata_get(name) {
+ return this.metadata[name] || null;
+ },
+
+ has: function Metadata_has(name) {
+ return typeof this.metadata[name] !== 'undefined';
+ }
+ };
+
+ return Metadata;
+})();
+
+
+// <canvas> contexts store most of the state we need natively.
+// However, PDF needs a bit more state, which we store here.
+
+// Minimal font size that would be used during canvas fillText operations.
+var MIN_FONT_SIZE = 16;
+
+var COMPILE_TYPE3_GLYPHS = true;
+
+function createScratchCanvas(width, height) {
+ var canvas = document.createElement('canvas');
+ canvas.width = width;
+ canvas.height = height;
+ return canvas;
+}
+
+function addContextCurrentTransform(ctx) {
+ // If the context doesn't expose a `mozCurrentTransform`, add a JS based on.
+ if (!ctx.mozCurrentTransform) {
+ // Store the original context
+ ctx._scaleX = ctx._scaleX || 1.0;
+ ctx._scaleY = ctx._scaleY || 1.0;
+ ctx._originalSave = ctx.save;
+ ctx._originalRestore = ctx.restore;
+ ctx._originalRotate = ctx.rotate;
+ ctx._originalScale = ctx.scale;
+ ctx._originalTranslate = ctx.translate;
+ ctx._originalTransform = ctx.transform;
+ ctx._originalSetTransform = ctx.setTransform;
+
+ ctx._transformMatrix = [ctx._scaleX, 0, 0, ctx._scaleY, 0, 0];
+ ctx._transformStack = [];
+
+ Object.defineProperty(ctx, 'mozCurrentTransform', {
+ get: function getCurrentTransform() {
+ return this._transformMatrix;
+ }
+ });
+
+ Object.defineProperty(ctx, 'mozCurrentTransformInverse', {
+ get: function getCurrentTransformInverse() {
+ // Calculation done using WolframAlpha:
+ // http://www.wolframalpha.com/input/?
+ // i=Inverse+{{a%2C+c%2C+e}%2C+{b%2C+d%2C+f}%2C+{0%2C+0%2C+1}}
+
+ var m = this._transformMatrix;
+ var a = m[0], b = m[1], c = m[2], d = m[3], e = m[4], f = m[5];
+
+ var ad_bc = a * d - b * c;
+ var bc_ad = b * c - a * d;
+
+ return [
+ d / ad_bc,
+ b / bc_ad,
+ c / bc_ad,
+ a / ad_bc,
+ (d * e - c * f) / bc_ad,
+ (b * e - a * f) / ad_bc
+ ];
+ }
+ });
+
+ ctx.save = function ctxSave() {
+ var old = this._transformMatrix;
+ this._transformStack.push(old);
+ this._transformMatrix = old.slice(0, 6);
+
+ this._originalSave();
+ };
+
+ ctx.restore = function ctxRestore() {
+ var prev = this._transformStack.pop();
+ if (prev) {
+ this._transformMatrix = prev;
+ this._originalRestore();
+ }
+ };
+
+ ctx.translate = function ctxTranslate(x, y) {
+ var m = this._transformMatrix;
+ m[4] = m[0] * x + m[2] * y + m[4];
+ m[5] = m[1] * x + m[3] * y + m[5];
+
+ this._originalTranslate(x, y);
+ };
+
+ ctx.scale = function ctxScale(x, y) {
+ var m = this._transformMatrix;
+ m[0] = m[0] * x;
+ m[1] = m[1] * x;
+ m[2] = m[2] * y;
+ m[3] = m[3] * y;
+
+ this._originalScale(x, y);
+ };
+
+ ctx.transform = function ctxTransform(a, b, c, d, e, f) {
+ var m = this._transformMatrix;
+ this._transformMatrix = [
+ m[0] * a + m[2] * b,
+ m[1] * a + m[3] * b,
+ m[0] * c + m[2] * d,
+ m[1] * c + m[3] * d,
+ m[0] * e + m[2] * f + m[4],
+ m[1] * e + m[3] * f + m[5]
+ ];
+
+ ctx._originalTransform(a, b, c, d, e, f);
+ };
+
+ ctx.setTransform = function ctxSetTransform(a, b, c, d, e, f) {
+ this._transformMatrix = [a, b, c, d, e, f];
+
+ ctx._originalSetTransform(a, b, c, d, e, f);
+ };
+
+ ctx.rotate = function ctxRotate(angle) {
+ var cosValue = Math.cos(angle);
+ var sinValue = Math.sin(angle);
+
+ var m = this._transformMatrix;
+ this._transformMatrix = [
+ m[0] * cosValue + m[2] * sinValue,
+ m[1] * cosValue + m[3] * sinValue,
+ m[0] * (-sinValue) + m[2] * cosValue,
+ m[1] * (-sinValue) + m[3] * cosValue,
+ m[4],
+ m[5]
+ ];
+
+ this._originalRotate(angle);
+ };
+ }
+}
+
+var CachedCanvases = (function CachedCanvasesClosure() {
+ var cache = {};
+ return {
+ getCanvas: function CachedCanvases_getCanvas(id, width, height,
+ trackTransform) {
+ var canvasEntry;
+ if (id in cache) {
+ canvasEntry = cache[id];
+ canvasEntry.canvas.width = width;
+ canvasEntry.canvas.height = height;
+ // reset canvas transform for emulated mozCurrentTransform, if needed
+ canvasEntry.context.setTransform(1, 0, 0, 1, 0, 0);
+ } else {
+ var canvas = createScratchCanvas(width, height);
+ var ctx = canvas.getContext('2d');
+ if (trackTransform) {
+ addContextCurrentTransform(ctx);
+ }
+ cache[id] = canvasEntry = {canvas: canvas, context: ctx};
+ }
+ return canvasEntry;
+ },
+ clear: function () {
+ cache = {};
+ }
+ };
+})();
+
+function compileType3Glyph(imgData) {
+ var POINT_TO_PROCESS_LIMIT = 1000;
+
+ var width = imgData.width, height = imgData.height;
+ var i, j, j0, width1 = width + 1;
+ var points = new Uint8Array(width1 * (height + 1));
+ var POINT_TYPES =
+ new Uint8Array([0, 2, 4, 0, 1, 0, 5, 4, 8, 10, 0, 8, 0, 2, 1, 0]);
+
+ // decodes bit-packed mask data
+ var lineSize = (width + 7) & ~7, data0 = imgData.data;
+ var data = new Uint8Array(lineSize * height), pos = 0, ii;
+ for (i = 0, ii = data0.length; i < ii; i++) {
+ var mask = 128, elem = data0[i];
+ while (mask > 0) {
+ data[pos++] = (elem & mask) ? 0 : 255;
+ mask >>= 1;
+ }
+ }
+
+ // finding iteresting points: every point is located between mask pixels,
+ // so there will be points of the (width + 1)x(height + 1) grid. Every point
+ // will have flags assigned based on neighboring mask pixels:
+ // 4 | 8
+ // --P--
+ // 2 | 1
+ // We are interested only in points with the flags:
+ // - outside corners: 1, 2, 4, 8;
+ // - inside corners: 7, 11, 13, 14;
+ // - and, intersections: 5, 10.
+ var count = 0;
+ pos = 0;
+ if (data[pos] !== 0) {
+ points[0] = 1;
+ ++count;
+ }
+ for (j = 1; j < width; j++) {
+ if (data[pos] !== data[pos + 1]) {
+ points[j] = data[pos] ? 2 : 1;
+ ++count;
+ }
+ pos++;
+ }
+ if (data[pos] !== 0) {
+ points[j] = 2;
+ ++count;
+ }
+ for (i = 1; i < height; i++) {
+ pos = i * lineSize;
+ j0 = i * width1;
+ if (data[pos - lineSize] !== data[pos]) {
+ points[j0] = data[pos] ? 1 : 8;
+ ++count;
+ }
+ // 'sum' is the position of the current pixel configuration in the 'TYPES'
+ // array (in order 8-1-2-4, so we can use '>>2' to shift the column).
+ var sum = (data[pos] ? 4 : 0) + (data[pos - lineSize] ? 8 : 0);
+ for (j = 1; j < width; j++) {
+ sum = (sum >> 2) + (data[pos + 1] ? 4 : 0) +
+ (data[pos - lineSize + 1] ? 8 : 0);
+ if (POINT_TYPES[sum]) {
+ points[j0 + j] = POINT_TYPES[sum];
+ ++count;
+ }
+ pos++;
+ }
+ if (data[pos - lineSize] !== data[pos]) {
+ points[j0 + j] = data[pos] ? 2 : 4;
+ ++count;
+ }
+
+ if (count > POINT_TO_PROCESS_LIMIT) {
+ return null;
+ }
+ }
+
+ pos = lineSize * (height - 1);
+ j0 = i * width1;
+ if (data[pos] !== 0) {
+ points[j0] = 8;
+ ++count;
+ }
+ for (j = 1; j < width; j++) {
+ if (data[pos] !== data[pos + 1]) {
+ points[j0 + j] = data[pos] ? 4 : 8;
+ ++count;
+ }
+ pos++;
+ }
+ if (data[pos] !== 0) {
+ points[j0 + j] = 4;
+ ++count;
+ }
+ if (count > POINT_TO_PROCESS_LIMIT) {
+ return null;
+ }
+
+ // building outlines
+ var steps = new Int32Array([0, width1, -1, 0, -width1, 0, 0, 0, 1]);
+ var outlines = [];
+ for (i = 0; count && i <= height; i++) {
+ var p = i * width1;
+ var end = p + width;
+ while (p < end && !points[p]) {
+ p++;
+ }
+ if (p === end) {
+ continue;
+ }
+ var coords = [p % width1, i];
+
+ var type = points[p], p0 = p, pp;
+ do {
+ var step = steps[type];
+ do { p += step; } while (!points[p]);
+
+ pp = points[p];
+ if (pp !== 5 && pp !== 10) {
+ // set new direction
+ type = pp;
+ // delete mark
+ points[p] = 0;
+ } else { // type is 5 or 10, ie, a crossing
+ // set new direction
+ type = pp & ((0x33 * type) >> 4);
+ // set new type for "future hit"
+ points[p] &= (type >> 2 | type << 2);
+ }
+
+ coords.push(p % width1);
+ coords.push((p / width1) | 0);
+ --count;
+ } while (p0 !== p);
+ outlines.push(coords);
+ --i;
+ }
+
+ var drawOutline = function(c) {
+ c.save();
+ // the path shall be painted in [0..1]x[0..1] space
+ c.scale(1 / width, -1 / height);
+ c.translate(0, -height);
+ c.beginPath();
+ for (var i = 0, ii = outlines.length; i < ii; i++) {
+ var o = outlines[i];
+ c.moveTo(o[0], o[1]);
+ for (var j = 2, jj = o.length; j < jj; j += 2) {
+ c.lineTo(o[j], o[j+1]);
+ }
+ }
+ c.fill();
+ c.beginPath();
+ c.restore();
+ };
+
+ return drawOutline;
+}
+
+var CanvasExtraState = (function CanvasExtraStateClosure() {
+ function CanvasExtraState(old) {
+ // Are soft masks and alpha values shapes or opacities?
+ this.alphaIsShape = false;
+ this.fontSize = 0;
+ this.fontSizeScale = 1;
+ this.textMatrix = IDENTITY_MATRIX;
+ this.fontMatrix = FONT_IDENTITY_MATRIX;
+ this.leading = 0;
+ // Current point (in user coordinates)
+ this.x = 0;
+ this.y = 0;
+ // Start of text line (in text coordinates)
+ this.lineX = 0;
+ this.lineY = 0;
+ // Character and word spacing
+ this.charSpacing = 0;
+ this.wordSpacing = 0;
+ this.textHScale = 1;
+ this.textRenderingMode = TextRenderingMode.FILL;
+ this.textRise = 0;
+ // Color spaces
+ this.fillColorSpace = ColorSpace.singletons.gray;
+ this.fillColorSpaceObj = null;
+ this.strokeColorSpace = ColorSpace.singletons.gray;
+ this.strokeColorSpaceObj = null;
+ this.fillColorObj = null;
+ this.strokeColorObj = null;
+ // Default fore and background colors
+ this.fillColor = '#000000';
+ this.strokeColor = '#000000';
+ // Note: fill alpha applies to all non-stroking operations
+ this.fillAlpha = 1;
+ this.strokeAlpha = 1;
+ this.lineWidth = 1;
+
+ this.old = old;
+ }
+
+ CanvasExtraState.prototype = {
+ clone: function CanvasExtraState_clone() {
+ return Object.create(this);
+ },
+ setCurrentPoint: function CanvasExtraState_setCurrentPoint(x, y) {
+ this.x = x;
+ this.y = y;
+ }
+ };
+ return CanvasExtraState;
+})();
+
+var CanvasGraphics = (function CanvasGraphicsClosure() {
+ // Defines the time the executeOperatorList is going to be executing
+ // before it stops and shedules a continue of execution.
+ var EXECUTION_TIME = 15;
+
+ function CanvasGraphics(canvasCtx, commonObjs, objs, textLayer, imageLayer) {
+ this.ctx = canvasCtx;
+ this.current = new CanvasExtraState();
+ this.stateStack = [];
+ this.pendingClip = null;
+ this.pendingEOFill = false;
+ this.res = null;
+ this.xobjs = null;
+ this.commonObjs = commonObjs;
+ this.objs = objs;
+ this.textLayer = textLayer;
+ this.imageLayer = imageLayer;
+ this.groupStack = [];
+ this.processingType3 = null;
+ // Patterns are painted relative to the initial page/form transform, see pdf
+ // spec 8.7.2 NOTE 1.
+ this.baseTransform = null;
+ this.baseTransformStack = [];
+ this.groupLevel = 0;
+ if (canvasCtx) {
+ addContextCurrentTransform(canvasCtx);
+ }
+ }
+
+ function putBinaryImageData(ctx, imgData) {
+ if (typeof ImageData !== 'undefined' && imgData instanceof ImageData) {
+ ctx.putImageData(imgData, 0, 0);
+ return;
+ }
+
+ // Put the image data to the canvas in chunks, rather than putting the
+ // whole image at once. This saves JS memory, because the ImageData object
+ // is smaller. It also possibly saves C++ memory within the implementation
+ // of putImageData(). (E.g. in Firefox we make two short-lived copies of
+ // the data passed to putImageData()). |n| shouldn't be too small, however,
+ // because too many putImageData() calls will slow things down.
+
+ var rowsInFullChunks = 16;
+ var fullChunks = (imgData.height / rowsInFullChunks) | 0;
+ var rowsInLastChunk = imgData.height - fullChunks * rowsInFullChunks;
+ var elemsInFullChunks = imgData.width * rowsInFullChunks * 4;
+ var elemsInLastChunk = imgData.width * rowsInLastChunk * 4;
+
+ var chunkImgData = ctx.createImageData(imgData.width, rowsInFullChunks);
+ var srcPos = 0;
+ var src = imgData.data;
+ var dst = chunkImgData.data;
+ var haveSetAndSubarray = 'set' in dst && 'subarray' in src;
+
+ // Do all the full-size chunks.
+ for (var i = 0; i < fullChunks; i++) {
+ if (haveSetAndSubarray) {
+ dst.set(src.subarray(srcPos, srcPos + elemsInFullChunks));
+ srcPos += elemsInFullChunks;
+ } else {
+ for (var j = 0; j < elemsInFullChunks; j++) {
+ chunkImgData.data[j] = imgData.data[srcPos++];
+ }
+ }
+ ctx.putImageData(chunkImgData, 0, i * rowsInFullChunks);
+ }
+
+ // Do the final, partial chunk, if required.
+ if (rowsInLastChunk !== 0) {
+ if (haveSetAndSubarray) {
+ dst.set(src.subarray(srcPos, srcPos + elemsInLastChunk));
+ srcPos += elemsInLastChunk;
+ } else {
+ for (var j = 0; j < elemsInLastChunk; j++) {
+ chunkImgData.data[j] = imgData.data[srcPos++];
+ }
+ }
+ // This (conceptually) puts pixels past the bounds of the canvas. But
+ // that's ok; any such pixels are ignored.
+ ctx.putImageData(chunkImgData, 0, fullChunks * rowsInFullChunks);
+ }
+ }
+
+ function putBinaryImageMask(ctx, imgData) {
+ var width = imgData.width, height = imgData.height;
+ var tmpImgData = ctx.createImageData(width, height);
+ var data = imgData.data;
+ var tmpImgDataPixels = tmpImgData.data;
+ var dataPos = 0;
+
+ // Expand the mask so it can be used by the canvas. Any required inversion
+ // has already been handled.
+ var tmpPos = 3; // alpha component offset
+ for (var i = 0; i < height; i++) {
+ var mask = 0;
+ for (var j = 0; j < width; j++) {
+ if (!mask) {
+ var elem = data[dataPos++];
+ mask = 128;
+ }
+ if (!(elem & mask)) {
+ tmpImgDataPixels[tmpPos] = 255;
+ }
+ tmpPos += 4;
+ mask >>= 1;
+ }
+ }
+
+ ctx.putImageData(tmpImgData, 0, 0);
+ }
+
+ function copyCtxState(sourceCtx, destCtx) {
+ var properties = ['strokeStyle', 'fillStyle', 'fillRule', 'globalAlpha',
+ 'lineWidth', 'lineCap', 'lineJoin', 'miterLimit',
+ 'globalCompositeOperation', 'font'];
+ for (var i = 0, ii = properties.length; i < ii; i++) {
+ var property = properties[i];
+ if (property in sourceCtx) {
+ destCtx[property] = sourceCtx[property];
+ }
+ }
+ if ('setLineDash' in sourceCtx) {
+ destCtx.setLineDash(sourceCtx.getLineDash());
+ destCtx.lineDashOffset = sourceCtx.lineDashOffset;
+ } else if ('mozDash' in sourceCtx) {
+ destCtx.mozDash = sourceCtx.mozDash;
+ destCtx.mozDashOffset = sourceCtx.mozDashOffset;
+ }
+ }
+
+ var LINE_CAP_STYLES = ['butt', 'round', 'square'];
+ var LINE_JOIN_STYLES = ['miter', 'round', 'bevel'];
+ var NORMAL_CLIP = {};
+ var EO_CLIP = {};
+
+ CanvasGraphics.prototype = {
+
+ beginDrawing: function CanvasGraphics_beginDrawing(viewport, transparency) {
+ // For pdfs that use blend modes we have to clear the canvas else certain
+ // blend modes can look wrong since we'd be blending with a white
+ // backdrop. The problem with a transparent backdrop though is we then
+ // don't get sub pixel anti aliasing on text, so we fill with white if
+ // we can.
+ var width = this.ctx.canvas.width;
+ var height = this.ctx.canvas.height;
+ if (transparency) {
+ this.ctx.clearRect(0, 0, width, height);
+ } else {
+ this.ctx.mozOpaque = true;
+ this.ctx.save();
+ this.ctx.fillStyle = 'rgb(255, 255, 255)';
+ this.ctx.fillRect(0, 0, width, height);
+ this.ctx.restore();
+ }
+
+ var transform = viewport.transform;
+ this.baseTransform = transform.slice();
+ this.ctx.save();
+ this.ctx.transform.apply(this.ctx, transform);
+
+ if (this.textLayer) {
+ this.textLayer.beginLayout();
+ }
+ if (this.imageLayer) {
+ this.imageLayer.beginLayout();
+ }
+ },
+
+ executeOperatorList: function CanvasGraphics_executeOperatorList(
+ operatorList,
+ executionStartIdx, continueCallback,
+ stepper) {
+ var argsArray = operatorList.argsArray;
+ var fnArray = operatorList.fnArray;
+ var i = executionStartIdx || 0;
+ var argsArrayLen = argsArray.length;
+
+ // Sometimes the OperatorList to execute is empty.
+ if (argsArrayLen == i) {
+ return i;
+ }
+
+ var executionEndIdx;
+ var endTime = Date.now() + EXECUTION_TIME;
+
+ var commonObjs = this.commonObjs;
+ var objs = this.objs;
+ var fnId;
+ var deferred = Promise.resolve();
+
+ while (true) {
+ if (stepper && i === stepper.nextBreakPoint) {
+ stepper.breakIt(i, continueCallback);
+ return i;
+ }
+
+ fnId = fnArray[i];
+
+ if (fnId !== OPS.dependency) {
+ this[fnId].apply(this, argsArray[i]);
+ } else {
+ var deps = argsArray[i];
+ for (var n = 0, nn = deps.length; n < nn; n++) {
+ var depObjId = deps[n];
+ var common = depObjId.substring(0, 2) == 'g_';
+
+ // If the promise isn't resolved yet, add the continueCallback
+ // to the promise and bail out.
+ if (!common && !objs.isResolved(depObjId)) {
+ objs.get(depObjId, continueCallback);
+ return i;
+ }
+ if (common && !commonObjs.isResolved(depObjId)) {
+ commonObjs.get(depObjId, continueCallback);
+ return i;
+ }
+ }
+ }
+
+ i++;
+
+ // If the entire operatorList was executed, stop as were done.
+ if (i == argsArrayLen) {
+ return i;
+ }
+
+ // If the execution took longer then a certain amount of time, schedule
+ // to continue exeution after a short delay.
+ // However, this is only possible if a 'continueCallback' is passed in.
+ if (continueCallback && Date.now() > endTime) {
+ deferred.then(continueCallback);
+ return i;
+ }
+
+ // If the operatorList isn't executed completely yet OR the execution
+ // time was short enough, do another execution round.
+ }
+ },
+
+ endDrawing: function CanvasGraphics_endDrawing() {
+ this.ctx.restore();
+ CachedCanvases.clear();
+
+ if (this.textLayer) {
+ this.textLayer.endLayout();
+ }
+ if (this.imageLayer) {
+ this.imageLayer.endLayout();
+ }
+ },
+
+ // Graphics state
+ setLineWidth: function CanvasGraphics_setLineWidth(width) {
+ this.current.lineWidth = width;
+ this.ctx.lineWidth = width;
+ },
+ setLineCap: function CanvasGraphics_setLineCap(style) {
+ this.ctx.lineCap = LINE_CAP_STYLES[style];
+ },
+ setLineJoin: function CanvasGraphics_setLineJoin(style) {
+ this.ctx.lineJoin = LINE_JOIN_STYLES[style];
+ },
+ setMiterLimit: function CanvasGraphics_setMiterLimit(limit) {
+ this.ctx.miterLimit = limit;
+ },
+ setDash: function CanvasGraphics_setDash(dashArray, dashPhase) {
+ var ctx = this.ctx;
+ if ('setLineDash' in ctx) {
+ ctx.setLineDash(dashArray);
+ ctx.lineDashOffset = dashPhase;
+ } else {
+ ctx.mozDash = dashArray;
+ ctx.mozDashOffset = dashPhase;
+ }
+ },
+ setRenderingIntent: function CanvasGraphics_setRenderingIntent(intent) {
+ // Maybe if we one day fully support color spaces this will be important
+ // for now we can ignore.
+ // TODO set rendering intent?
+ },
+ setFlatness: function CanvasGraphics_setFlatness(flatness) {
+ // There's no way to control this with canvas, but we can safely ignore.
+ // TODO set flatness?
+ },
+ setGState: function CanvasGraphics_setGState(states) {
+ for (var i = 0, ii = states.length; i < ii; i++) {
+ var state = states[i];
+ var key = state[0];
+ var value = state[1];
+
+ switch (key) {
+ case 'LW':
+ this.setLineWidth(value);
+ break;
+ case 'LC':
+ this.setLineCap(value);
+ break;
+ case 'LJ':
+ this.setLineJoin(value);
+ break;
+ case 'ML':
+ this.setMiterLimit(value);
+ break;
+ case 'D':
+ this.setDash(value[0], value[1]);
+ break;
+ case 'RI':
+ this.setRenderingIntent(value);
+ break;
+ case 'FL':
+ this.setFlatness(value);
+ break;
+ case 'Font':
+ this.setFont(value[0], value[1]);
+ break;
+ case 'CA':
+ this.current.strokeAlpha = state[1];
+ break;
+ case 'ca':
+ this.current.fillAlpha = state[1];
+ this.ctx.globalAlpha = state[1];
+ break;
+ case 'BM':
+ if (value && value.name && (value.name !== 'Normal')) {
+ var mode = value.name.replace(/([A-Z])/g,
+ function(c) {
+ return '-' + c.toLowerCase();
+ }
+ ).substring(1);
+ this.ctx.globalCompositeOperation = mode;
+ if (this.ctx.globalCompositeOperation !== mode) {
+ warn('globalCompositeOperation "' + mode +
+ '" is not supported');
+ }
+ } else {
+ this.ctx.globalCompositeOperation = 'source-over';
+ }
+ break;
+ }
+ }
+ },
+ save: function CanvasGraphics_save() {
+ this.ctx.save();
+ var old = this.current;
+ this.stateStack.push(old);
+ this.current = old.clone();
+ },
+ restore: function CanvasGraphics_restore() {
+ var prev = this.stateStack.pop();
+ if (prev) {
+ this.current = prev;
+ this.ctx.restore();
+ }
+ },
+ transform: function CanvasGraphics_transform(a, b, c, d, e, f) {
+ this.ctx.transform(a, b, c, d, e, f);
+ },
+
+ // Path
+ moveTo: function CanvasGraphics_moveTo(x, y) {
+ this.ctx.moveTo(x, y);
+ this.current.setCurrentPoint(x, y);
+ },
+ lineTo: function CanvasGraphics_lineTo(x, y) {
+ this.ctx.lineTo(x, y);
+ this.current.setCurrentPoint(x, y);
+ },
+ curveTo: function CanvasGraphics_curveTo(x1, y1, x2, y2, x3, y3) {
+ this.ctx.bezierCurveTo(x1, y1, x2, y2, x3, y3);
+ this.current.setCurrentPoint(x3, y3);
+ },
+ curveTo2: function CanvasGraphics_curveTo2(x2, y2, x3, y3) {
+ var current = this.current;
+ this.ctx.bezierCurveTo(current.x, current.y, x2, y2, x3, y3);
+ current.setCurrentPoint(x3, y3);
+ },
+ curveTo3: function CanvasGraphics_curveTo3(x1, y1, x3, y3) {
+ this.curveTo(x1, y1, x3, y3, x3, y3);
+ this.current.setCurrentPoint(x3, y3);
+ },
+ closePath: function CanvasGraphics_closePath() {
+ this.ctx.closePath();
+ },
+ rectangle: function CanvasGraphics_rectangle(x, y, width, height) {
+ this.ctx.rect(x, y, width, height);
+ },
+ stroke: function CanvasGraphics_stroke(consumePath) {
+ consumePath = typeof consumePath !== 'undefined' ? consumePath : true;
+ var ctx = this.ctx;
+ var strokeColor = this.current.strokeColor;
+ if (this.current.lineWidth === 0)
+ ctx.lineWidth = this.getSinglePixelWidth();
+ // For stroke we want to temporarily change the global alpha to the
+ // stroking alpha.
+ ctx.globalAlpha = this.current.strokeAlpha;
+ if (strokeColor && strokeColor.hasOwnProperty('type') &&
+ strokeColor.type === 'Pattern') {
+ // for patterns, we transform to pattern space, calculate
+ // the pattern, call stroke, and restore to user space
+ ctx.save();
+ ctx.strokeStyle = strokeColor.getPattern(ctx, this);
+ ctx.stroke();
+ ctx.restore();
+ } else {
+ ctx.stroke();
+ }
+ if (consumePath)
+ this.consumePath();
+ // Restore the global alpha to the fill alpha
+ ctx.globalAlpha = this.current.fillAlpha;
+ },
+ closeStroke: function CanvasGraphics_closeStroke() {
+ this.closePath();
+ this.stroke();
+ },
+ fill: function CanvasGraphics_fill(consumePath) {
+ consumePath = typeof consumePath !== 'undefined' ? consumePath : true;
+ var ctx = this.ctx;
+ var fillColor = this.current.fillColor;
+ var needRestore = false;
+
+ if (fillColor && fillColor.hasOwnProperty('type') &&
+ fillColor.type === 'Pattern') {
+ ctx.save();
+ ctx.fillStyle = fillColor.getPattern(ctx, this);
+ needRestore = true;
+ }
+
+ if (this.pendingEOFill) {
+ if ('mozFillRule' in this.ctx) {
+ this.ctx.mozFillRule = 'evenodd';
+ this.ctx.fill();
+ this.ctx.mozFillRule = 'nonzero';
+ } else {
+ try {
+ this.ctx.fill('evenodd');
+ } catch (ex) {
+ // shouldn't really happen, but browsers might think differently
+ this.ctx.fill();
+ }
+ }
+ this.pendingEOFill = false;
+ } else {
+ this.ctx.fill();
+ }
+
+ if (needRestore) {
+ ctx.restore();
+ }
+ if (consumePath) {
+ this.consumePath();
+ }
+ },
+ eoFill: function CanvasGraphics_eoFill() {
+ this.pendingEOFill = true;
+ this.fill();
+ },
+ fillStroke: function CanvasGraphics_fillStroke() {
+ this.fill(false);
+ this.stroke(false);
+
+ this.consumePath();
+ },
+ eoFillStroke: function CanvasGraphics_eoFillStroke() {
+ this.pendingEOFill = true;
+ this.fillStroke();
+ },
+ closeFillStroke: function CanvasGraphics_closeFillStroke() {
+ this.closePath();
+ this.fillStroke();
+ },
+ closeEOFillStroke: function CanvasGraphics_closeEOFillStroke() {
+ this.pendingEOFill = true;
+ this.closePath();
+ this.fillStroke();
+ },
+ endPath: function CanvasGraphics_endPath() {
+ this.consumePath();
+ },
+
+ // Clipping
+ clip: function CanvasGraphics_clip() {
+ this.pendingClip = NORMAL_CLIP;
+ },
+ eoClip: function CanvasGraphics_eoClip() {
+ this.pendingClip = EO_CLIP;
+ },
+
+ // Text
+ beginText: function CanvasGraphics_beginText() {
+ this.current.textMatrix = IDENTITY_MATRIX;
+ this.current.x = this.current.lineX = 0;
+ this.current.y = this.current.lineY = 0;
+ },
+ endText: function CanvasGraphics_endText() {
+ if (!('pendingTextPaths' in this)) {
+ this.ctx.beginPath();
+ return;
+ }
+ var paths = this.pendingTextPaths;
+ var ctx = this.ctx;
+
+ ctx.save();
+ ctx.beginPath();
+ for (var i = 0; i < paths.length; i++) {
+ var path = paths[i];
+ ctx.setTransform.apply(ctx, path.transform);
+ ctx.translate(path.x, path.y);
+ path.addToPath(ctx, path.fontSize);
+ }
+ ctx.restore();
+ ctx.clip();
+ ctx.beginPath();
+ delete this.pendingTextPaths;
+ },
+ setCharSpacing: function CanvasGraphics_setCharSpacing(spacing) {
+ this.current.charSpacing = spacing;
+ },
+ setWordSpacing: function CanvasGraphics_setWordSpacing(spacing) {
+ this.current.wordSpacing = spacing;
+ },
+ setHScale: function CanvasGraphics_setHScale(scale) {
+ this.current.textHScale = scale / 100;
+ },
+ setLeading: function CanvasGraphics_setLeading(leading) {
+ this.current.leading = -leading;
+ },
+ setFont: function CanvasGraphics_setFont(fontRefName, size) {
+ var fontObj = this.commonObjs.get(fontRefName);
+ var current = this.current;
+
+ if (!fontObj)
+ error('Can\'t find font for ' + fontRefName);
+
+ current.fontMatrix = fontObj.fontMatrix ? fontObj.fontMatrix :
+ FONT_IDENTITY_MATRIX;
+
+ // A valid matrix needs all main diagonal elements to be non-zero
+ // This also ensures we bypass FF bugzilla bug #719844.
+ if (current.fontMatrix[0] === 0 ||
+ current.fontMatrix[3] === 0) {
+ warn('Invalid font matrix for font ' + fontRefName);
+ }
+
+ // The spec for Tf (setFont) says that 'size' specifies the font 'scale',
+ // and in some docs this can be negative (inverted x-y axes).
+ if (size < 0) {
+ size = -size;
+ current.fontDirection = -1;
+ } else {
+ current.fontDirection = 1;
+ }
+
+ this.current.font = fontObj;
+ this.current.fontSize = size;
+
+ if (fontObj.coded)
+ return; // we don't need ctx.font for Type3 fonts
+
+ var name = fontObj.loadedName || 'sans-serif';
+ var bold = fontObj.black ? (fontObj.bold ? 'bolder' : 'bold') :
+ (fontObj.bold ? 'bold' : 'normal');
+
+ var italic = fontObj.italic ? 'italic' : 'normal';
+ var typeface = '"' + name + '", ' + fontObj.fallbackName;
+
+ // Some font backends cannot handle fonts below certain size.
+ // Keeping the font at minimal size and using the fontSizeScale to change
+ // the current transformation matrix before the fillText/strokeText.
+ // See https://bugzilla.mozilla.org/show_bug.cgi?id=726227
+ var browserFontSize = size >= MIN_FONT_SIZE ? size : MIN_FONT_SIZE;
+ this.current.fontSizeScale = browserFontSize != MIN_FONT_SIZE ? 1.0 :
+ size / MIN_FONT_SIZE;
+
+ var rule = italic + ' ' + bold + ' ' + browserFontSize + 'px ' + typeface;
+ this.ctx.font = rule;
+ },
+ setTextRenderingMode: function CanvasGraphics_setTextRenderingMode(mode) {
+ this.current.textRenderingMode = mode;
+ },
+ setTextRise: function CanvasGraphics_setTextRise(rise) {
+ this.current.textRise = rise;
+ },
+ moveText: function CanvasGraphics_moveText(x, y) {
+ this.current.x = this.current.lineX += x;
+ this.current.y = this.current.lineY += y;
+ },
+ setLeadingMoveText: function CanvasGraphics_setLeadingMoveText(x, y) {
+ this.setLeading(-y);
+ this.moveText(x, y);
+ },
+ setTextMatrix: function CanvasGraphics_setTextMatrix(a, b, c, d, e, f) {
+ this.current.textMatrix = [a, b, c, d, e, f];
+
+ this.current.x = this.current.lineX = 0;
+ this.current.y = this.current.lineY = 0;
+ },
+ nextLine: function CanvasGraphics_nextLine() {
+ this.moveText(0, this.current.leading);
+ },
+ applyTextTransforms: function CanvasGraphics_applyTextTransforms() {
+ var ctx = this.ctx;
+ var current = this.current;
+ ctx.transform.apply(ctx, current.textMatrix);
+ ctx.translate(current.x, current.y + current.textRise);
+ if (current.fontDirection > 0) {
+ ctx.scale(current.textHScale, -1);
+ } else {
+ ctx.scale(-current.textHScale, 1);
+ }
+ },
+ createTextGeometry: function CanvasGraphics_createTextGeometry() {
+ var geometry = {};
+ var ctx = this.ctx;
+ var font = this.current.font;
+ var ctxMatrix = ctx.mozCurrentTransform;
+ var a = ctxMatrix[0], b = ctxMatrix[1], c = ctxMatrix[2];
+ var d = ctxMatrix[3], e = ctxMatrix[4], f = ctxMatrix[5];
+ var sx = (a >= 0) ?
+ Math.sqrt((a * a) + (b * b)) : -Math.sqrt((a * a) + (b * b));
+ var sy = (d >= 0) ?
+ Math.sqrt((c * c) + (d * d)) : -Math.sqrt((c * c) + (d * d));
+ var angle = Math.atan2(b, a);
+ var x = e;
+ var y = f;
+ geometry.x = x;
+ geometry.y = y;
+ geometry.hScale = sx;
+ geometry.vScale = sy;
+ geometry.angle = angle;
+ geometry.spaceWidth = font.spaceWidth;
+ geometry.fontName = font.loadedName;
+ geometry.fontFamily = font.fallbackName;
+ geometry.fontSize = this.current.fontSize;
+ geometry.ascent = font.ascent;
+ geometry.descent = font.descent;
+ return geometry;
+ },
+
+ paintChar: function (character, x, y) {
+ var ctx = this.ctx;
+ var current = this.current;
+ var font = current.font;
+ var fontSize = current.fontSize / current.fontSizeScale;
+ var textRenderingMode = current.textRenderingMode;
+ var fillStrokeMode = textRenderingMode &
+ TextRenderingMode.FILL_STROKE_MASK;
+ var isAddToPathSet = !!(textRenderingMode &
+ TextRenderingMode.ADD_TO_PATH_FLAG);
+
+ var addToPath;
+ if (font.disableFontFace || isAddToPathSet) {
+ addToPath = font.getPathGenerator(this.commonObjs, character);
+ }
+
+ if (font.disableFontFace) {
+ ctx.save();
+ ctx.translate(x, y);
+ ctx.beginPath();
+ addToPath(ctx, fontSize);
+ if (fillStrokeMode === TextRenderingMode.FILL ||
+ fillStrokeMode === TextRenderingMode.FILL_STROKE) {
+ ctx.fill();
+ }
+ if (fillStrokeMode === TextRenderingMode.STROKE ||
+ fillStrokeMode === TextRenderingMode.FILL_STROKE) {
+ ctx.stroke();
+ }
+ ctx.restore();
+ } else {
+ if (fillStrokeMode === TextRenderingMode.FILL ||
+ fillStrokeMode === TextRenderingMode.FILL_STROKE) {
+ ctx.fillText(character, x, y);
+ }
+ if (fillStrokeMode === TextRenderingMode.STROKE ||
+ fillStrokeMode === TextRenderingMode.FILL_STROKE) {
+ ctx.strokeText(character, x, y);
+ }
+ }
+
+ if (isAddToPathSet) {
+ var paths = this.pendingTextPaths || (this.pendingTextPaths = []);
+ paths.push({
+ transform: ctx.mozCurrentTransform,
+ x: x,
+ y: y,
+ fontSize: fontSize,
+ addToPath: addToPath
+ });
+ }
+ },
+
+ get isFontSubpixelAAEnabled() {
+ // Checks if anti-aliasing is enabled when scaled text is painted.
+ // On Windows GDI scaled fonts looks bad.
+ var ctx = document.createElement('canvas').getContext('2d');
+ ctx.scale(1.5, 1);
+ ctx.fillText('I', 0, 10);
+ var data = ctx.getImageData(0, 0, 10, 10).data;
+ var enabled = false;
+ for (var i = 3; i < data.length; i += 4) {
+ if (data[i] > 0 && data[i] < 255) {
+ enabled = true;
+ break;
+ }
+ }
+ return shadow(this, 'isFontSubpixelAAEnabled', enabled);
+ },
+
+ showText: function CanvasGraphics_showText(glyphs, skipTextSelection) {
+ var ctx = this.ctx;
+ var current = this.current;
+ var font = current.font;
+ var fontSize = current.fontSize;
+ var fontSizeScale = current.fontSizeScale;
+ var charSpacing = current.charSpacing;
+ var wordSpacing = current.wordSpacing;
+ var textHScale = current.textHScale * current.fontDirection;
+ var fontMatrix = current.fontMatrix || FONT_IDENTITY_MATRIX;
+ var glyphsLength = glyphs.length;
+ var textLayer = this.textLayer;
+ var geom;
+ var textSelection = textLayer && !skipTextSelection ? true : false;
+ var canvasWidth = 0.0;
+ var vertical = font.vertical;
+ var defaultVMetrics = font.defaultVMetrics;
+
+ // Type3 fonts - each glyph is a "mini-PDF"
+ if (font.coded) {
+ ctx.save();
+ ctx.transform.apply(ctx, current.textMatrix);
+ ctx.translate(current.x, current.y);
+
+ ctx.scale(textHScale, 1);
+
+ if (textSelection) {
+ this.save();
+ ctx.scale(1, -1);
+ geom = this.createTextGeometry();
+ this.restore();
+ }
+ for (var i = 0; i < glyphsLength; ++i) {
+
+ var glyph = glyphs[i];
+ if (glyph === null) {
+ // word break
+ this.ctx.translate(wordSpacing, 0);
+ current.x += wordSpacing * textHScale;
+ continue;
+ }
+
+ this.processingType3 = glyph;
+ this.save();
+ ctx.scale(fontSize, fontSize);
+ ctx.transform.apply(ctx, fontMatrix);
+ this.executeOperatorList(glyph.operatorList);
+ this.restore();
+
+ var transformed = Util.applyTransform([glyph.width, 0], fontMatrix);
+ var width = (transformed[0] * fontSize + charSpacing) *
+ current.fontDirection;
+
+ ctx.translate(width, 0);
+ current.x += width * textHScale;
+
+ canvasWidth += width;
+ }
+ ctx.restore();
+ this.processingType3 = null;
+ } else {
+ ctx.save();
+ this.applyTextTransforms();
+
+ var lineWidth = current.lineWidth;
+ var a1 = current.textMatrix[0], b1 = current.textMatrix[1];
+ var scale = Math.sqrt(a1 * a1 + b1 * b1);
+ if (scale === 0 || lineWidth === 0)
+ lineWidth = this.getSinglePixelWidth();
+ else
+ lineWidth /= scale;
+
+ if (textSelection)
+ geom = this.createTextGeometry();
+
+ if (fontSizeScale != 1.0) {
+ ctx.scale(fontSizeScale, fontSizeScale);
+ lineWidth /= fontSizeScale;
+ }
+
+ ctx.lineWidth = lineWidth;
+
+ var x = 0;
+ for (var i = 0; i < glyphsLength; ++i) {
+ var glyph = glyphs[i];
+ if (glyph === null) {
+ // word break
+ x += current.fontDirection * wordSpacing;
+ continue;
+ }
+
+ var restoreNeeded = false;
+ var character = glyph.fontChar;
+ var vmetric = glyph.vmetric || defaultVMetrics;
+ if (vertical) {
+ var vx = glyph.vmetric ? vmetric[1] : glyph.width * 0.5;
+ vx = -vx * fontSize * current.fontMatrix[0];
+ var vy = vmetric[2] * fontSize * current.fontMatrix[0];
+ }
+ var width = vmetric ? -vmetric[0] : glyph.width;
+ var charWidth = width * fontSize * current.fontMatrix[0] +
+ charSpacing * current.fontDirection;
+ var accent = glyph.accent;
+
+ var scaledX, scaledY, scaledAccentX, scaledAccentY;
+ if (!glyph.disabled) {
+ if (vertical) {
+ scaledX = vx / fontSizeScale;
+ scaledY = (x + vy) / fontSizeScale;
+ } else {
+ scaledX = x / fontSizeScale;
+ scaledY = 0;
+ }
+
+ if (font.remeasure && width > 0 && this.isFontSubpixelAAEnabled) {
+ // some standard fonts may not have the exact width, trying to
+ // rescale per character
+ var measuredWidth = ctx.measureText(character).width * 1000 /
+ current.fontSize * current.fontSizeScale;
+ var characterScaleX = width / measuredWidth;
+ restoreNeeded = true;
+ ctx.save();
+ ctx.scale(characterScaleX, 1);
+ scaledX /= characterScaleX;
+ if (accent) {
+ scaledAccentX /= characterScaleX;
+ }
+ }
+
+ this.paintChar(character, scaledX, scaledY);
+ if (accent) {
+ scaledAccentX = scaledX + accent.offset.x / fontSizeScale;
+ scaledAccentY = scaledY - accent.offset.y / fontSizeScale;
+ this.paintChar(accent.fontChar, scaledAccentX, scaledAccentY);
+ }
+ }
+
+ x += charWidth;
+
+ canvasWidth += charWidth;
+
+ if (restoreNeeded) {
+ ctx.restore();
+ }
+ }
+ if (vertical) {
+ current.y -= x * textHScale;
+ } else {
+ current.x += x * textHScale;
+ }
+ ctx.restore();
+ }
+
+ if (textSelection) {
+ geom.canvasWidth = canvasWidth;
+ if (vertical) {
+ var VERTICAL_TEXT_ROTATION = Math.PI / 2;
+ geom.angle += VERTICAL_TEXT_ROTATION;
+ }
+ this.textLayer.appendText(geom);
+ }
+
+ return canvasWidth;
+ },
+ showSpacedText: function CanvasGraphics_showSpacedText(arr) {
+ var ctx = this.ctx;
+ var current = this.current;
+ var font = current.font;
+ var fontSize = current.fontSize;
+ // TJ array's number is independent from fontMatrix
+ var textHScale = current.textHScale * 0.001 * current.fontDirection;
+ var arrLength = arr.length;
+ var textLayer = this.textLayer;
+ var geom;
+ var canvasWidth = 0.0;
+ var textSelection = textLayer ? true : false;
+ var vertical = font.vertical;
+ var spacingAccumulator = 0;
+
+ if (textSelection) {
+ ctx.save();
+ this.applyTextTransforms();
+ geom = this.createTextGeometry();
+ ctx.restore();
+ }
+
+ for (var i = 0; i < arrLength; ++i) {
+ var e = arr[i];
+ if (isNum(e)) {
+ var spacingLength = -e * fontSize * textHScale;
+ if (vertical) {
+ current.y += spacingLength;
+ } else {
+ current.x += spacingLength;
+ }
+
+ if (textSelection)
+ spacingAccumulator += spacingLength;
+ } else {
+ var shownCanvasWidth = this.showText(e, true);
+
+ if (textSelection) {
+ canvasWidth += spacingAccumulator + shownCanvasWidth;
+ spacingAccumulator = 0;
+ }
+ }
+ }
+
+ if (textSelection) {
+ geom.canvasWidth = canvasWidth;
+ if (vertical) {
+ var VERTICAL_TEXT_ROTATION = Math.PI / 2;
+ geom.angle += VERTICAL_TEXT_ROTATION;
+ }
+ this.textLayer.appendText(geom);
+ }
+ },
+ nextLineShowText: function CanvasGraphics_nextLineShowText(text) {
+ this.nextLine();
+ this.showText(text);
+ },
+ nextLineSetSpacingShowText:
+ function CanvasGraphics_nextLineSetSpacingShowText(wordSpacing,
+ charSpacing,
+ text) {
+ this.setWordSpacing(wordSpacing);
+ this.setCharSpacing(charSpacing);
+ this.nextLineShowText(text);
+ },
+
+ // Type3 fonts
+ setCharWidth: function CanvasGraphics_setCharWidth(xWidth, yWidth) {
+ // We can safely ignore this since the width should be the same
+ // as the width in the Widths array.
+ },
+ setCharWidthAndBounds: function CanvasGraphics_setCharWidthAndBounds(xWidth,
+ yWidth,
+ llx,
+ lly,
+ urx,
+ ury) {
+ // TODO According to the spec we're also suppose to ignore any operators
+ // that set color or include images while processing this type3 font.
+ this.rectangle(llx, lly, urx - llx, ury - lly);
+ this.clip();
+ this.endPath();
+ },
+
+ // Color
+ setStrokeColorSpace: function CanvasGraphics_setStrokeColorSpace(raw) {
+ this.current.strokeColorSpace = ColorSpace.fromIR(raw);
+ },
+ setFillColorSpace: function CanvasGraphics_setFillColorSpace(raw) {
+ this.current.fillColorSpace = ColorSpace.fromIR(raw);
+ },
+ setStrokeColor: function CanvasGraphics_setStrokeColor(/*...*/) {
+ var cs = this.current.strokeColorSpace;
+ var rgbColor = cs.getRgb(arguments, 0);
+ var color = Util.makeCssRgb(rgbColor);
+ this.ctx.strokeStyle = color;
+ this.current.strokeColor = color;
+ },
+ getColorN_Pattern: function CanvasGraphics_getColorN_Pattern(IR, cs) {
+ if (IR[0] == 'TilingPattern') {
+ var args = IR[1];
+ var base = cs.base;
+ var color;
+ if (base) {
+ var baseComps = base.numComps;
+
+ color = base.getRgb(args, 0);
+ }
+ var pattern = new TilingPattern(IR, color, this.ctx, this.objs,
+ this.commonObjs, this.baseTransform);
+ } else if (IR[0] == 'RadialAxial' || IR[0] == 'Dummy') {
+ var pattern = Pattern.shadingFromIR(IR);
+ } else {
+ error('Unkown IR type ' + IR[0]);
+ }
+ return pattern;
+ },
+ setStrokeColorN: function CanvasGraphics_setStrokeColorN(/*...*/) {
+ var cs = this.current.strokeColorSpace;
+
+ if (cs.name == 'Pattern') {
+ this.current.strokeColor = this.getColorN_Pattern(arguments, cs);
+ } else {
+ this.setStrokeColor.apply(this, arguments);
+ }
+ },
+ setFillColor: function CanvasGraphics_setFillColor(/*...*/) {
+ var cs = this.current.fillColorSpace;
+ var rgbColor = cs.getRgb(arguments, 0);
+ var color = Util.makeCssRgb(rgbColor);
+ this.ctx.fillStyle = color;
+ this.current.fillColor = color;
+ },
+ setFillColorN: function CanvasGraphics_setFillColorN(/*...*/) {
+ var cs = this.current.fillColorSpace;
+
+ if (cs.name == 'Pattern') {
+ this.current.fillColor = this.getColorN_Pattern(arguments, cs);
+ } else {
+ this.setFillColor.apply(this, arguments);
+ }
+ },
+ setStrokeGray: function CanvasGraphics_setStrokeGray(gray) {
+ this.current.strokeColorSpace = ColorSpace.singletons.gray;
+
+ var rgbColor = this.current.strokeColorSpace.getRgb(arguments, 0);
+ var color = Util.makeCssRgb(rgbColor);
+ this.ctx.strokeStyle = color;
+ this.current.strokeColor = color;
+ },
+ setFillGray: function CanvasGraphics_setFillGray(gray) {
+ this.current.fillColorSpace = ColorSpace.singletons.gray;
+
+ var rgbColor = this.current.fillColorSpace.getRgb(arguments, 0);
+ var color = Util.makeCssRgb(rgbColor);
+ this.ctx.fillStyle = color;
+ this.current.fillColor = color;
+ },
+ setStrokeRGBColor: function CanvasGraphics_setStrokeRGBColor(r, g, b) {
+ this.current.strokeColorSpace = ColorSpace.singletons.rgb;
+
+ var rgbColor = this.current.strokeColorSpace.getRgb(arguments, 0);
+ var color = Util.makeCssRgb(rgbColor);
+ this.ctx.strokeStyle = color;
+ this.current.strokeColor = color;
+ },
+ setFillRGBColor: function CanvasGraphics_setFillRGBColor(r, g, b) {
+ this.current.fillColorSpace = ColorSpace.singletons.rgb;
+
+ var rgbColor = this.current.fillColorSpace.getRgb(arguments, 0);
+ var color = Util.makeCssRgb(rgbColor);
+ this.ctx.fillStyle = color;
+ this.current.fillColor = color;
+ },
+ setStrokeCMYKColor: function CanvasGraphics_setStrokeCMYKColor(c, m, y, k) {
+ this.current.strokeColorSpace = ColorSpace.singletons.cmyk;
+
+ var color = Util.makeCssCmyk(arguments);
+ this.ctx.strokeStyle = color;
+ this.current.strokeColor = color;
+ },
+ setFillCMYKColor: function CanvasGraphics_setFillCMYKColor(c, m, y, k) {
+ this.current.fillColorSpace = ColorSpace.singletons.cmyk;
+
+ var color = Util.makeCssCmyk(arguments);
+ this.ctx.fillStyle = color;
+ this.current.fillColor = color;
+ },
+
+ shadingFill: function CanvasGraphics_shadingFill(patternIR) {
+ var ctx = this.ctx;
+
+ this.save();
+ var pattern = Pattern.shadingFromIR(patternIR);
+ ctx.fillStyle = pattern.getPattern(ctx, this);
+
+ var inv = ctx.mozCurrentTransformInverse;
+ if (inv) {
+ var canvas = ctx.canvas;
+ var width = canvas.width;
+ var height = canvas.height;
+
+ var bl = Util.applyTransform([0, 0], inv);
+ var br = Util.applyTransform([0, height], inv);
+ var ul = Util.applyTransform([width, 0], inv);
+ var ur = Util.applyTransform([width, height], inv);
+
+ var x0 = Math.min(bl[0], br[0], ul[0], ur[0]);
+ var y0 = Math.min(bl[1], br[1], ul[1], ur[1]);
+ var x1 = Math.max(bl[0], br[0], ul[0], ur[0]);
+ var y1 = Math.max(bl[1], br[1], ul[1], ur[1]);
+
+ this.ctx.fillRect(x0, y0, x1 - x0, y1 - y0);
+ } else {
+ // HACK to draw the gradient onto an infinite rectangle.
+ // PDF gradients are drawn across the entire image while
+ // Canvas only allows gradients to be drawn in a rectangle
+ // The following bug should allow us to remove this.
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=664884
+
+ this.ctx.fillRect(-1e10, -1e10, 2e10, 2e10);
+ }
+
+ this.restore();
+ },
+
+ // Images
+ beginInlineImage: function CanvasGraphics_beginInlineImage() {
+ error('Should not call beginInlineImage');
+ },
+ beginImageData: function CanvasGraphics_beginImageData() {
+ error('Should not call beginImageData');
+ },
+
+ paintFormXObjectBegin: function CanvasGraphics_paintFormXObjectBegin(matrix,
+ bbox) {
+ this.save();
+ this.baseTransformStack.push(this.baseTransform);
+
+ if (matrix && isArray(matrix) && 6 == matrix.length)
+ this.transform.apply(this, matrix);
+
+ this.baseTransform = this.ctx.mozCurrentTransform;
+
+ if (bbox && isArray(bbox) && 4 == bbox.length) {
+ var width = bbox[2] - bbox[0];
+ var height = bbox[3] - bbox[1];
+ this.rectangle(bbox[0], bbox[1], width, height);
+ this.clip();
+ this.endPath();
+ }
+ },
+
+ paintFormXObjectEnd: function CanvasGraphics_paintFormXObjectEnd() {
+ this.restore();
+ this.baseTransform = this.baseTransformStack.pop();
+ },
+
+ beginGroup: function CanvasGraphics_beginGroup(group) {
+ this.save();
+ var currentCtx = this.ctx;
+ // TODO non-isolated groups - according to Rik at adobe non-isolated
+ // group results aren't usually that different and they even have tools
+ // that ignore this setting. Notes from Rik on implmenting:
+ // - When you encounter an transparency group, create a new canvas with
+ // the dimensions of the bbox
+ // - copy the content from the previous canvas to the new canvas
+ // - draw as usual
+ // - remove the backdrop alpha:
+ // alphaNew = 1 - (1 - alpha)/(1 - alphaBackdrop) with 'alpha' the alpha
+ // value of your transparency group and 'alphaBackdrop' the alpha of the
+ // backdrop
+ // - remove background color:
+ // colorNew = color - alphaNew *colorBackdrop /(1 - alphaNew)
+ if (!group.isolated) {
+ info('TODO: Support non-isolated groups.');
+ }
+
+ // TODO knockout - supposedly possible with the clever use of compositing
+ // modes.
+ if (group.knockout) {
+ warn('Knockout groups not supported.');
+ }
+
+ var currentTransform = currentCtx.mozCurrentTransform;
+ if (group.matrix) {
+ currentCtx.transform.apply(currentCtx, group.matrix);
+ }
+ assert(group.bbox, 'Bounding box is required.');
+
+ // Based on the current transform figure out how big the bounding box
+ // will actually be.
+ var bounds = Util.getAxialAlignedBoundingBox(
+ group.bbox,
+ currentCtx.mozCurrentTransform);
+ // Clip the bounding box to the current canvas.
+ var canvasBounds = [0,
+ 0,
+ currentCtx.canvas.width,
+ currentCtx.canvas.height];
+ bounds = Util.intersect(bounds, canvasBounds) || [0, 0, 0, 0];
+ // Use ceil in case we're between sizes so we don't create canvas that is
+ // too small and make the canvas at least 1x1 pixels.
+ var drawnWidth = Math.max(Math.ceil(bounds[2] - bounds[0]), 1);
+ var drawnHeight = Math.max(Math.ceil(bounds[3] - bounds[1]), 1);
+
+ var scratchCanvas = CachedCanvases.getCanvas(
+ 'groupAt' + this.groupLevel, drawnWidth, drawnHeight, true);
+ var groupCtx = scratchCanvas.context;
+ // Since we created a new canvas that is just the size of the bounding box
+ // we have to translate the group ctx.
+ var offsetX = bounds[0];
+ var offsetY = bounds[1];
+ groupCtx.translate(-offsetX, -offsetY);
+ groupCtx.transform.apply(groupCtx, currentTransform);
+
+ // Setup the current ctx so when the group is popped we draw it the right
+ // location.
+ currentCtx.setTransform(1, 0, 0, 1, 0, 0);
+ currentCtx.translate(offsetX, offsetY);
+ // The transparency group inherits all off the current graphics state
+ // except the blend mode, soft mask, and alpha constants.
+ copyCtxState(currentCtx, groupCtx);
+ this.ctx = groupCtx;
+ this.setGState([
+ ['SMask', 'None'],
+ ['BM', 'Normal'],
+ ['ca', 1],
+ ['CA', 1]
+ ]);
+ this.groupStack.push(currentCtx);
+ this.groupLevel++;
+ },
+
+ endGroup: function CanvasGraphics_endGroup(group) {
+ this.groupLevel--;
+ var groupCtx = this.ctx;
+ this.ctx = this.groupStack.pop();
+ // Turn off image smoothing to avoid sub pixel interpolation which can
+ // look kind of blurry for some pdfs.
+ if ('imageSmoothingEnabled' in this.ctx) {
+ this.ctx.imageSmoothingEnabled = false;
+ } else {
+ this.ctx.mozImageSmoothingEnabled = false;
+ }
+ this.ctx.drawImage(groupCtx.canvas, 0, 0);
+ this.restore();
+ },
+
+ beginAnnotations: function CanvasGraphics_beginAnnotations() {
+ this.save();
+ this.current = new CanvasExtraState();
+ },
+
+ endAnnotations: function CanvasGraphics_endAnnotations() {
+ this.restore();
+ },
+
+ beginAnnotation: function CanvasGraphics_beginAnnotation(rect, transform,
+ matrix) {
+ this.save();
+
+ if (rect && isArray(rect) && 4 == rect.length) {
+ var width = rect[2] - rect[0];
+ var height = rect[3] - rect[1];
+ this.rectangle(rect[0], rect[1], width, height);
+ this.clip();
+ this.endPath();
+ }
+
+ this.transform.apply(this, transform);
+ this.transform.apply(this, matrix);
+ },
+
+ endAnnotation: function CanvasGraphics_endAnnotation() {
+ this.restore();
+ },
+
+ paintJpegXObject: function CanvasGraphics_paintJpegXObject(objId, w, h) {
+ var domImage = this.objs.get(objId);
+ if (!domImage) {
+ error('Dependent image isn\'t ready yet');
+ }
+
+ this.save();
+
+ var ctx = this.ctx;
+ // scale the image to the unit square
+ ctx.scale(1 / w, -1 / h);
+
+ ctx.drawImage(domImage, 0, 0, domImage.width, domImage.height,
+ 0, -h, w, h);
+ if (this.imageLayer) {
+ var currentTransform = ctx.mozCurrentTransformInverse;
+ var position = this.getCanvasPosition(0, 0);
+ this.imageLayer.appendImage({
+ objId: objId,
+ left: position[0],
+ top: position[1],
+ width: w / currentTransform[0],
+ height: h / currentTransform[3]
+ });
+ }
+ this.restore();
+ },
+
+ paintImageMaskXObject: function CanvasGraphics_paintImageMaskXObject(img) {
+ var ctx = this.ctx;
+ var width = img.width, height = img.height;
+
+ var glyph = this.processingType3;
+
+ if (COMPILE_TYPE3_GLYPHS && glyph && !('compiled' in glyph)) {
+ var MAX_SIZE_TO_COMPILE = 1000;
+ if (width <= MAX_SIZE_TO_COMPILE && height <= MAX_SIZE_TO_COMPILE) {
+ glyph.compiled =
+ compileType3Glyph({data: img.data, width: width, height: height});
+ } else {
+ glyph.compiled = null;
+ }
+ }
+
+ if (glyph && glyph.compiled) {
+ glyph.compiled(ctx);
+ return;
+ }
+
+ var maskCanvas = CachedCanvases.getCanvas('maskCanvas', width, height);
+ var maskCtx = maskCanvas.context;
+ maskCtx.save();
+
+ putBinaryImageMask(maskCtx, img);
+
+ maskCtx.globalCompositeOperation = 'source-in';
+
+ var fillColor = this.current.fillColor;
+ maskCtx.fillStyle = (fillColor && fillColor.hasOwnProperty('type') &&
+ fillColor.type === 'Pattern') ?
+ fillColor.getPattern(maskCtx, this) : fillColor;
+ maskCtx.fillRect(0, 0, width, height);
+
+ maskCtx.restore();
+
+ this.paintInlineImageXObject(maskCanvas.canvas);
+ },
+
+ paintImageMaskXObjectGroup:
+ function CanvasGraphics_paintImageMaskXObjectGroup(images) {
+ var ctx = this.ctx;
+
+ for (var i = 0, ii = images.length; i < ii; i++) {
+ var image = images[i];
+ var width = image.width, height = image.height;
+
+ var maskCanvas = CachedCanvases.getCanvas('maskCanvas', width, height);
+ var maskCtx = maskCanvas.context;
+ maskCtx.save();
+
+ putBinaryImageMask(maskCtx, image);
+
+ maskCtx.globalCompositeOperation = 'source-in';
+
+ var fillColor = this.current.fillColor;
+ maskCtx.fillStyle = (fillColor && fillColor.hasOwnProperty('type') &&
+ fillColor.type === 'Pattern') ?
+ fillColor.getPattern(maskCtx, this) : fillColor;
+ maskCtx.fillRect(0, 0, width, height);
+
+ maskCtx.restore();
+
+ ctx.save();
+ ctx.transform.apply(ctx, image.transform);
+ ctx.scale(1, -1);
+ ctx.drawImage(maskCanvas.canvas, 0, 0, width, height,
+ 0, -1, 1, 1);
+ ctx.restore();
+ }
+ },
+
+ paintImageXObject: function CanvasGraphics_paintImageXObject(objId) {
+ var imgData = this.objs.get(objId);
+ if (!imgData)
+ error('Dependent image isn\'t ready yet');
+
+ this.paintInlineImageXObject(imgData);
+ },
+
+ paintInlineImageXObject:
+ function CanvasGraphics_paintInlineImageXObject(imgData) {
+ var width = imgData.width;
+ var height = imgData.height;
+ var ctx = this.ctx;
+
+ this.save();
+ // scale the image to the unit square
+ ctx.scale(1 / width, -1 / height);
+
+ var currentTransform = ctx.mozCurrentTransformInverse;
+ var a = currentTransform[0], b = currentTransform[1];
+ var widthScale = Math.max(Math.sqrt(a * a + b * b), 1);
+ var c = currentTransform[2], d = currentTransform[3];
+ var heightScale = Math.max(Math.sqrt(c * c + d * d), 1);
+
+ var imgToPaint;
+ // instanceof HTMLElement does not work in jsdom node.js module
+ if (imgData instanceof HTMLElement || !imgData.data) {
+ imgToPaint = imgData;
+ } else {
+ var tmpCanvas = CachedCanvases.getCanvas('inlineImage', width, height);
+ var tmpCtx = tmpCanvas.context;
+ putBinaryImageData(tmpCtx, imgData);
+ imgToPaint = tmpCanvas.canvas;
+ }
+
+ var paintWidth = width, paintHeight = height;
+ var tmpCanvasId = 'prescale1';
+ // Vertial or horizontal scaling shall not be more than 2 to not loose the
+ // pixels during drawImage operation, painting on the temporary canvas(es)
+ // that are twice smaller in size
+ while ((widthScale > 2 && paintWidth > 1) ||
+ (heightScale > 2 && paintHeight > 1)) {
+ var newWidth = paintWidth, newHeight = paintHeight;
+ if (widthScale > 2 && paintWidth > 1) {
+ newWidth = Math.ceil(paintWidth / 2);
+ widthScale /= paintWidth / newWidth;
+ }
+ if (heightScale > 2 && paintHeight > 1) {
+ newHeight = Math.ceil(paintHeight / 2);
+ heightScale /= paintHeight / newHeight;
+ }
+ var tmpCanvas = CachedCanvases.getCanvas(tmpCanvasId,
+ newWidth, newHeight);
+ tmpCtx = tmpCanvas.context;
+ tmpCtx.clearRect(0, 0, newWidth, newHeight);
+ tmpCtx.drawImage(imgToPaint, 0, 0, paintWidth, paintHeight,
+ 0, 0, newWidth, newHeight);
+ imgToPaint = tmpCanvas.canvas;
+ paintWidth = newWidth;
+ paintHeight = newHeight;
+ tmpCanvasId = tmpCanvasId === 'prescale1' ? 'prescale2' : 'prescale1';
+ }
+ ctx.drawImage(imgToPaint, 0, 0, paintWidth, paintHeight,
+ 0, -height, width, height);
+
+ if (this.imageLayer) {
+ var position = this.getCanvasPosition(0, -height);
+ this.imageLayer.appendImage({
+ imgData: imgData,
+ left: position[0],
+ top: position[1],
+ width: width / currentTransform[0],
+ height: height / currentTransform[3]
+ });
+ }
+ this.restore();
+ },
+
+ paintInlineImageXObjectGroup:
+ function CanvasGraphics_paintInlineImageXObjectGroup(imgData, map) {
+ var ctx = this.ctx;
+ var w = imgData.width;
+ var h = imgData.height;
+
+ var tmpCanvas = CachedCanvases.getCanvas('inlineImage', w, h);
+ var tmpCtx = tmpCanvas.context;
+ putBinaryImageData(tmpCtx, imgData);
+
+ for (var i = 0, ii = map.length; i < ii; i++) {
+ var entry = map[i];
+ ctx.save();
+ ctx.transform.apply(ctx, entry.transform);
+ ctx.scale(1, -1);
+ ctx.drawImage(tmpCanvas.canvas, entry.x, entry.y, entry.w, entry.h,
+ 0, -1, 1, 1);
+ if (this.imageLayer) {
+ var position = this.getCanvasPosition(entry.x, entry.y);
+ this.imageLayer.appendImage({
+ imgData: imgData,
+ left: position[0],
+ top: position[1],
+ width: w,
+ height: h
+ });
+ }
+ ctx.restore();
+ }
+ },
+
+ // Marked content
+
+ markPoint: function CanvasGraphics_markPoint(tag) {
+ // TODO Marked content.
+ },
+ markPointProps: function CanvasGraphics_markPointProps(tag, properties) {
+ // TODO Marked content.
+ },
+ beginMarkedContent: function CanvasGraphics_beginMarkedContent(tag) {
+ // TODO Marked content.
+ },
+ beginMarkedContentProps: function CanvasGraphics_beginMarkedContentProps(
+ tag, properties) {
+ // TODO Marked content.
+ },
+ endMarkedContent: function CanvasGraphics_endMarkedContent() {
+ // TODO Marked content.
+ },
+
+ // Compatibility
+
+ beginCompat: function CanvasGraphics_beginCompat() {
+ // TODO ignore undefined operators (should we do that anyway?)
+ },
+ endCompat: function CanvasGraphics_endCompat() {
+ // TODO stop ignoring undefined operators
+ },
+
+ // Helper functions
+
+ consumePath: function CanvasGraphics_consumePath() {
+ if (this.pendingClip) {
+ if (this.pendingClip == EO_CLIP) {
+ if ('mozFillRule' in this.ctx) {
+ this.ctx.mozFillRule = 'evenodd';
+ this.ctx.clip();
+ this.ctx.mozFillRule = 'nonzero';
+ } else {
+ try {
+ this.ctx.clip('evenodd');
+ } catch (ex) {
+ // shouldn't really happen, but browsers might think differently
+ this.ctx.clip();
+ }
+ }
+ } else {
+ this.ctx.clip();
+ }
+ this.pendingClip = null;
+ }
+ this.ctx.beginPath();
+ },
+ getSinglePixelWidth: function CanvasGraphics_getSinglePixelWidth(scale) {
+ var inverse = this.ctx.mozCurrentTransformInverse;
+ // max of the current horizontal and vertical scale
+ return Math.sqrt(Math.max(
+ (inverse[0] * inverse[0] + inverse[1] * inverse[1]),
+ (inverse[2] * inverse[2] + inverse[3] * inverse[3])));
+ },
+ getCanvasPosition: function CanvasGraphics_getCanvasPosition(x, y) {
+ var transform = this.ctx.mozCurrentTransform;
+ return [
+ transform[0] * x + transform[2] * y + transform[4],
+ transform[1] * x + transform[3] * y + transform[5]
+ ];
+ }
+ };
+
+ for (var op in OPS) {
+ CanvasGraphics.prototype[OPS[op]] = CanvasGraphics.prototype[op];
+ }
+
+ return CanvasGraphics;
+})();
+
+
+
+PDFJS.disableFontFace = false;
+
+var FontLoader = {
+ insertRule: function fontLoaderInsertRule(rule) {
+ var styleElement = document.getElementById('PDFJS_FONT_STYLE_TAG');
+ if (!styleElement) {
+ styleElement = document.createElement('style');
+ styleElement.id = 'PDFJS_FONT_STYLE_TAG';
+ document.documentElement.getElementsByTagName('head')[0].appendChild(
+ styleElement);
+ }
+
+ var styleSheet = styleElement.sheet;
+ styleSheet.insertRule(rule, styleSheet.cssRules.length);
+ },
+ clear: function fontLoaderClear() {
+ var styleElement = document.getElementById('PDFJS_FONT_STYLE_TAG');
+ if (styleElement) {
+ styleElement.parentNode.removeChild(styleElement);
+ }
+ },
+ get loadTestFont() {
+ // This is a CFF font with 1 glyph for '.' that fills its entire width and
+ // height.
+ return shadow(this, 'loadTestFont', atob(
+ 'T1RUTwALAIAAAwAwQ0ZGIDHtZg4AAAOYAAAAgUZGVE1lkzZwAAAEHAAAABxHREVGABQAFQ' +
+ 'AABDgAAAAeT1MvMlYNYwkAAAEgAAAAYGNtYXABDQLUAAACNAAAAUJoZWFk/xVFDQAAALwA' +
+ 'AAA2aGhlYQdkA+oAAAD0AAAAJGhtdHgD6AAAAAAEWAAAAAZtYXhwAAJQAAAAARgAAAAGbm' +
+ 'FtZVjmdH4AAAGAAAAAsXBvc3T/hgAzAAADeAAAACAAAQAAAAEAALZRFsRfDzz1AAsD6AAA' +
+ 'AADOBOTLAAAAAM4KHDwAAAAAA+gDIQAAAAgAAgAAAAAAAAABAAADIQAAAFoD6AAAAAAD6A' +
+ 'ABAAAAAAAAAAAAAAAAAAAAAQAAUAAAAgAAAAQD6AH0AAUAAAKKArwAAACMAooCvAAAAeAA' +
+ 'MQECAAACAAYJAAAAAAAAAAAAAQAAAAAAAAAAAAAAAFBmRWQAwAAuAC4DIP84AFoDIQAAAA' +
+ 'AAAQAAAAAAAAAAACAAIAABAAAADgCuAAEAAAAAAAAAAQAAAAEAAAAAAAEAAQAAAAEAAAAA' +
+ 'AAIAAQAAAAEAAAAAAAMAAQAAAAEAAAAAAAQAAQAAAAEAAAAAAAUAAQAAAAEAAAAAAAYAAQ' +
+ 'AAAAMAAQQJAAAAAgABAAMAAQQJAAEAAgABAAMAAQQJAAIAAgABAAMAAQQJAAMAAgABAAMA' +
+ 'AQQJAAQAAgABAAMAAQQJAAUAAgABAAMAAQQJAAYAAgABWABYAAAAAAAAAwAAAAMAAAAcAA' +
+ 'EAAAAAADwAAwABAAAAHAAEACAAAAAEAAQAAQAAAC7//wAAAC7////TAAEAAAAAAAABBgAA' +
+ 'AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAA' +
+ 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' +
+ 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' +
+ 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' +
+ 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAA' +
+ 'AAAAD/gwAyAAAAAQAAAAAAAAAAAAAAAAAAAAABAAQEAAEBAQJYAAEBASH4DwD4GwHEAvgc' +
+ 'A/gXBIwMAYuL+nz5tQXkD5j3CBLnEQACAQEBIVhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWF' +
+ 'hYWFhYWFhYAAABAQAADwACAQEEE/t3Dov6fAH6fAT+fPp8+nwHDosMCvm1Cvm1DAz6fBQA' +
+ 'AAAAAAABAAAAAMmJbzEAAAAAzgTjFQAAAADOBOQpAAEAAAAAAAAADAAUAAQAAAABAAAAAg' +
+ 'ABAAAAAAAAAAAD6AAAAAAAAA=='
+ ));
+ },
+
+ loadTestFontId: 0,
+
+ loadingContext: {
+ requests: [],
+ nextRequestId: 0
+ },
+
+ isSyncFontLoadingSupported: (function detectSyncFontLoadingSupport() {
+ if (isWorker)
+ return false;
+
+ // User agent string sniffing is bad, but there is no reliable way to tell
+ // if font is fully loaded and ready to be used with canvas.
+ var userAgent = window.navigator.userAgent;
+ var m = /Mozilla\/5.0.*?rv:(\d+).*? Gecko/.exec(userAgent);
+ if (m && m[1] >= 14)
+ return true;
+ // TODO other browsers
+ return false;
+ })(),
+
+ bind: function fontLoaderBind(fonts, callback) {
+ assert(!isWorker, 'bind() shall be called from main thread');
+
+ var rules = [], fontsToLoad = [];
+ for (var i = 0, ii = fonts.length; i < ii; i++) {
+ var font = fonts[i];
+
+ // Add the font to the DOM only once or skip if the font
+ // is already loaded.
+ if (font.attached || font.loading === false) {
+ continue;
+ }
+ font.attached = true;
+
+ var rule = font.bindDOM();
+ if (rule) {
+ rules.push(rule);
+ fontsToLoad.push(font);
+ }
+ }
+
+ var request = FontLoader.queueLoadingCallback(callback);
+ if (rules.length > 0 && !this.isSyncFontLoadingSupported) {
+ FontLoader.prepareFontLoadEvent(rules, fontsToLoad, request);
+ } else {
+ request.complete();
+ }
+ },
+
+ queueLoadingCallback: function FontLoader_queueLoadingCallback(callback) {
+ function LoadLoader_completeRequest() {
+ assert(!request.end, 'completeRequest() cannot be called twice');
+ request.end = Date.now();
+
+ // sending all completed requests in order how they were queued
+ while (context.requests.length > 0 && context.requests[0].end) {
+ var otherRequest = context.requests.shift();
+ setTimeout(otherRequest.callback, 0);
+ }
+ }
+
+ var context = FontLoader.loadingContext;
+ var requestId = 'pdfjs-font-loading-' + (context.nextRequestId++);
+ var request = {
+ id: requestId,
+ complete: LoadLoader_completeRequest,
+ callback: callback,
+ started: Date.now()
+ };
+ context.requests.push(request);
+ return request;
+ },
+
+ prepareFontLoadEvent: function fontLoaderPrepareFontLoadEvent(rules,
+ fonts,
+ request) {
+ /** Hack begin */
+ // There's currently no event when a font has finished downloading so the
+ // following code is a dirty hack to 'guess' when a font is
+ // ready. It's assumed fonts are loaded in order, so add a known test
+ // font after the desired fonts and then test for the loading of that
+ // test font.
+
+ function int32(data, offset) {
+ return (data.charCodeAt(offset) << 24) |
+ (data.charCodeAt(offset + 1) << 16) |
+ (data.charCodeAt(offset + 2) << 8) |
+ (data.charCodeAt(offset + 3) & 0xff);
+ }
+
+ function string32(value) {
+ return String.fromCharCode((value >> 24) & 0xff) +
+ String.fromCharCode((value >> 16) & 0xff) +
+ String.fromCharCode((value >> 8) & 0xff) +
+ String.fromCharCode(value & 0xff);
+ }
+
+ function spliceString(s, offset, remove, insert) {
+ var chunk1 = data.substr(0, offset);
+ var chunk2 = data.substr(offset + remove);
+ return chunk1 + insert + chunk2;
+ }
+
+ var i, ii;
+
+ var canvas = document.createElement('canvas');
+ canvas.width = 1;
+ canvas.height = 1;
+ var ctx = canvas.getContext('2d');
+
+ var called = 0;
+ function isFontReady(name, callback) {
+ called++;
+ // With setTimeout clamping this gives the font ~100ms to load.
+ if(called > 30) {
+ warn('Load test font never loaded.');
+ callback();
+ return;
+ }
+ ctx.font = '30px ' + name;
+ ctx.fillText('.', 0, 20);
+ var imageData = ctx.getImageData(0, 0, 1, 1);
+ if (imageData.data[3] > 0) {
+ callback();
+ return;
+ }
+ setTimeout(isFontReady.bind(null, name, callback));
+ }
+
+ var loadTestFontId = 'lt' + Date.now() + this.loadTestFontId++;
+ // Chromium seems to cache fonts based on a hash of the actual font data,
+ // so the font must be modified for each load test else it will appear to
+ // be loaded already.
+ // TODO: This could maybe be made faster by avoiding the btoa of the full
+ // font by splitting it in chunks before hand and padding the font id.
+ var data = this.loadTestFont;
+ var COMMENT_OFFSET = 976; // has to be on 4 byte boundary (for checksum)
+ data = spliceString(data, COMMENT_OFFSET, loadTestFontId.length,
+ loadTestFontId);
+ // CFF checksum is important for IE, adjusting it
+ var CFF_CHECKSUM_OFFSET = 16;
+ var XXXX_VALUE = 0x58585858; // the "comment" filled with 'X'
+ var checksum = int32(data, CFF_CHECKSUM_OFFSET);
+ for (i = 0, ii = loadTestFontId.length - 3; i < ii; i += 4) {
+ checksum = (checksum - XXXX_VALUE + int32(loadTestFontId, i)) | 0;
+ }
+ if (i < loadTestFontId.length) { // align to 4 bytes boundary
+ checksum = (checksum - XXXX_VALUE +
+ int32(loadTestFontId + 'XXX', i)) | 0;
+ }
+ data = spliceString(data, CFF_CHECKSUM_OFFSET, 4, string32(checksum));
+
+ var url = 'url(data:font/opentype;base64,' + btoa(data) + ');';
+ var rule = '@font-face { font-family:"' + loadTestFontId + '";src:' +
+ url + '}';
+ FontLoader.insertRule(rule);
+
+ var names = [];
+ for (i = 0, ii = fonts.length; i < ii; i++) {
+ names.push(fonts[i].loadedName);
+ }
+ names.push(loadTestFontId);
+
+ var div = document.createElement('div');
+ div.setAttribute('style',
+ 'visibility: hidden;' +
+ 'width: 10px; height: 10px;' +
+ 'position: absolute; top: 0px; left: 0px;');
+ for (i = 0, ii = names.length; i < ii; ++i) {
+ var span = document.createElement('span');
+ span.textContent = 'Hi';
+ span.style.fontFamily = names[i];
+ div.appendChild(span);
+ }
+ document.body.appendChild(div);
+
+ isFontReady(loadTestFontId, function() {
+ document.body.removeChild(div);
+ request.complete();
+ });
+ /** Hack end */
+ }
+};
+
+var FontFace = (function FontFaceClosure() {
+ function FontFace(name, file, properties) {
+ this.compiledGlyphs = {};
+ if (arguments.length === 1) {
+ // importing translated data
+ var data = arguments[0];
+ for (var i in data) {
+ this[i] = data[i];
+ }
+ return;
+ }
+ }
+ FontFace.prototype = {
+ bindDOM: function FontFace_bindDOM() {
+ if (!this.data)
+ return null;
+
+ if (PDFJS.disableFontFace) {
+ this.disableFontFace = true;
+ return null;
+ }
+
+ var data = bytesToString(this.data);
+ var fontName = this.loadedName;
+
+ // Add the font-face rule to the document
+ var url = ('url(data:' + this.mimetype + ';base64,' +
+ window.btoa(data) + ');');
+ var rule = '@font-face { font-family:"' + fontName + '";src:' + url + '}';
+
+ FontLoader.insertRule(rule);
+
+ if (PDFJS.pdfBug && 'FontInspector' in globalScope &&
+ globalScope['FontInspector'].enabled)
+ globalScope['FontInspector'].fontAdded(this, url);
+
+ return rule;
+ },
+ getPathGenerator: function (objs, character) {
+ if (!(character in this.compiledGlyphs)) {
+ var js = objs.get(this.loadedName + '_path_' + character);
+ /*jshint -W054 */
+ this.compiledGlyphs[character] = new Function('c', 'size', js);
+ }
+ return this.compiledGlyphs[character];
+ }
+ };
+ return FontFace;
+})();
+
+
+}).call((typeof window === 'undefined') ? this : window);
+
+if (!PDFJS.workerSrc && typeof document !== 'undefined') {
+ // workerSrc is not set -- using last script url to define default location
+ PDFJS.workerSrc = (function () {
+ 'use strict';
+ var scriptTagContainer = document.body ||
+ document.getElementsByTagName('head')[0];
+ var pdfjsSrc = scriptTagContainer.lastChild.src;
+ return pdfjsSrc && pdfjsSrc.replace(/\.js$/i, '.worker.js');
+ })();
+}
+
+
diff --git a/plugins/pdfviewer/viewer/pdf.min.js b/plugins/pdfviewer/viewer/pdf.min.js
new file mode 100644
index 0000000..5688c2e
--- /dev/null
+++ b/plugins/pdfviewer/viewer/pdf.min.js
@@ -0,0 +1,178 @@
+"undefined"===typeof PDFJS&&(("undefined"!==typeof window?window:this).PDFJS={});PDFJS.version="0.8.894";PDFJS.build="ac91047";
+(function(){var E,X;function K(b){PDFJS.verbosity>=PDFJS.VERBOSITY_LEVELS.infos&&console.log("Info: "+b)}function x(b){PDFJS.verbosity>=PDFJS.VERBOSITY_LEVELS.warnings&&console.log("Warning: "+b)}function m(b){if(1<arguments.length){var a=["Error:"];a.push.apply(a,arguments);console.log.apply(console,a);b=[].join.call(arguments," ")}else console.log("Error: "+b);console.log(oa());Z.notify(da.unknown);throw Error(b);}function oa(){try{throw Error();}catch(b){return b.stack?b.stack.split("\n").slice(2).join("\n"):
+""}}function pa(b,a){if(!a)return b;if(0<=a.indexOf(":"))return a;if("/"==a.charAt(0)){var c=b.indexOf("://"),c=b.indexOf("/",c+3);return b.substring(0,c)+a}var e=b.length,c=b.lastIndexOf("#"),e=0<=c?c:e,c=b.lastIndexOf("?",e),c=b.lastIndexOf("/",0<=c?c:e);return b.substring(0,c+1)+a}function $(b,a){if(!b)return!1;var c=b.indexOf(":");if(0>c)return a;switch(b.substr(0,c)){case "http":case "https":case "ftp":case "mailto":return!0;default:return!1}}function U(b,a,c){Object.defineProperty(b,a,{value:c,
+enumerable:!0,configurable:!0,writable:!1});return c}function V(b){var a,c=b.length,e="";if("\u00fe"===b[0]&&"\u00ff"===b[1])for(a=2;a<c;a+=2)e+=String.fromCharCode(b.charCodeAt(a)<<8|b.charCodeAt(a+1));else for(a=0;a<c;++a)var d=qa[b.charCodeAt(a)],e=e+(d?String.fromCharCode(d):b.charAt(a));return e}function L(b){return"boolean"==typeof b}function P(b){return b instanceof Name}function R(b,a){if(!(b instanceof Dict))return!1;if(!a)return!0;var c=b.get("Type");return P(c)&&c.name==a}function D(b){return b instanceof
+Array}function Y(b){return"object"==typeof b&&null!==b&&void 0!==b&&"getBytes"in b}function ea(b){if("object"!=typeof b)return!1;if(!R(b))if(Y(b))b=b.dict;else return!1;return b.has("FunctionType")}function aa(b,a){this.name=b;this.comObj=a;this.callbackIndex=1;this.postMessageTransfers=!0;var c=this.callbacks={},e=this.actionHandler={};e.console_log=[function(a){console.log.apply(console,a)}];e.console_error=[function(a){console.error.apply(console,a)}];e._unsupported_feature=[function(a){Z.notify(a)}];
+a.onmessage=function(d){var b=d.data;if(b.isReply)if(d=b.callbackId,b.callbackId in c){var f=c[d];delete c[d];f(b.data)}else m("Cannot resolve callback "+d);else if(b.action in e)if(d=e[b.action],b.callbackId){var h={},f=new Promise(function(a,c){h.resolve=a;h.reject=c});h.promise=f;f.then(function(c){a.postMessage({isReply:!0,callbackId:b.callbackId,data:c})});d[0].call(d[1],b.data,h)}else d[0].call(d[1],b.data);else m("Unkown action from worker: "+b.action)}}function ra(b,a,c){var e=new Image;e.onload=
+function(){c.resolve(b,e)};e.src=a}function fa(b,a){var c=document.createElement("canvas");c.width=b;c.height=a;return c}function ga(b){b.mozCurrentTransform||(b._scaleX=b._scaleX||1,b._scaleY=b._scaleY||1,b._originalSave=b.save,b._originalRestore=b.restore,b._originalRotate=b.rotate,b._originalScale=b.scale,b._originalTranslate=b.translate,b._originalTransform=b.transform,b._originalSetTransform=b.setTransform,b._transformMatrix=[b._scaleX,0,0,b._scaleY,0,0],b._transformStack=[],Object.defineProperty(b,
+"mozCurrentTransform",{get:function(){return this._transformMatrix}}),Object.defineProperty(b,"mozCurrentTransformInverse",{get:function(){var a=this._transformMatrix,c=a[0],e=a[1],d=a[2],b=a[3],f=a[4],a=a[5],h=c*b-e*d,k=e*d-c*b;return[b/h,e/k,d/k,c/h,(b*f-d*a)/k,(e*f-c*a)/h]}}),b.save=function(){var a=this._transformMatrix;this._transformStack.push(a);this._transformMatrix=a.slice(0,6);this._originalSave()},b.restore=function(){var a=this._transformStack.pop();a&&(this._transformMatrix=a,this._originalRestore())},
+b.translate=function(a,c){var e=this._transformMatrix;e[4]=e[0]*a+e[2]*c+e[4];e[5]=e[1]*a+e[3]*c+e[5];this._originalTranslate(a,c)},b.scale=function(a,c){var e=this._transformMatrix;e[0]*=a;e[1]*=a;e[2]*=c;e[3]*=c;this._originalScale(a,c)},b.transform=function(a,c,e,d,g,f){var h=this._transformMatrix;this._transformMatrix=[h[0]*a+h[2]*c,h[1]*a+h[3]*c,h[0]*e+h[2]*d,h[1]*e+h[3]*d,h[0]*g+h[2]*f+h[4],h[1]*g+h[3]*f+h[5]];b._originalTransform(a,c,e,d,g,f)},b.setTransform=function(a,c,e,d,g,f){this._transformMatrix=
+[a,c,e,d,g,f];b._originalSetTransform(a,c,e,d,g,f)},b.rotate=function(a){var c=Math.cos(a),e=Math.sin(a),d=this._transformMatrix;this._transformMatrix=[d[0]*c+d[2]*e,d[1]*c+d[3]*e,d[0]*-e+d[2]*c,d[1]*-e+d[3]*c,d[4],d[5]];this._originalRotate(a)})}function sa(b){var a=b.width,c=b.height,e,d,g=a+1,f=new Uint8Array(g*(c+1)),h=new Uint8Array([0,2,4,0,1,0,5,4,8,10,0,8,0,2,1,0]),k=a+7&-8,l=b.data,n=new Uint8Array(k*c),p=0;b=0;for(e=l.length;b<e;b++){d=128;for(var z=l[b];0<d;)n[p++]=z&d?0:255,d>>=1}p=l=
+0;0!==n[p]&&(f[0]=1,++l);for(e=1;e<a;e++)n[p]!==n[p+1]&&(f[e]=n[p]?2:1,++l),p++;0!==n[p]&&(f[e]=2,++l);for(b=1;b<c;b++){p=b*k;d=b*g;n[p-k]!==n[p]&&(f[d]=n[p]?1:8,++l);z=(n[p]?4:0)+(n[p-k]?8:0);for(e=1;e<a;e++)z=(z>>2)+(n[p+1]?4:0)+(n[p-k+1]?8:0),h[z]&&(f[d+e]=h[z],++l),p++;n[p-k]!==n[p]&&(f[d+e]=n[p]?2:4,++l);if(1E3<l)return null}p=k*(c-1);d=b*g;0!==n[p]&&(f[d]=8,++l);for(e=1;e<a;e++)n[p]!==n[p+1]&&(f[d+e]=n[p]?4:8,++l),p++;0!==n[p]&&(f[d+e]=4,++l);if(1E3<l)return null;var h=new Int32Array([0,g,-1,
+0,-g,0,0,0,1]),s=[];for(b=0;l&&b<=c;b++){k=b*g;for(n=k+a;k<n&&!f[k];)k++;if(k!==n){n=[k%g,b];p=f[k];e=k;do{d=h[p];do k+=d;while(!f[k]);d=f[k];5!==d&&10!==d?(p=d,f[k]=0):(p=d&51*p>>4,f[k]&=p>>2|p<<2);n.push(k%g);n.push(k/g|0);--l}while(e!==k);s.push(n);--b}}return function(d){d.save();d.scale(1/a,-1/c);d.translate(0,-c);d.beginPath();for(var e=0,k=s.length;e<k;e++){var b=s[e];d.moveTo(b[0],b[1]);for(var g=2,l=b.length;g<l;g+=2)d.lineTo(b[g],b[g+1])}d.fill();d.beginPath();d.restore()}}var t="undefined"===
+typeof window?this:window,W="undefined"==typeof window,ba=[0.0010,0,0,0.0010,0,0];X=0;t.PDFJS||(t.PDFJS={});t.PDFJS.pdfBug=!1;PDFJS.VERBOSITY_LEVELS={errors:0,warnings:1,infos:5};var y=PDFJS.OPS={dependency:1,setLineWidth:2,setLineCap:3,setLineJoin:4,setMiterLimit:5,setDash:6,setRenderingIntent:7,setFlatness:8,setGState:9,save:10,restore:11,transform:12,moveTo:13,lineTo:14,curveTo:15,curveTo2:16,curveTo3:17,closePath:18,rectangle:19,stroke:20,closeStroke:21,fill:22,eoFill:23,fillStroke:24,eoFillStroke:25,
+closeFillStroke:26,closeEOFillStroke:27,endPath:28,clip:29,eoClip:30,beginText:31,endText:32,setCharSpacing:33,setWordSpacing:34,setHScale:35,setLeading:36,setFont:37,setTextRenderingMode:38,setTextRise:39,moveText:40,setLeadingMoveText:41,setTextMatrix:42,nextLine:43,showText:44,showSpacedText:45,nextLineShowText:46,nextLineSetSpacingShowText:47,setCharWidth:48,setCharWidthAndBounds:49,setStrokeColorSpace:50,setFillColorSpace:51,setStrokeColor:52,setStrokeColorN:53,setFillColor:54,setFillColorN:55,
+setStrokeGray:56,setFillGray:57,setStrokeRGBColor:58,setFillRGBColor:59,setStrokeCMYKColor:60,setFillCMYKColor:61,shadingFill:62,beginInlineImage:63,beginImageData:64,endInlineImage:65,paintXObject:66,markPoint:67,markPointProps:68,beginMarkedContent:69,beginMarkedContentProps:70,endMarkedContent:71,beginCompat:72,endCompat:73,paintFormXObjectBegin:74,paintFormXObjectEnd:75,beginGroup:76,endGroup:77,beginAnnotations:78,endAnnotations:79,beginAnnotation:80,endAnnotation:81,paintJpegXObject:82,paintImageMaskXObject:83,
+paintImageMaskXObjectGroup:84,paintImageXObject:85,paintInlineImageXObject:86,paintInlineImageXObjectGroup:87},da=PDFJS.UNSUPPORTED_FEATURES={unknown:"unknown",forms:"forms",javaScript:"javaScript",smask:"smask",shadingPattern:"shadingPattern",font:"font"},Z=PDFJS.UnsupportedManager=function(){var b=[];return{listen:function(a){b.push(a)},notify:function(a){x('Unsupported feature "'+a+'"');for(var c=0,e=b.length;c<e;c++)b[c](a)}}}();PDFJS.isValidUrl=$;var ha=PDFJS.PasswordResponses={NEED_PASSWORD:1,
+INCORRECT_PASSWORD:2};(function(){function b(a,c){this.name="PasswordException";this.message=a;this.code=c}b.prototype=Error();return b.constructor=b})();(function(){function b(a,c){this.name="UnknownErrorException";this.message=a;this.details=c}b.prototype=Error();return b.constructor=b})();(function(){function b(a){this.name="InvalidPDFException";this.message=a}b.prototype=Error();return b.constructor=b})();(function(){function b(a){this.name="MissingPDFException";this.message=a}b.prototype=Error();
+return b.constructor=b})();var ta=function(){function b(a){this.message=a}b.prototype=Error();b.prototype.name="NotImplementedException";return b.constructor=b}();(function(){function b(a,c){this.begin=a;this.end=c;this.message="Missing data ["+a+", "+c+")"}b.prototype=Error();b.prototype.name="MissingDataException";return b.constructor=b})();(function(){function b(a){this.message=a}b.prototype=Error();b.prototype.name="XRefParseException";return b.constructor=b})();var ia=[1,0,0,1,0,0],q=PDFJS.Util=
+function(){function b(){}b.makeCssRgb=function(a){return"rgb("+a[0]+","+a[1]+","+a[2]+")"};b.makeCssCmyk=function(a){a=r.singletons.cmyk.getRgb(a,0);return b.makeCssRgb(a)};b.transform=function(a,c){return[a[0]*c[0]+a[2]*c[1],a[1]*c[0]+a[3]*c[1],a[0]*c[2]+a[2]*c[3],a[1]*c[2]+a[3]*c[3],a[0]*c[4]+a[2]*c[5]+a[4],a[1]*c[4]+a[3]*c[5]+a[5]]};b.applyTransform=function(a,c){return[a[0]*c[0]+a[1]*c[2]+c[4],a[0]*c[1]+a[1]*c[3]+c[5]]};b.applyInverseTransform=function(a,c){var e=c[0]*c[3]-c[1]*c[2];return[(a[0]*
+c[3]-a[1]*c[2]+c[2]*c[5]-c[4]*c[3])/e,(-a[0]*c[1]+a[1]*c[0]+c[4]*c[1]-c[5]*c[0])/e]};b.getAxialAlignedBoundingBox=function(a,c){var e=b.applyTransform(a,c),d=b.applyTransform(a.slice(2,4),c),g=b.applyTransform([a[0],a[3]],c),f=b.applyTransform([a[2],a[1]],c);return[Math.min(e[0],d[0],g[0],f[0]),Math.min(e[1],d[1],g[1],f[1]),Math.max(e[0],d[0],g[0],f[0]),Math.max(e[1],d[1],g[1],f[1])]};b.inverseTransform=function(a){var c=a[0]*a[3]-a[1]*a[2];return[a[3]/c,-a[1]/c,-a[2]/c,a[0]/c,(a[2]*a[5]-a[4]*a[3])/
+c,(a[4]*a[1]-a[5]*a[0])/c]};b.apply3dTransform=function(a,c){return[a[0]*c[0]+a[1]*c[1]+a[2]*c[2],a[3]*c[0]+a[4]*c[1]+a[5]*c[2],a[6]*c[0]+a[7]*c[1]+a[8]*c[2]]};b.singularValueDecompose2dScale=function(a){var c=[a[0],a[2],a[1],a[3]],e=a[0]*c[0]+a[1]*c[2],d=a[2]*c[1]+a[3]*c[3],b=(e+d)/2;a=Math.sqrt((e+d)*(e+d)-4*(e*d-(a[2]*c[0]+a[3]*c[2])*(a[0]*c[1]+a[1]*c[3])))/2;c=b-a||1;return[Math.sqrt(b+a||1),Math.sqrt(c)]};b.normalizeRect=function(a){var c=a.slice(0);a[0]>a[2]&&(c[0]=a[2],c[2]=a[0]);a[1]>a[3]&&
+(c[1]=a[3],c[3]=a[1]);return c};b.intersect=function(a,c){function e(a,c){return a-c}var d=[a[0],a[2],c[0],c[2]].sort(e),g=[a[1],a[3],c[1],c[3]].sort(e),f=[];a=b.normalizeRect(a);c=b.normalizeRect(c);if(d[0]===a[0]&&d[1]===c[0]||d[0]===c[0]&&d[1]===a[0])f[0]=d[1],f[2]=d[2];else return!1;if(g[0]===a[1]&&g[1]===c[1]||g[0]===c[1]&&g[1]===a[1])f[1]=g[1],f[3]=g[2];else return!1;return f};b.sign=function(a){return 0>a?-1:1};b.concatenateToArray=function(a,c){Array.prototype.push.apply(a,c)};b.prependToArray=
+function(a,c){Array.prototype.unshift.apply(a,c)};b.extendObj=function(a,c){for(var e in c)a[e]=c[e]};b.getInheritableProperty=function(a,c){for(;a&&!a.has(c);)a=a.get("Parent");return a?a.get(c):null};b.inherit=function(a,c,e){a.prototype=Object.create(c.prototype);a.prototype.constructor=a;for(var d in e)a.prototype[d]=e[d]};b.loadScript=function(a,c){var e=document.createElement("script"),d=!1;e.setAttribute("src",a);c&&(e.onload=function(){d||c();d=!0});document.getElementsByTagName("head")[0].appendChild(e)};
+return b}();PDFJS.PageViewport=function(){function b(a,c,e,d,b,f){this.viewBox=a;this.scale=c;this.rotation=e;this.offsetX=d;this.offsetY=b;var h=(a[2]+a[0])/2,k=(a[3]+a[1])/2,l,n,p;e%=360;switch(0>e?e+360:e){case 180:e=-1;n=l=0;p=1;break;case 90:e=0;n=l=1;p=0;break;case 270:e=0;n=l=-1;p=0;break;default:e=1,n=l=0,p=-1}f&&(n=-n,p=-p);0===e?(d=Math.abs(k-a[1])*c+d,b=Math.abs(h-a[0])*c+b,f=Math.abs(a[3]-a[1])*c,a=Math.abs(a[2]-a[0])*c):(d=Math.abs(h-a[0])*c+d,b=Math.abs(k-a[1])*c+b,f=Math.abs(a[2]-a[0])*
+c,a=Math.abs(a[3]-a[1])*c);this.transform=[e*c,l*c,n*c,p*c,d-e*c*h-n*c*k,b-l*c*h-p*c*k];this.width=f;this.height=a;this.fontScale=c}b.prototype={clone:function(a){a=a||{};var c="scale"in a?a.scale:this.scale,e="rotation"in a?a.rotation:this.rotation;return new b(this.viewBox.slice(),c,e,this.offsetX,this.offsetY,a.dontFlip)},convertToViewportPoint:function(a,c){return q.applyTransform([a,c],this.transform)},convertToViewportRectangle:function(a){var c=q.applyTransform([a[0],a[1]],this.transform);
+a=q.applyTransform([a[2],a[3]],this.transform);return[c[0],c[1],a[0],a[1]]},convertToPdfPoint:function(a,c){return q.applyInverseTransform([a,c],this.transform)}};return b}();var qa=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,728,711,710,729,733,731,730,732,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8226,8224,8225,8230,8212,8211,402,8260,8249,8250,
+8722,8240,8222,8220,8221,8216,8217,8218,8482,64257,64258,321,338,352,376,381,305,322,339,353,382,0,8364],G=PDFJS.LegacyPromise=function(){return function(){var b,a,c=new Promise(function(c,d){b=c;a=d});c.resolve=b;c.reject=a;return c}}();(function(){function b(c){this._status=a;this._handlers=[];c.call(this,this._resolve.bind(this),this._reject.bind(this))}if(t.Promise)"function"!==typeof t.Promise.all&&(t.Promise.all=function(a){var c=0,e=[],b,k,l=new t.Promise(function(a,c){b=a;k=c});a.forEach(function(a,
+d){c++;a.then(function(a){e[d]=a;c--;0===c&&b(e)},k)});0===c&&b(e);return l}),"function"!==typeof t.Promise.resolve&&(t.Promise.resolve=function(a){return new t.Promise(function(c){c(a)})});else{var a=0,c=2,e={handlers:[],running:!1,unhandledRejections:[],pendingRejectionCheck:!1,scheduleHandlers:function(c){c._status!=a&&(this.handlers=this.handlers.concat(c._handlers),c._handlers=[],this.running||(this.running=!0,setTimeout(this.runHandlers.bind(this),0)))},runHandlers:function(){for(var a=Date.now()+
+1;0<this.handlers.length;){var e=this.handlers.shift(),b=e.thisPromise._status,h=e.thisPromise._value;try{1===b?"function"==typeof e.onResolve&&(h=e.onResolve(h)):"function"===typeof e.onReject&&(h=e.onReject(h),b=1,e.thisPromise._unhandledRejection&&this.removeUnhandeledRejection(e.thisPromise))}catch(k){b=c,h=k}e.nextPromise._updateStatus(b,h);if(Date.now()>=a)break}0<this.handlers.length?setTimeout(this.runHandlers.bind(this),0):this.running=!1},addUnhandledRejection:function(a){this.unhandledRejections.push({promise:a,
+time:Date.now()});this.scheduleRejectionCheck()},removeUnhandeledRejection:function(a){a._unhandledRejection=!1;for(var c=0;c<this.unhandledRejections.length;c++)this.unhandledRejections[c].promise===a&&(this.unhandledRejections.splice(c),c--)},scheduleRejectionCheck:function(){this.pendingRejectionCheck||(this.pendingRejectionCheck=!0,setTimeout(function(){this.pendingRejectionCheck=!1;for(var a=Date.now(),c=0;c<this.unhandledRejections.length;c++)if(500<a-this.unhandledRejections[c].time){var e=
+this.unhandledRejections[c].promise._value,b="Unhandled rejection: "+e;e.stack&&(b+="\n"+e.stack);x(b);this.unhandledRejections.splice(c);c--}this.unhandledRejections.length&&this.scheduleRejectionCheck()}.bind(this),500))}};b.all=function(a){function e(a){k._status!==c&&(n=[],h(a))}var f,h,k=new b(function(a,c){f=a;h=c}),l=a.length,n=[];if(0===l)return f(n),k;for(var p=0,z=a.length;p<z;++p){var s=a[p],w=function(a){return function(e){k._status!==c&&(n[a]=e,l--,0===l&&f(n))}}(p);b.isPromise(s)?s.then(w,
+e):w(s)}return k};b.isPromise=function(a){return a&&"function"===typeof a.then};b.resolve=function(a){return new b(function(c){c(a)})};b.prototype={_status:null,_value:null,_handlers:null,_unhandledRejection:null,_updateStatus:function(a,g){1!==this._status&&this._status!==c&&(1==a&&b.isPromise(g)?g.then(this._updateStatus.bind(this,1),this._updateStatus.bind(this,c)):(this._status=a,this._value=g,a===c&&0===this._handlers.length&&(this._unhandledRejection=!0,e.addUnhandledRejection(this)),e.scheduleHandlers(this)))},
+_resolve:function(a){this._updateStatus(1,a)},_reject:function(a){this._updateStatus(c,a)},then:function(a,c){var f=new b(function(a,c){this.reject=this.resolve=c});this._handlers.push({thisPromise:this,onResolve:a,onReject:c,nextPromise:f});e.scheduleHandlers(this);return f}};t.Promise=b}})();var ua=function(){function b(){this.started={};this.times=[];this.enabled=!0}b.prototype={time:function(a){this.enabled&&(a in this.started&&x("Timer is already running for "+a),this.started[a]=Date.now())},
+timeEnd:function(a){this.enabled&&(a in this.started||x("Timer has not been started for "+a),this.times.push({name:a,start:this.started[a],end:Date.now()}),delete this.started[a])},toString:function(){for(var a=this.times,c="",e=0,d=0,b=a.length;d<b;++d){var f=a[d].name;f.length>e&&(e=f.length)}d=0;for(b=a.length;d<b;++d){for(var h=a[d],f=h.end-h.start,h=h.name;h.length<e;)h+=" ";c+=h+" "+f+"ms\n"}return c}};return b}();PDFJS.createBlob=function(b,a){if("undefined"!==typeof Blob)return new Blob([b],
+{type:a});var c=new MozBlobBuilder;c.append(b);return c.getBlob(a)};PDFJS.createObjectURL=function(){return function(b,a){if(!PDFJS.disableCreateObjectURL&&"undefined"!==typeof URL&&URL.createObjectURL){var c=PDFJS.createBlob(b,a);return URL.createObjectURL(c)}for(var c="data:"+a+";base64,",e=0,d=b.length;e<d;e+=3)var g=b[e]&255,f=b[e+1]&255,h=b[e+2]&255,c=c+("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="[g>>2]+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="[(g&
+3)<<4|f>>4]+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="[e+1<d?(f&15)<<2|h>>6:64]+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="[e+2<d?h&63:64]);return c}}();aa.prototype={on:function(b,a,c){var e=this.actionHandler;e[b]&&m('There is already an actionName called "'+b+'"');e[b]=[a,c]},send:function(b,a,c,e){b={action:b,data:a};c&&(a=this.callbackIndex++,this.callbacks[a]=c,b.callbackId=a);e&&this.postMessageTransfers?this.comObj.postMessage(b,e):this.comObj.postMessage(b)}};
+var r=function(){function b(){m("should not call ColorSpace constructor")}b.prototype={getRgb:function(a,c){m("Should not call ColorSpace.getRgb")},getRgbItem:function(a,c,e,d){m("Should not call ColorSpace.getRgbItem")},getRgbBuffer:function(a,c,e,d,b,f){m("Should not call ColorSpace.getRgbBuffer")},getOutputLength:function(a){m("Should not call ColorSpace.getOutputLength")},isPassthrough:function(a){return!1},createRgbBuffer:function(a,c,e,d){if(this.isPassthrough(d))return a.subarray(c);var b=
+new Uint8Array(3*e),f=1<<d;if(1===this.numComps&&e>f&&"DeviceGray"!==this.name&&"DeviceRGB"!==this.name){for(var h=8>=d?new Uint8Array(f):new Uint16Array(f),k=0;k<f;k++)h[k]=k;var l=new Uint8Array(3*f);this.getRgbBuffer(h,0,f,l,0,d);for(k=d=0;k<e;++k)f=3*a[c++],b[d++]=l[f],b[d++]=l[f+1],b[d++]=l[f+2];return b}this.getRgbBuffer(a,c,e,b,0,d);return b},usesZeroToOneRange:!0};b.parse=function(a,c,e){a=b.parseToIR(a,c,e);return a instanceof ja?a:b.fromIR(a)};b.fromIR=function(a){var c=D(a)?a[0]:a;switch(c){case "DeviceGrayCS":return this.singletons.gray;
+case "DeviceRgbCS":return this.singletons.rgb;case "DeviceCmykCS":return this.singletons.cmyk;case "CalGrayCS":var c=a[1].WhitePoint,e=a[1].BlackPoint;return new va(c,e,a[1].Gamma);case "PatternCS":return(a=a[1])&&(a=b.fromIR(a)),new wa(a);case "IndexedCS":return c=a[2],e=a[3],new xa(b.fromIR(a[1]),c,e);case "AlternateCS":return c=a[3],new ja(a[1],b.fromIR(a[2]),S.fromIR(c));case "LabCS":return c=a[1].WhitePoint,e=a[1].BlackPoint,new ya(c,e,a[1].Range);default:m("Unkown name "+c)}return null};b.parseToIR=
+function(a,c,e){if(P(a)){var d=e.get("ColorSpace");R(d)&&(d=d.get(a.name))&&(a=d)}a=c.fetchIfRef(a);if(P(a))switch(this.mode=d=a.name,d){case "DeviceGray":case "G":return"DeviceGrayCS";case "DeviceRGB":case "RGB":return"DeviceRgbCS";case "DeviceCMYK":case "CMYK":return"DeviceCmykCS";case "Pattern":return["PatternCS",null];default:m("unrecognized colorspace "+d)}else if(D(a))switch(this.mode=d=a[0].name,d){case "DeviceGray":case "G":return"DeviceGrayCS";case "DeviceRGB":case "RGB":return"DeviceRgbCS";
+case "DeviceCMYK":case "CMYK":return"DeviceCmykCS";case "CalGray":return c=a[1].getAll(),["CalGrayCS",c];case "CalRGB":return"DeviceRgbCS";case "ICCBased":d=c.fetchIfRef(a[1]).dict.get("N");if(1==d)return"DeviceGrayCS";if(3==d)return"DeviceRgbCS";if(4==d)return"DeviceCmykCS";break;case "Pattern":return(a=a[1])&&(a=b.parseToIR(a,c,e)),["PatternCS",a];case "Indexed":case "I":return e=b.parseToIR(a[1],c,e),d=a[2]+1,c=c.fetchIfRef(a[3]),Y(c)&&(c=c.getBytes()),["IndexedCS",e,d,c];case "Separation":case "DeviceN":var g=
+a[1],d=1;P(g)?d=1:D(g)&&(d=g.length);e=b.parseToIR(a[2],c,e);c=S.getIR(c,c.fetchIfRef(a[3]));return["AlternateCS",d,e,c];case "Lab":return c=a[1].getAll(),["LabCS",c];default:m('unimplemented color space object "'+d+'"')}else m('unrecognized color space object: "'+a+'"');return null};b.isDefaultDecode=function(a,c){if(!a)return!0;if(2*c!==a.length)return x("The decode map is not the correct length"),!0;for(var e=0,d=a.length;e<d;e+=2)if(0!==a[e]||1!=a[e+1])return!1;return!0};b.singletons={get gray(){return U(this,
+"gray",new za)},get rgb(){return U(this,"rgb",new Aa)},get cmyk(){return U(this,"cmyk",new Ba)}};return b}(),ja=function(){function b(a,c,e){this.name="Alternate";this.numComps=a;this.defaultColor=new Float32Array(a);for(var d=0;d<a;++d)this.defaultColor[d]=1;this.base=c;this.tintFn=e}b.prototype={getRgb:function(a,c){var e=new Uint8Array(3);this.getRgbItem(a,c,e,0);return e},getRgbItem:function(a,c,e,d){a="subarray"in a?a.subarray(c,c+this.numComps):Array.prototype.slice.call(a,c,c+this.numComps);
+a=this.tintFn(a);this.base.getRgbItem(a,0,e,d)},getRgbBuffer:function(a,c,e,d,b,f){var h=this.tintFn,k=this.base;f=1/((1<<f)-1);for(var l=k.numComps,n=k.usesZeroToOneRange,p=k.isPassthrough(8)||!n,z=p?b:0,s=p?d:new Uint8Array(l*e),w=this.numComps,F=new Float32Array(w),A=0;A<e;A++){for(var C=0;C<w;C++)F[C]=a[c++]*f;var m=h(F);if(n)for(C=0;C<l;C++)s[z++]=255*m[C];else k.getRgbItem(m,0,s,z),z+=l}p||k.getRgbBuffer(s,0,e,d,b,8)},getOutputLength:function(a){return this.base.getOutputLength(a*this.base.numComps/
+this.numComps)},isPassthrough:r.prototype.isPassthrough,createRgbBuffer:r.prototype.createRgbBuffer,isDefaultDecode:function(a){return r.isDefaultDecode(a,this.numComps)},usesZeroToOneRange:!0};return b}(),wa=function(){function b(a){this.name="Pattern";this.base=a}b.prototype={};return b}(),xa=function(){function b(a,c,e){this.name="Indexed";this.numComps=1;this.defaultColor=new Uint8Array([0]);this.base=a;this.highVal=c;a=a.numComps*c;var d;if(Y(e))d=new Uint8Array(a),e=e.getBytes(a),d.set(e);else if("string"==
+typeof e)for(d=new Uint8Array(a),c=0;c<a;++c)d[c]=e.charCodeAt(c);else e instanceof Uint8Array||e instanceof Array?d=e:m("Unrecognized lookup table: "+e);this.lookup=d}b.prototype={getRgb:function(a,c){return this.base.getRgb(this.lookup,a[c]*this.base.numComps)},getRgbItem:function(a,c,e,d){this.base.getRgbItem(this.lookup,a[c]*this.base.numComps,e,d)},getRgbBuffer:function(a,c,e,d,b){for(var f=this.base,h=f.numComps,k=f.getOutputLength(h),l=this.lookup,n=0;n<e;++n){var p=a[c++]*h;f.getRgbBuffer(l,
+p,1,d,b,8);b+=k}},getOutputLength:function(a){return this.base.getOutputLength(a*this.base.numComps)},isPassthrough:r.prototype.isPassthrough,createRgbBuffer:r.prototype.createRgbBuffer,isDefaultDecode:function(a){return!0},usesZeroToOneRange:!0};return b}(),za=function(){function b(){this.name="DeviceGray";this.numComps=1;this.defaultColor=new Float32Array([0])}b.prototype={getRgb:function(a,c){var e=new Uint8Array(3);this.getRgbItem(a,c,e,0);return e},getRgbItem:function(a,c,e,d){a=255*a[c]|0;e[d]=
+e[d+1]=e[d+2]=0>a?0:255<a?255:a},getRgbBuffer:function(a,c,e,d,b,f){f=255/((1<<f)-1);for(var h=0;h<e;++h){var k=f*a[c++]|0;d[b++]=k;d[b++]=k;d[b++]=k}},getOutputLength:function(a){return 3*a},isPassthrough:r.prototype.isPassthrough,createRgbBuffer:r.prototype.createRgbBuffer,isDefaultDecode:function(a){return r.isDefaultDecode(a,this.numComps)},usesZeroToOneRange:!0};return b}(),Aa=function(){function b(){this.name="DeviceRGB";this.numComps=3;this.defaultColor=new Float32Array([0,0,0])}b.prototype=
+{getRgb:function(a,c){var e=new Uint8Array(3);this.getRgbItem(a,c,e,0);return e},getRgbItem:function(a,c,e,d){var b=255*a[c]|0,f=255*a[c+1]|0;a=255*a[c+2]|0;e[d]=0>b?0:255<b?255:b;e[d+1]=0>f?0:255<f?255:f;e[d+2]=0>a?0:255<a?255:a},getRgbBuffer:function(a,c,e,d,b,f){e*=3;if(8==f)d.set(a.subarray(c,c+e),b);else{f=255/((1<<f)-1);for(var h=0;h<e;++h)d[b++]=f*a[c++]|0}},getOutputLength:function(a){return a},isPassthrough:function(a){return 8==a},createRgbBuffer:r.prototype.createRgbBuffer,isDefaultDecode:function(a){return r.isDefaultDecode(a,
+this.numComps)},usesZeroToOneRange:!0};return b}(),Ba=function(){function b(a,e,d,b,f){var h=a[e+0]*d,k=a[e+1]*d,l=a[e+2]*d;d*=a[e+3];a=h*(-4.387332384609988*h+54.48615194189176*k+18.82290502165302*l+212.25662451639585*d+-285.2331026137004)+k*(1.7149763477362134*k-5.6096736904047315*l+-17.873870861415444*d-5.497006427196366)+l*(-2.5217340131683033*l-21.248923337353073*d+17.5119270841813)+d*(-21.86122147463605*d-189.48180835922747)+255;e=h*(8.841041422036149*h+60.118027045597366*k+6.871425592049007*
+l+31.159100130055922*d+-79.2970844816548)+k*(-15.310361306967817*k+17.575251261109482*l+131.35250912493976*d-190.9453302588951)+l*(4.444339102852739*l+9.8632861493405*d-24.86741582555878)+d*(-20.737325471181034*d-187.80453709719578)+255;h=h*(0.8842522430003296*h+8.078677503112928*k+30.89978309703729*l-0.23883238689178934*d+-14.183576799673286)+k*(10.49593273432072*k+63.02378494754052*l+50.606957656360734*d-112.23884253719248)+l*(0.03296041114873217*l+115.60384449646641*d+-193.58209356861505)+d*(-22.33816807309886*
+d-180.12613974708367)+255;b[f]=255<a?255:0>a?0:a;b[f+1]=255<e?255:0>e?0:e;b[f+2]=255<h?255:0>h?0:h}function a(){this.name="DeviceCMYK";this.numComps=4;this.defaultColor=new Float32Array([0,0,0,1])}a.prototype={getRgb:function(a,e){var d=new Uint8Array(3);b(a,e,1,d,0);return d},getRgbItem:function(a,e,d,g){b(a,e,1,d,g)},getRgbBuffer:function(a,e,d,g,f,h){h=1/((1<<h)-1);for(var k=0;k<d;k++)b(a,e,h,g,f),e+=4,f+=3},getOutputLength:function(a){return 3*(a>>2)},isPassthrough:r.prototype.isPassthrough,createRgbBuffer:r.prototype.createRgbBuffer,
+isDefaultDecode:function(a){return r.isDefaultDecode(a,this.numComps)},usesZeroToOneRange:!0};return a}(),va=function(){function b(a,e,d){this.name="CalGray";this.numComps=1;this.defaultColor=new Float32Array([0]);a||m("WhitePoint missing - required for color space CalGray");e=e||[0,0,0];this.XW=a[0];this.YW=a[1];this.ZW=a[2];this.XB=e[0];this.YB=e[1];this.ZB=e[2];this.G=d||1;(0>this.XW||0>this.ZW||1!==this.YW)&&m("Invalid WhitePoint components for "+this.name+", no fallback available");if(0>this.XB||
+0>this.YB||0>this.ZB)K("Invalid BlackPoint for "+this.name+", falling back to default"),this.XB=this.YB=this.ZB=0;0===this.XB&&0===this.YB&&0===this.ZB||x(this.name+", BlackPoint: XB: "+this.XB+", YB: "+this.YB+", ZB: "+this.ZB+", only default values are supported.");1>this.G&&(K("Invalid Gamma: "+this.G+" for "+this.name+", falling back to default"),this.G=1)}function a(a,e,d,b,f,h){e=Math.pow(e[d]*h,a.G);a=Math.max(116*Math.pow(a.YW*e,1/3)-16,0);b[f]=255*a/100;b[f+1]=255*a/100;b[f+2]=255*a/100}
+b.prototype={getRgb:function(a,e){var d=new Uint8Array(3);this.getRgbItem(a,e,d,0);return d},getRgbItem:function(c,e,d,b){a(this,c,e,d,b,1)},getRgbBuffer:function(c,e,d,b,f,h){h=1/((1<<h)-1);for(var k=0;k<d;++k)a(this,c,e,b,f,h),e+=1,f+=3},getOutputLength:function(a){return 3*a},isPassthrough:r.prototype.isPassthrough,createRgbBuffer:r.prototype.createRgbBuffer,isDefaultDecode:function(a){return r.isDefaultDecode(a,this.numComps)},usesZeroToOneRange:!0};return b}(),ya=function(){function b(a,c,b){this.name=
+"Lab";this.numComps=3;this.defaultColor=new Float32Array([0,0,0]);a||m("WhitePoint missing - required for color space Lab");c=c||[0,0,0];b=b||[-100,100,-100,100];this.XW=a[0];this.YW=a[1];this.ZW=a[2];this.amin=b[0];this.amax=b[1];this.bmin=b[2];this.bmax=b[3];this.XB=c[0];this.YB=c[1];this.ZB=c[2];(0>this.XW||0>this.ZW||1!==this.YW)&&m("Invalid WhitePoint components, no fallback available");if(0>this.XB||0>this.YB||0>this.ZB)K("Invalid BlackPoint, falling back to default"),this.XB=this.YB=this.ZB=
+0;if(this.amin>this.amax||this.bmin>this.bmax)K("Invalid Range, falling back to defaults"),this.amin=-100,this.amax=100,this.bmin=-100,this.bmax=100}function a(a){return a>=6/29?a*a*a:108/841*(a-4/29)}function c(c,d,b,f,h,k){var l=d[b],n=d[b+1];d=d[b+2];!1!==f&&(l=0+100*l/f,n=c.amin+n*(c.amax-c.amin)/f,d=c.bmin+d*(c.bmax-c.bmin)/f);n=n>c.amax?c.amax:n<c.amin?c.amin:n;d=d>c.bmax?c.bmax:d<c.bmin?c.bmin:d;f=(l+16)/116;l=f-d/200;n=c.XW*a(f+n/500);f=c.YW*a(f);l=c.ZW*a(l);1>c.ZW?(c=3.1339*n+-1.617*f+-0.4906*
+l,d=-0.9785*n+1.916*f+0.0333*l,n=0.072*n+-0.229*f+1.4057*l):(c=3.2406*n+-1.5372*f+-0.4986*l,d=-0.9689*n+1.8758*f+0.0415*l,n=0.0557*n+-0.204*f+1.057*l);h[k]=255*Math.sqrt(0>c?0:1<c?1:c);h[k+1]=255*Math.sqrt(0>d?0:1<d?1:d);h[k+2]=255*Math.sqrt(0>n?0:1<n?1:n)}b.prototype={getRgb:function(a,d){var b=new Uint8Array(3);c(this,a,d,!1,b,0);return b},getRgbItem:function(a,b,g,f){c(this,a,b,!1,g,f)},getRgbBuffer:function(a,b,g,f,h,k){k=(1<<k)-1;for(var l=0;l<g;l++)c(this,a,b,k,f,h),b+=3,h+=3},getOutputLength:function(a){return a},
+isPassthrough:r.prototype.isPassthrough,isDefaultDecode:function(a){return!0},usesZeroToOneRange:!1};return b}();E=3;var ka=function(){function b(){m("should not call Pattern constructor")}b.prototype={getPattern:function(a){m("Should not call Pattern.getStyle: "+a)}};b.shadingFromIR=function(a){return N[a[0]].fromIR(a)};b.parseShading=function(a,c,b,d){a=Y(a)?a.dict:a;switch(a.get("ShadingType")){case 2:case E:return new N.RadialAxial(a,c,b,d);default:return Z.notify(da.shadingPattern),new N.Dummy}};
+return b}(),N={SMALL_NUMBER:0.01};N.RadialAxial=function(){function b(a,c,b,d,g){this.matrix=c;this.coordsArr=a.get("Coords");this.shadingType=a.get("ShadingType");this.type="Pattern";this.ctx=g;c=a.get("ColorSpace","CS");this.cs=c=r.parse(c,b,d);d=0;var f=1;a.has("Domain")&&(g=a.get("Domain"),d=g[0],f=g[1]);var h=g=!1;a.has("Extend")&&(h=a.get("Extend"),g=h[0],h=h[1]);if(!(this.shadingType!==E||g&&h)){var k=this.coordsArr[0],l=this.coordsArr[1],n=this.coordsArr[2],p=this.coordsArr[3],z=this.coordsArr[4],
+s=this.coordsArr[5],k=Math.sqrt((k-p)*(k-p)+(l-z)*(l-z));n<=s+k&&s<=n+k&&x("Unsupported radial gradient.")}this.extendStart=g;this.extendEnd=h;n=a.get("Function");if(D(n)){for(var w=[],s=0,k=n.length;s<k;s++)l=b.fetchIfRef(n[s]),ea(l)||m("Invalid function"),w.push(S.parse(b,l));n=function(a){for(var c=[],b=0,d=w.length;b<d;b++)c.push(w[b](a)[0]);return c}}else ea(n)||m("Invalid function"),n=S.parse(b,n);s=f-d;k=s/10;b=this.colorStops=[];if(d>=f||0>=k)K("Bad shading domain.");else{for(l=d;l<=f;l+=
+k)p=c.getRgb(n([l]),0),p=q.makeCssRgb(p),b.push([(l-d)/s,p]);d="transparent";a.has("Background")&&(p=c.getRgb(a.get("Background"),0),d=q.makeCssRgb(p));g||(b.unshift([0,d]),b[1][0]+=N.SMALL_NUMBER);h||(b[b.length-1][0]-=N.SMALL_NUMBER,b.push([1,d]));this.colorStops=b}}b.fromIR=function(a){var c=a[1],b=a[2],d=a[3],g=a[4],f=a[5],h=a[6];return{type:"Pattern",getPattern:function(a){var l;2==c?l=a.createLinearGradient(d[0],d[1],g[0],g[1]):c==E&&(l=a.createRadialGradient(d[0],d[1],f,g[0],g[1],h));a=0;for(var n=
+b.length;a<n;++a){var p=b[a];l.addColorStop(p[0],p[1])}return l}}};b.prototype={getIR:function(){var a=this.coordsArr,c=this.shadingType;if(2==c)var b=[a[0],a[1]],d=[a[2],a[3]],g=null,f=null;else c==E?(b=[a[0],a[1]],d=[a[3],a[4]],g=a[2],f=a[5]):m("getPattern type unknown: "+c);if(a=this.matrix)b=q.applyTransform(b,a),d=q.applyTransform(d,a);return["RadialAxial",c,this.colorStops,b,d,g,f]}};return b}();N.Dummy=function(){function b(){this.type="Pattern"}b.fromIR=function(){return{type:"Pattern",getPattern:function(){return"hotpink"}}};
+b.prototype={getIR:function(){return["Dummy"]}};return b}();var Ca=function(){function b(a,c,b,d,g,f){this.name=a[1][0].name;this.operatorList=a[2];this.matrix=a[3]||[1,0,0,1,0,0];this.bbox=a[4];this.xstep=a[5];this.ystep=a[6];this.paintType=a[7];this.tilingType=a[8];this.color=c;this.objs=d;this.commonObjs=g;this.baseTransform=f;this.type="Pattern";this.ctx=b}b.getIR=function(a,c,b){var d=c.get("Matrix"),g=c.get("BBox"),f=c.get("XStep"),h=c.get("YStep"),k=c.get("PaintType");c=c.get("TilingType");
+return["TilingPattern",b,a,d,g,f,h,k,c]};b.prototype={createPatternCanvas:function(a){var c=this.operatorList,b=this.bbox,d=this.xstep,g=this.ystep,f=this.paintType,h=this.color,k=this.objs,l=this.commonObjs;K("TilingType: "+this.tilingType);var n=b[0],p=b[1],z=b[2],s=b[3],w=[n,p],F=[n+d,p+g],A=F[0]-w[0],F=F[1]-w[1],m=q.singularValueDecompose2dScale(this.matrix),u=q.singularValueDecompose2dScale(this.baseTransform),m=[m[0]*u[0],m[1]*u[1]],A=Math.min(Math.ceil(Math.abs(A*m[0])),3E3),F=Math.min(Math.ceil(Math.abs(F*
+m[1])),3E3),m=J.getCanvas("pattern",A,F,!0),u=m.context,k=new la(u,l,k);k.groupLevel=a.groupLevel;this.setFillAndStrokeStyleToContext(u,f,h);this.setScale(A,F,d,g);this.transformToScale(k);k.transform.apply(k,[1,0,0,1,-w[0],-w[1]]);this.clipBbox(k,b,n,p,z,s);k.executeOperatorList(c);return m.canvas},setScale:function(a,c,b,d){this.scale=[a/b,c/d]},transformToScale:function(a){var c=this.scale;a.transform.apply(a,[c[0],0,0,c[1],0,0])},scaleToContext:function(){var a=this.scale;this.ctx.scale(1/a[0],
+1/a[1])},clipBbox:function(a,c,b,d,g,f){c&&D(c)&&4==c.length&&(a.rectangle(b,d,g-b,f-d),a.clip(),a.endPath())},setFillAndStrokeStyleToContext:function(a,c,b){switch(c){case 1:c=this.ctx;a.fillStyle=c.fillStyle;a.strokeStyle=c.strokeStyle;break;case 2:c=r.singletons.rgb.getRgb(b,0);c=q.makeCssRgb(c);a.fillStyle=c;a.strokeStyle=c;break;default:m("Unsupported paint type: "+c)}},getPattern:function(a,c){var b=this.createPatternCanvas(c);a=this.ctx;a.setTransform.apply(a,this.baseTransform);a.transform.apply(a,
+this.matrix);this.scaleToContext();return a.createPattern(b,"repeat")}};return b}(),S=function(){return{getSampleArray:function(b,a,c,e){for(var d=1,g=0,f=b.length;g<f;g++)d*=b[g];d*=a;b=[];var f=a=0,h=1/(Math.pow(2,c)-1);e=e.getBytes((d*c+7)/8);for(var k=0,g=0;g<d;g++){for(;a<c;)f<<=8,f|=e[k++],a+=8;a-=c;b.push((f>>a)*h);f&=(1<<a)-1}return b},getIR:function(b,a){var c=a.dict;c||(c=a);var e=[this.constructSampled,null,this.constructInterpolated,this.constructStiched,this.constructPostScript],d=c.get("FunctionType");
+(e=e[d])||m("Unknown type of function");return e.call(this,a,c,b)},fromIR:function(b){switch(b[0]){case 0:return this.constructSampledFromIR(b);case 2:return this.constructInterpolatedFromIR(b);case 3:return this.constructStichedFromIR(b);default:return this.constructPostScriptFromIR(b)}},parse:function(b,a){var c=this.getIR(b,a);return this.fromIR(c)},constructSampled:function(b,a){function c(a){for(var c=a.length,b=[],d=0,e=0;e<c;e+=2)b[d]=[a[e],a[e+1]],++d;return b}var e=a.get("Domain"),d=a.get("Range");
+e&&d||m("No domain or range");var g=e.length/2,f=d.length/2,e=c(e),d=c(d),h=a.get("Size"),k=a.get("BitsPerSample"),l=a.get("Order")||1;1!==l&&K("No support for cubic spline interpolation: "+l);l=a.get("Encode");if(!l)for(var l=[],n=0;n<g;++n)l.push(0),l.push(h[n]-1);var l=c(l),n=(n=a.get("Decode"))?c(n):d,p=this.getSampleArray(h,f,k,b);return[0,g,e,l,n,p,h,f,Math.pow(2,k)-1,d]},constructSampledFromIR:function(b){return function(a){var c=b[1],e=b[2],d=b[3],g=b[4],f=b[5],h=b[6],k=b[7],l=b[9];c!=a.length&&
+m("Incorrect number of arguments: "+c+" != "+a.length);for(var n=1<<c,p=new Float64Array(n),z=new Uint32Array(n),s=0;s<n;s++)p[s]=1;for(var w=k,F=1,A=0;A<c;++A){for(var s=e[A][0],C=e[A][1],u=Math.min(Math.max(a[A],s),C),M=d[A][0]+(d[A][1]-d[A][0])/(C-s)*(u-s),C=h[A],M=Math.min(Math.max(M,0),C-1),s=M<C-1?Math.floor(M):M-1,u=s+1-M,M=M-s,q=s*w,r=q+w,s=0;s<n;s++)s&F?(p[s]*=M,z[s]+=r):(p[s]*=u,z[s]+=q);w*=C;F<<=1}a=new Float64Array(k);for(s=0;s<k;++s){for(A=c=0;A<n;A++)c+=f[z[A]+s]*p[A];c=g[s][0]+(g[s][1]-
+g[s][0])/1*(c-0);a[s]=Math.min(Math.max(c,l[s][0]),l[s][1])}return a}},constructInterpolated:function(b,a){var c=a.get("C0")||[0],e=a.get("C1")||[1],d=a.get("N");D(c)&&D(e)||m("Illegal dictionary for interpolated function");for(var g=c.length,f=[],h=0;h<g;++h)f.push(e[h]-c[h]);return[2,c,f,d]},constructInterpolatedFromIR:function(b){var a=b[1],c=b[2],e=b[3],d=c.length;return function(b){b=1==e?b[0]:Math.pow(b[0],e);for(var f=[],h=0;h<d;++h)f.push(a[h]+b*c[h]);return f}},constructStiched:function(b,
+a,c){(b=a.get("Domain"))||m("No domain");1!=b.length/2&&m("Bad domain for stiched function");for(var e=a.get("Functions"),d=[],g=0,f=e.length;g<f;++g)d.push(S.getIR(c,c.fetchIfRef(e[g])));c=a.get("Bounds");a=a.get("Encode");return[3,b,c,a,d]},constructStichedFromIR:function(b){var a=b[1],c=b[2],e=b[3];b=b[4];for(var d=[],g=0,f=b.length;g<f;g++)d.push(S.fromIR(b[g]));return function(b){b=b[0];var k=a[0],l=a[1];b>l?b=l:b<k&&(b=k);k=0;for(l=c.length;k<l&&!(b<c[k]);++k);l=a[0];0<k&&(l=c[k-1]);var f=a[1];
+k<c.length&&(f=c[k]);var g=e[2*k];return d[k]([g+(b-l)*(e[2*k+1]-g)/(f-l)])}},constructPostScript:function(b,a,c){c=a.get("Domain");a=a.get("Range");c||m("No domain.");a||m("No range.");b=new Da(b);b=(new Ea(b)).parse();return[4,c,a,b]},constructPostScriptFromIR:function(b){var a=b[1],c=b[2],e=c.length/2,d=new Fa(b[3]),g=new Ga;return function(b){for(var h=[],k=0,l=a.length/2;k<l;++k)h.push(b[k]);b=h.join("_");if(g.has(b))return g.get(b);h=d.execute(h);l=[];for(k=e-1;0<=k;--k){var n=h.pop(),p=2*k;
+n<c[p]?n=c[p]:n>c[p+1]&&(n=c[p+1]);l[k]=n}g.set(b,l);return l}}}}(),Ga=function(){function b(){this.cache={};this.total=0}b.prototype={has:function(a){return a in this.cache},get:function(a){return this.cache[a]},set:function(a,c){1024>this.total&&(this.cache[a]=c,this.total++)}};return b}(),Ha=function(){function b(a){this.stack=a||[]}b.prototype={push:function(a){100<=this.stack.length&&m("PostScript function stack overflow.");this.stack.push(a)},pop:function(){0>=this.stack.length&&m("PostScript function stack underflow.");
+return this.stack.pop()},copy:function(a){100<=this.stack.length+a&&m("PostScript function stack overflow.");var c=this.stack,b=c.length-a;for(a-=1;0<=a;a--,b++)c.push(c[b])},index:function(a){this.push(this.stack[this.stack.length-a-1])},roll:function(a,c){var b=this.stack,d=b.length-a,g=b.length-1,f=d+(c-Math.floor(c/a)*a),h,k,l;h=d;for(k=g;h<k;h++,k--)l=b[h],b[h]=b[k],b[k]=l;h=d;for(k=f-1;h<k;h++,k--)l=b[h],b[h]=b[k],b[k]=l;h=f;for(k=g;h<k;h++,k--)l=b[h],b[h]=b[k],b[k]=l}};return b}(),Fa=function(){function b(a,
+c){this.operators=a;this.operands=c}b.prototype={execute:function(a){a=new Ha(a);for(var c=0,b=this.operators,d=b.length,g,f;c<d;)if(g=b[c++],"number"==typeof g)a.push(g);else switch(g){case "jz":f=a.pop();(g=a.pop())||(c=f);break;case "j":c=g=a.pop();break;case "abs":g=a.pop();a.push(Math.abs(g));break;case "add":f=a.pop();g=a.pop();a.push(g+f);break;case "and":f=a.pop();g=a.pop();L(g)&&L(f)?a.push(g&&f):a.push(g&f);break;case "atan":g=a.pop();a.push(Math.atan(g));break;case "bitshift":f=a.pop();
+g=a.pop();0<g?a.push(g<<f):a.push(g>>f);break;case "ceiling":g=a.pop();a.push(Math.ceil(g));break;case "copy":g=a.pop();a.copy(g);break;case "cos":g=a.pop();a.push(Math.cos(g));break;case "cvi":g=a.pop()|0;a.push(g);break;case "cvr":break;case "div":f=a.pop();g=a.pop();a.push(g/f);break;case "dup":a.copy(1);break;case "eq":f=a.pop();g=a.pop();a.push(g==f);break;case "exch":a.roll(2,1);break;case "exp":f=a.pop();g=a.pop();a.push(Math.pow(g,f));break;case "false":a.push(!1);break;case "floor":g=a.pop();
+a.push(Math.floor(g));break;case "ge":f=a.pop();g=a.pop();a.push(g>=f);break;case "gt":f=a.pop();g=a.pop();a.push(g>f);break;case "idiv":f=a.pop();g=a.pop();a.push(g/f|0);break;case "index":g=a.pop();a.index(g);break;case "le":f=a.pop();g=a.pop();a.push(g<=f);break;case "ln":g=a.pop();a.push(Math.log(g));break;case "log":g=a.pop();a.push(Math.log(g)/Math.LN10);break;case "lt":f=a.pop();g=a.pop();a.push(g<f);break;case "mod":f=a.pop();g=a.pop();a.push(g%f);break;case "mul":f=a.pop();g=a.pop();a.push(g*
+f);break;case "ne":f=a.pop();g=a.pop();a.push(g!=f);break;case "neg":a.pop();a.push(-f);break;case "not":g=a.pop();L(g)&&L(f)?a.push(g&&f):a.push(g&f);break;case "or":f=a.pop();g=a.pop();L(g)&&L(f)?a.push(g||f):a.push(g|f);break;case "pop":a.pop();break;case "roll":f=a.pop();g=a.pop();a.roll(g,f);break;case "round":g=a.pop();a.push(Math.round(g));break;case "sin":g=a.pop();a.push(Math.sin(g));break;case "sqrt":g=a.pop();a.push(Math.sqrt(g));break;case "sub":f=a.pop();g=a.pop();a.push(g-f);break;case "true":a.push(!0);
+break;case "truncate":g=a.pop();g=0>g?Math.ceil(g):Math.floor(g);a.push(g);break;case "xor":f=a.pop();g=a.pop();L(g)&&L(f)?a.push(g!=f):a.push(g^f);break;default:m("Unknown operator "+g)}return a.stack}};return b}(),Ea=function(){function b(a){this.lexer=a;this.operators=[];this.prev=this.token=null}b.prototype={nextToken:function(){this.prev=this.token;this.token=this.lexer.getToken()},accept:function(a){return this.token.type==a?(this.nextToken(),!0):!1},expect:function(a){if(this.accept(a))return!0;
+m("Unexpected symbol: found "+this.token.type+" expected "+a+".")},parse:function(){this.nextToken();this.expect(v.LBRACE);this.parseBlock();this.expect(v.RBRACE);return this.operators},parseBlock:function(){for(;;)if(this.accept(v.NUMBER))this.operators.push(this.prev.value);else if(this.accept(v.OPERATOR))this.operators.push(this.prev.value);else if(this.accept(v.LBRACE))this.parseCondition();else break},parseCondition:function(){var a=this.operators.length;this.operators.push(null,null);this.parseBlock();
+this.expect(v.RBRACE);if(this.accept(v.IF))this.operators[a]=this.operators.length,this.operators[a+1]="jz";else if(this.accept(v.LBRACE)){var c=this.operators.length;this.operators.push(null,null);var b=this.operators.length;this.parseBlock();this.expect(v.RBRACE);this.expect(v.IFELSE);this.operators[c]=this.operators.length;this.operators[c+1]="j";this.operators[a]=b;this.operators[a+1]="jz"}else m("PS Function: error parsing conditional.")}};return b}(),v={LBRACE:0,RBRACE:1,NUMBER:2,OPERATOR:3,
+IF:4,IFELSE:5},T=function(){function b(a,b){this.type=a;this.value=b}var a={};b.getOperator=function(c){var e=a[c];return e?e:a[c]=new b(v.OPERATOR,c)};b.LBRACE=new b(v.LBRACE,"{");b.RBRACE=new b(v.RBRACE,"}");b.IF=new b(v.IF,"IF");b.IFELSE=new b(v.IFELSE,"IFELSE");return b}(),Da=function(){function b(a){this.stream=a;this.nextChar()}b.prototype={nextChar:function(){return this.currentChar=this.stream.getByte()},getToken:function(){for(var a=!1,c=this.currentChar;;){if(0>c)return EOF;if(a){if(10===
+c||13===c)a=!1}else if(37==c)a=!0;else if(!Lexer.isSpace(c))break;c=this.nextChar()}switch(c|0){case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:case 43:case 45:case 46:return new T(v.NUMBER,this.getNumber());case 123:return this.nextChar(),T.LBRACE;case 125:return this.nextChar(),T.RBRACE}for(a=String.fromCharCode(c);0<=(c=this.nextChar())&&(65<=c&&90>=c||97<=c&&122>=c);)a+=String.fromCharCode(c);switch(a.toLowerCase()){case "if":return T.IF;case "ifelse":return T.IFELSE;
+default:return T.getOperator(a)}},getNumber:function(){for(var a=this.currentChar,c=String.fromCharCode(a);0<=(a=this.nextChar());)if(48<=a&&57>=a||45===a||46===a)c+=String.fromCharCode(a);else break;a=parseFloat(c);isNaN(a)&&m("Invalid floating point number: "+a);return a}};return b}(),H=function(){function b(a,b,d){var g=q.getAxialAlignedBoundingBox(b,d);b=g[0];d=g[1];var f=g[2],g=g[3];if(b===f||d===g)return[1,0,0,1,a[0],a[1]];f=(a[2]-a[0])/(f-b);g=(a[3]-a[1])/(g-d);return[f,0,0,g,a[0]-b*f,a[1]-
+d*g]}function a(a){if(a.data)this.data=a.data;else{var b=a.dict;a=this.data={};a.subtype=b.get("Subtype").name;var d=b.get("Rect");a.rect=q.normalizeRect(d);a.annotationFlags=b.get("F");d=b.get("C");D(d)&&3===d.length?a.color=d:a.color=[0,0,0];if(b.has("BS"))d=b.get("BS"),a.borderWidth=d.has("W")?d.get("W"):1;else if(d=b.get("Border")||[0,0,1],a.borderWidth=d[2]||0,(d=d[3])&&D(d)){var g=d.length;if(0<g){for(var f=!1,h=0,k=0;k<g;k++)if(0<=+d[k])0<d[k]&&h++;else{f=!0;break}if(f||0===h)a.borderWidth=
+0}}var l;d=b.get("AP");R(d)?(d=d.get("N"),R(d)?(b=b.get("AS"))&&d.has(b.name)&&(l=d.get(b.name)):l=d):l=void 0;this.appearance=l;a.hasAppearance=!!this.appearance}}a.prototype={getData:function(){return this.data},hasHtml:function(){return!1},getHtmlElement:function(a){throw new ta("getHtmlElement() should be implemented in subclass");},getEmptyContainer:function(a,b){W&&m("getEmptyContainer() should be called from main thread");b=b||this.data.rect;var d=document.createElement(a);d.style.width=Math.ceil(b[2]-
+b[0])+"px";d.style.height=Math.ceil(b[3]-b[1])+"px";return d},isViewable:function(){var a=this.data;return!(!a||a.annotationFlags&&a.annotationFlags&34||!a.rect)},loadResources:function(a){var b=new G;this.appearance.dict.getAsync("Resources").then(function(d){d?(new ObjectLoader(d.map,a,d.xref)).load().then(function(){b.resolve(d)}):b.resolve()}.bind(this));return b},getOperatorList:function(a){var e=new G;if(!this.appearance)return e.resolve(new OperatorList),e;var d=this.data,g=this.appearance.dict,
+f=this.loadResources("ExtGState ColorSpace Pattern Shading XObject Font".split(" ")),h=g.get("BBox")||[0,0,1,1],k=g.get("Matrix")||[1,0,0,1,0,0],l=b(d.rect,h,k);f.then(function(b){var f=new OperatorList;f.addOp(y.beginAnnotation,[d.rect,l,k]);a.getOperatorList(this.appearance,b,f);f.addOp(y.endAnnotation,[]);e.resolve(f)}.bind(this));return e}};a.getConstructor=function(c,b){if(c){if("Link"===c)return Ia;if("Text"===c)return Ja;if("Widget"===c){if(b)return"Tx"===b?Ka:ca}else return a}};a.fromData=
+function(c){var b=a.getConstructor(c.subtype,c.fieldType);if(b)return new b({data:c})};a.fromRef=function(c,b){var d=c.fetchIfRef(b);if(R(d)){var g=d.get("Subtype");if(g=P(g)?g.name:""){var f=q.getInheritableProperty(d,"FT"),f=P(f)?f.name:"";if(f=a.getConstructor(g,f)){d=new f({dict:d,ref:b});if(d.isViewable())return d;x("unimplemented annotation type: "+g)}}}};a.appendToOperatorList=function(a,b,d,g){var f=new G;d=[];for(var h=0,k=a.length;h<k;++h)d.push(a[h].getOperatorList(g));Promise.all(d).then(function(a){b.addOp(y.beginAnnotations,
+[]);for(var c=0,d=a.length;c<d;++c)b.addOpList(a[c]);b.addOp(y.endAnnotations,[]);f.resolve()},function(a){f.reject(a)});return f};return a}();PDFJS.Annotation=H;var ca=function(){function b(a){H.call(this,a);if(!a.data){var b=a.dict,d=this.data;d.fieldValue=V(q.getInheritableProperty(b,"V")||"");d.alternativeText=V(b.get("TU")||"");d.defaultAppearance=q.getInheritableProperty(b,"DA")||"";var g=q.getInheritableProperty(b,"FT");d.fieldType=P(g)?g.name:"";d.fieldFlags=q.getInheritableProperty(b,"Ff")||
+0;this.fieldResources=q.getInheritableProperty(b,"DR")||new Dict;var g=[],f=b;for(a=a.ref;f;){var b=f.get("Parent"),h=f.getRaw("Parent");if(f=f.get("T"))g.unshift(V(f));else{var f=b.get("Kids"),k,l;k=0;for(l=f.length;k<l;k++){var n=f[k];if(n.num==a.num&&n.gen==a.gen)break}g.unshift("`"+k)}f=b;a=h}d.fullName=g.join(".")}}var a=H.prototype;q.inherit(b,H,{isViewable:function(){return"Sig"===this.data.fieldType?(x("unimplemented annotation type: Widget signature"),!1):a.isViewable.call(this)}});return b}(),
+Ka=function(){function b(a){ca.call(this,a);a.data||(this.data.textAlignment=q.getInheritableProperty(a.dict,"Q"))}q.inherit(b,ca,{hasHtml:function(){return!this.data.hasAppearance&&!!this.data.fieldValue},getHtmlElement:function(a){W&&m("getHtmlElement() shall be called from main thread");var c=this.data,b=this.getEmptyContainer("div");b.style.display="table";var d=document.createElement("div");d.textContent=c.fieldValue;d.style.textAlign=["left","center","right"][c.textAlignment];d.style.verticalAlign=
+"middle";d.style.display="table-cell";a=c.fontRefName?a.getData(c.fontRefName):null;var g=d.style;g.fontSize=c.fontSize+"px";g.direction=0>c.fontDirection?"rtl":"ltr";a&&(g.fontWeight=a.black?a.bold?"bolder":"bold":a.bold?"bold":"normal",g.fontStyle=a.italic?"italic":"normal",c=a.loadedName,g.fontFamily=(c?'"'+c+'", ':"")+(a.fallbackName||"Helvetica, sans-serif"));b.appendChild(d);return b},getOperatorList:function(a){if(this.appearance)return H.prototype.getOperatorList.call(this,a);var c=new G,
+b=new OperatorList,d=this.data,g=d.defaultAppearance;if(!g)return c.resolve(b),c;for(var f=Stream,h=g.length,k=new Uint8Array(h),l=0;l<h;++l)k[l]=g.charCodeAt(l)&255;g=new f(k);a.getOperatorList(g,this.fieldResources,b);a=b.fnArray;g=b.argsArray;d.rgb=[0,0,0];for(f=0;0>f;++f)h=a[f],k=g[f],h===y.setFont?(d.fontRefName=k[0],h=k[1],0>h?(d.fontDirection=-1,d.fontSize=-h):(d.fontDirection=1,d.fontSize=h)):h===y.setFillRGBColor?d.rgb=k:h===y.setFillGray&&(h=255*k[0],d.rgb=[h,h,h]);c.resolve(b);return c}});
+return b}(),Ja=function(){function b(a){H.call(this,a);if(!a.data){a=a.dict;var c=this.data,b=a.get("Contents"),d=a.get("T");c.content=V(b||"");c.title=V(d||"");c.name=a.has("Name")?a.get("Name").name:"Note"}}q.inherit(b,H,{getOperatorList:function(a){a=new G;a.resolve(new OperatorList);return a},hasHtml:function(){return!0},getHtmlElement:function(a){W&&m("getHtmlElement() shall be called from main thread");var c=this.data,b=c.rect;10>b[3]-b[1]&&(b[3]=b[1]+10);10>b[2]-b[0]&&(b[2]=b[0]+(b[3]-b[1]));
+var d=this.getEmptyContainer("section",b);d.className="annotText";a=document.createElement("img");a.style.height=d.style.height;var g=c.name;a.src=PDFJS.imageResourcesPath+"annotation-"+g.toLowerCase()+".svg";a.alt="[{{type}} Annotation]";a.dataset.l10nId="text_annotation_type";a.dataset.l10nArgs=JSON.stringify({type:g});var f=document.createElement("div");f.setAttribute("hidden",!0);var g=document.createElement("h1"),h=document.createElement("p");f.style.left=Math.floor(b[2]-b[0])+"px";f.style.top=
+"0px";g.textContent=c.title;if(c.content||c.title){for(var b=document.createElement("span"),c=c.content.split(/(?:\r\n?|\n)/),k=0,l=c.length;k<l;++k)b.appendChild(document.createTextNode(c[k])),k<l-1&&b.appendChild(document.createElement("br"));h.appendChild(b);b=function(){d.style.zIndex+=1;f.removeAttribute("hidden")};c=function(a){if(a.toElement||a.relatedTarget)d.style.zIndex-=1,f.setAttribute("hidden",!0)};f.addEventListener("mouseover",b,!1);f.addEventListener("mouseout",c,!1);a.addEventListener("mouseover",
+b,!1);a.addEventListener("mouseout",c,!1)}else f.setAttribute("hidden",!0);f.appendChild(g);f.appendChild(h);d.appendChild(a);d.appendChild(f);return d}});return b}(),Ia=function(){function b(a){H.call(this,a);if(!a.data){var c=a.dict;a=this.data;var b=c.get("A");if(b)if(c=b.get("S").name,"URI"===c){var d;d=b.get("URI");d=0===d.indexOf("www.")?"http://"+d:d;$(d,!1)||(d="");a.url=d}else"GoTo"===c?a.dest=b.get("D"):"GoToR"===c?(c=b.get("F"),R(c)&&(d=c.get("F")||""),$(d,!1)||(d=""),a.url=d,a.dest=b.get("D")):
+"Named"===c?a.action=b.get("N").name:x("unrecognized link type: "+c);else c.has("Dest")&&(d=c.get("Dest"),a.dest=P(d)?d.name:d)}}q.inherit(b,H,{hasOperatorList:function(){return!1},hasHtml:function(){return!0},getHtmlElement:function(a){a=this.data.rect;var c=document.createElement("a"),b=this.data.borderWidth;c.style.borderWidth=b+"px";for(var d=this.data.color,g=[],f=0;3>f;++f)g[f]=Math.round(255*d[f]);c.style.borderColor=q.makeCssRgb(g);c.style.borderStyle="solid";d=a[3]-a[1]-2*b;c.style.width=
+a[2]-a[0]-2*b+"px";c.style.height=d+"px";c.href=this.data.url||"";return c}});return b}();PDFJS.maxImageSize=void 0===PDFJS.maxImageSize?-1:PDFJS.maxImageSize;PDFJS.disableFontFace=void 0===PDFJS.disableFontFace?!1:PDFJS.disableFontFace;PDFJS.imageResourcesPath=void 0===PDFJS.imageResourcesPath?"":PDFJS.imageResourcesPath;PDFJS.disableWorker=void 0===PDFJS.disableWorker?!1:PDFJS.disableWorker;PDFJS.workerSrc=void 0===PDFJS.workerSrc?null:PDFJS.workerSrc;PDFJS.disableRange=void 0===PDFJS.disableRange?
+!1:PDFJS.disableRange;PDFJS.disableAutoFetch=void 0===PDFJS.disableAutoFetch?!1:PDFJS.disableAutoFetch;PDFJS.pdfBug=void 0===PDFJS.pdfBug?!1:PDFJS.pdfBug;PDFJS.postMessageTransfers=void 0===PDFJS.postMessageTransfers?!0:PDFJS.postMessageTransfers;PDFJS.disableCreateObjectURL=void 0===PDFJS.disableCreateObjectURL?!1:PDFJS.disableCreateObjectURL;PDFJS.verbosity=void 0===PDFJS.verbosity?PDFJS.VERBOSITY_LEVELS.warnings:PDFJS.verbosity;PDFJS.getDocument=function(b,a,c,e){var d,g;"string"===typeof b?b=
+{url:b}:"object"==typeof b&&null!==b&&void 0!==b&&"byteLength"in b?b={data:b}:"object"!==typeof b&&m("Invalid parameter in getDocument, need either Uint8Array, string or a parameter object");b.url||b.data||m("Invalid parameter array, need either .data or .url");var f={};for(d in b)f[d]="url"===d&&"undefined"!==typeof window?pa(window.location.href,b[d]):b[d];b=new PDFJS.LegacyPromise;d=new PDFJS.LegacyPromise;g=new La(b,d,a,e);b.then(function(){g.passwordCallback=c;g.fetchDocument(f)});return d};
+var Ma=function(){function b(a,c){this.pdfInfo=a;this.transport=c}b.prototype={get numPages(){return this.pdfInfo.numPages},get fingerprint(){return this.pdfInfo.fingerprint},get embeddedFontsUsed(){return this.transport.embeddedFontsUsed},getPage:function(a){return this.transport.getPage(a)},getPageIndex:function(a){return this.transport.getPageIndex(a)},getDestinations:function(){return this.transport.getDestinations()},getJavaScript:function(){var a=new PDFJS.LegacyPromise;a.resolve(this.pdfInfo.javaScript);
+return a},getOutline:function(){var a=new PDFJS.LegacyPromise;a.resolve(this.pdfInfo.outline);return a},getMetadata:function(){var a=new PDFJS.LegacyPromise,c=this.pdfInfo.metadata;a.resolve({info:this.pdfInfo.info,metadata:c?new PDFJS.Metadata(c):null});return a},isEncrypted:function(){var a=new PDFJS.LegacyPromise;a.resolve(this.pdfInfo.encrypted);return a},getData:function(){var a=new PDFJS.LegacyPromise;this.transport.getData(a);return a},dataLoaded:function(){return this.transport.dataLoaded()},
+cleanup:function(){this.transport.startCleanup()},destroy:function(){this.transport.destroy()}};return b}(),Pa=function(){function b(a,c){this.pageInfo=a;this.transport=c;this.stats=new ua;this.stats.enabled=!!t.PDFJS.enableStats;this.commonObjs=c.commonObjs;this.objs=new ma;this.pendingDestroy=this.cleanupAfterRender=this.receivingOperatorList=!1;this.renderTasks=[]}b.prototype={get pageNumber(){return this.pageInfo.pageIndex+1},get rotate(){return this.pageInfo.rotate},get ref(){return this.pageInfo.ref},
+get view(){return this.pageInfo.view},getViewport:function(a,c){2>arguments.length&&(c=this.rotate);return new PDFJS.PageViewport(this.view,a,c,0,0)},getAnnotations:function(){if(this.annotationsPromise)return this.annotationsPromise;var a=new PDFJS.LegacyPromise;this.annotationsPromise=a;this.transport.getAnnotations(this.pageInfo.pageIndex);return a},render:function(a){function c(a){var c=f.renderTasks.indexOf(d);0<=c&&f.renderTasks.splice(c,1);f.cleanupAfterRender&&(f.pendingDestroy=!0);f._tryDestroy();
+a?g.promise.reject(a):g.promise.resolve();b.timeEnd("Rendering");b.timeEnd("Overall")}var b=this.stats;b.time("Overall");this.pendingDestroy=!1;this.displayReadyPromise||(this.receivingOperatorList=!0,this.displayReadyPromise=new G,this.operatorList={fnArray:[],argsArray:[],lastChunk:!1},this.stats.time("Page Request"),this.transport.messageHandler.send("RenderPageRequest",{pageIndex:this.pageNumber-1}));var d=new Na(c,a,this.objs,this.commonObjs,this.operatorList,this.pageNumber);this.renderTasks.push(d);
+var g=new Oa(d),f=this;this.displayReadyPromise.then(function(a){f.pendingDestroy?c():(b.time("Rendering"),d.initalizeGraphics(a),d.operatorListChanged())},function(a){c(a)});return g},getTextContent:function(){var a=new PDFJS.LegacyPromise;this.transport.messageHandler.send("GetTextContent",{pageIndex:this.pageNumber-1},function(c){a.resolve(c)});return a},getOperationList:function(){var a=new PDFJS.LegacyPromise;a.resolve({dependencyFontsID:null,operatorList:null});return a},destroy:function(){this.pendingDestroy=
+!0;this._tryDestroy()},_tryDestroy:function(){this.pendingDestroy&&0===this.renderTasks.length&&!this.receivingOperatorList&&(delete this.operatorList,delete this.displayReadyPromise,this.objs.clear(),this.pendingDestroy=!1)},_startRenderPage:function(a){this.displayReadyPromise.resolve(a)},_renderPageChunk:function(a){for(var c=0,b=a.length;c<b;c++)this.operatorList.fnArray.push(a.fnArray[c]),this.operatorList.argsArray.push(a.argsArray[c]);this.operatorList.lastChunk=a.lastChunk;for(c=0;c<this.renderTasks.length;c++)this.renderTasks[c].operatorListChanged();
+a.lastChunk&&(this.receivingOperatorList=!1,this._tryDestroy())}};return b}(),La=function(){function b(a,c,b,d){this.pdfDataRangeTransport=b;this.workerReadyPromise=c;this.progressCallback=d;this.commonObjs=new ma;this.pageCache=[];this.pagePromises=[];this.embeddedFontsUsed=!1;this.passwordCallback=null;if(!t.PDFJS.disableWorker&&"undefined"!==typeof Worker){(c=PDFJS.workerSrc)||m("No PDFJS.workerSrc specified");try{var g=new Worker(c),f=new aa("main",g);this.messageHandler=f;f.on("test",function(b){b&&
+b.supportTypedArray?(this.worker=g,b.supportTransfers||(PDFJS.postMessageTransfers=!1),this.setupMessageHandler(f),a.resolve()):(t.PDFJS.disableWorker=!0,this.loadFakeWorkerFiles().then(function(){this.setupFakeWorker();a.resolve()}.bind(this)))}.bind(this));var h=new Uint8Array([PDFJS.postMessageTransfers?255:0]);try{f.send("test",h,null,[h.buffer])}catch(k){K("Cannot use postMessage transfers"),h[0]=0,f.send("test",h)}return}catch(l){K("The worker has been disabled.")}}t.PDFJS.disableWorker=!0;
+this.loadFakeWorkerFiles().then(function(){this.setupFakeWorker();a.resolve()}.bind(this))}b.prototype={destroy:function(){this.pageCache=[];this.pagePromises=[];var a=this;this.messageHandler.send("Terminate",null,function(){a.worker&&a.worker.terminate()})},loadFakeWorkerFiles:function(){PDFJS.fakeWorkerFilesLoadedPromise||(PDFJS.fakeWorkerFilesLoadedPromise=new G,q.loadScript(PDFJS.workerSrc,function(){PDFJS.fakeWorkerFilesLoadedPromise.resolve()}));return PDFJS.fakeWorkerFilesLoadedPromise},setupFakeWorker:function(){x("Setting up fake worker.");
+var a={postMessage:function(b){a.onmessage({data:b})},terminate:function(){}},b=new aa("main",a);this.setupMessageHandler(b);PDFJS.WorkerMessageHandler.setup(b)},setupMessageHandler:function(a){function b(c){a.send("UpdatePassword",c)}this.messageHandler=a;var e=this.pdfDataRangeTransport;e&&(e.addRangeListener(function(b,c){a.send("OnDataRange",{begin:b,chunk:c})}),e.addProgressListener(function(b){a.send("OnDataProgress",{loaded:b})}),a.on("RequestDataRange",function(a){e.requestDataRange(a.begin,
+a.end)},this));a.on("GetDoc",function(a){this.pdfDocument=a=new Ma(a.pdfInfo,this);this.workerReadyPromise.resolve(a)},this);a.on("NeedPassword",function(a){if(this.passwordCallback)return this.passwordCallback(b,ha.NEED_PASSWORD);this.workerReadyPromise.reject(a.exception.message,a.exception)},this);a.on("IncorrectPassword",function(a){if(this.passwordCallback)return this.passwordCallback(b,ha.INCORRECT_PASSWORD);this.workerReadyPromise.reject(a.exception.message,a.exception)},this);a.on("InvalidPDF",
+function(a){this.workerReadyPromise.reject(a.exception.name,a.exception)},this);a.on("MissingPDF",function(a){this.workerReadyPromise.reject(a.exception.message,a.exception)},this);a.on("UnknownError",function(a){this.workerReadyPromise.reject(a.exception.message,a.exception)},this);a.on("GetPage",function(a){a=a.pageInfo;var b=new Pa(a,this);this.pageCache[a.pageIndex]=b;this.pagePromises[a.pageIndex].resolve(b)},this);a.on("GetAnnotations",function(a){this.pageCache[a.pageIndex].annotationsPromise.resolve(a.annotations)},
+this);a.on("StartRenderPage",function(a){var b=this.pageCache[a.pageIndex];b.stats.timeEnd("Page Request");b._startRenderPage(a.transparency)},this);a.on("RenderPageChunk",function(a){this.pageCache[a.pageIndex]._renderPageChunk(a.operatorList)},this);a.on("commonobj",function(a){var b=a[0],c=a[1];if(!this.commonObjs.hasData(b))switch(c){case "Font":a=a[2];var e;if("error"in a){var k=a.error;x("Error during font loading: "+k);this.commonObjs.resolve(b,k);break}else e=new Qa(a);Q.bind([e],function(a){this.commonObjs.resolve(b,
+e)}.bind(this));break;case "FontPath":this.commonObjs.resolve(b,a[2]);break;default:k("Got unknown common object type "+c)}},this);a.on("obj",function(a){var b=a[0],c=a[2],e=this.pageCache[a[1]];if(!e.objs.hasData(b))switch(c){case "JpegStream":a=a[3];ra(b,a,e.objs);break;case "Image":a=a[3];e.objs.resolve(b,a);"data"in a&&8E6<a.data.length&&(e.cleanupAfterRender=!0);break;default:m("Got unknown object type "+c)}},this);a.on("DocProgress",function(a){this.progressCallback&&this.progressCallback({loaded:a.loaded,
+total:a.total})},this);a.on("DocError",function(a){this.workerReadyPromise.reject(a)},this);a.on("PageError",function(a){var b=this.pageCache[a.pageNum-1];b.displayReadyPromise?b.displayReadyPromise.reject(a.error):m(a.error)},this);a.on("JpegDecode",function(a,b){var c=a[0],e=a[1];3!=e&&1!=e&&m("Only 3 component or 1 component can be returned");var k=new Image;k.onload=function(){var a=k.width,c=k.height,d=a*c,f=4*d,d=new Uint8Array(d*e),s=fa(a,c).getContext("2d");s.drawImage(k,0,0);s=s.getImageData(0,
+0,a,c).data;if(3==e)for(var w=0,m=0;w<f;w+=4,m+=3)d[m]=s[w],d[m+1]=s[w+1],d[m+2]=s[w+2];else if(1==e)for(m=w=0;w<f;w+=4,m++)d[m]=s[w];b.resolve({data:d,width:a,height:c})}.bind(this);k.src=c})},fetchDocument:function(a){a.disableAutoFetch=PDFJS.disableAutoFetch;a.chunkedViewerLoading=!!this.pdfDataRangeTransport;this.messageHandler.send("GetDocRequest",{source:a,disableRange:PDFJS.disableRange,maxImageSize:PDFJS.maxImageSize,disableFontFace:PDFJS.disableFontFace,disableCreateObjectURL:PDFJS.disableCreateObjectURL,
+verbosity:PDFJS.verbosity})},getData:function(a){this.messageHandler.send("GetData",null,function(b){a.resolve(b)})},dataLoaded:function(){var a=new PDFJS.LegacyPromise;this.messageHandler.send("DataLoaded",null,function(b){a.resolve(b)});return a},getPage:function(a,b){var e=a-1;if(e in this.pagePromises)return this.pagePromises[e];b=new PDFJS.LegacyPromise;this.pagePromises[e]=b;this.messageHandler.send("GetPageRequest",{pageIndex:e});return b},getPageIndex:function(a){var b=new PDFJS.LegacyPromise;
+this.messageHandler.send("GetPageIndex",{ref:a},function(a){b.resolve(a)});return b},getAnnotations:function(a){this.messageHandler.send("GetAnnotationsRequest",{pageIndex:a})},getDestinations:function(){var a=new PDFJS.LegacyPromise;this.messageHandler.send("GetDestinations",null,function(b){a.resolve(b)});return a},startCleanup:function(){this.messageHandler.send("Cleanup",null,function(){for(var a=0,b=this.pageCache.length;a<b;a++){var e=this.pageCache[a];e&&e.destroy()}this.commonObjs.clear();
+Q.clear()}.bind(this))}};return b}(),ma=function(){function b(){this.objs={}}b.prototype={ensureObj:function(a){if(this.objs[a])return this.objs[a];var b={promise:new G,data:null,resolved:!1};return this.objs[a]=b},get:function(a,b){if(b)return this.ensureObj(a).promise.then(b),null;var e=this.objs[a];e&&e.resolved||m("Requesting object that isn't resolved yet "+a);return e.data},resolve:function(a,b){var e=this.ensureObj(a);e.resolved=!0;e.data=b;e.promise.resolve(b)},isResolved:function(a){var b=
+this.objs;return b[a]?b[a].resolved:!1},hasData:function(a){return this.isResolved(a)},getData:function(a){var b=this.objs;return b[a]&&b[a].resolved?b[a].data:null},clear:function(){this.objs={}}};return b}(),Oa=function(){function b(a){this.internalRenderTask=a;this.promise=new PDFJS.LegacyPromise}b.prototype.cancel=function(){this.internalRenderTask.cancel()};return b}(),Na=function(){function b(a,b,e,d,g,f){this.callback=a;this.params=b;this.objs=e;this.commonObjs=d;this.operatorListIdx=null;
+this.operatorList=g;this.pageNumber=f;this.running=!1;this.graphicsReadyCallback=null;this.cancelled=this.graphicsReady=!1}b.prototype={initalizeGraphics:function(a){if(!this.cancelled){PDFJS.pdfBug&&"StepperManager"in t&&t.StepperManager.enabled&&(this.stepper=t.StepperManager.create(this.pageNumber-1),this.stepper.init(this.operatorList),this.stepper.nextBreakPoint=this.stepper.getNextBreakPoint());var b=this.params;this.gfx=new la(b.canvasContext,this.commonObjs,this.objs,b.textLayer,b.imageLayer);
+this.gfx.beginDrawing(b.viewport,a);this.operatorListIdx=0;this.graphicsReady=!0;this.graphicsReadyCallback&&this.graphicsReadyCallback()}},cancel:function(){this.running=!1;this.cancelled=!0;this.callback("cancelled")},operatorListChanged:function(){this.graphicsReady?(this.stepper&&this.stepper.updateOperatorList(this.operatorList),this.running||this._continue()):this.graphicsReadyCallback||(this.graphicsReadyCallback=this._continue.bind(this))},_continue:function(){this.running=!0;this.cancelled||
+(this.params.continueCallback?this.params.continueCallback(this._next.bind(this)):this._next())},_next:function(){this.cancelled||(this.operatorListIdx=this.gfx.executeOperatorList(this.operatorList,this.operatorListIdx,this._continue.bind(this),this.stepper),this.operatorListIdx===this.operatorList.argsArray.length&&(this.running=!1,this.operatorList.lastChunk&&(this.gfx.endDrawing(),this.callback())))}};return b}();PDFJS.Metadata=function(){function b(a){return a.replace(/>\\376\\377([^<]+)/g,function(a,
+b){for(var c=b.replace(/\\([0-3])([0-7])([0-7])/g,function(a,b,c,d){return String.fromCharCode(64*b+8*c+1*d)}),f="",h=0;h<c.length;h+=2)var k=256*c.charCodeAt(h)+c.charCodeAt(h+1),f=f+("&#x"+(65536+k).toString(16).substring(1)+";");return">"+f})}function a(a){"string"===typeof a?(a=b(a),a=(new DOMParser).parseFromString(a,"application/xml")):a instanceof Document||m("Metadata: Invalid metadata object");this.metaDocument=a;this.metadata={};this.parse()}a.prototype={parse:function(){var a=this.metaDocument.documentElement;
+if("rdf:rdf"!==a.nodeName.toLowerCase())for(a=a.firstChild;a&&"rdf:rdf"!==a.nodeName.toLowerCase();)a=a.nextSibling;var b=a?a.nodeName.toLowerCase():null;if(a&&"rdf:rdf"===b&&a.hasChildNodes()){var a=a.childNodes,d,g,f,h,k,l;f=0;for(k=a.length;f<k;f++)if(b=a[f],"rdf:description"===b.nodeName.toLowerCase())for(h=0,l=b.childNodes.length;h<l;h++)"#text"!==b.childNodes[h].nodeName.toLowerCase()&&(d=b.childNodes[h],g=d.nodeName.toLowerCase(),this.metadata[g]=d.textContent.trim())}},get:function(a){return this.metadata[a]||
+null},has:function(a){return"undefined"!==typeof this.metadata[a]}};return a}();var J=function(){var b={};return{getCanvas:function(a,c,e,d){a in b?(a=b[a],a.canvas.width=c,a.canvas.height=e,a.context.setTransform(1,0,0,1,0,0)):(c=fa(c,e),e=c.getContext("2d"),d&&ga(e),b[a]=a={canvas:c,context:e});return a},clear:function(){b={}}}}(),na=function(){function b(a){this.alphaIsShape=!1;this.fontSize=0;this.fontSizeScale=1;this.textMatrix=ia;this.fontMatrix=ba;this.wordSpacing=this.charSpacing=this.lineY=
+this.lineX=this.y=this.x=this.leading=0;this.textHScale=1;this.textRenderingMode=X;this.textRise=0;this.fillColorSpace=r.singletons.gray;this.fillColorSpaceObj=null;this.strokeColorSpace=r.singletons.gray;this.strokeColorObj=this.fillColorObj=this.strokeColorSpaceObj=null;this.strokeColor=this.fillColor="#000000";this.lineWidth=this.strokeAlpha=this.fillAlpha=1;this.old=a}b.prototype={clone:function(){return Object.create(this)},setCurrentPoint:function(a,b){this.x=a;this.y=b}};return b}(),la=function(){function b(a,
+b,c,d,e){this.ctx=a;this.current=new na;this.stateStack=[];this.pendingClip=null;this.pendingEOFill=!1;this.xobjs=this.res=null;this.commonObjs=b;this.objs=c;this.textLayer=d;this.imageLayer=e;this.groupStack=[];this.baseTransform=this.processingType3=null;this.baseTransformStack=[];this.groupLevel=0;a&&ga(a)}function a(a,b){if("undefined"!==typeof ImageData&&b instanceof ImageData)a.putImageData(b,0,0);else{var c=b.height/16|0,d=b.height-16*c,e=64*b.width,f=b.width*d*4,g=a.createImageData(b.width,
+16),h=0,m=b.data,C=g.data,u="set"in C&&"subarray"in m,q=0;for(;q<c;q++){if(u)C.set(m.subarray(h,h+e)),h+=e;else for(var r=0;r<e;r++)g.data[r]=b.data[h++];a.putImageData(g,0,16*q)}if(0!==d){if(u)C.set(m.subarray(h,h+f));else for(r=0;r<f;r++)g.data[r]=b.data[h++];a.putImageData(g,0,16*c)}}}function c(a,b){for(var c=b.width,d=b.height,e=a.createImageData(c,d),f=b.data,g=e.data,h=0,m=3,q=0;q<d;q++)for(var u=0,r=0;r<c;r++){if(!u)var t=f[h++],u=128;t&u||(g[m]=255);m+=4;u>>=1}a.putImageData(e,0,0)}var e=
+["butt","round","square"],d=["miter","round","bevel"],g={},f={};b.prototype={beginDrawing:function(a,b){var c=this.ctx.canvas.width,d=this.ctx.canvas.height;b?this.ctx.clearRect(0,0,c,d):(this.ctx.mozOpaque=!0,this.ctx.save(),this.ctx.fillStyle="rgb(255, 255, 255)",this.ctx.fillRect(0,0,c,d),this.ctx.restore());c=a.transform;this.baseTransform=c.slice();this.ctx.save();this.ctx.transform.apply(this.ctx,c);this.textLayer&&this.textLayer.beginLayout();this.imageLayer&&this.imageLayer.beginLayout()},
+executeOperatorList:function(a,b,c,d){var e=a.argsArray;a=a.fnArray;b=b||0;var f=e.length;if(f==b)return b;for(var g=Date.now()+15,h=this.commonObjs,m=this.objs,q,u=Promise.resolve();;){if(d&&b===d.nextBreakPoint)return d.breakIt(b,c),b;q=a[b];if(q!==y.dependency)this[q].apply(this,e[b]);else{q=e[b];for(var r=0,t=q.length;r<t;r++){var x=q[r],v="g_"==x.substring(0,2);if(!v&&!m.isResolved(x))return m.get(x,c),b;if(v&&!h.isResolved(x))return h.get(x,c),b}}b++;if(b==f)return b;if(c&&Date.now()>g)return u.then(c),
+b}},endDrawing:function(){this.ctx.restore();J.clear();this.textLayer&&this.textLayer.endLayout();this.imageLayer&&this.imageLayer.endLayout()},setLineWidth:function(a){this.current.lineWidth=a;this.ctx.lineWidth=a},setLineCap:function(a){this.ctx.lineCap=e[a]},setLineJoin:function(a){this.ctx.lineJoin=d[a]},setMiterLimit:function(a){this.ctx.miterLimit=a},setDash:function(a,b){var c=this.ctx;"setLineDash"in c?(c.setLineDash(a),c.lineDashOffset=b):(c.mozDash=a,c.mozDashOffset=b)},setRenderingIntent:function(a){},
+setFlatness:function(a){},setGState:function(a){for(var b=0,c=a.length;b<c;b++){var d=a[b],e=d[1];switch(d[0]){case "LW":this.setLineWidth(e);break;case "LC":this.setLineCap(e);break;case "LJ":this.setLineJoin(e);break;case "ML":this.setMiterLimit(e);break;case "D":this.setDash(e[0],e[1]);break;case "RI":this.setRenderingIntent(e);break;case "FL":this.setFlatness(e);break;case "Font":this.setFont(e[0],e[1]);break;case "CA":this.current.strokeAlpha=d[1];break;case "ca":this.current.fillAlpha=d[1];
+this.ctx.globalAlpha=d[1];break;case "BM":e&&e.name&&"Normal"!==e.name?(d=e.name.replace(/([A-Z])/g,function(a){return"-"+a.toLowerCase()}).substring(1),this.ctx.globalCompositeOperation=d,this.ctx.globalCompositeOperation!==d&&x('globalCompositeOperation "'+d+'" is not supported')):this.ctx.globalCompositeOperation="source-over"}}},save:function(){this.ctx.save();var a=this.current;this.stateStack.push(a);this.current=a.clone()},restore:function(){var a=this.stateStack.pop();a&&(this.current=a,this.ctx.restore())},
+transform:function(a,b,c,d,e,f){this.ctx.transform(a,b,c,d,e,f)},moveTo:function(a,b){this.ctx.moveTo(a,b);this.current.setCurrentPoint(a,b)},lineTo:function(a,b){this.ctx.lineTo(a,b);this.current.setCurrentPoint(a,b)},curveTo:function(a,b,c,d,e,f){this.ctx.bezierCurveTo(a,b,c,d,e,f);this.current.setCurrentPoint(e,f)},curveTo2:function(a,b,c,d){var e=this.current;this.ctx.bezierCurveTo(e.x,e.y,a,b,c,d);e.setCurrentPoint(c,d)},curveTo3:function(a,b,c,d){this.curveTo(a,b,c,d,c,d);this.current.setCurrentPoint(c,
+d)},closePath:function(){this.ctx.closePath()},rectangle:function(a,b,c,d){this.ctx.rect(a,b,c,d)},stroke:function(a){a="undefined"!==typeof a?a:!0;var b=this.ctx,c=this.current.strokeColor;0===this.current.lineWidth&&(b.lineWidth=this.getSinglePixelWidth());b.globalAlpha=this.current.strokeAlpha;c&&c.hasOwnProperty("type")&&"Pattern"===c.type?(b.save(),b.strokeStyle=c.getPattern(b,this),b.stroke(),b.restore()):b.stroke();a&&this.consumePath();b.globalAlpha=this.current.fillAlpha},closeStroke:function(){this.closePath();
+this.stroke()},fill:function(a){a="undefined"!==typeof a?a:!0;var b=this.ctx,c=this.current.fillColor,d=!1;c&&c.hasOwnProperty("type")&&"Pattern"===c.type&&(b.save(),b.fillStyle=c.getPattern(b,this),d=!0);if(this.pendingEOFill){if("mozFillRule"in this.ctx)this.ctx.mozFillRule="evenodd",this.ctx.fill(),this.ctx.mozFillRule="nonzero";else try{this.ctx.fill("evenodd")}catch(e){this.ctx.fill()}this.pendingEOFill=!1}else this.ctx.fill();d&&b.restore();a&&this.consumePath()},eoFill:function(){this.pendingEOFill=
+!0;this.fill()},fillStroke:function(){this.fill(!1);this.stroke(!1);this.consumePath()},eoFillStroke:function(){this.pendingEOFill=!0;this.fillStroke()},closeFillStroke:function(){this.closePath();this.fillStroke()},closeEOFillStroke:function(){this.pendingEOFill=!0;this.closePath();this.fillStroke()},endPath:function(){this.consumePath()},clip:function(){this.pendingClip=g},eoClip:function(){this.pendingClip=f},beginText:function(){this.current.textMatrix=ia;this.current.x=this.current.lineX=0;this.current.y=
+this.current.lineY=0},endText:function(){if("pendingTextPaths"in this){var a=this.pendingTextPaths,b=this.ctx;b.save();b.beginPath();for(var c=0;c<a.length;c++){var d=a[c];b.setTransform.apply(b,d.transform);b.translate(d.x,d.y);d.addToPath(b,d.fontSize)}b.restore();b.clip();b.beginPath();delete this.pendingTextPaths}else this.ctx.beginPath()},setCharSpacing:function(a){this.current.charSpacing=a},setWordSpacing:function(a){this.current.wordSpacing=a},setHScale:function(a){this.current.textHScale=
+a/100},setLeading:function(a){this.current.leading=-a},setFont:function(a,b){var c=this.commonObjs.get(a),d=this.current;c||m("Can't find font for "+a);d.fontMatrix=c.fontMatrix?c.fontMatrix:ba;0!==d.fontMatrix[0]&&0!==d.fontMatrix[3]||x("Invalid font matrix for font "+a);0>b?(b=-b,d.fontDirection=-1):d.fontDirection=1;this.current.font=c;this.current.fontSize=b;if(!c.coded){var d=c.black?c.bold?"bolder":"bold":c.bold?"bold":"normal",e=c.italic?"italic":"normal",c='"'+(c.loadedName||"sans-serif")+
+'", '+c.fallbackName,f=16<=b?b:16;this.current.fontSizeScale=16!=f?1:b/16;this.ctx.font=e+" "+d+" "+f+"px "+c}},setTextRenderingMode:function(a){this.current.textRenderingMode=a},setTextRise:function(a){this.current.textRise=a},moveText:function(a,b){this.current.x=this.current.lineX+=a;this.current.y=this.current.lineY+=b},setLeadingMoveText:function(a,b){this.setLeading(-b);this.moveText(a,b)},setTextMatrix:function(a,b,c,d,e,f){this.current.textMatrix=[a,b,c,d,e,f];this.current.x=this.current.lineX=
+0;this.current.y=this.current.lineY=0},nextLine:function(){this.moveText(0,this.current.leading)},applyTextTransforms:function(){var a=this.ctx,b=this.current;a.transform.apply(a,b.textMatrix);a.translate(b.x,b.y+b.textRise);0<b.fontDirection?a.scale(b.textHScale,-1):a.scale(-b.textHScale,1)},createTextGeometry:function(){var a={},b=this.current.font,c=this.ctx.mozCurrentTransform,d=c[0],e=c[1],f=c[2],g=c[3],h=c[4],c=c[5],m=0<=d?Math.sqrt(d*d+e*e):-Math.sqrt(d*d+e*e),f=0<=g?Math.sqrt(f*f+g*g):-Math.sqrt(f*
+f+g*g),d=Math.atan2(e,d);a.x=h;a.y=c;a.hScale=m;a.vScale=f;a.angle=d;a.spaceWidth=b.spaceWidth;a.fontName=b.loadedName;a.fontFamily=b.fallbackName;a.fontSize=this.current.fontSize;a.ascent=b.ascent;a.descent=b.descent;return a},paintChar:function(a,b,c){var d=this.ctx,e=this.current,f=e.font,g=e.fontSize/e.fontSizeScale,h=e.textRenderingMode,e=h&3,h=!!(h&4),m;if(f.disableFontFace||h)m=f.getPathGenerator(this.commonObjs,a);f.disableFontFace?(d.save(),d.translate(b,c),d.beginPath(),m(d,g),e!==X&&2!==
+e||d.fill(),1!==e&&2!==e||d.stroke(),d.restore()):(e!==X&&2!==e||d.fillText(a,b,c),1!==e&&2!==e||d.strokeText(a,b,c));h&&(this.pendingTextPaths||(this.pendingTextPaths=[])).push({transform:d.mozCurrentTransform,x:b,y:c,fontSize:g,addToPath:m})},get isFontSubpixelAAEnabled(){var a=document.createElement("canvas").getContext("2d");a.scale(1.5,1);a.fillText("I",0,10);for(var a=a.getImageData(0,0,10,10).data,b=!1,c=3;c<a.length;c+=4)if(0<a[c]&&255>a[c]){b=!0;break}return U(this,"isFontSubpixelAAEnabled",
+b)},showText:function(a,b){var c=this.ctx,d=this.current,e=d.font,f=d.fontSize,g=d.fontSizeScale,h=d.charSpacing,m=d.wordSpacing,r=d.textHScale*d.fontDirection,u=d.fontMatrix||ba,M=a.length,t,x=this.textLayer&&!b?!0:!1,v=0,D=e.vertical,K=e.defaultVMetrics;if(e.coded){c.save();c.transform.apply(c,d.textMatrix);c.translate(d.x,d.y);c.scale(r,1);x&&(this.save(),c.scale(1,-1),t=this.createTextGeometry(),this.restore());for(var I=0;I<M;++I){var B=a[I];if(null===B)this.ctx.translate(m,0),d.x+=m*r;else{this.processingType3=
+B;this.save();c.scale(f,f);c.transform.apply(c,u);this.executeOperatorList(B.operatorList);this.restore();var O=(q.applyTransform([B.width,0],u)[0]*f+h)*d.fontDirection;c.translate(O,0);d.x+=O*r;v+=O}}c.restore();this.processingType3=null}else{c.save();this.applyTextTransforms();var I=d.lineWidth,u=d.textMatrix[0],y=d.textMatrix[1],u=Math.sqrt(u*u+y*y),I=0===u||0===I?this.getSinglePixelWidth():I/u;x&&(t=this.createTextGeometry());1!=g&&(c.scale(g,g),I/=g);c.lineWidth=I;for(I=u=0;I<M;++I)if(B=a[I],
+null===B)u+=d.fontDirection*m;else{var y=!1,H=B.fontChar,E=B.vmetric||K;if(D)var L=B.vmetric?E[1]:0.5*B.width,L=-L*f*d.fontMatrix[0],P=E[2]*f*d.fontMatrix[0];var O=E?-E[0]:B.width,E=O*f*d.fontMatrix[0]+h*d.fontDirection,G=B.accent,J,N;B.disabled||(D?(B=L/g,J=(u+P)/g):(B=u/g,J=0),e.remeasure&&0<O&&this.isFontSubpixelAAEnabled&&(y=1E3*c.measureText(H).width/d.fontSize*d.fontSizeScale,O/=y,y=!0,c.save(),c.scale(O,1),B/=O,G&&(N/=O)),this.paintChar(H,B,J),G&&(N=B+G.offset.x/g,H=J-G.offset.y/g,this.paintChar(G.fontChar,
+N,H)));u+=E;v+=E;y&&c.restore()}D?d.y-=u*r:d.x+=u*r;c.restore()}x&&(t.canvasWidth=v,D&&(t.angle+=Math.PI/2),this.textLayer.appendText(t));return v},showSpacedText:function(a){var b=this.ctx,c=this.current,d=c.fontSize,e=0.0010*c.textHScale*c.fontDirection,f=a.length,g,h=0,m=this.textLayer?!0:!1,q=c.font.vertical,r=0;m&&(b.save(),this.applyTextTransforms(),g=this.createTextGeometry(),b.restore());for(b=0;b<f;++b){var t=a[b];"number"==typeof t?(t=-t*d*e,q?c.y+=t:c.x+=t,m&&(r+=t)):(t=this.showText(t,
+!0),m&&(h+=r+t,r=0))}m&&(g.canvasWidth=h,q&&(g.angle+=Math.PI/2),this.textLayer.appendText(g))},nextLineShowText:function(a){this.nextLine();this.showText(a)},nextLineSetSpacingShowText:function(a,b,c){this.setWordSpacing(a);this.setCharSpacing(b);this.nextLineShowText(c)},setCharWidth:function(a,b){},setCharWidthAndBounds:function(a,b,c,d,e,f){this.rectangle(c,d,e-c,f-d);this.clip();this.endPath()},setStrokeColorSpace:function(a){this.current.strokeColorSpace=r.fromIR(a)},setFillColorSpace:function(a){this.current.fillColorSpace=
+r.fromIR(a)},setStrokeColor:function(){var a=this.current.strokeColorSpace.getRgb(arguments,0),a=q.makeCssRgb(a);this.ctx.strokeStyle=a;this.current.strokeColor=a},getColorN_Pattern:function(a,b){if("TilingPattern"==a[0]){var c=a[1],d=b.base,e;d&&(e=d.getRgb(c,0));c=new Ca(a,e,this.ctx,this.objs,this.commonObjs,this.baseTransform)}else"RadialAxial"==a[0]||"Dummy"==a[0]?c=ka.shadingFromIR(a):m("Unkown IR type "+a[0]);return c},setStrokeColorN:function(){var a=this.current.strokeColorSpace;"Pattern"==
+a.name?this.current.strokeColor=this.getColorN_Pattern(arguments,a):this.setStrokeColor.apply(this,arguments)},setFillColor:function(){var a=this.current.fillColorSpace.getRgb(arguments,0),a=q.makeCssRgb(a);this.ctx.fillStyle=a;this.current.fillColor=a},setFillColorN:function(){var a=this.current.fillColorSpace;"Pattern"==a.name?this.current.fillColor=this.getColorN_Pattern(arguments,a):this.setFillColor.apply(this,arguments)},setStrokeGray:function(a){this.current.strokeColorSpace=r.singletons.gray;
+var b=this.current.strokeColorSpace.getRgb(arguments,0),b=q.makeCssRgb(b);this.ctx.strokeStyle=b;this.current.strokeColor=b},setFillGray:function(a){this.current.fillColorSpace=r.singletons.gray;var b=this.current.fillColorSpace.getRgb(arguments,0),b=q.makeCssRgb(b);this.ctx.fillStyle=b;this.current.fillColor=b},setStrokeRGBColor:function(a,b,c){this.current.strokeColorSpace=r.singletons.rgb;var d=this.current.strokeColorSpace.getRgb(arguments,0),d=q.makeCssRgb(d);this.ctx.strokeStyle=d;this.current.strokeColor=
+d},setFillRGBColor:function(a,b,c){this.current.fillColorSpace=r.singletons.rgb;var d=this.current.fillColorSpace.getRgb(arguments,0),d=q.makeCssRgb(d);this.ctx.fillStyle=d;this.current.fillColor=d},setStrokeCMYKColor:function(a,b,c,d){this.current.strokeColorSpace=r.singletons.cmyk;var e=q.makeCssCmyk(arguments);this.ctx.strokeStyle=e;this.current.strokeColor=e},setFillCMYKColor:function(a,b,c,d){this.current.fillColorSpace=r.singletons.cmyk;var e=q.makeCssCmyk(arguments);this.ctx.fillStyle=e;this.current.fillColor=
+e},shadingFill:function(a){var b=this.ctx;this.save();a=ka.shadingFromIR(a);b.fillStyle=a.getPattern(b,this);var c=b.mozCurrentTransformInverse;if(c){var b=b.canvas,d=b.width,e=b.height,b=q.applyTransform([0,0],c);a=q.applyTransform([0,e],c);var f=q.applyTransform([d,0],c),g=q.applyTransform([d,e],c),c=Math.min(b[0],a[0],f[0],g[0]),d=Math.min(b[1],a[1],f[1],g[1]),e=Math.max(b[0],a[0],f[0],g[0]),b=Math.max(b[1],a[1],f[1],g[1]);this.ctx.fillRect(c,d,e-c,b-d)}else this.ctx.fillRect(-1E10,-1E10,2E10,
+2E10);this.restore()},beginInlineImage:function(){m("Should not call beginInlineImage")},beginImageData:function(){m("Should not call beginImageData")},paintFormXObjectBegin:function(a,b){this.save();this.baseTransformStack.push(this.baseTransform);a&&D(a)&&6==a.length&&this.transform.apply(this,a);this.baseTransform=this.ctx.mozCurrentTransform;b&&D(b)&&4==b.length&&(this.rectangle(b[0],b[1],b[2]-b[0],b[3]-b[1]),this.clip(),this.endPath())},paintFormXObjectEnd:function(){this.restore();this.baseTransform=
+this.baseTransformStack.pop()},beginGroup:function(a){this.save();var b=this.ctx;a.isolated||K("TODO: Support non-isolated groups.");a.knockout&&x("Knockout groups not supported.");var c=b.mozCurrentTransform;a.matrix&&b.transform.apply(b,a.matrix);a.bbox||m("Bounding box is required.");var d=q.getAxialAlignedBoundingBox(a.bbox,b.mozCurrentTransform),d=q.intersect(d,[0,0,b.canvas.width,b.canvas.height])||[0,0,0,0];a=Math.max(Math.ceil(d[2]-d[0]),1);var e=Math.max(Math.ceil(d[3]-d[1]),1);a=J.getCanvas("groupAt"+
+this.groupLevel,a,e,!0).context;e=d[0];d=d[1];a.translate(-e,-d);a.transform.apply(a,c);b.setTransform(1,0,0,1,0,0);b.translate(e,d);c="strokeStyle fillStyle fillRule globalAlpha lineWidth lineCap lineJoin miterLimit globalCompositeOperation font".split(" ");d=0;for(e=c.length;d<e;d++){var f=c[d];f in b&&(a[f]=b[f])}"setLineDash"in b?(a.setLineDash(b.getLineDash()),a.lineDashOffset=b.lineDashOffset):"mozDash"in b&&(a.mozDash=b.mozDash,a.mozDashOffset=b.mozDashOffset);this.ctx=a;this.setGState([["SMask",
+"None"],["BM","Normal"],["ca",1],["CA",1]]);this.groupStack.push(b);this.groupLevel++},endGroup:function(a){this.groupLevel--;a=this.ctx;this.ctx=this.groupStack.pop();"imageSmoothingEnabled"in this.ctx?this.ctx.imageSmoothingEnabled=!1:this.ctx.mozImageSmoothingEnabled=!1;this.ctx.drawImage(a.canvas,0,0);this.restore()},beginAnnotations:function(){this.save();this.current=new na},endAnnotations:function(){this.restore()},beginAnnotation:function(a,b,c){this.save();a&&D(a)&&4==a.length&&(this.rectangle(a[0],
+a[1],a[2]-a[0],a[3]-a[1]),this.clip(),this.endPath());this.transform.apply(this,b);this.transform.apply(this,c)},endAnnotation:function(){this.restore()},paintJpegXObject:function(a,b,c){var d=this.objs.get(a);d||m("Dependent image isn't ready yet");this.save();var e=this.ctx;e.scale(1/b,-1/c);e.drawImage(d,0,0,d.width,d.height,0,-c,b,c);this.imageLayer&&(d=e.mozCurrentTransformInverse,e=this.getCanvasPosition(0,0),this.imageLayer.appendImage({objId:a,left:e[0],top:e[1],width:b/d[0],height:c/d[3]}));
+this.restore()},paintImageMaskXObject:function(a){var b=this.ctx,d=a.width,e=a.height,f=this.processingType3;!f||"compiled"in f||(f.compiled=1E3>=d&&1E3>=e?sa({data:a.data,width:d,height:e}):null);f&&f.compiled?f.compiled(b):(b=J.getCanvas("maskCanvas",d,e),f=b.context,f.save(),c(f,a),f.globalCompositeOperation="source-in",a=this.current.fillColor,f.fillStyle=a&&a.hasOwnProperty("type")&&"Pattern"===a.type?a.getPattern(f,this):a,f.fillRect(0,0,d,e),f.restore(),this.paintInlineImageXObject(b.canvas))},
+paintImageMaskXObjectGroup:function(a){for(var b=this.ctx,d=0,e=a.length;d<e;d++){var f=a[d],g=f.width,h=f.height,m=J.getCanvas("maskCanvas",g,h),q=m.context;q.save();c(q,f);q.globalCompositeOperation="source-in";var r=this.current.fillColor;q.fillStyle=r&&r.hasOwnProperty("type")&&"Pattern"===r.type?r.getPattern(q,this):r;q.fillRect(0,0,g,h);q.restore();b.save();b.transform.apply(b,f.transform);b.scale(1,-1);b.drawImage(m.canvas,0,0,g,h,0,-1,1,1);b.restore()}},paintImageXObject:function(a){(a=this.objs.get(a))||
+m("Dependent image isn't ready yet");this.paintInlineImageXObject(a)},paintInlineImageXObject:function(b){var c=b.width,d=b.height,e=this.ctx;this.save();e.scale(1/c,-1/d);var f=e.mozCurrentTransformInverse,g=f[0],h=f[1],g=Math.max(Math.sqrt(g*g+h*h),1),h=f[2],m=f[3],h=Math.max(Math.sqrt(h*h+m*m),1);if(b instanceof HTMLElement||!b.data)m=b;else{var q=J.getCanvas("inlineImage",c,d),r=q.context;a(r,b);m=q.canvas}for(var u=c,t=d,x="prescale1";2<g&&1<u||2<h&&1<t;){var v=u,y=t;2<g&&1<u&&(v=Math.ceil(u/
+2),g/=u/v);2<h&&1<t&&(y=Math.ceil(t/2),h/=t/y);q=J.getCanvas(x,v,y);r=q.context;r.clearRect(0,0,v,y);r.drawImage(m,0,0,u,t,0,0,v,y);m=q.canvas;u=v;t=y;x="prescale1"===x?"prescale2":"prescale1"}e.drawImage(m,0,0,u,t,0,-d,c,d);this.imageLayer&&(e=this.getCanvasPosition(0,-d),this.imageLayer.appendImage({imgData:b,left:e[0],top:e[1],width:c/f[0],height:d/f[3]}));this.restore()},paintInlineImageXObjectGroup:function(b,c){var d=this.ctx,e=b.width,f=b.height,g=J.getCanvas("inlineImage",e,f);a(g.context,
+b);for(var h=0,m=c.length;h<m;h++){var q=c[h];d.save();d.transform.apply(d,q.transform);d.scale(1,-1);d.drawImage(g.canvas,q.x,q.y,q.w,q.h,0,-1,1,1);this.imageLayer&&(q=this.getCanvasPosition(q.x,q.y),this.imageLayer.appendImage({imgData:b,left:q[0],top:q[1],width:e,height:f}));d.restore()}},markPoint:function(a){},markPointProps:function(a,b){},beginMarkedContent:function(a){},beginMarkedContentProps:function(a,b){},endMarkedContent:function(){},beginCompat:function(){},endCompat:function(){},consumePath:function(){if(this.pendingClip){if(this.pendingClip==
+f)if("mozFillRule"in this.ctx)this.ctx.mozFillRule="evenodd",this.ctx.clip(),this.ctx.mozFillRule="nonzero";else try{this.ctx.clip("evenodd")}catch(a){this.ctx.clip()}else this.ctx.clip();this.pendingClip=null}this.ctx.beginPath()},getSinglePixelWidth:function(a){a=this.ctx.mozCurrentTransformInverse;return Math.sqrt(Math.max(a[0]*a[0]+a[1]*a[1],a[2]*a[2]+a[3]*a[3]))},getCanvasPosition:function(a,b){var c=this.ctx.mozCurrentTransform;return[c[0]*a+c[2]*b+c[4],c[1]*a+c[3]*b+c[5]]}};for(var h in y)b.prototype[y[h]]=
+b.prototype[h];return b}();PDFJS.disableFontFace=!1;var Q={insertRule:function(b){var a=document.getElementById("PDFJS_FONT_STYLE_TAG");a||(a=document.createElement("style"),a.id="PDFJS_FONT_STYLE_TAG",document.documentElement.getElementsByTagName("head")[0].appendChild(a));a=a.sheet;a.insertRule(b,a.cssRules.length)},clear:function(){var b=document.getElementById("PDFJS_FONT_STYLE_TAG");b&&b.parentNode.removeChild(b)},get loadTestFont(){return U(this,"loadTestFont",atob("T1RUTwALAIAAAwAwQ0ZGIDHtZg4AAAOYAAAAgUZGVE1lkzZwAAAEHAAAABxHREVGABQAFQAABDgAAAAeT1MvMlYNYwkAAAEgAAAAYGNtYXABDQLUAAACNAAAAUJoZWFk/xVFDQAAALwAAAA2aGhlYQdkA+oAAAD0AAAAJGhtdHgD6AAAAAAEWAAAAAZtYXhwAAJQAAAAARgAAAAGbmFtZVjmdH4AAAGAAAAAsXBvc3T/hgAzAAADeAAAACAAAQAAAAEAALZRFsRfDzz1AAsD6AAAAADOBOTLAAAAAM4KHDwAAAAAA+gDIQAAAAgAAgAAAAAAAAABAAADIQAAAFoD6AAAAAAD6AABAAAAAAAAAAAAAAAAAAAAAQAAUAAAAgAAAAQD6AH0AAUAAAKKArwAAACMAooCvAAAAeAAMQECAAACAAYJAAAAAAAAAAAAAQAAAAAAAAAAAAAAAFBmRWQAwAAuAC4DIP84AFoDIQAAAAAAAQAAAAAAAAAAACAAIAAB
AAAADgCuAAEAAAAAAAAAAQAAAAEAAAAAAAEAAQAAAAEAAAAAAAIAAQAAAAEAAAAAAAMAAQAAAAEAAAAAAAQAAQAAAAEAAAAAAAUAAQAAAAEAAAAAAAYAAQAAAAMAAQQJAAAAAgABAAMAAQQJAAEAAgABAAMAAQQJAAIAAgABAAMAAQQJAAMAAgABAAMAAQQJAAQAAgABAAMAAQQJAAUAAgABAAMAAQQJAAYAAgABWABYAAAAAAAAAwAAAAMAAAAcAAEAAAAAADwAAwABAAAAHAAEACAAAAAEAAQAAQAAAC7//wAAAC7////TAAEAAAAAAAABBgAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAD/gwAyAAAAAQAAAAAAAAAAAAAAAAAAAAABAAQEAAEBAQJYAAEBASH4DwD4GwHEAvgcA/gXBIwMAYuL+nz5tQXkD5j3CBLnEQACAQEBIVhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYAAABAQAADwACAQEEE/t3Dov6fAH6fAT+fPp8+nwHDosMCvm1Cvm1DAz6fBQAAAAAAAABAAAAAMmJbzEAAAAAzgTjFQAAAADOBOQpAAEAAAAAAAAADAAUAAQAAAABAAAAAgABAAAAAAAAAAAD6AAAAAAAAA=="))},
+loadTestFontId:0,loadingContext:{requests:[],nextRequestId:0},isSyncFontLoadingSupported:function(){if(W)return!1;var b=/Mozilla\/5.0.*?rv:(\d+).*? Gecko/.exec(window.navigator.userAgent);return b&&14<=b[1]?!0:!1}(),bind:function(b,a){W&&m("bind() shall be called from main thread");for(var c=[],e=[],d=0,g=b.length;d<g;d++){var f=b[d];if(!f.attached&&!1!==f.loading){f.attached=!0;var h=f.bindDOM();h&&(c.push(h),e.push(f))}}d=Q.queueLoadingCallback(a);0<c.length&&!this.isSyncFontLoadingSupported?Q.prepareFontLoadEvent(c,
+e,d):d.complete()},queueLoadingCallback:function(b){var a=Q.loadingContext,c={id:"pdfjs-font-loading-"+a.nextRequestId++,complete:function(){c.end&&m("completeRequest() cannot be called twice");for(c.end=Date.now();0<a.requests.length&&a.requests[0].end;){var b=a.requests.shift();setTimeout(b.callback,0)}},callback:b,started:Date.now()};a.requests.push(c);return c},prepareFontLoadEvent:function(b,a,c){function e(a,b){return a.charCodeAt(b)<<24|a.charCodeAt(b+1)<<16|a.charCodeAt(b+2)<<8|a.charCodeAt(b+
+3)&255}function d(a,b,c,d){a=m.substr(0,b);b=m.substr(b+c);return a+d+b}function g(a,b){l++;30<l?(x("Load test font never loaded."),b()):(k.font="30px "+a,k.fillText(".",0,20),0<k.getImageData(0,0,1,1).data[3]?b():setTimeout(g.bind(null,a,b)))}var f,h;b=document.createElement("canvas");b.width=1;b.height=1;var k=b.getContext("2d"),l=0;b="lt"+Date.now()+this.loadTestFontId++;var m=this.loadTestFont,m=d(m,976,b.length,b),p=e(m,16);f=0;for(h=b.length-3;f<h;f+=4)p=p-1482184792+e(b,f)|0;f<b.length&&(p=
+p-1482184792+e(b+"XXX",f)|0);m=d(m,16,4,String.fromCharCode(p>>24&255)+String.fromCharCode(p>>16&255)+String.fromCharCode(p>>8&255)+String.fromCharCode(p&255));f="url(data:font/opentype;base64,"+btoa(m)+");";Q.insertRule('@font-face { font-family:"'+b+'";src:'+f+"}");p=[];f=0;for(h=a.length;f<h;f++)p.push(a[f].loadedName);p.push(b);var q=document.createElement("div");q.setAttribute("style","visibility: hidden;width: 10px; height: 10px;position: absolute; top: 0px; left: 0px;");f=0;for(h=p.length;f<
+h;++f)a=document.createElement("span"),a.textContent="Hi",a.style.fontFamily=p[f],q.appendChild(a);document.body.appendChild(q);g(b,function(){document.body.removeChild(q);c.complete()})}},Qa=function(){function b(a,b,e){this.compiledGlyphs={};if(1===arguments.length){var d=arguments[0],g;for(g in d)this[g]=d[g]}}b.prototype={bindDOM:function(){if(!this.data)return null;if(PDFJS.disableFontFace)return this.disableFontFace=!0,null;for(var a=this.data,b="",e=a.length,d=0;d<e;++d)b+=String.fromCharCode(a[d]);
+a=this.loadedName;b="url(data:"+this.mimetype+";base64,"+window.btoa(b)+");";a='@font-face { font-family:"'+a+'";src:'+b+"}";Q.insertRule(a);PDFJS.pdfBug&&"FontInspector"in t&&t.FontInspector.enabled&&t.FontInspector.fontAdded(this,b);return a},getPathGenerator:function(a,b){if(!(b in this.compiledGlyphs)){var e=a.get(this.loadedName+"_path_"+b);this.compiledGlyphs[b]=new Function("c","size",e)}return this.compiledGlyphs[b]}};return b}()}).call("undefined"===typeof window?this:window);
+PDFJS.workerSrc||"undefined"===typeof document||(PDFJS.workerSrc=function(){var E=(document.body||document.getElementsByTagName("head")[0]).lastChild.src;return E&&E.replace(/\.js$/i,".worker.js")}());
diff --git a/plugins/pdfviewer/viewer/pdf.worker.js b/plugins/pdfviewer/viewer/pdf.worker.js
index 0f954c3..13debfc 100644
--- a/plugins/pdfviewer/viewer/pdf.worker.js
+++ b/plugins/pdfviewer/viewer/pdf.worker.js
@@ -20,8 +20,8 @@ if (typeof PDFJS === 'undefined') {
(typeof window !== 'undefined' ? window : this).PDFJS = {};
}
-PDFJS.version = '0.8.573';
-PDFJS.build = 'e97e003';
+PDFJS.version = '0.8.894';
+PDFJS.build = 'ac91047';
(function pdfjsWrapper() {
// Use strict in our context only - users might not want it
@@ -43,7 +43,8 @@ PDFJS.build = 'e97e003';
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/* globals Cmd, ColorSpace, Dict, MozBlobBuilder, Name, PDFJS, Ref */
+/* globals Cmd, ColorSpace, Dict, MozBlobBuilder, Name, PDFJS, Ref, URL,
+ Promise */
'use strict';
@@ -51,9 +52,6 @@ var globalScope = (typeof window === 'undefined') ? this : window;
var isWorker = (typeof window == 'undefined');
-var ERRORS = 0, WARNINGS = 1, INFOS = 5;
-var verbosity = WARNINGS;
-
var FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0];
var TextRenderingMode = {
@@ -78,33 +76,118 @@ if (!globalScope.PDFJS) {
globalScope.PDFJS.pdfBug = false;
+PDFJS.VERBOSITY_LEVELS = {
+ errors: 0,
+ warnings: 1,
+ infos: 5
+};
-// Use only for debugging purposes. This should not be used in any code that is
-// in mozilla master.
-var log = (function() {
- if ('console' in globalScope && 'log' in globalScope['console']) {
- return globalScope['console']['log'].bind(globalScope['console']);
- } else {
- return function nop() {
- };
- }
-})();
+// All the possible operations for an operator list.
+var OPS = PDFJS.OPS = {
+ // Intentionally start from 1 so it is easy to spot bad operators that will be
+ // 0's.
+ dependency: 1,
+ setLineWidth: 2,
+ setLineCap: 3,
+ setLineJoin: 4,
+ setMiterLimit: 5,
+ setDash: 6,
+ setRenderingIntent: 7,
+ setFlatness: 8,
+ setGState: 9,
+ save: 10,
+ restore: 11,
+ transform: 12,
+ moveTo: 13,
+ lineTo: 14,
+ curveTo: 15,
+ curveTo2: 16,
+ curveTo3: 17,
+ closePath: 18,
+ rectangle: 19,
+ stroke: 20,
+ closeStroke: 21,
+ fill: 22,
+ eoFill: 23,
+ fillStroke: 24,
+ eoFillStroke: 25,
+ closeFillStroke: 26,
+ closeEOFillStroke: 27,
+ endPath: 28,
+ clip: 29,
+ eoClip: 30,
+ beginText: 31,
+ endText: 32,
+ setCharSpacing: 33,
+ setWordSpacing: 34,
+ setHScale: 35,
+ setLeading: 36,
+ setFont: 37,
+ setTextRenderingMode: 38,
+ setTextRise: 39,
+ moveText: 40,
+ setLeadingMoveText: 41,
+ setTextMatrix: 42,
+ nextLine: 43,
+ showText: 44,
+ showSpacedText: 45,
+ nextLineShowText: 46,
+ nextLineSetSpacingShowText: 47,
+ setCharWidth: 48,
+ setCharWidthAndBounds: 49,
+ setStrokeColorSpace: 50,
+ setFillColorSpace: 51,
+ setStrokeColor: 52,
+ setStrokeColorN: 53,
+ setFillColor: 54,
+ setFillColorN: 55,
+ setStrokeGray: 56,
+ setFillGray: 57,
+ setStrokeRGBColor: 58,
+ setFillRGBColor: 59,
+ setStrokeCMYKColor: 60,
+ setFillCMYKColor: 61,
+ shadingFill: 62,
+ beginInlineImage: 63,
+ beginImageData: 64,
+ endInlineImage: 65,
+ paintXObject: 66,
+ markPoint: 67,
+ markPointProps: 68,
+ beginMarkedContent: 69,
+ beginMarkedContentProps: 70,
+ endMarkedContent: 71,
+ beginCompat: 72,
+ endCompat: 73,
+ paintFormXObjectBegin: 74,
+ paintFormXObjectEnd: 75,
+ beginGroup: 76,
+ endGroup: 77,
+ beginAnnotations: 78,
+ endAnnotations: 79,
+ beginAnnotation: 80,
+ endAnnotation: 81,
+ paintJpegXObject: 82,
+ paintImageMaskXObject: 83,
+ paintImageMaskXObjectGroup: 84,
+ paintImageXObject: 85,
+ paintInlineImageXObject: 86,
+ paintInlineImageXObjectGroup: 87
+};
-// A notice for devs that will not trigger the fallback UI. These are good
-// for things that are helpful to devs, such as warning that Workers were
-// disabled, which is important to devs but not end users.
+// A notice for devs. These are good for things that are helpful to devs, such
+// as warning that Workers were disabled, which is important to devs but not
+// end users.
function info(msg) {
- if (verbosity >= INFOS) {
- log('Info: ' + msg);
- PDFJS.LogManager.notify('info', msg);
+ if (PDFJS.verbosity >= PDFJS.VERBOSITY_LEVELS.infos) {
+ console.log('Info: ' + msg);
}
}
-// Non-fatal warnings that should trigger the fallback UI.
+// Non-fatal warnings.
function warn(msg) {
- if (verbosity >= WARNINGS) {
- log('Warning: ' + msg);
- PDFJS.LogManager.notify('warn', msg);
+ if (PDFJS.verbosity >= PDFJS.VERBOSITY_LEVELS.warnings) {
+ console.log('Warning: ' + msg);
}
}
@@ -115,22 +198,17 @@ function error(msg) {
if (arguments.length > 1) {
var logArguments = ['Error:'];
logArguments.push.apply(logArguments, arguments);
- log.apply(null, logArguments);
+ console.log.apply(console, logArguments);
// Join the arguments into a single string for the lines below.
msg = [].join.call(arguments, ' ');
} else {
- log('Error: ' + msg);
+ console.log('Error: ' + msg);
}
- log(backtrace());
- PDFJS.LogManager.notify('error', msg);
+ console.log(backtrace());
+ UnsupportedManager.notify(UNSUPPORTED_FEATURES.unknown);
throw new Error(msg);
}
-// Missing features that should trigger the fallback UI.
-function TODO(what) {
- warn('TODO: ' + what);
-}
-
function backtrace() {
try {
throw new Error();
@@ -144,6 +222,31 @@ function assert(cond, msg) {
error(msg);
}
+var UNSUPPORTED_FEATURES = PDFJS.UNSUPPORTED_FEATURES = {
+ unknown: 'unknown',
+ forms: 'forms',
+ javaScript: 'javaScript',
+ smask: 'smask',
+ shadingPattern: 'shadingPattern',
+ font: 'font'
+};
+
+var UnsupportedManager = PDFJS.UnsupportedManager =
+ (function UnsupportedManagerClosure() {
+ var listeners = [];
+ return {
+ listen: function (cb) {
+ listeners.push(cb);
+ },
+ notify: function (featureId) {
+ warn('Unsupported feature "' + featureId + '"');
+ for (var i = 0, ii = listeners.length; i < ii; i++) {
+ listeners[i](featureId);
+ }
+ }
+ };
+})();
+
// Combines two URLs. The baseUrl shall be absolute URL. If the url is an
// absolute URL, it will be returned as is.
function combineUrl(baseUrl, url) {
@@ -197,22 +300,6 @@ function assertWellFormed(cond, msg) {
error(msg);
}
-var LogManager = PDFJS.LogManager = (function LogManagerClosure() {
- var loggers = [];
- return {
- addLogger: function logManager_addLogger(logger) {
- loggers.push(logger);
- },
- notify: function(type, message) {
- for (var i = 0, ii = loggers.length; i < ii; i++) {
- var logger = loggers[i];
- if (logger[type])
- logger[type](message);
- }
- }
- };
-})();
-
function shadow(obj, prop, value) {
Object.defineProperty(obj, prop, { value: value,
enumerable: true,
@@ -292,7 +379,7 @@ var MissingDataException = (function MissingDataExceptionClosure() {
function MissingDataException(begin, end) {
this.begin = begin;
this.end = end;
- this.message = 'Missing data [begin, end)';
+ this.message = 'Missing data [' + begin + ', ' + end + ')';
}
MissingDataException.prototype = new Error();
@@ -742,6 +829,24 @@ function isPDFFunction(v) {
}
/**
+ * Legacy support for PDFJS Promise implementation.
+ * TODO remove eventually
+ */
+var LegacyPromise = PDFJS.LegacyPromise = (function LegacyPromiseClosure() {
+ return function LegacyPromise() {
+ var resolve, reject;
+ var promise = new Promise(function (resolve_, reject_) {
+ resolve = resolve_;
+ reject = reject_;
+ });
+ promise.resolve = resolve;
+ promise.reject = reject;
+ return promise;
+ };
+})();
+
+/**
+ * Polyfill for Promises:
* The following promise implementation tries to generally implment the
* Promise/A+ spec. Some notable differences from other promise libaries are:
* - There currently isn't a seperate deferred and promise object.
@@ -750,7 +855,39 @@ function isPDFFunction(v) {
* Based off of the work in:
* https://bugzilla.mozilla.org/show_bug.cgi?id=810490
*/
-var Promise = PDFJS.Promise = (function PromiseClosure() {
+(function PromiseClosure() {
+ if (globalScope.Promise) {
+ // Promises existing in the DOM/Worker, checking presence of all/resolve
+ if (typeof globalScope.Promise.all !== 'function') {
+ globalScope.Promise.all = function (iterable) {
+ var count = 0, results = [], resolve, reject;
+ var promise = new globalScope.Promise(function (resolve_, reject_) {
+ resolve = resolve_;
+ reject = reject_;
+ });
+ iterable.forEach(function (p, i) {
+ count++;
+ p.then(function (result) {
+ results[i] = result;
+ count--;
+ if (count === 0) {
+ resolve(results);
+ }
+ }, reject);
+ });
+ if (count === 0) {
+ resolve(results);
+ }
+ return promise;
+ };
+ }
+ if (typeof globalScope.Promise.resolve !== 'function') {
+ globalScope.Promise.resolve = function (x) {
+ return new globalScope.Promise(function (resolve) { resolve(x); });
+ };
+ }
+ return;
+ }
var STATUS_PENDING = 0;
var STATUS_RESOLVED = 1;
var STATUS_REJECTED = 2;
@@ -783,6 +920,8 @@ var Promise = PDFJS.Promise = (function PromiseClosure() {
},
runHandlers: function runHandlers() {
+ var RUN_TIMEOUT = 1; // ms
+ var timeoutAt = Date.now() + RUN_TIMEOUT;
while (this.handlers.length > 0) {
var handler = this.handlers.shift();
@@ -808,6 +947,14 @@ var Promise = PDFJS.Promise = (function PromiseClosure() {
}
handler.nextPromise._updateStatus(nextStatus, nextValue);
+ if (Date.now() >= timeoutAt) {
+ break;
+ }
+ }
+
+ if (this.handlers.length > 0) {
+ setTimeout(this.runHandlers.bind(this), 0);
+ return;
}
this.running = false;
@@ -858,22 +1005,27 @@ var Promise = PDFJS.Promise = (function PromiseClosure() {
}
};
- function Promise() {
+ function Promise(resolver) {
this._status = STATUS_PENDING;
this._handlers = [];
+ resolver.call(this, this._resolve.bind(this), this._reject.bind(this));
}
/**
* Builds a promise that is resolved when all the passed in promises are
* resolved.
- * @param {Promise[]} promises Array of promises to wait for.
+ * @param {array} array of data and/or promises to wait for.
* @return {Promise} New dependant promise.
*/
Promise.all = function Promise_all(promises) {
- var deferred = new Promise();
+ var resolveAll, rejectAll;
+ var deferred = new Promise(function (resolve, reject) {
+ resolveAll = resolve;
+ rejectAll = reject;
+ });
var unresolved = promises.length;
var results = [];
if (unresolved === 0) {
- deferred.resolve(results);
+ resolveAll(results);
return deferred;
}
function reject(reason) {
@@ -881,11 +1033,11 @@ var Promise = PDFJS.Promise = (function PromiseClosure() {
return;
}
results = [];
- deferred.reject(reason);
+ rejectAll(reason);
}
for (var i = 0, ii = promises.length; i < ii; ++i) {
var promise = promises[i];
- promise.then((function(i) {
+ var resolve = (function(i) {
return function(value) {
if (deferred._status === STATUS_REJECTED) {
return;
@@ -893,13 +1045,34 @@ var Promise = PDFJS.Promise = (function PromiseClosure() {
results[i] = value;
unresolved--;
if (unresolved === 0)
- deferred.resolve(results);
+ resolveAll(results);
};
- })(i), reject);
+ })(i);
+ if (Promise.isPromise(promise)) {
+ promise.then(resolve, reject);
+ } else {
+ resolve(promise);
+ }
}
return deferred;
};
+ /**
+ * Checks if the value is likely a promise (has a 'then' function).
+ * @return {boolean} true if x is thenable
+ */
+ Promise.isPromise = function Promise_isPromise(value) {
+ return value && typeof value.then === 'function';
+ };
+ /**
+ * Creates resolved promise
+ * @param x resolve value
+ * @returns {Promise}
+ */
+ Promise.resolve = function Promise_resolve(x) {
+ return new Promise(function (resolve) { resolve(x); });
+ };
+
Promise.prototype = {
_status: null,
_value: null,
@@ -913,7 +1086,7 @@ var Promise = PDFJS.Promise = (function PromiseClosure() {
}
if (status == STATUS_RESOLVED &&
- value && typeof(value.then) === 'function') {
+ Promise.isPromise(value)) {
value.then(this._updateStatus.bind(this, STATUS_RESOLVED),
this._updateStatus.bind(this, STATUS_REJECTED));
return;
@@ -930,24 +1103,19 @@ var Promise = PDFJS.Promise = (function PromiseClosure() {
HandlerManager.scheduleHandlers(this);
},
- get isResolved() {
- return this._status === STATUS_RESOLVED;
- },
-
- get isRejected() {
- return this._status === STATUS_REJECTED;
- },
-
- resolve: function Promise_resolve(value) {
+ _resolve: function Promise_resolve(value) {
this._updateStatus(STATUS_RESOLVED, value);
},
- reject: function Promise_reject(reason) {
+ _reject: function Promise_reject(reason) {
this._updateStatus(STATUS_REJECTED, reason);
},
then: function Promise_then(onResolve, onReject) {
- var nextPromise = new Promise();
+ var nextPromise = new Promise(function (resolve, reject) {
+ this.resolve = reject;
+ this.reject = reject;
+ });
this._handlers.push({
thisPromise: this,
onResolve: onResolve,
@@ -959,7 +1127,7 @@ var Promise = PDFJS.Promise = (function PromiseClosure() {
}
};
- return Promise;
+ globalScope.Promise = Promise;
})();
var StatTimer = (function StatTimerClosure() {
@@ -1016,7 +1184,7 @@ var StatTimer = (function StatTimerClosure() {
})();
PDFJS.createBlob = function createBlob(data, contentType) {
- if (typeof Blob === 'function')
+ if (typeof Blob !== 'undefined')
return new Blob([data], { type: contentType });
// Blob builder is deprecated in FF14 and removed in FF18.
var bb = new MozBlobBuilder();
@@ -1024,29 +1192,48 @@ PDFJS.createBlob = function createBlob(data, contentType) {
return bb.getBlob(contentType);
};
+PDFJS.createObjectURL = (function createObjectURLClosure() {
+ // Blob/createObjectURL is not available, falling back to data schema.
+ var digits =
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
+
+ return function createObjectURL(data, contentType) {
+ if (!PDFJS.disableCreateObjectURL &&
+ typeof URL !== 'undefined' && URL.createObjectURL) {
+ var blob = PDFJS.createBlob(data, contentType);
+ return URL.createObjectURL(blob);
+ }
+
+ var buffer = 'data:' + contentType + ';base64,';
+ for (var i = 0, ii = data.length; i < ii; i += 3) {
+ var b1 = data[i] & 0xFF;
+ var b2 = data[i + 1] & 0xFF;
+ var b3 = data[i + 2] & 0xFF;
+ var d1 = b1 >> 2, d2 = ((b1 & 3) << 4) | (b2 >> 4);
+ var d3 = i + 1 < ii ? ((b2 & 0xF) << 2) | (b3 >> 6) : 64;
+ var d4 = i + 2 < ii ? (b3 & 0x3F) : 64;
+ buffer += digits[d1] + digits[d2] + digits[d3] + digits[d4];
+ }
+ return buffer;
+ };
+})();
+
function MessageHandler(name, comObj) {
this.name = name;
this.comObj = comObj;
this.callbackIndex = 1;
+ this.postMessageTransfers = true;
var callbacks = this.callbacks = {};
var ah = this.actionHandler = {};
ah['console_log'] = [function ahConsoleLog(data) {
- log.apply(null, data);
+ console.log.apply(console, data);
}];
- // If there's no console available, console_error in the
- // action handler will do nothing.
- if ('console' in globalScope) {
- ah['console_error'] = [function ahConsoleError(data) {
- globalScope['console'].error.apply(null, data);
- }];
- } else {
- ah['console_error'] = [function ahConsoleError(data) {
- log.apply(null, data);
- }];
- }
- ah['_warn'] = [function ah_Warn(data) {
- warn(data);
+ ah['console_error'] = [function ahConsoleError(data) {
+ console.error.apply(console, data);
+ }];
+ ah['_unsupported_feature'] = [function ah_unsupportedFeature(data) {
+ UnsupportedManager.notify(data);
}];
comObj.onmessage = function messageHandlerComObjOnMessage(event) {
@@ -1063,7 +1250,12 @@ function MessageHandler(name, comObj) {
} else if (data.action in ah) {
var action = ah[data.action];
if (data.callbackId) {
- var promise = new Promise();
+ var deferred = {};
+ var promise = new Promise(function (resolve, reject) {
+ deferred.resolve = resolve;
+ deferred.reject = reject;
+ });
+ deferred.promise = promise;
promise.then(function(resolvedData) {
comObj.postMessage({
isReply: true,
@@ -1071,7 +1263,7 @@ function MessageHandler(name, comObj) {
data: resolvedData
});
});
- action[0].call(action[1], data.data, promise);
+ action[0].call(action[1], data.data, deferred);
} else {
action[0].call(action[1], data.data);
}
@@ -1094,8 +1286,9 @@ MessageHandler.prototype = {
* @param {String} actionName Action to call.
* @param {JSON} data JSON data to send.
* @param {function} [callback] Optional callback that will handle a reply.
+ * @param {Array} [transfers] Optional list of transfers/ArrayBuffers
*/
- send: function messageHandlerSend(actionName, data, callback) {
+ send: function messageHandlerSend(actionName, data, callback, transfers) {
var message = {
action: actionName,
data: data
@@ -1105,693 +1298,1563 @@ MessageHandler.prototype = {
this.callbacks[callbackId] = callback;
message.callbackId = callbackId;
}
- this.comObj.postMessage(message);
+ if (transfers && this.postMessageTransfers) {
+ this.comObj.postMessage(message, transfers);
+ } else {
+ this.comObj.postMessage(message);
+ }
}
};
-function loadJpegStream(id, imageData, objs) {
+function loadJpegStream(id, imageUrl, objs) {
var img = new Image();
img.onload = (function loadJpegStream_onloadClosure() {
objs.resolve(id, img);
});
- img.src = 'data:image/jpeg;base64,' + window.btoa(imageData);
+ img.src = imageUrl;
}
-var PatternType = {
- AXIAL: 2,
- RADIAL: 3
-};
-
-var Pattern = (function PatternClosure() {
- // Constructor should define this.getPattern
- function Pattern() {
- error('should not call Pattern constructor');
+var ColorSpace = (function ColorSpaceClosure() {
+ // Constructor should define this.numComps, this.defaultColor, this.name
+ function ColorSpace() {
+ error('should not call ColorSpace constructor');
}
- Pattern.prototype = {
- // Input: current Canvas context
- // Output: the appropriate fillStyle or strokeStyle
- getPattern: function Pattern_getPattern(ctx) {
- error('Should not call Pattern.getStyle: ' + ctx);
- }
+ ColorSpace.prototype = {
+ /**
+ * Converts the color value to the RGB color. The color components are
+ * located in the src array starting from the srcOffset. Returns the array
+ * of the rgb components, each value ranging from [0,255].
+ */
+ getRgb: function ColorSpace_getRgb(src, srcOffset) {
+ error('Should not call ColorSpace.getRgb');
+ },
+ /**
+ * Converts the color value to the RGB color, similar to the getRgb method.
+ * The result placed into the dest array starting from the destOffset.
+ */
+ getRgbItem: function ColorSpace_getRgb(src, srcOffset, dest, destOffset) {
+ error('Should not call ColorSpace.getRgbItem');
+ },
+ /**
+ * Converts the specified number of the color values to the RGB colors.
+ * The colors are located in the src array starting from the srcOffset.
+ * The result is placed into the dest array starting from the destOffset.
+ * The src array items shall be in [0,2^bits) range, the dest array items
+ * will be in [0,255] range.
+ */
+ getRgbBuffer: function ColorSpace_getRgbBuffer(src, srcOffset, count,
+ dest, destOffset, bits) {
+ error('Should not call ColorSpace.getRgbBuffer');
+ },
+ /**
+ * Determines amount of the bytes is required to store the reslut of the
+ * conversion that done by the getRgbBuffer method.
+ */
+ getOutputLength: function ColorSpace_getOutputLength(inputLength) {
+ error('Should not call ColorSpace.getOutputLength');
+ },
+ /**
+ * Returns true if source data will be equal the result/output data.
+ */
+ isPassthrough: function ColorSpace_isPassthrough(bits) {
+ return false;
+ },
+ /**
+ * Creates the output buffer and converts the specified number of the color
+ * values to the RGB colors, similar to the getRgbBuffer.
+ */
+ createRgbBuffer: function ColorSpace_createRgbBuffer(src, srcOffset,
+ count, bits) {
+ if (this.isPassthrough(bits)) {
+ return src.subarray(srcOffset);
+ }
+ var dest = new Uint8Array(count * 3);
+ var numComponentColors = 1 << bits;
+ // Optimization: create a color map when there is just one component and
+ // we are converting more colors than the size of the color map. We
+ // don't build the map if the colorspace is gray or rgb since those
+ // methods are faster than building a map. This mainly offers big speed
+ // ups for indexed and alternate colorspaces.
+ if (this.numComps === 1 && count > numComponentColors &&
+ this.name !== 'DeviceGray' && this.name !== 'DeviceRGB') {
+ // TODO it may be worth while to cache the color map. While running
+ // testing I never hit a cache so I will leave that out for now (perhaps
+ // we are reparsing colorspaces too much?).
+ var allColors = bits <= 8 ? new Uint8Array(numComponentColors) :
+ new Uint16Array(numComponentColors);
+ for (var i = 0; i < numComponentColors; i++) {
+ allColors[i] = i;
+ }
+ var colorMap = new Uint8Array(numComponentColors * 3);
+ this.getRgbBuffer(allColors, 0, numComponentColors, colorMap, 0, bits);
+
+ var destOffset = 0;
+ for (var i = 0; i < count; ++i) {
+ var key = src[srcOffset++] * 3;
+ dest[destOffset++] = colorMap[key];
+ dest[destOffset++] = colorMap[key + 1];
+ dest[destOffset++] = colorMap[key + 2];
+ }
+ return dest;
+ }
+ this.getRgbBuffer(src, srcOffset, count, dest, 0, bits);
+ return dest;
+ },
+ /**
+ * True if the colorspace has components in the default range of [0, 1].
+ * This should be true for all colorspaces except for lab color spaces
+ * which are [0,100], [-128, 127], [-128, 127].
+ */
+ usesZeroToOneRange: true
};
- Pattern.shadingFromIR = function Pattern_shadingFromIR(raw) {
- return Shadings[raw[0]].fromIR(raw);
+ ColorSpace.parse = function ColorSpace_parse(cs, xref, res) {
+ var IR = ColorSpace.parseToIR(cs, xref, res);
+ if (IR instanceof AlternateCS)
+ return IR;
+
+ return ColorSpace.fromIR(IR);
};
- Pattern.parseShading = function Pattern_parseShading(shading, matrix, xref,
- res) {
+ ColorSpace.fromIR = function ColorSpace_fromIR(IR) {
+ var name = isArray(IR) ? IR[0] : IR;
- var dict = isStream(shading) ? shading.dict : shading;
- var type = dict.get('ShadingType');
+ switch (name) {
+ case 'DeviceGrayCS':
+ return this.singletons.gray;
+ case 'DeviceRgbCS':
+ return this.singletons.rgb;
+ case 'DeviceCmykCS':
+ return this.singletons.cmyk;
+ case 'CalGrayCS':
+ var whitePoint = IR[1].WhitePoint;
+ var blackPoint = IR[1].BlackPoint;
+ var gamma = IR[1].Gamma;
+ return new CalGrayCS(whitePoint, blackPoint, gamma);
+ case 'PatternCS':
+ var basePatternCS = IR[1];
+ if (basePatternCS)
+ basePatternCS = ColorSpace.fromIR(basePatternCS);
+ return new PatternCS(basePatternCS);
+ case 'IndexedCS':
+ var baseIndexedCS = IR[1];
+ var hiVal = IR[2];
+ var lookup = IR[3];
+ return new IndexedCS(ColorSpace.fromIR(baseIndexedCS), hiVal, lookup);
+ case 'AlternateCS':
+ var numComps = IR[1];
+ var alt = IR[2];
+ var tintFnIR = IR[3];
- switch (type) {
- case PatternType.AXIAL:
- case PatternType.RADIAL:
- // Both radial and axial shadings are handled by RadialAxial shading.
- return new Shadings.RadialAxial(dict, matrix, xref, res);
+ return new AlternateCS(numComps, ColorSpace.fromIR(alt),
+ PDFFunction.fromIR(tintFnIR));
+ case 'LabCS':
+ var whitePoint = IR[1].WhitePoint;
+ var blackPoint = IR[1].BlackPoint;
+ var range = IR[1].Range;
+ return new LabCS(whitePoint, blackPoint, range);
default:
- TODO('Unsupported shading type: ' + type);
- return new Shadings.Dummy();
+ error('Unkown name ' + name);
}
+ return null;
};
- return Pattern;
-})();
-
-var Shadings = {};
-
-// A small number to offset the first/last color stops so we can insert ones to
-// support extend. Number.MIN_VALUE appears to be too small and breaks the
-// extend. 1e-7 works in FF but chrome seems to use an even smaller sized number
-// internally so we have to go bigger.
-Shadings.SMALL_NUMBER = 1e-2;
-
-// Radial and axial shading have very similar implementations
-// If needed, the implementations can be broken into two classes
-Shadings.RadialAxial = (function RadialAxialClosure() {
- function RadialAxial(dict, matrix, xref, res, ctx) {
- this.matrix = matrix;
- this.coordsArr = dict.get('Coords');
- this.shadingType = dict.get('ShadingType');
- this.type = 'Pattern';
- this.ctx = ctx;
- var cs = dict.get('ColorSpace', 'CS');
- cs = ColorSpace.parse(cs, xref, res);
- this.cs = cs;
- var t0 = 0.0, t1 = 1.0;
- if (dict.has('Domain')) {
- var domainArr = dict.get('Domain');
- t0 = domainArr[0];
- t1 = domainArr[1];
+ ColorSpace.parseToIR = function ColorSpace_parseToIR(cs, xref, res) {
+ if (isName(cs)) {
+ var colorSpaces = res.get('ColorSpace');
+ if (isDict(colorSpaces)) {
+ var refcs = colorSpaces.get(cs.name);
+ if (refcs)
+ cs = refcs;
+ }
}
- var extendStart = false, extendEnd = false;
- if (dict.has('Extend')) {
- var extendArr = dict.get('Extend');
- extendStart = extendArr[0];
- extendEnd = extendArr[1];
- }
+ cs = xref.fetchIfRef(cs);
+ var mode;
- if (this.shadingType === PatternType.RADIAL &&
- (!extendStart || !extendEnd)) {
- // Radial gradient only currently works if either circle is fully within
- // the other circle.
- var x1 = this.coordsArr[0];
- var y1 = this.coordsArr[1];
- var r1 = this.coordsArr[2];
- var x2 = this.coordsArr[3];
- var y2 = this.coordsArr[4];
- var r2 = this.coordsArr[5];
- var distance = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
- if (r1 <= r2 + distance &&
- r2 <= r1 + distance) {
- warn('Unsupported radial gradient.');
- }
- }
+ if (isName(cs)) {
+ mode = cs.name;
+ this.mode = mode;
- this.extendStart = extendStart;
- this.extendEnd = extendEnd;
+ switch (mode) {
+ case 'DeviceGray':
+ case 'G':
+ return 'DeviceGrayCS';
+ case 'DeviceRGB':
+ case 'RGB':
+ return 'DeviceRgbCS';
+ case 'DeviceCMYK':
+ case 'CMYK':
+ return 'DeviceCmykCS';
+ case 'Pattern':
+ return ['PatternCS', null];
+ default:
+ error('unrecognized colorspace ' + mode);
+ }
+ } else if (isArray(cs)) {
+ mode = cs[0].name;
+ this.mode = mode;
- var fnObj = dict.get('Function');
- var fn;
- if (isArray(fnObj)) {
- var fnArray = [];
- for (var j = 0, jj = fnObj.length; j < jj; j++) {
- var obj = xref.fetchIfRef(fnObj[j]);
- if (!isPDFFunction(obj)) {
- error('Invalid function');
- }
- fnArray.push(PDFFunction.parse(xref, obj));
+ switch (mode) {
+ case 'DeviceGray':
+ case 'G':
+ return 'DeviceGrayCS';
+ case 'DeviceRGB':
+ case 'RGB':
+ return 'DeviceRgbCS';
+ case 'DeviceCMYK':
+ case 'CMYK':
+ return 'DeviceCmykCS';
+ case 'CalGray':
+ var params = cs[1].getAll();
+ return ['CalGrayCS', params];
+ case 'CalRGB':
+ return 'DeviceRgbCS';
+ case 'ICCBased':
+ var stream = xref.fetchIfRef(cs[1]);
+ var dict = stream.dict;
+ var numComps = dict.get('N');
+ if (numComps == 1)
+ return 'DeviceGrayCS';
+ if (numComps == 3)
+ return 'DeviceRgbCS';
+ if (numComps == 4)
+ return 'DeviceCmykCS';
+ break;
+ case 'Pattern':
+ var basePatternCS = cs[1];
+ if (basePatternCS)
+ basePatternCS = ColorSpace.parseToIR(basePatternCS, xref, res);
+ return ['PatternCS', basePatternCS];
+ case 'Indexed':
+ case 'I':
+ var baseIndexedCS = ColorSpace.parseToIR(cs[1], xref, res);
+ var hiVal = cs[2] + 1;
+ var lookup = xref.fetchIfRef(cs[3]);
+ if (isStream(lookup)) {
+ lookup = lookup.getBytes();
+ }
+ return ['IndexedCS', baseIndexedCS, hiVal, lookup];
+ case 'Separation':
+ case 'DeviceN':
+ var name = cs[1];
+ var numComps = 1;
+ if (isName(name))
+ numComps = 1;
+ else if (isArray(name))
+ numComps = name.length;
+ var alt = ColorSpace.parseToIR(cs[2], xref, res);
+ var tintFnIR = PDFFunction.getIR(xref, xref.fetchIfRef(cs[3]));
+ return ['AlternateCS', numComps, alt, tintFnIR];
+ case 'Lab':
+ var params = cs[1].getAll();
+ return ['LabCS', params];
+ default:
+ error('unimplemented color space object "' + mode + '"');
}
- fn = function radialAxialColorFunction(arg) {
- var out = [];
- for (var i = 0, ii = fnArray.length; i < ii; i++) {
- out.push(fnArray[i](arg)[0]);
- }
- return out;
- };
} else {
- if (!isPDFFunction(fnObj)) {
- error('Invalid function');
- }
- fn = PDFFunction.parse(xref, fnObj);
+ error('unrecognized color space object: "' + cs + '"');
}
+ return null;
+ };
+ /**
+ * Checks if a decode map matches the default decode map for a color space.
+ * This handles the general decode maps where there are two values per
+ * component. e.g. [0, 1, 0, 1, 0, 1] for a RGB color.
+ * This does not handle Lab, Indexed, or Pattern decode maps since they are
+ * slightly different.
+ * @param {Array} decode Decode map (usually from an image).
+ * @param {Number} n Number of components the color space has.
+ */
+ ColorSpace.isDefaultDecode = function ColorSpace_isDefaultDecode(decode, n) {
+ if (!decode)
+ return true;
- // 10 samples seems good enough for now, but probably won't work
- // if there are sharp color changes. Ideally, we would implement
- // the spec faithfully and add lossless optimizations.
- var diff = t1 - t0;
- var step = diff / 10;
-
- var colorStops = this.colorStops = [];
-
- // Protect against bad domains so we don't end up in an infinte loop below.
- if (t0 >= t1 || step <= 0) {
- // Acrobat doesn't seem to handle these cases so we'll ignore for
- // now.
- info('Bad shading domain.');
- return;
+ if (n * 2 !== decode.length) {
+ warn('The decode map is not the correct length');
+ return true;
}
-
- for (var i = t0; i <= t1; i += step) {
- var rgbColor = cs.getRgb(fn([i]), 0);
- var cssColor = Util.makeCssRgb(rgbColor);
- colorStops.push([(i - t0) / diff, cssColor]);
+ for (var i = 0, ii = decode.length; i < ii; i += 2) {
+ if (decode[i] !== 0 || decode[i + 1] != 1)
+ return false;
}
+ return true;
+ };
- var background = 'transparent';
- if (dict.has('Background')) {
- var rgbColor = cs.getRgb(dict.get('Background'), 0);
- background = Util.makeCssRgb(rgbColor);
+ ColorSpace.singletons = {
+ get gray() {
+ return shadow(this, 'gray', new DeviceGrayCS());
+ },
+ get rgb() {
+ return shadow(this, 'rgb', new DeviceRgbCS());
+ },
+ get cmyk() {
+ return shadow(this, 'cmyk', new DeviceCmykCS());
}
+ };
- if (!extendStart) {
- // Insert a color stop at the front and offset the first real color stop
- // so it doesn't conflict with the one we insert.
- colorStops.unshift([0, background]);
- colorStops[1][0] += Shadings.SMALL_NUMBER;
- }
- if (!extendEnd) {
- // Same idea as above in extendStart but for the end.
- colorStops[colorStops.length - 1][0] -= Shadings.SMALL_NUMBER;
- colorStops.push([1, background]);
- }
+ return ColorSpace;
+})();
- this.colorStops = colorStops;
+/**
+ * Alternate color space handles both Separation and DeviceN color spaces. A
+ * Separation color space is actually just a DeviceN with one color component.
+ * Both color spaces use a tinting function to convert colors to a base color
+ * space.
+ */
+var AlternateCS = (function AlternateCSClosure() {
+ function AlternateCS(numComps, base, tintFn) {
+ this.name = 'Alternate';
+ this.numComps = numComps;
+ this.defaultColor = new Float32Array(numComps);
+ for (var i = 0; i < numComps; ++i) {
+ this.defaultColor[i] = 1;
+ }
+ this.base = base;
+ this.tintFn = tintFn;
}
- RadialAxial.fromIR = function RadialAxial_fromIR(raw) {
- var type = raw[1];
- var colorStops = raw[2];
- var p0 = raw[3];
- var p1 = raw[4];
- var r0 = raw[5];
- var r1 = raw[6];
- return {
- type: 'Pattern',
- getPattern: function RadialAxial_getPattern(ctx) {
- var grad;
- if (type == PatternType.AXIAL)
- grad = ctx.createLinearGradient(p0[0], p0[1], p1[0], p1[1]);
- else if (type == PatternType.RADIAL)
- grad = ctx.createRadialGradient(p0[0], p0[1], r0, p1[0], p1[1], r1);
-
- for (var i = 0, ii = colorStops.length; i < ii; ++i) {
- var c = colorStops[i];
- grad.addColorStop(c[0], c[1]);
- }
- return grad;
- }
- };
- };
-
- RadialAxial.prototype = {
- getIR: function RadialAxial_getIR() {
- var coordsArr = this.coordsArr;
- var type = this.shadingType;
- if (type == PatternType.AXIAL) {
- var p0 = [coordsArr[0], coordsArr[1]];
- var p1 = [coordsArr[2], coordsArr[3]];
- var r0 = null;
- var r1 = null;
- } else if (type == PatternType.RADIAL) {
- var p0 = [coordsArr[0], coordsArr[1]];
- var p1 = [coordsArr[3], coordsArr[4]];
- var r0 = coordsArr[2];
- var r1 = coordsArr[5];
- } else {
- error('getPattern type unknown: ' + type);
- }
+ AlternateCS.prototype = {
+ getRgb: function AlternateCS_getRgb(src, srcOffset) {
+ var rgb = new Uint8Array(3);
+ this.getRgbItem(src, srcOffset, rgb, 0);
+ return rgb;
+ },
+ getRgbItem: function AlternateCS_getRgbItem(src, srcOffset,
+ dest, destOffset) {
+ var baseNumComps = this.base.numComps;
+ var input = 'subarray' in src ?
+ src.subarray(srcOffset, srcOffset + this.numComps) :
+ Array.prototype.slice.call(src, srcOffset, srcOffset + this.numComps);
+ var tinted = this.tintFn(input);
+ this.base.getRgbItem(tinted, 0, dest, destOffset);
+ },
+ getRgbBuffer: function AlternateCS_getRgbBuffer(src, srcOffset, count,
+ dest, destOffset, bits) {
+ var tintFn = this.tintFn;
+ var base = this.base;
+ var scale = 1 / ((1 << bits) - 1);
+ var baseNumComps = base.numComps;
+ var usesZeroToOneRange = base.usesZeroToOneRange;
+ var isPassthrough = base.isPassthrough(8) || !usesZeroToOneRange;
+ var pos = isPassthrough ? destOffset : 0;
+ var baseBuf = isPassthrough ? dest : new Uint8Array(baseNumComps * count);
+ var numComps = this.numComps;
- var matrix = this.matrix;
- if (matrix) {
- p0 = Util.applyTransform(p0, matrix);
- p1 = Util.applyTransform(p1, matrix);
+ var scaled = new Float32Array(numComps);
+ for (var i = 0; i < count; i++) {
+ for (var j = 0; j < numComps; j++) {
+ scaled[j] = src[srcOffset++] * scale;
+ }
+ var tinted = tintFn(scaled);
+ if (usesZeroToOneRange) {
+ for (var j = 0; j < baseNumComps; j++) {
+ baseBuf[pos++] = tinted[j] * 255;
+ }
+ } else {
+ base.getRgbItem(tinted, 0, baseBuf, pos);
+ pos += baseNumComps;
+ }
}
-
- return ['RadialAxial', type, this.colorStops, p0, p1, r0, r1];
- }
+ if (!isPassthrough) {
+ base.getRgbBuffer(baseBuf, 0, count, dest, destOffset, 8);
+ }
+ },
+ getOutputLength: function AlternateCS_getOutputLength(inputLength) {
+ return this.base.getOutputLength(inputLength *
+ this.base.numComps / this.numComps);
+ },
+ isPassthrough: ColorSpace.prototype.isPassthrough,
+ createRgbBuffer: ColorSpace.prototype.createRgbBuffer,
+ isDefaultDecode: function AlternateCS_isDefaultDecode(decodeMap) {
+ return ColorSpace.isDefaultDecode(decodeMap, this.numComps);
+ },
+ usesZeroToOneRange: true
};
- return RadialAxial;
+ return AlternateCS;
})();
-Shadings.Dummy = (function DummyClosure() {
- function Dummy() {
- this.type = 'Pattern';
+var PatternCS = (function PatternCSClosure() {
+ function PatternCS(baseCS) {
+ this.name = 'Pattern';
+ this.base = baseCS;
}
+ PatternCS.prototype = {};
- Dummy.fromIR = function Dummy_fromIR() {
- return {
- type: 'Pattern',
- getPattern: function Dummy_fromIR_getPattern() {
- return 'hotpink';
- }
- };
- };
+ return PatternCS;
+})();
- Dummy.prototype = {
- getIR: function Dummy_getIR() {
- return ['Dummy'];
+var IndexedCS = (function IndexedCSClosure() {
+ function IndexedCS(base, highVal, lookup) {
+ this.name = 'Indexed';
+ this.numComps = 1;
+ this.defaultColor = new Uint8Array([0]);
+ this.base = base;
+ this.highVal = highVal;
+
+ var baseNumComps = base.numComps;
+ var length = baseNumComps * highVal;
+ var lookupArray;
+
+ if (isStream(lookup)) {
+ lookupArray = new Uint8Array(length);
+ var bytes = lookup.getBytes(length);
+ lookupArray.set(bytes);
+ } else if (isString(lookup)) {
+ lookupArray = new Uint8Array(length);
+ for (var i = 0; i < length; ++i)
+ lookupArray[i] = lookup.charCodeAt(i);
+ } else if (lookup instanceof Uint8Array || lookup instanceof Array) {
+ lookupArray = lookup;
+ } else {
+ error('Unrecognized lookup table: ' + lookup);
}
- };
- return Dummy;
-})();
+ this.lookup = lookupArray;
+ }
-var TilingPattern = (function TilingPatternClosure() {
- var PaintType = {
- COLORED: 1,
- UNCOLORED: 2
- };
+ IndexedCS.prototype = {
+ getRgb: function IndexedCS_getRgb(src, srcOffset) {
+ var numComps = this.base.numComps;
+ var start = src[srcOffset] * numComps;
+ return this.base.getRgb(this.lookup, start);
+ },
+ getRgbItem: function IndexedCS_getRgbItem(src, srcOffset,
+ dest, destOffset) {
+ var numComps = this.base.numComps;
+ var start = src[srcOffset] * numComps;
+ this.base.getRgbItem(this.lookup, start, dest, destOffset);
+ },
+ getRgbBuffer: function IndexedCS_getRgbBuffer(src, srcOffset, count,
+ dest, destOffset) {
+ var base = this.base;
+ var numComps = base.numComps;
+ var outputDelta = base.getOutputLength(numComps);
+ var lookup = this.lookup;
- var MAX_PATTERN_SIZE = 3000; // 10in @ 300dpi shall be enough
+ for (var i = 0; i < count; ++i) {
+ var lookupPos = src[srcOffset++] * numComps;
+ base.getRgbBuffer(lookup, lookupPos, 1, dest, destOffset, 8);
+ destOffset += outputDelta;
+ }
+ },
+ getOutputLength: function IndexedCS_getOutputLength(inputLength) {
+ return this.base.getOutputLength(inputLength * this.base.numComps);
+ },
+ isPassthrough: ColorSpace.prototype.isPassthrough,
+ createRgbBuffer: ColorSpace.prototype.createRgbBuffer,
+ isDefaultDecode: function IndexedCS_isDefaultDecode(decodeMap) {
+ // indexed color maps shouldn't be changed
+ return true;
+ },
+ usesZeroToOneRange: true
+ };
+ return IndexedCS;
+})();
- function TilingPattern(IR, color, ctx, objs, commonObjs, baseTransform) {
- this.name = IR[1][0].name;
- this.operatorList = IR[2];
- this.matrix = IR[3] || [1, 0, 0, 1, 0, 0];
- this.bbox = IR[4];
- this.xstep = IR[5];
- this.ystep = IR[6];
- this.paintType = IR[7];
- this.tilingType = IR[8];
- this.color = color;
- this.objs = objs;
- this.commonObjs = commonObjs;
- this.baseTransform = baseTransform;
- this.type = 'Pattern';
- this.ctx = ctx;
+var DeviceGrayCS = (function DeviceGrayCSClosure() {
+ function DeviceGrayCS() {
+ this.name = 'DeviceGray';
+ this.numComps = 1;
+ this.defaultColor = new Float32Array([0]);
}
- TilingPattern.getIR = function TilingPattern_getIR(operatorList, dict, args) {
- var matrix = dict.get('Matrix');
- var bbox = dict.get('BBox');
- var xstep = dict.get('XStep');
- var ystep = dict.get('YStep');
- var paintType = dict.get('PaintType');
- var tilingType = dict.get('TilingType');
+ DeviceGrayCS.prototype = {
+ getRgb: function DeviceGrayCS_getRgb(src, srcOffset) {
+ var rgb = new Uint8Array(3);
+ this.getRgbItem(src, srcOffset, rgb, 0);
+ return rgb;
+ },
+ getRgbItem: function DeviceGrayCS_getRgbItem(src, srcOffset,
+ dest, destOffset) {
+ var c = (src[srcOffset] * 255) | 0;
+ c = c < 0 ? 0 : c > 255 ? 255 : c;
+ dest[destOffset] = dest[destOffset + 1] = dest[destOffset + 2] = c;
+ },
+ getRgbBuffer: function DeviceGrayCS_getRgbBuffer(src, srcOffset, count,
+ dest, destOffset, bits) {
+ var scale = 255 / ((1 << bits) - 1);
+ var j = srcOffset, q = destOffset;
+ for (var i = 0; i < count; ++i) {
+ var c = (scale * src[j++]) | 0;
+ dest[q++] = c;
+ dest[q++] = c;
+ dest[q++] = c;
+ }
+ },
+ getOutputLength: function DeviceGrayCS_getOutputLength(inputLength) {
+ return inputLength * 3;
+ },
+ isPassthrough: ColorSpace.prototype.isPassthrough,
+ createRgbBuffer: ColorSpace.prototype.createRgbBuffer,
+ isDefaultDecode: function DeviceGrayCS_isDefaultDecode(decodeMap) {
+ return ColorSpace.isDefaultDecode(decodeMap, this.numComps);
+ },
+ usesZeroToOneRange: true
+ };
+ return DeviceGrayCS;
+})();
- return [
- 'TilingPattern', args, operatorList, matrix, bbox, xstep, ystep,
- paintType, tilingType
- ];
+var DeviceRgbCS = (function DeviceRgbCSClosure() {
+ function DeviceRgbCS() {
+ this.name = 'DeviceRGB';
+ this.numComps = 3;
+ this.defaultColor = new Float32Array([0, 0, 0]);
+ }
+ DeviceRgbCS.prototype = {
+ getRgb: function DeviceRgbCS_getRgb(src, srcOffset) {
+ var rgb = new Uint8Array(3);
+ this.getRgbItem(src, srcOffset, rgb, 0);
+ return rgb;
+ },
+ getRgbItem: function DeviceRgbCS_getRgbItem(src, srcOffset,
+ dest, destOffset) {
+ var r = (src[srcOffset] * 255) | 0;
+ var g = (src[srcOffset + 1] * 255) | 0;
+ var b = (src[srcOffset + 2] * 255) | 0;
+ dest[destOffset] = r < 0 ? 0 : r > 255 ? 255 : r;
+ dest[destOffset + 1] = g < 0 ? 0 : g > 255 ? 255 : g;
+ dest[destOffset + 2] = b < 0 ? 0 : b > 255 ? 255 : b;
+ },
+ getRgbBuffer: function DeviceRgbCS_getRgbBuffer(src, srcOffset, count,
+ dest, destOffset, bits) {
+ var length = count * 3;
+ if (bits == 8) {
+ dest.set(src.subarray(srcOffset, srcOffset + length), destOffset);
+ return;
+ }
+ var scale = 255 / ((1 << bits) - 1);
+ var j = srcOffset, q = destOffset;
+ for (var i = 0; i < length; ++i) {
+ dest[q++] = (scale * src[j++]) | 0;
+ }
+ },
+ getOutputLength: function DeviceRgbCS_getOutputLength(inputLength) {
+ return inputLength;
+ },
+ isPassthrough: function DeviceRgbCS_isPassthrough(bits) {
+ return bits == 8;
+ },
+ createRgbBuffer: ColorSpace.prototype.createRgbBuffer,
+ isDefaultDecode: function DeviceRgbCS_isDefaultDecode(decodeMap) {
+ return ColorSpace.isDefaultDecode(decodeMap, this.numComps);
+ },
+ usesZeroToOneRange: true
};
+ return DeviceRgbCS;
+})();
- TilingPattern.prototype = {
- createPatternCanvas: function TilinPattern_createPatternCanvas(owner) {
- var operatorList = this.operatorList;
- var bbox = this.bbox;
- var xstep = this.xstep;
- var ystep = this.ystep;
- var paintType = this.paintType;
- var tilingType = this.tilingType;
- var color = this.color;
- var objs = this.objs;
- var commonObjs = this.commonObjs;
- var ctx = this.ctx;
+var DeviceCmykCS = (function DeviceCmykCSClosure() {
+ // The coefficients below was found using numerical analysis: the method of
+ // steepest descent for the sum((f_i - color_value_i)^2) for r/g/b colors,
+ // where color_value is the tabular value from the table of sampled RGB colors
+ // from CMYK US Web Coated (SWOP) colorspace, and f_i is the corresponding
+ // CMYK color conversion using the estimation below:
+ // f(A, B,.. N) = Acc+Bcm+Ccy+Dck+c+Fmm+Gmy+Hmk+Im+Jyy+Kyk+Ly+Mkk+Nk+255
+ function convertToRgb(src, srcOffset, srcScale, dest, destOffset) {
+ var c = src[srcOffset + 0] * srcScale;
+ var m = src[srcOffset + 1] * srcScale;
+ var y = src[srcOffset + 2] * srcScale;
+ var k = src[srcOffset + 3] * srcScale;
- TODO('TilingType: ' + tilingType);
+ var r =
+ c * (-4.387332384609988 * c + 54.48615194189176 * m +
+ 18.82290502165302 * y + 212.25662451639585 * k +
+ -285.2331026137004) +
+ m * (1.7149763477362134 * m - 5.6096736904047315 * y +
+ -17.873870861415444 * k - 5.497006427196366) +
+ y * (-2.5217340131683033 * y - 21.248923337353073 * k +
+ 17.5119270841813) +
+ k * (-21.86122147463605 * k - 189.48180835922747) + 255;
+ var g =
+ c * (8.841041422036149 * c + 60.118027045597366 * m +
+ 6.871425592049007 * y + 31.159100130055922 * k +
+ -79.2970844816548) +
+ m * (-15.310361306967817 * m + 17.575251261109482 * y +
+ 131.35250912493976 * k - 190.9453302588951) +
+ y * (4.444339102852739 * y + 9.8632861493405 * k - 24.86741582555878) +
+ k * (-20.737325471181034 * k - 187.80453709719578) + 255;
+ var b =
+ c * (0.8842522430003296 * c + 8.078677503112928 * m +
+ 30.89978309703729 * y - 0.23883238689178934 * k +
+ -14.183576799673286) +
+ m * (10.49593273432072 * m + 63.02378494754052 * y +
+ 50.606957656360734 * k - 112.23884253719248) +
+ y * (0.03296041114873217 * y + 115.60384449646641 * k +
+ -193.58209356861505) +
+ k * (-22.33816807309886 * k - 180.12613974708367) + 255;
- var x0 = bbox[0], y0 = bbox[1], x1 = bbox[2], y1 = bbox[3];
+ dest[destOffset] = r > 255 ? 255 : r < 0 ? 0 : r;
+ dest[destOffset + 1] = g > 255 ? 255 : g < 0 ? 0 : g;
+ dest[destOffset + 2] = b > 255 ? 255 : b < 0 ? 0 : b;
+ }
- var topLeft = [x0, y0];
- // we want the canvas to be as large as the step size
- var botRight = [x0 + xstep, y0 + ystep];
+ function DeviceCmykCS() {
+ this.name = 'DeviceCMYK';
+ this.numComps = 4;
+ this.defaultColor = new Float32Array([0, 0, 0, 1]);
+ }
+ DeviceCmykCS.prototype = {
+ getRgb: function DeviceCmykCS_getRgb(src, srcOffset) {
+ var rgb = new Uint8Array(3);
+ convertToRgb(src, srcOffset, 1, rgb, 0);
+ return rgb;
+ },
+ getRgbItem: function DeviceCmykCS_getRgbItem(src, srcOffset,
+ dest, destOffset) {
+ convertToRgb(src, srcOffset, 1, dest, destOffset);
+ },
+ getRgbBuffer: function DeviceCmykCS_getRgbBuffer(src, srcOffset, count,
+ dest, destOffset, bits) {
+ var scale = 1 / ((1 << bits) - 1);
+ for (var i = 0; i < count; i++) {
+ convertToRgb(src, srcOffset, scale, dest, destOffset);
+ srcOffset += 4;
+ destOffset += 3;
+ }
+ },
+ getOutputLength: function DeviceCmykCS_getOutputLength(inputLength) {
+ return (inputLength >> 2) * 3;
+ },
+ isPassthrough: ColorSpace.prototype.isPassthrough,
+ createRgbBuffer: ColorSpace.prototype.createRgbBuffer,
+ isDefaultDecode: function DeviceCmykCS_isDefaultDecode(decodeMap) {
+ return ColorSpace.isDefaultDecode(decodeMap, this.numComps);
+ },
+ usesZeroToOneRange: true
+ };
- var width = botRight[0] - topLeft[0];
- var height = botRight[1] - topLeft[1];
+ return DeviceCmykCS;
+})();
- // Obtain scale from matrix and current transformation matrix.
- var matrixScale = Util.singularValueDecompose2dScale(this.matrix);
- var curMatrixScale = Util.singularValueDecompose2dScale(
- this.baseTransform);
- var combinedScale = [matrixScale[0] * curMatrixScale[0],
- matrixScale[1] * curMatrixScale[1]];
+//
+// CalGrayCS: Based on "PDF Reference, Sixth Ed", p.245
+//
+var CalGrayCS = (function CalGrayCSClosure() {
+ function CalGrayCS(whitePoint, blackPoint, gamma) {
+ this.name = 'CalGray';
+ this.numComps = 1;
+ this.defaultColor = new Float32Array([0]);
- // MAX_PATTERN_SIZE is used to avoid OOM situation.
- // Use width and height values that are as close as possible to the end
- // result when the pattern is used. Too low value makes the pattern look
- // blurry. Too large value makes it look too crispy.
- width = Math.min(Math.ceil(Math.abs(width * combinedScale[0])),
- MAX_PATTERN_SIZE);
+ if (!whitePoint) {
+ error('WhitePoint missing - required for color space CalGray');
+ }
+ blackPoint = blackPoint || [0, 0, 0];
+ gamma = gamma || 1;
- height = Math.min(Math.ceil(Math.abs(height * combinedScale[1])),
- MAX_PATTERN_SIZE);
+ // Translate arguments to spec variables.
+ this.XW = whitePoint[0];
+ this.YW = whitePoint[1];
+ this.ZW = whitePoint[2];
- var tmpCanvas = CachedCanvases.getCanvas('pattern', width, height, true);
- var tmpCtx = tmpCanvas.context;
- var graphics = new CanvasGraphics(tmpCtx, commonObjs, objs);
- graphics.groupLevel = owner.groupLevel;
+ this.XB = blackPoint[0];
+ this.YB = blackPoint[1];
+ this.ZB = blackPoint[2];
- this.setFillAndStrokeStyleToContext(tmpCtx, paintType, color);
+ this.G = gamma;
- this.setScale(width, height, xstep, ystep);
- this.transformToScale(graphics);
+ // Validate variables as per spec.
+ if (this.XW < 0 || this.ZW < 0 || this.YW !== 1) {
+ error('Invalid WhitePoint components for ' + this.name +
+ ', no fallback available');
+ }
- // transform coordinates to pattern space
- var tmpTranslate = [1, 0, 0, 1, -topLeft[0], -topLeft[1]];
- graphics.transform.apply(graphics, tmpTranslate);
+ if (this.XB < 0 || this.YB < 0 || this.ZB < 0) {
+ info('Invalid BlackPoint for ' + this.name + ', falling back to default');
+ this.XB = this.YB = this.ZB = 0;
+ }
- this.clipBbox(graphics, bbox, x0, y0, x1, y1);
+ if (this.XB !== 0 || this.YB !== 0 || this.ZB !== 0) {
+ warn(this.name + ', BlackPoint: XB: ' + this.XB + ', YB: ' + this.YB +
+ ', ZB: ' + this.ZB + ', only default values are supported.');
+ }
- graphics.executeOperatorList(operatorList);
- return tmpCanvas.canvas;
- },
+ if (this.G < 1) {
+ info('Invalid Gamma: ' + this.G + ' for ' + this.name +
+ ', falling back to default');
+ this.G = 1;
+ }
+ }
- setScale: function TilingPattern_setScale(width, height, xstep, ystep) {
- this.scale = [width / xstep, height / ystep];
- },
+ function convertToRgb(cs, src, srcOffset, dest, destOffset, scale) {
+ // A represents a gray component of a calibrated gray space.
+ // A <---> AG in the spec
+ var A = src[srcOffset] * scale;
+ var AG = Math.pow(A, cs.G);
+
+ // Computes intermediate variables M, L, N as per spec.
+ // Except if other than default BlackPoint values are used.
+ var M = cs.XW * AG;
+ var L = cs.YW * AG;
+ var N = cs.ZW * AG;
+
+ // Decode XYZ, as per spec.
+ var X = M;
+ var Y = L;
+ var Z = N;
+
+ // http://www.poynton.com/notes/colour_and_gamma/ColorFAQ.html, Ch 4.
+ // This yields values in range [0, 100].
+ var Lstar = Math.max(116 * Math.pow(Y, 1 / 3) - 16, 0);
+
+ // Convert values to rgb range [0, 255].
+ dest[destOffset] = Lstar * 255 / 100;
+ dest[destOffset + 1] = Lstar * 255 / 100;
+ dest[destOffset + 2] = Lstar * 255 / 100;
+ }
- transformToScale: function TilingPattern_transformToScale(graphics) {
- var scale = this.scale;
- var tmpScale = [scale[0], 0, 0, scale[1], 0, 0];
- graphics.transform.apply(graphics, tmpScale);
+ CalGrayCS.prototype = {
+ getRgb: function CalGrayCS_getRgb(src, srcOffset) {
+ var rgb = new Uint8Array(3);
+ this.getRgbItem(src, srcOffset, rgb, 0);
+ return rgb;
},
-
- scaleToContext: function TilingPattern_scaleToContext() {
- var scale = this.scale;
- this.ctx.scale(1 / scale[0], 1 / scale[1]);
+ getRgbItem: function CalGrayCS_getRgbItem(src, srcOffset,
+ dest, destOffset) {
+ convertToRgb(this, src, srcOffset, dest, destOffset, 1);
},
+ getRgbBuffer: function CalGrayCS_getRgbBuffer(src, srcOffset, count,
+ dest, destOffset, bits) {
+ var scale = 1 / ((1 << bits) - 1);
- clipBbox: function clipBbox(graphics, bbox, x0, y0, x1, y1) {
- if (bbox && isArray(bbox) && 4 == bbox.length) {
- var bboxWidth = x1 - x0;
- var bboxHeight = y1 - y0;
- graphics.rectangle(x0, y0, bboxWidth, bboxHeight);
- graphics.clip();
- graphics.endPath();
+ for (var i = 0; i < count; ++i) {
+ convertToRgb(this, src, srcOffset, dest, destOffset, scale);
+ srcOffset += 1;
+ destOffset += 3;
}
},
-
- setFillAndStrokeStyleToContext:
- function setFillAndStrokeStyleToContext(context, paintType, color) {
- switch (paintType) {
- case PaintType.COLORED:
- var ctx = this.ctx;
- context.fillStyle = ctx.fillStyle;
- context.strokeStyle = ctx.strokeStyle;
- break;
- case PaintType.UNCOLORED:
- var rgbColor = ColorSpace.singletons.rgb.getRgb(color, 0);
- var cssColor = Util.makeCssRgb(rgbColor);
- context.fillStyle = cssColor;
- context.strokeStyle = cssColor;
- break;
- default:
- error('Unsupported paint type: ' + paintType);
- }
+ getOutputLength: function CalGrayCS_getOutputLength(inputLength) {
+ return inputLength * 3;
},
-
- getPattern: function TilingPattern_getPattern(ctx, owner) {
- var temporaryPatternCanvas = this.createPatternCanvas(owner);
-
- var ctx = this.ctx;
- ctx.setTransform.apply(ctx, this.baseTransform);
- ctx.transform.apply(ctx, this.matrix);
- this.scaleToContext();
-
- return ctx.createPattern(temporaryPatternCanvas, 'repeat');
- }
+ isPassthrough: ColorSpace.prototype.isPassthrough,
+ createRgbBuffer: ColorSpace.prototype.createRgbBuffer,
+ isDefaultDecode: function CalGrayCS_isDefaultDecode(decodeMap) {
+ return ColorSpace.isDefaultDecode(decodeMap, this.numComps);
+ },
+ usesZeroToOneRange: true
};
-
- return TilingPattern;
+ return CalGrayCS;
})();
+//
+// LabCS: Based on "PDF Reference, Sixth Ed", p.250
+//
+var LabCS = (function LabCSClosure() {
+ function LabCS(whitePoint, blackPoint, range) {
+ this.name = 'Lab';
+ this.numComps = 3;
+ this.defaultColor = new Float32Array([0, 0, 0]);
+ if (!whitePoint)
+ error('WhitePoint missing - required for color space Lab');
+ blackPoint = blackPoint || [0, 0, 0];
+ range = range || [-100, 100, -100, 100];
-var PDFFunction = (function PDFFunctionClosure() {
- var CONSTRUCT_SAMPLED = 0;
- var CONSTRUCT_INTERPOLATED = 2;
- var CONSTRUCT_STICHED = 3;
- var CONSTRUCT_POSTSCRIPT = 4;
+ // Translate args to spec variables
+ this.XW = whitePoint[0];
+ this.YW = whitePoint[1];
+ this.ZW = whitePoint[2];
+ this.amin = range[0];
+ this.amax = range[1];
+ this.bmin = range[2];
+ this.bmax = range[3];
- return {
- getSampleArray: function PDFFunction_getSampleArray(size, outputSize, bps,
- str) {
- var length = 1;
- for (var i = 0, ii = size.length; i < ii; i++)
- length *= size[i];
- length *= outputSize;
-
- var array = [];
- var codeSize = 0;
- var codeBuf = 0;
- // 32 is a valid bps so shifting won't work
- var sampleMul = 1.0 / (Math.pow(2.0, bps) - 1);
-
- var strBytes = str.getBytes((length * bps + 7) / 8);
- var strIdx = 0;
- for (var i = 0; i < length; i++) {
- while (codeSize < bps) {
- codeBuf <<= 8;
- codeBuf |= strBytes[strIdx++];
- codeSize += 8;
- }
- codeSize -= bps;
- array.push((codeBuf >> codeSize) * sampleMul);
- codeBuf &= (1 << codeSize) - 1;
- }
- return array;
- },
+ // These are here just for completeness - the spec doesn't offer any
+ // formulas that use BlackPoint in Lab
+ this.XB = blackPoint[0];
+ this.YB = blackPoint[1];
+ this.ZB = blackPoint[2];
- getIR: function PDFFunction_getIR(xref, fn) {
- var dict = fn.dict;
- if (!dict)
- dict = fn;
+ // Validate vars as per spec
+ if (this.XW < 0 || this.ZW < 0 || this.YW !== 1)
+ error('Invalid WhitePoint components, no fallback available');
- var types = [this.constructSampled,
- null,
- this.constructInterpolated,
- this.constructStiched,
- this.constructPostScript];
+ if (this.XB < 0 || this.YB < 0 || this.ZB < 0) {
+ info('Invalid BlackPoint, falling back to default');
+ this.XB = this.YB = this.ZB = 0;
+ }
- var typeNum = dict.get('FunctionType');
- var typeFn = types[typeNum];
- if (!typeFn)
- error('Unknown type of function');
+ if (this.amin > this.amax || this.bmin > this.bmax) {
+ info('Invalid Range, falling back to defaults');
+ this.amin = -100;
+ this.amax = 100;
+ this.bmin = -100;
+ this.bmax = 100;
+ }
+ }
- return typeFn.call(this, fn, dict, xref);
- },
+ // Function g(x) from spec
+ function fn_g(x) {
+ if (x >= 6 / 29)
+ return x * x * x;
+ else
+ return (108 / 841) * (x - 4 / 29);
+ }
- fromIR: function PDFFunction_fromIR(IR) {
- var type = IR[0];
- switch (type) {
- case CONSTRUCT_SAMPLED:
- return this.constructSampledFromIR(IR);
- case CONSTRUCT_INTERPOLATED:
- return this.constructInterpolatedFromIR(IR);
- case CONSTRUCT_STICHED:
- return this.constructStichedFromIR(IR);
- //case CONSTRUCT_POSTSCRIPT:
- default:
- return this.constructPostScriptFromIR(IR);
- }
- },
+ function decode(value, high1, low2, high2) {
+ return low2 + (value) * (high2 - low2) / (high1);
+ }
- parse: function PDFFunction_parse(xref, fn) {
- var IR = this.getIR(xref, fn);
- return this.fromIR(IR);
- },
+ // If decoding is needed maxVal should be 2^bits per component - 1.
+ function convertToRgb(cs, src, srcOffset, maxVal, dest, destOffset) {
+ // XXX: Lab input is in the range of [0, 100], [amin, amax], [bmin, bmax]
+ // not the usual [0, 1]. If a command like setFillColor is used the src
+ // values will already be within the correct range. However, if we are
+ // converting an image we have to map the values to the correct range given
+ // above.
+ // Ls,as,bs <---> L*,a*,b* in the spec
+ var Ls = src[srcOffset];
+ var as = src[srcOffset + 1];
+ var bs = src[srcOffset + 2];
+ if (maxVal !== false) {
+ Ls = decode(Ls, maxVal, 0, 100);
+ as = decode(as, maxVal, cs.amin, cs.amax);
+ bs = decode(bs, maxVal, cs.bmin, cs.bmax);
+ }
- constructSampled: function PDFFunction_constructSampled(str, dict) {
- function toMultiArray(arr) {
- var inputLength = arr.length;
- var outputLength = arr.length / 2;
- var out = [];
- var index = 0;
- for (var i = 0; i < inputLength; i += 2) {
- out[index] = [arr[i], arr[i + 1]];
- ++index;
- }
- return out;
- }
- var domain = dict.get('Domain');
- var range = dict.get('Range');
+ // Adjust limits of 'as' and 'bs'
+ as = as > cs.amax ? cs.amax : as < cs.amin ? cs.amin : as;
+ bs = bs > cs.bmax ? cs.bmax : bs < cs.bmin ? cs.bmin : bs;
- if (!domain || !range)
- error('No domain or range');
+ // Computes intermediate variables X,Y,Z as per spec
+ var M = (Ls + 16) / 116;
+ var L = M + (as / 500);
+ var N = M - (bs / 200);
- var inputSize = domain.length / 2;
- var outputSize = range.length / 2;
+ var X = cs.XW * fn_g(L);
+ var Y = cs.YW * fn_g(M);
+ var Z = cs.ZW * fn_g(N);
- domain = toMultiArray(domain);
- range = toMultiArray(range);
+ var r, g, b;
+ // Using different conversions for D50 and D65 white points,
+ // per http://www.color.org/srgb.pdf
+ if (cs.ZW < 1) {
+ // Assuming D50 (X=0.9642, Y=1.00, Z=0.8249)
+ r = X * 3.1339 + Y * -1.6170 + Z * -0.4906;
+ g = X * -0.9785 + Y * 1.9160 + Z * 0.0333;
+ b = X * 0.0720 + Y * -0.2290 + Z * 1.4057;
+ } else {
+ // Assuming D65 (X=0.9505, Y=1.00, Z=1.0888)
+ r = X * 3.2406 + Y * -1.5372 + Z * -0.4986;
+ g = X * -0.9689 + Y * 1.8758 + Z * 0.0415;
+ b = X * 0.0557 + Y * -0.2040 + Z * 1.0570;
+ }
+ // clamp color values to [0,1] range then convert to [0,255] range.
+ dest[destOffset] = Math.sqrt(r < 0 ? 0 : r > 1 ? 1 : r) * 255;
+ dest[destOffset + 1] = Math.sqrt(g < 0 ? 0 : g > 1 ? 1 : g) * 255;
+ dest[destOffset + 2] = Math.sqrt(b < 0 ? 0 : b > 1 ? 1 : b) * 255;
+ }
- var size = dict.get('Size');
- var bps = dict.get('BitsPerSample');
- var order = dict.get('Order') || 1;
- if (order !== 1) {
- // No description how cubic spline interpolation works in PDF32000:2008
- // As in poppler, ignoring order, linear interpolation may work as good
- TODO('No support for cubic spline interpolation: ' + order);
+ LabCS.prototype = {
+ getRgb: function LabCS_getRgb(src, srcOffset) {
+ var rgb = new Uint8Array(3);
+ convertToRgb(this, src, srcOffset, false, rgb, 0);
+ return rgb;
+ },
+ getRgbItem: function LabCS_getRgbItem(src, srcOffset, dest, destOffset) {
+ convertToRgb(this, src, srcOffset, false, dest, destOffset);
+ },
+ getRgbBuffer: function LabCS_getRgbBuffer(src, srcOffset, count,
+ dest, destOffset, bits) {
+ var maxVal = (1 << bits) - 1;
+ for (var i = 0; i < count; i++) {
+ convertToRgb(this, src, srcOffset, maxVal, dest, destOffset);
+ srcOffset += 3;
+ destOffset += 3;
}
+ },
+ getOutputLength: function LabCS_getOutputLength(inputLength) {
+ return inputLength;
+ },
+ isPassthrough: ColorSpace.prototype.isPassthrough,
+ isDefaultDecode: function LabCS_isDefaultDecode(decodeMap) {
+ // XXX: Decoding is handled with the lab conversion because of the strange
+ // ranges that are used.
+ return true;
+ },
+ usesZeroToOneRange: false
+ };
+ return LabCS;
+})();
- var encode = dict.get('Encode');
- if (!encode) {
- encode = [];
- for (var i = 0; i < inputSize; ++i) {
- encode.push(0);
- encode.push(size[i] - 1);
- }
- }
- encode = toMultiArray(encode);
- var decode = dict.get('Decode');
- if (!decode)
- decode = range;
- else
- decode = toMultiArray(decode);
- var samples = this.getSampleArray(size, outputSize, bps, str);
+var PatternType = {
+ AXIAL: 2,
+ RADIAL: 3
+};
- return [
- CONSTRUCT_SAMPLED, inputSize, domain, encode, decode, samples, size,
- outputSize, Math.pow(2, bps) - 1, range
- ];
- },
+var Pattern = (function PatternClosure() {
+ // Constructor should define this.getPattern
+ function Pattern() {
+ error('should not call Pattern constructor');
+ }
- constructSampledFromIR: function PDFFunction_constructSampledFromIR(IR) {
- // See chapter 3, page 109 of the PDF reference
- function interpolate(x, xmin, xmax, ymin, ymax) {
- return ymin + ((x - xmin) * ((ymax - ymin) / (xmax - xmin)));
- }
+ Pattern.prototype = {
+ // Input: current Canvas context
+ // Output: the appropriate fillStyle or strokeStyle
+ getPattern: function Pattern_getPattern(ctx) {
+ error('Should not call Pattern.getStyle: ' + ctx);
+ }
+ };
- return function constructSampledFromIRResult(args) {
- // See chapter 3, page 110 of the PDF reference.
- var m = IR[1];
- var domain = IR[2];
- var encode = IR[3];
- var decode = IR[4];
- var samples = IR[5];
- var size = IR[6];
- var n = IR[7];
- var mask = IR[8];
- var range = IR[9];
+ Pattern.shadingFromIR = function Pattern_shadingFromIR(raw) {
+ return Shadings[raw[0]].fromIR(raw);
+ };
- if (m != args.length)
- error('Incorrect number of arguments: ' + m + ' != ' +
- args.length);
+ Pattern.parseShading = function Pattern_parseShading(shading, matrix, xref,
+ res) {
- var x = args;
+ var dict = isStream(shading) ? shading.dict : shading;
+ var type = dict.get('ShadingType');
- // Building the cube vertices: its part and sample index
- // http://rjwagner49.com/Mathematics/Interpolation.pdf
- var cubeVertices = 1 << m;
- var cubeN = new Float64Array(cubeVertices);
- var cubeVertex = new Uint32Array(cubeVertices);
- for (var j = 0; j < cubeVertices; j++)
- cubeN[j] = 1;
+ switch (type) {
+ case PatternType.AXIAL:
+ case PatternType.RADIAL:
+ // Both radial and axial shadings are handled by RadialAxial shading.
+ return new Shadings.RadialAxial(dict, matrix, xref, res);
+ default:
+ UnsupportedManager.notify(UNSUPPORTED_FEATURES.shadingPattern);
+ return new Shadings.Dummy();
+ }
+ };
+ return Pattern;
+})();
- var k = n, pos = 1;
- // Map x_i to y_j for 0 <= i < m using the sampled function.
- for (var i = 0; i < m; ++i) {
- // x_i' = min(max(x_i, Domain_2i), Domain_2i+1)
- var domain_2i = domain[i][0];
- var domain_2i_1 = domain[i][1];
- var xi = Math.min(Math.max(x[i], domain_2i), domain_2i_1);
+var Shadings = {};
- // e_i = Interpolate(x_i', Domain_2i, Domain_2i+1,
- // Encode_2i, Encode_2i+1)
- var e = interpolate(xi, domain_2i, domain_2i_1,
- encode[i][0], encode[i][1]);
+// A small number to offset the first/last color stops so we can insert ones to
+// support extend. Number.MIN_VALUE appears to be too small and breaks the
+// extend. 1e-7 works in FF but chrome seems to use an even smaller sized number
+// internally so we have to go bigger.
+Shadings.SMALL_NUMBER = 1e-2;
- // e_i' = min(max(e_i, 0), Size_i - 1)
- var size_i = size[i];
- e = Math.min(Math.max(e, 0), size_i - 1);
+// Radial and axial shading have very similar implementations
+// If needed, the implementations can be broken into two classes
+Shadings.RadialAxial = (function RadialAxialClosure() {
+ function RadialAxial(dict, matrix, xref, res, ctx) {
+ this.matrix = matrix;
+ this.coordsArr = dict.get('Coords');
+ this.shadingType = dict.get('ShadingType');
+ this.type = 'Pattern';
+ this.ctx = ctx;
+ var cs = dict.get('ColorSpace', 'CS');
+ cs = ColorSpace.parse(cs, xref, res);
+ this.cs = cs;
- // Adjusting the cube: N and vertex sample index
- var e0 = e < size_i - 1 ? Math.floor(e) : e - 1; // e1 = e0 + 1;
- var n0 = e0 + 1 - e; // (e1 - e) / (e1 - e0);
- var n1 = e - e0; // (e - e0) / (e1 - e0);
- var offset0 = e0 * k;
- var offset1 = offset0 + k; // e1 * k
- for (var j = 0; j < cubeVertices; j++) {
- if (j & pos) {
- cubeN[j] *= n1;
- cubeVertex[j] += offset1;
- } else {
- cubeN[j] *= n0;
- cubeVertex[j] += offset0;
- }
- }
+ var t0 = 0.0, t1 = 1.0;
+ if (dict.has('Domain')) {
+ var domainArr = dict.get('Domain');
+ t0 = domainArr[0];
+ t1 = domainArr[1];
+ }
- k *= size_i;
- pos <<= 1;
- }
+ var extendStart = false, extendEnd = false;
+ if (dict.has('Extend')) {
+ var extendArr = dict.get('Extend');
+ extendStart = extendArr[0];
+ extendEnd = extendArr[1];
+ }
- var y = new Float64Array(n);
- for (var j = 0; j < n; ++j) {
- // Sum all cube vertices' samples portions
- var rj = 0;
- for (var i = 0; i < cubeVertices; i++)
- rj += samples[cubeVertex[i] + j] * cubeN[i];
+ if (this.shadingType === PatternType.RADIAL &&
+ (!extendStart || !extendEnd)) {
+ // Radial gradient only currently works if either circle is fully within
+ // the other circle.
+ var x1 = this.coordsArr[0];
+ var y1 = this.coordsArr[1];
+ var r1 = this.coordsArr[2];
+ var x2 = this.coordsArr[3];
+ var y2 = this.coordsArr[4];
+ var r2 = this.coordsArr[5];
+ var distance = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
+ if (r1 <= r2 + distance &&
+ r2 <= r1 + distance) {
+ warn('Unsupported radial gradient.');
+ }
+ }
- // r_j' = Interpolate(r_j, 0, 2^BitsPerSample - 1,
- // Decode_2j, Decode_2j+1)
- rj = interpolate(rj, 0, 1, decode[j][0], decode[j][1]);
+ this.extendStart = extendStart;
+ this.extendEnd = extendEnd;
- // y_j = min(max(r_j, range_2j), range_2j+1)
- y[j] = Math.min(Math.max(rj, range[j][0]), range[j][1]);
+ var fnObj = dict.get('Function');
+ var fn;
+ if (isArray(fnObj)) {
+ var fnArray = [];
+ for (var j = 0, jj = fnObj.length; j < jj; j++) {
+ var obj = xref.fetchIfRef(fnObj[j]);
+ if (!isPDFFunction(obj)) {
+ error('Invalid function');
}
-
- return y;
+ fnArray.push(PDFFunction.parse(xref, obj));
+ }
+ fn = function radialAxialColorFunction(arg) {
+ var out = [];
+ for (var i = 0, ii = fnArray.length; i < ii; i++) {
+ out.push(fnArray[i](arg)[0]);
+ }
+ return out;
};
- },
-
- constructInterpolated: function PDFFunction_constructInterpolated(str,
- dict) {
- var c0 = dict.get('C0') || [0];
- var c1 = dict.get('C1') || [1];
- var n = dict.get('N');
+ } else {
+ if (!isPDFFunction(fnObj)) {
+ error('Invalid function');
+ }
+ fn = PDFFunction.parse(xref, fnObj);
+ }
- if (!isArray(c0) || !isArray(c1))
- error('Illegal dictionary for interpolated function');
+ // 10 samples seems good enough for now, but probably won't work
+ // if there are sharp color changes. Ideally, we would implement
+ // the spec faithfully and add lossless optimizations.
+ var diff = t1 - t0;
+ var step = diff / 10;
- var length = c0.length;
- var diff = [];
- for (var i = 0; i < length; ++i)
- diff.push(c1[i] - c0[i]);
+ var colorStops = this.colorStops = [];
- return [CONSTRUCT_INTERPOLATED, c0, diff, n];
- },
+ // Protect against bad domains so we don't end up in an infinte loop below.
+ if (t0 >= t1 || step <= 0) {
+ // Acrobat doesn't seem to handle these cases so we'll ignore for
+ // now.
+ info('Bad shading domain.');
+ return;
+ }
- constructInterpolatedFromIR:
- function PDFFunction_constructInterpolatedFromIR(IR) {
- var c0 = IR[1];
- var diff = IR[2];
- var n = IR[3];
+ for (var i = t0; i <= t1; i += step) {
+ var rgbColor = cs.getRgb(fn([i]), 0);
+ var cssColor = Util.makeCssRgb(rgbColor);
+ colorStops.push([(i - t0) / diff, cssColor]);
+ }
- var length = diff.length;
+ var background = 'transparent';
+ if (dict.has('Background')) {
+ var rgbColor = cs.getRgb(dict.get('Background'), 0);
+ background = Util.makeCssRgb(rgbColor);
+ }
- return function constructInterpolatedFromIRResult(args) {
- var x = n == 1 ? args[0] : Math.pow(args[0], n);
+ if (!extendStart) {
+ // Insert a color stop at the front and offset the first real color stop
+ // so it doesn't conflict with the one we insert.
+ colorStops.unshift([0, background]);
+ colorStops[1][0] += Shadings.SMALL_NUMBER;
+ }
+ if (!extendEnd) {
+ // Same idea as above in extendStart but for the end.
+ colorStops[colorStops.length - 1][0] -= Shadings.SMALL_NUMBER;
+ colorStops.push([1, background]);
+ }
- var out = [];
- for (var j = 0; j < length; ++j)
- out.push(c0[j] + (x * diff[j]));
+ this.colorStops = colorStops;
+ }
- return out;
+ RadialAxial.fromIR = function RadialAxial_fromIR(raw) {
+ var type = raw[1];
+ var colorStops = raw[2];
+ var p0 = raw[3];
+ var p1 = raw[4];
+ var r0 = raw[5];
+ var r1 = raw[6];
+ return {
+ type: 'Pattern',
+ getPattern: function RadialAxial_getPattern(ctx) {
+ var grad;
+ if (type == PatternType.AXIAL)
+ grad = ctx.createLinearGradient(p0[0], p0[1], p1[0], p1[1]);
+ else if (type == PatternType.RADIAL)
+ grad = ctx.createRadialGradient(p0[0], p0[1], r0, p1[0], p1[1], r1);
- };
- },
+ for (var i = 0, ii = colorStops.length; i < ii; ++i) {
+ var c = colorStops[i];
+ grad.addColorStop(c[0], c[1]);
+ }
+ return grad;
+ }
+ };
+ };
- constructStiched: function PDFFunction_constructStiched(fn, dict, xref) {
- var domain = dict.get('Domain');
+ RadialAxial.prototype = {
+ getIR: function RadialAxial_getIR() {
+ var coordsArr = this.coordsArr;
+ var type = this.shadingType;
+ if (type == PatternType.AXIAL) {
+ var p0 = [coordsArr[0], coordsArr[1]];
+ var p1 = [coordsArr[2], coordsArr[3]];
+ var r0 = null;
+ var r1 = null;
+ } else if (type == PatternType.RADIAL) {
+ var p0 = [coordsArr[0], coordsArr[1]];
+ var p1 = [coordsArr[3], coordsArr[4]];
+ var r0 = coordsArr[2];
+ var r1 = coordsArr[5];
+ } else {
+ error('getPattern type unknown: ' + type);
+ }
- if (!domain)
- error('No domain');
+ var matrix = this.matrix;
+ if (matrix) {
+ p0 = Util.applyTransform(p0, matrix);
+ p1 = Util.applyTransform(p1, matrix);
+ }
- var inputSize = domain.length / 2;
- if (inputSize != 1)
- error('Bad domain for stiched function');
+ return ['RadialAxial', type, this.colorStops, p0, p1, r0, r1];
+ }
+ };
- var fnRefs = dict.get('Functions');
- var fns = [];
- for (var i = 0, ii = fnRefs.length; i < ii; ++i)
- fns.push(PDFFunction.getIR(xref, xref.fetchIfRef(fnRefs[i])));
+ return RadialAxial;
+})();
+
+Shadings.Dummy = (function DummyClosure() {
+ function Dummy() {
+ this.type = 'Pattern';
+ }
+
+ Dummy.fromIR = function Dummy_fromIR() {
+ return {
+ type: 'Pattern',
+ getPattern: function Dummy_fromIR_getPattern() {
+ return 'hotpink';
+ }
+ };
+ };
+
+ Dummy.prototype = {
+ getIR: function Dummy_getIR() {
+ return ['Dummy'];
+ }
+ };
+ return Dummy;
+})();
+
+var TilingPattern = (function TilingPatternClosure() {
+ var PaintType = {
+ COLORED: 1,
+ UNCOLORED: 2
+ };
+
+ var MAX_PATTERN_SIZE = 3000; // 10in @ 300dpi shall be enough
+
+ function TilingPattern(IR, color, ctx, objs, commonObjs, baseTransform) {
+ this.name = IR[1][0].name;
+ this.operatorList = IR[2];
+ this.matrix = IR[3] || [1, 0, 0, 1, 0, 0];
+ this.bbox = IR[4];
+ this.xstep = IR[5];
+ this.ystep = IR[6];
+ this.paintType = IR[7];
+ this.tilingType = IR[8];
+ this.color = color;
+ this.objs = objs;
+ this.commonObjs = commonObjs;
+ this.baseTransform = baseTransform;
+ this.type = 'Pattern';
+ this.ctx = ctx;
+ }
+
+ TilingPattern.getIR = function TilingPattern_getIR(operatorList, dict, args) {
+ var matrix = dict.get('Matrix');
+ var bbox = dict.get('BBox');
+ var xstep = dict.get('XStep');
+ var ystep = dict.get('YStep');
+ var paintType = dict.get('PaintType');
+ var tilingType = dict.get('TilingType');
+
+ return [
+ 'TilingPattern', args, operatorList, matrix, bbox, xstep, ystep,
+ paintType, tilingType
+ ];
+ };
+
+ TilingPattern.prototype = {
+ createPatternCanvas: function TilinPattern_createPatternCanvas(owner) {
+ var operatorList = this.operatorList;
+ var bbox = this.bbox;
+ var xstep = this.xstep;
+ var ystep = this.ystep;
+ var paintType = this.paintType;
+ var tilingType = this.tilingType;
+ var color = this.color;
+ var objs = this.objs;
+ var commonObjs = this.commonObjs;
+ var ctx = this.ctx;
+
+ info('TilingType: ' + tilingType);
+
+ var x0 = bbox[0], y0 = bbox[1], x1 = bbox[2], y1 = bbox[3];
+
+ var topLeft = [x0, y0];
+ // we want the canvas to be as large as the step size
+ var botRight = [x0 + xstep, y0 + ystep];
+
+ var width = botRight[0] - topLeft[0];
+ var height = botRight[1] - topLeft[1];
+
+ // Obtain scale from matrix and current transformation matrix.
+ var matrixScale = Util.singularValueDecompose2dScale(this.matrix);
+ var curMatrixScale = Util.singularValueDecompose2dScale(
+ this.baseTransform);
+ var combinedScale = [matrixScale[0] * curMatrixScale[0],
+ matrixScale[1] * curMatrixScale[1]];
+
+ // MAX_PATTERN_SIZE is used to avoid OOM situation.
+ // Use width and height values that are as close as possible to the end
+ // result when the pattern is used. Too low value makes the pattern look
+ // blurry. Too large value makes it look too crispy.
+ width = Math.min(Math.ceil(Math.abs(width * combinedScale[0])),
+ MAX_PATTERN_SIZE);
+
+ height = Math.min(Math.ceil(Math.abs(height * combinedScale[1])),
+ MAX_PATTERN_SIZE);
+
+ var tmpCanvas = CachedCanvases.getCanvas('pattern', width, height, true);
+ var tmpCtx = tmpCanvas.context;
+ var graphics = new CanvasGraphics(tmpCtx, commonObjs, objs);
+ graphics.groupLevel = owner.groupLevel;
+
+ this.setFillAndStrokeStyleToContext(tmpCtx, paintType, color);
+
+ this.setScale(width, height, xstep, ystep);
+ this.transformToScale(graphics);
+
+ // transform coordinates to pattern space
+ var tmpTranslate = [1, 0, 0, 1, -topLeft[0], -topLeft[1]];
+ graphics.transform.apply(graphics, tmpTranslate);
+
+ this.clipBbox(graphics, bbox, x0, y0, x1, y1);
+
+ graphics.executeOperatorList(operatorList);
+ return tmpCanvas.canvas;
+ },
+
+ setScale: function TilingPattern_setScale(width, height, xstep, ystep) {
+ this.scale = [width / xstep, height / ystep];
+ },
+
+ transformToScale: function TilingPattern_transformToScale(graphics) {
+ var scale = this.scale;
+ var tmpScale = [scale[0], 0, 0, scale[1], 0, 0];
+ graphics.transform.apply(graphics, tmpScale);
+ },
+
+ scaleToContext: function TilingPattern_scaleToContext() {
+ var scale = this.scale;
+ this.ctx.scale(1 / scale[0], 1 / scale[1]);
+ },
+
+ clipBbox: function clipBbox(graphics, bbox, x0, y0, x1, y1) {
+ if (bbox && isArray(bbox) && 4 == bbox.length) {
+ var bboxWidth = x1 - x0;
+ var bboxHeight = y1 - y0;
+ graphics.rectangle(x0, y0, bboxWidth, bboxHeight);
+ graphics.clip();
+ graphics.endPath();
+ }
+ },
+
+ setFillAndStrokeStyleToContext:
+ function setFillAndStrokeStyleToContext(context, paintType, color) {
+ switch (paintType) {
+ case PaintType.COLORED:
+ var ctx = this.ctx;
+ context.fillStyle = ctx.fillStyle;
+ context.strokeStyle = ctx.strokeStyle;
+ break;
+ case PaintType.UNCOLORED:
+ var rgbColor = ColorSpace.singletons.rgb.getRgb(color, 0);
+ var cssColor = Util.makeCssRgb(rgbColor);
+ context.fillStyle = cssColor;
+ context.strokeStyle = cssColor;
+ break;
+ default:
+ error('Unsupported paint type: ' + paintType);
+ }
+ },
+
+ getPattern: function TilingPattern_getPattern(ctx, owner) {
+ var temporaryPatternCanvas = this.createPatternCanvas(owner);
+
+ var ctx = this.ctx;
+ ctx.setTransform.apply(ctx, this.baseTransform);
+ ctx.transform.apply(ctx, this.matrix);
+ this.scaleToContext();
+
+ return ctx.createPattern(temporaryPatternCanvas, 'repeat');
+ }
+ };
+
+ return TilingPattern;
+})();
+
+
+
+var PDFFunction = (function PDFFunctionClosure() {
+ var CONSTRUCT_SAMPLED = 0;
+ var CONSTRUCT_INTERPOLATED = 2;
+ var CONSTRUCT_STICHED = 3;
+ var CONSTRUCT_POSTSCRIPT = 4;
+
+ return {
+ getSampleArray: function PDFFunction_getSampleArray(size, outputSize, bps,
+ str) {
+ var length = 1;
+ for (var i = 0, ii = size.length; i < ii; i++)
+ length *= size[i];
+ length *= outputSize;
+
+ var array = [];
+ var codeSize = 0;
+ var codeBuf = 0;
+ // 32 is a valid bps so shifting won't work
+ var sampleMul = 1.0 / (Math.pow(2.0, bps) - 1);
+
+ var strBytes = str.getBytes((length * bps + 7) / 8);
+ var strIdx = 0;
+ for (var i = 0; i < length; i++) {
+ while (codeSize < bps) {
+ codeBuf <<= 8;
+ codeBuf |= strBytes[strIdx++];
+ codeSize += 8;
+ }
+ codeSize -= bps;
+ array.push((codeBuf >> codeSize) * sampleMul);
+ codeBuf &= (1 << codeSize) - 1;
+ }
+ return array;
+ },
+
+ getIR: function PDFFunction_getIR(xref, fn) {
+ var dict = fn.dict;
+ if (!dict)
+ dict = fn;
+
+ var types = [this.constructSampled,
+ null,
+ this.constructInterpolated,
+ this.constructStiched,
+ this.constructPostScript];
+
+ var typeNum = dict.get('FunctionType');
+ var typeFn = types[typeNum];
+ if (!typeFn)
+ error('Unknown type of function');
+
+ return typeFn.call(this, fn, dict, xref);
+ },
+
+ fromIR: function PDFFunction_fromIR(IR) {
+ var type = IR[0];
+ switch (type) {
+ case CONSTRUCT_SAMPLED:
+ return this.constructSampledFromIR(IR);
+ case CONSTRUCT_INTERPOLATED:
+ return this.constructInterpolatedFromIR(IR);
+ case CONSTRUCT_STICHED:
+ return this.constructStichedFromIR(IR);
+ //case CONSTRUCT_POSTSCRIPT:
+ default:
+ return this.constructPostScriptFromIR(IR);
+ }
+ },
+
+ parse: function PDFFunction_parse(xref, fn) {
+ var IR = this.getIR(xref, fn);
+ return this.fromIR(IR);
+ },
+
+ constructSampled: function PDFFunction_constructSampled(str, dict) {
+ function toMultiArray(arr) {
+ var inputLength = arr.length;
+ var outputLength = arr.length / 2;
+ var out = [];
+ var index = 0;
+ for (var i = 0; i < inputLength; i += 2) {
+ out[index] = [arr[i], arr[i + 1]];
+ ++index;
+ }
+ return out;
+ }
+ var domain = dict.get('Domain');
+ var range = dict.get('Range');
+
+ if (!domain || !range)
+ error('No domain or range');
+
+ var inputSize = domain.length / 2;
+ var outputSize = range.length / 2;
+
+ domain = toMultiArray(domain);
+ range = toMultiArray(range);
+
+ var size = dict.get('Size');
+ var bps = dict.get('BitsPerSample');
+ var order = dict.get('Order') || 1;
+ if (order !== 1) {
+ // No description how cubic spline interpolation works in PDF32000:2008
+ // As in poppler, ignoring order, linear interpolation may work as good
+ info('No support for cubic spline interpolation: ' + order);
+ }
+
+ var encode = dict.get('Encode');
+ if (!encode) {
+ encode = [];
+ for (var i = 0; i < inputSize; ++i) {
+ encode.push(0);
+ encode.push(size[i] - 1);
+ }
+ }
+ encode = toMultiArray(encode);
+
+ var decode = dict.get('Decode');
+ if (!decode)
+ decode = range;
+ else
+ decode = toMultiArray(decode);
+
+ var samples = this.getSampleArray(size, outputSize, bps, str);
+
+ return [
+ CONSTRUCT_SAMPLED, inputSize, domain, encode, decode, samples, size,
+ outputSize, Math.pow(2, bps) - 1, range
+ ];
+ },
+
+ constructSampledFromIR: function PDFFunction_constructSampledFromIR(IR) {
+ // See chapter 3, page 109 of the PDF reference
+ function interpolate(x, xmin, xmax, ymin, ymax) {
+ return ymin + ((x - xmin) * ((ymax - ymin) / (xmax - xmin)));
+ }
+
+ return function constructSampledFromIRResult(args) {
+ // See chapter 3, page 110 of the PDF reference.
+ var m = IR[1];
+ var domain = IR[2];
+ var encode = IR[3];
+ var decode = IR[4];
+ var samples = IR[5];
+ var size = IR[6];
+ var n = IR[7];
+ var mask = IR[8];
+ var range = IR[9];
+
+ if (m != args.length)
+ error('Incorrect number of arguments: ' + m + ' != ' +
+ args.length);
+
+ var x = args;
+
+ // Building the cube vertices: its part and sample index
+ // http://rjwagner49.com/Mathematics/Interpolation.pdf
+ var cubeVertices = 1 << m;
+ var cubeN = new Float64Array(cubeVertices);
+ var cubeVertex = new Uint32Array(cubeVertices);
+ for (var j = 0; j < cubeVertices; j++)
+ cubeN[j] = 1;
+
+ var k = n, pos = 1;
+ // Map x_i to y_j for 0 <= i < m using the sampled function.
+ for (var i = 0; i < m; ++i) {
+ // x_i' = min(max(x_i, Domain_2i), Domain_2i+1)
+ var domain_2i = domain[i][0];
+ var domain_2i_1 = domain[i][1];
+ var xi = Math.min(Math.max(x[i], domain_2i), domain_2i_1);
+
+ // e_i = Interpolate(x_i', Domain_2i, Domain_2i+1,
+ // Encode_2i, Encode_2i+1)
+ var e = interpolate(xi, domain_2i, domain_2i_1,
+ encode[i][0], encode[i][1]);
+
+ // e_i' = min(max(e_i, 0), Size_i - 1)
+ var size_i = size[i];
+ e = Math.min(Math.max(e, 0), size_i - 1);
+
+ // Adjusting the cube: N and vertex sample index
+ var e0 = e < size_i - 1 ? Math.floor(e) : e - 1; // e1 = e0 + 1;
+ var n0 = e0 + 1 - e; // (e1 - e) / (e1 - e0);
+ var n1 = e - e0; // (e - e0) / (e1 - e0);
+ var offset0 = e0 * k;
+ var offset1 = offset0 + k; // e1 * k
+ for (var j = 0; j < cubeVertices; j++) {
+ if (j & pos) {
+ cubeN[j] *= n1;
+ cubeVertex[j] += offset1;
+ } else {
+ cubeN[j] *= n0;
+ cubeVertex[j] += offset0;
+ }
+ }
+
+ k *= size_i;
+ pos <<= 1;
+ }
+
+ var y = new Float64Array(n);
+ for (var j = 0; j < n; ++j) {
+ // Sum all cube vertices' samples portions
+ var rj = 0;
+ for (var i = 0; i < cubeVertices; i++)
+ rj += samples[cubeVertex[i] + j] * cubeN[i];
+
+ // r_j' = Interpolate(r_j, 0, 2^BitsPerSample - 1,
+ // Decode_2j, Decode_2j+1)
+ rj = interpolate(rj, 0, 1, decode[j][0], decode[j][1]);
+
+ // y_j = min(max(r_j, range_2j), range_2j+1)
+ y[j] = Math.min(Math.max(rj, range[j][0]), range[j][1]);
+ }
+
+ return y;
+ };
+ },
+
+ constructInterpolated: function PDFFunction_constructInterpolated(str,
+ dict) {
+ var c0 = dict.get('C0') || [0];
+ var c1 = dict.get('C1') || [1];
+ var n = dict.get('N');
+
+ if (!isArray(c0) || !isArray(c1))
+ error('Illegal dictionary for interpolated function');
+
+ var length = c0.length;
+ var diff = [];
+ for (var i = 0; i < length; ++i)
+ diff.push(c1[i] - c0[i]);
+
+ return [CONSTRUCT_INTERPOLATED, c0, diff, n];
+ },
+
+ constructInterpolatedFromIR:
+ function PDFFunction_constructInterpolatedFromIR(IR) {
+ var c0 = IR[1];
+ var diff = IR[2];
+ var n = IR[3];
+
+ var length = diff.length;
+
+ return function constructInterpolatedFromIRResult(args) {
+ var x = n == 1 ? args[0] : Math.pow(args[0], n);
+
+ var out = [];
+ for (var j = 0; j < length; ++j)
+ out.push(c0[j] + (x * diff[j]));
+
+ return out;
+
+ };
+ },
+
+ constructStiched: function PDFFunction_constructStiched(fn, dict, xref) {
+ var domain = dict.get('Domain');
+
+ if (!domain)
+ error('No domain');
+
+ var inputSize = domain.length / 2;
+ if (inputSize != 1)
+ error('Bad domain for stiched function');
+
+ var fnRefs = dict.get('Functions');
+ var fns = [];
+ for (var i = 0, ii = fnRefs.length; i < ii; ++i)
+ fns.push(PDFFunction.getIR(xref, xref.fetchIfRef(fnRefs[i])));
var bounds = dict.get('Bounds');
var encode = dict.get('Encode');
@@ -2475,6 +3538,29 @@ var Annotation = (function AnnotationClosure() {
} else {
var borderArray = dict.get('Border') || [0, 0, 1];
data.borderWidth = borderArray[2] || 0;
+
+ // TODO: implement proper support for annotations with line dash patterns.
+ var dashArray = borderArray[3];
+ if (dashArray && isArray(dashArray)) {
+ var dashArrayLength = dashArray.length;
+ if (dashArrayLength > 0) {
+ // According to the PDF specification: the elements in a dashArray
+ // shall be numbers that are nonnegative and not all equal to zero.
+ var isInvalid = false;
+ var numPositive = 0;
+ for (var i = 0; i < dashArrayLength; i++) {
+ if (!(+dashArray[i] >= 0)) {
+ isInvalid = true;
+ break;
+ } else if (dashArray[i] > 0) {
+ numPositive++;
+ }
+ }
+ if (isInvalid || numPositive === 0) {
+ data.borderWidth = 0;
+ }
+ }
+ }
}
this.appearance = getDefaultAppearance(dict);
@@ -2519,7 +3605,7 @@ var Annotation = (function AnnotationClosure() {
},
loadResources: function(keys) {
- var promise = new Promise();
+ var promise = new LegacyPromise();
this.appearance.dict.getAsync('Resources').then(function(resources) {
if (!resources) {
promise.resolve();
@@ -2538,7 +3624,7 @@ var Annotation = (function AnnotationClosure() {
getOperatorList: function Annotation_getToOperatorList(evaluator) {
- var promise = new Promise();
+ var promise = new LegacyPromise();
if (!this.appearance) {
promise.resolve(new OperatorList());
@@ -2566,9 +3652,9 @@ var Annotation = (function AnnotationClosure() {
resourcesPromise.then(function(resources) {
var opList = new OperatorList();
- opList.addOp('beginAnnotation', [data.rect, transform, matrix]);
+ opList.addOp(OPS.beginAnnotation, [data.rect, transform, matrix]);
evaluator.getOperatorList(this.appearance, resources, opList);
- opList.addOp('endAnnotation', []);
+ opList.addOp(OPS.endAnnotation, []);
promise.resolve(opList);
}.bind(this));
@@ -2644,7 +3730,7 @@ var Annotation = (function AnnotationClosure() {
if (annotation.isViewable()) {
return annotation;
} else {
- TODO('unimplemented annotation type: ' + subtype);
+ warn('unimplemented annotation type: ' + subtype);
}
};
@@ -2655,19 +3741,19 @@ var Annotation = (function AnnotationClosure() {
annotationsReadyPromise.reject(e);
}
- var annotationsReadyPromise = new Promise();
+ var annotationsReadyPromise = new LegacyPromise();
var annotationPromises = [];
for (var i = 0, n = annotations.length; i < n; ++i) {
annotationPromises.push(annotations[i].getOperatorList(partialEvaluator));
}
Promise.all(annotationPromises).then(function(datas) {
- opList.addOp('beginAnnotations', []);
+ opList.addOp(OPS.beginAnnotations, []);
for (var i = 0, n = datas.length; i < n; ++i) {
var annotOpList = datas[i];
opList.addOpList(annotOpList);
}
- opList.addOp('endAnnotations', []);
+ opList.addOp(OPS.endAnnotations, []);
annotationsReadyPromise.resolve();
}, reject);
@@ -2736,7 +3822,7 @@ var WidgetAnnotation = (function WidgetAnnotationClosure() {
Util.inherit(WidgetAnnotation, Annotation, {
isViewable: function WidgetAnnotation_isViewable() {
if (this.data.fieldType === 'Sig') {
- TODO('unimplemented annotation type: Widget signature');
+ warn('unimplemented annotation type: Widget signature');
return false;
}
@@ -2817,7 +3903,7 @@ var TextWidgetAnnotation = (function TextWidgetAnnotationClosure() {
return Annotation.prototype.getOperatorList.call(this, evaluator);
}
- var promise = new Promise();
+ var promise = new LegacyPromise();
var opList = new OperatorList();
var data = this.data;
@@ -2843,10 +3929,10 @@ var TextWidgetAnnotation = (function TextWidgetAnnotationClosure() {
data.rgb = [0, 0, 0];
// TODO THIS DOESN'T MAKE ANY SENSE SINCE THE fnArray IS EMPTY!
for (var i = 0, n = fnArray.length; i < n; ++i) {
- var fnName = appearanceFnArray[i];
+ var fnId = appearanceFnArray[i];
var args = appearanceArgsArray[i];
- if (fnName === 'setFont') {
+ if (fnId === OPS.setFont) {
data.fontRefName = args[0];
var size = args[1];
if (size < 0) {
@@ -2856,9 +3942,9 @@ var TextWidgetAnnotation = (function TextWidgetAnnotationClosure() {
data.fontDirection = 1;
data.fontSize = size;
}
- } else if (fnName === 'setFillRGBColor') {
+ } else if (fnId === OPS.setFillRGBColor) {
data.rgb = args;
- } else if (fnName === 'setFillGray') {
+ } else if (fnId === OPS.setFillGray) {
var rgbValue = args[0] * 255;
data.rgb = [rgbValue, rgbValue, rgbValue];
}
@@ -2894,7 +3980,7 @@ var TextAnnotation = (function TextAnnotationClosure() {
Util.inherit(TextAnnotation, Annotation, {
getOperatorList: function TextAnnotation_getOperatorList(evaluator) {
- var promise = new Promise();
+ var promise = new LegacyPromise();
promise.resolve(new OperatorList());
return promise;
},
@@ -2994,7 +4080,7 @@ var LinkAnnotation = (function LinkAnnotationClosure() {
if (action) {
var linkType = action.get('S').name;
if (linkType === 'URI') {
- var url = action.get('URI');
+ var url = addDefaultProtocolToUrl(action.get('URI'));
// TODO: pdf spec mentions urls can be relative to a Base
// entry in the dictionary.
if (!isValidUrl(url, false)) {
@@ -3021,7 +4107,7 @@ var LinkAnnotation = (function LinkAnnotationClosure() {
} else if (linkType === 'Named') {
data.action = action.get('N').name;
} else {
- TODO('unrecognized link type: ' + linkType);
+ warn('unrecognized link type: ' + linkType);
}
} else if (dict.has('Dest')) {
// simple destination link
@@ -3030,6 +4116,14 @@ var LinkAnnotation = (function LinkAnnotationClosure() {
}
}
+ // Lets URLs beginning with 'www.' default to using the 'http://' protocol.
+ function addDefaultProtocolToUrl(url) {
+ if (url.indexOf('www.') === 0) {
+ return ('http://' + url);
+ }
+ return url;
+ }
+
Util.inherit(LinkAnnotation, Annotation, {
hasOperatorList: function LinkAnnotation_hasOperatorList() {
return false;
@@ -3078,6 +4172,7 @@ var NetworkManager = (function NetworkManagerClosure() {
this.url = url;
args = args || {};
this.httpHeaders = args.httpHeaders || {};
+ this.withCredentials = args.withCredentials || false;
this.getXhr = args.getXhr ||
function NetworkManager_getXhr() {
return new XMLHttpRequest();
@@ -3126,6 +4221,7 @@ var NetworkManager = (function NetworkManagerClosure() {
};
xhr.open('GET', this.url);
+ xhr.withCredentials = this.withCredentials;
for (var property in this.httpHeaders) {
var value = this.httpHeaders[property];
if (typeof value === 'undefined') {
@@ -3278,6 +4374,7 @@ var ChunkedStream = (function ChunkedStreamClosure() {
this.numChunksLoaded = 0;
this.numChunks = Math.ceil(length / chunkSize);
this.manager = manager;
+ this.initialDataLength = 0;
}
// required methods for a stream. if a particular stream does not
@@ -3325,11 +4422,26 @@ var ChunkedStream = (function ChunkedStreamClosure() {
}
},
+ onReceiveInitialData: function (data) {
+ this.bytes.set(data);
+ this.initialDataLength = data.length;
+ var endChunk = this.end === data.length ?
+ this.numChunks : Math.floor(data.length / this.chunkSize);
+ for (var i = 0; i < endChunk; i++) {
+ this.loadedChunks[i] = true;
+ ++this.numChunksLoaded;
+ }
+ },
+
ensureRange: function ChunkedStream_ensureRange(begin, end) {
if (begin >= end) {
return;
}
+ if (end <= this.initialDataLength) {
+ return;
+ }
+
var chunkSize = this.chunkSize;
var beginChunk = Math.floor(begin / chunkSize);
var endChunk = Math.floor((end - 1) / chunkSize) + 1;
@@ -3470,7 +4582,8 @@ var ChunkedStreamManager = (function ChunkedStreamManagerClosure() {
};
this.networkManager = new NetworkManager(this.url, {
getXhr: getXhr,
- httpHeaders: args.httpHeaders
+ httpHeaders: args.httpHeaders,
+ withCredentials: args.withCredentials
});
this.sendRequest = function ChunkedStreamManager_sendRequest(begin, end) {
this.networkManager.requestRange(begin, end, {
@@ -3486,11 +4599,26 @@ var ChunkedStreamManager = (function ChunkedStreamManagerClosure() {
this.requestsByChunk = {};
this.callbacksByRequest = {};
- this.loadedStream = new Promise();
+ this.loadedStream = new LegacyPromise();
+ if (args.initialData) {
+ this.setInitialData(args.initialData);
+ }
}
ChunkedStreamManager.prototype = {
+ setInitialData: function ChunkedStreamManager_setInitialData(data) {
+ this.stream.onReceiveInitialData(data);
+ if (this.stream.allChunksLoaded()) {
+ this.loadedStream.resolve(this.stream);
+ } else if (this.msgHandler) {
+ this.msgHandler.send('DocProgress', {
+ loaded: data.length,
+ total: this.length
+ });
+ }
+ },
+
onLoadedStream: function ChunkedStreamManager_getLoadedStream() {
return this.loadedStream;
},
@@ -3592,16 +4720,16 @@ var ChunkedStreamManager = (function ChunkedStreamManagerClosure() {
// chunks as possible
groupChunks: function ChunkedStreamManager_groupChunks(chunks) {
var groupedChunks = [];
- var beginChunk;
- var prevChunk;
+ var beginChunk = -1;
+ var prevChunk = -1;
for (var i = 0; i < chunks.length; ++i) {
var chunk = chunks[i];
- if (!beginChunk) {
+ if (beginChunk < 0) {
beginChunk = chunk;
}
- if (prevChunk && prevChunk + 1 !== chunk) {
+ if (prevChunk >= 0 && prevChunk + 1 !== chunk) {
groupedChunks.push({
beginChunk: beginChunk, endChunk: prevChunk + 1});
beginChunk = chunk;
@@ -3747,6 +4875,10 @@ var BasePdfManager = (function BasePdfManagerClosure() {
return this.pdfModel.getPage(pageIndex);
},
+ cleanup: function BasePdfManager_cleanup() {
+ return this.pdfModel.cleanup();
+ },
+
ensure: function BasePdfManager_ensure(obj, prop, args) {
return new NotImplementedException();
},
@@ -3778,7 +4910,7 @@ var LocalPdfManager = (function LocalPdfManagerClosure() {
function LocalPdfManager(data, password) {
var stream = new Stream(data);
this.pdfModel = new PDFDocument(this, stream, password);
- this.loadedStream = new Promise();
+ this.loadedStream = new LegacyPromise();
this.loadedStream.resolve(stream);
}
@@ -3787,7 +4919,7 @@ var LocalPdfManager = (function LocalPdfManagerClosure() {
LocalPdfManager.prototype.ensure =
function LocalPdfManager_ensure(obj, prop, args) {
- var promise = new Promise();
+ var promise = new LegacyPromise();
try {
var value = obj[prop];
var result;
@@ -3806,7 +4938,7 @@ var LocalPdfManager = (function LocalPdfManagerClosure() {
LocalPdfManager.prototype.requestRange =
function LocalPdfManager_requestRange(begin, end) {
- var promise = new Promise();
+ var promise = new LegacyPromise();
promise.resolve();
return promise;
};
@@ -3839,8 +4971,10 @@ var NetworkPdfManager = (function NetworkPdfManagerClosure() {
var params = {
msgHandler: msgHandler,
httpHeaders: args.httpHeaders,
+ withCredentials: args.withCredentials,
chunkedViewerLoading: args.chunkedViewerLoading,
- disableAutoFetch: args.disableAutoFetch
+ disableAutoFetch: args.disableAutoFetch,
+ initialData: args.initialData
};
this.streamManager = new ChunkedStreamManager(args.length, CHUNK_SIZE,
args.url, params);
@@ -3854,7 +4988,7 @@ var NetworkPdfManager = (function NetworkPdfManagerClosure() {
NetworkPdfManager.prototype.ensure =
function NetworkPdfManager_ensure(obj, prop, args) {
- var promise = new Promise();
+ var promise = new LegacyPromise();
this.ensureHelper(promise, obj, prop, args);
return promise;
};
@@ -3885,7 +5019,7 @@ var NetworkPdfManager = (function NetworkPdfManagerClosure() {
NetworkPdfManager.prototype.requestRange =
function NetworkPdfManager_requestRange(begin, end) {
- var promise = new Promise();
+ var promise = new LegacyPromise();
this.streamManager.requestRange(begin, end, function() {
promise.resolve();
});
@@ -3914,12 +5048,13 @@ var NetworkPdfManager = (function NetworkPdfManagerClosure() {
var Page = (function PageClosure() {
- function Page(pdfManager, xref, pageIndex, pageDict, ref) {
+ function Page(pdfManager, xref, pageIndex, pageDict, ref, fontCache) {
this.pdfManager = pdfManager;
this.pageIndex = pageIndex;
this.pageDict = pageDict;
this.xref = xref;
this.ref = ref;
+ this.fontCache = fontCache;
this.idCounters = {
obj: 0
};
@@ -4011,7 +5146,7 @@ var Page = (function PageClosure() {
// TODO: add async inheritPageProp and remove this.
this.resourcesPromise = this.pdfManager.ensure(this, 'resources');
}
- var promise = new Promise();
+ var promise = new LegacyPromise();
this.resourcesPromise.then(function resourceSuccess() {
var objectLoader = new ObjectLoader(this.resources.map,
keys,
@@ -4024,13 +5159,13 @@ var Page = (function PageClosure() {
},
getOperatorList: function Page_getOperatorList(handler) {
var self = this;
- var promise = new Promise();
+ var promise = new LegacyPromise();
function reject(e) {
promise.reject(e);
}
- var pageListPromise = new Promise();
+ var pageListPromise = new LegacyPromise();
var pdfManager = this.pdfManager;
var contentStreamPromise = pdfManager.ensure(this, 'getContentStream',
@@ -4049,7 +5184,7 @@ var Page = (function PageClosure() {
var partialEvaluator = new PartialEvaluator(
pdfManager, this.xref, handler,
this.pageIndex, 'p' + this.pageIndex + '_',
- this.idCounters);
+ this.idCounters, this.fontCache);
var dataPromises = Promise.all(
[contentStreamPromise, resourcesPromise], reject);
@@ -4073,7 +5208,6 @@ var Page = (function PageClosure() {
var annotations = datas[1];
if (annotations.length === 0) {
- PartialEvaluator.optimizeQueue(pageOpList);
pageOpList.flush(true);
promise.resolve(pageOpList);
return;
@@ -4082,7 +5216,6 @@ var Page = (function PageClosure() {
var annotationsReadyPromise = Annotation.appendToOperatorList(
annotations, pageOpList, pdfManager, partialEvaluator);
annotationsReadyPromise.then(function () {
- PartialEvaluator.optimizeQueue(pageOpList);
pageOpList.flush(true);
promise.resolve(pageOpList);
}, reject);
@@ -4098,7 +5231,7 @@ var Page = (function PageClosure() {
var self = this;
- var textContentPromise = new Promise();
+ var textContentPromise = new LegacyPromise();
var pdfManager = this.pdfManager;
var contentStreamPromise = pdfManager.ensure(this, 'getContentStream',
@@ -4117,7 +5250,7 @@ var Page = (function PageClosure() {
var partialEvaluator = new PartialEvaluator(
pdfManager, self.xref, handler,
self.pageIndex, 'p' + self.pageIndex + '_',
- self.idCounters);
+ self.idCounters, self.fontCache);
var bidiTexts = partialEvaluator.getTextContent(contentStream,
self.resources);
@@ -4370,33 +5503,27 @@ var PDFDocument = (function PDFDocumentClosure() {
return shadow(this, 'documentInfo', docInfo);
},
get fingerprint() {
- var xref = this.xref, fileID;
+ var xref = this.xref, hash, fileID = '';
+
if (xref.trailer.has('ID')) {
- fileID = '';
- var id = xref.trailer.get('ID')[0];
- id.split('').forEach(function(el) {
- fileID += Number(el.charCodeAt(0)).toString(16);
- });
+ hash = stringToBytes(xref.trailer.get('ID')[0]);
} else {
- // If we got no fileID, then we generate one,
- // from the first 100 bytes of PDF
- var data = this.stream.bytes.subarray(0, 100);
- var hash = calculateMD5(data, 0, data.length);
- fileID = '';
- for (var i = 0, length = hash.length; i < length; i++) {
- fileID += Number(hash[i]).toString(16);
- }
+ hash = calculateMD5(this.stream.bytes.subarray(0, 100), 0, 100);
}
- return shadow(this, 'fingerprint', fileID);
- },
+ for (var i = 0, n = hash.length; i < n; i++) {
+ fileID += hash[i].toString(16);
+ }
- traversePages: function PDFDocument_traversePages() {
- this.catalog.traversePages();
+ return shadow(this, 'fingerprint', fileID);
},
getPage: function PDFDocument_getPage(pageIndex) {
return this.catalog.getPage(pageIndex);
+ },
+
+ cleanup: function PDFDocument_cleanup() {
+ return this.catalog.cleanup();
}
};
@@ -4479,7 +5606,7 @@ var Dict = (function DictClosure() {
if (xref) {
return xref.fetchIfRefAsync(value);
}
- promise = new Promise();
+ promise = new LegacyPromise();
promise.resolve(value);
return promise;
}
@@ -4488,7 +5615,7 @@ var Dict = (function DictClosure() {
if (xref) {
return xref.fetchIfRefAsync(value);
}
- promise = new Promise();
+ promise = new LegacyPromise();
promise.resolve(value);
return promise;
}
@@ -4496,7 +5623,7 @@ var Dict = (function DictClosure() {
if (xref) {
return xref.fetchIfRefAsync(value);
}
- promise = new Promise();
+ promise = new LegacyPromise();
promise.resolve(value);
return promise;
},
@@ -4571,7 +5698,7 @@ var RefSet = (function RefSetClosure() {
var RefSetCache = (function RefSetCacheClosure() {
function RefSetCache() {
- this.dict = {};
+ this.dict = Object.create(null);
}
RefSetCache.prototype = {
@@ -4585,6 +5712,16 @@ var RefSetCache = (function RefSetCacheClosure() {
put: function RefSetCache_put(ref, obj) {
this.dict['R' + ref.num + '.' + ref.gen] = obj;
+ },
+
+ forEach: function RefSetCache_forEach(fn, thisArg) {
+ for (var i in this.dict) {
+ fn.call(thisArg, this.dict[i]);
+ }
+ },
+
+ clear: function RefSetCache_clear() {
+ this.dict = Object.create(null);
}
};
@@ -4596,17 +5733,11 @@ var Catalog = (function CatalogClosure() {
this.pdfManager = pdfManager;
this.xref = xref;
this.catDict = xref.getCatalogObj();
+ this.fontCache = new RefSetCache();
assertWellFormed(isDict(this.catDict),
'catalog object is not a dictionary');
- // Stores state as we traverse the pages catalog so that we can resume
- // parsing if an exception is thrown
- this.traversePagesQueue = [{
- pagesDict: this.toplevelPagesDict,
- posInKids: 0
- }];
this.pagePromises = [];
- this.currPageIndex = 0;
}
Catalog.prototype = {
@@ -4789,59 +5920,156 @@ var Catalog = (function CatalogClosure() {
return shadow(this, 'javaScript', javaScript);
},
+ cleanup: function Catalog_cleanup() {
+ this.fontCache.forEach(function (font) {
+ delete font.sent;
+ delete font.translated;
+ });
+ this.fontCache.clear();
+ },
+
getPage: function Catalog_getPage(pageIndex) {
- if (pageIndex < 0 || pageIndex >= this.numPages ||
- (pageIndex|0) !== pageIndex) {
- var pagePromise = new Promise();
- pagePromise.reject(new Error('Invalid page index'));
- return pagePromise;
- }
if (!(pageIndex in this.pagePromises)) {
- this.pagePromises[pageIndex] = new Promise();
+ this.pagePromises[pageIndex] = this.getPageDict(pageIndex).then(
+ function (a) {
+ var dict = a[0];
+ var ref = a[1];
+ return new Page(this.pdfManager, this.xref, pageIndex, dict, ref,
+ this.fontCache);
+ }.bind(this)
+ );
}
return this.pagePromises[pageIndex];
},
- // Traverses pages in DFS order so that pages are processed in increasing
- // order
- traversePages: function Catalog_traversePages() {
- var queue = this.traversePagesQueue;
- while (queue.length) {
- var queueItem = queue[queue.length - 1];
- var pagesDict = queueItem.pagesDict;
+ getPageDict: function Catalog_getPageDict(pageIndex) {
+ var promise = new LegacyPromise();
+ var nodesToVisit = [this.catDict.getRaw('Pages')];
+ var currentPageIndex = 0;
+ var xref = this.xref;
- var kids = pagesDict.get('Kids');
- assert(isArray(kids), 'page dictionary kids object is not an array');
- if (queueItem.posInKids >= kids.length) {
- queue.pop();
- continue;
- }
- var kidRef = kids[queueItem.posInKids];
- assert(isRef(kidRef), 'page dictionary kid is not a reference');
+ function next() {
+ while (nodesToVisit.length) {
+ var currentNode = nodesToVisit.pop();
- var kid = this.xref.fetch(kidRef);
- if (isDict(kid, 'Page') || (isDict(kid) && !kid.has('Kids'))) {
- var pageIndex = this.currPageIndex++;
- var page = new Page(this.pdfManager, this.xref, pageIndex, kid,
- kidRef);
- if (!(pageIndex in this.pagePromises)) {
- this.pagePromises[pageIndex] = new Promise();
+ if (isRef(currentNode)) {
+ xref.fetchAsync(currentNode).then(function (obj) {
+ if ((isDict(obj, 'Page') || (isDict(obj) && !obj.has('Kids')))) {
+ if (pageIndex === currentPageIndex) {
+ promise.resolve([obj, currentNode]);
+ } else {
+ currentPageIndex++;
+ next();
+ }
+ return;
+ }
+ nodesToVisit.push(obj);
+ next();
+ }.bind(this), promise.reject.bind(promise));
+ return;
}
- this.pagePromises[pageIndex].resolve(page);
- } else { // must be a child page dictionary
+ // must be a child page dictionary
assert(
- isDict(kid),
+ isDict(currentNode),
'page dictionary kid reference points to wrong type of object'
);
+ var count = currentNode.get('Count');
+ // Skip nodes where the page can't be.
+ if (currentPageIndex + count <= pageIndex) {
+ currentPageIndex += count;
+ continue;
+ }
- queue.push({
- pagesDict: kid,
- posInKids: 0
- });
+ var kids = currentNode.get('Kids');
+ assert(isArray(kids), 'page dictionary kids object is not an array');
+ if (count === kids.length) {
+ // Nodes that don't have the page have been skipped and this is the
+ // bottom of the tree which means the page requested must be a
+ // descendant of this pages node. Ideally we would just resolve the
+ // promise with the page ref here, but there is the case where more
+ // pages nodes could link to single a page (see issue 3666 pdf). To
+ // handle this push it back on the queue so if it is a pages node it
+ // will be descended into.
+ nodesToVisit = [kids[pageIndex - currentPageIndex]];
+ currentPageIndex = pageIndex;
+ continue;
+ } else {
+ for (var last = kids.length - 1; last >= 0; last--) {
+ nodesToVisit.push(kids[last]);
+ }
+ }
}
- ++queueItem.posInKids;
+ promise.reject('Page index ' + pageIndex + ' not found.');
+ }
+ next();
+ return promise;
+ },
+
+ getPageIndex: function Catalog_getPageIndex(ref) {
+ // The page tree nodes have the count of all the leaves below them. To get
+ // how many pages are before we just have to walk up the tree and keep
+ // adding the count of siblings to the left of the node.
+ var xref = this.xref;
+ function pagesBeforeRef(kidRef) {
+ var total = 0;
+ var parentRef;
+ return xref.fetchAsync(kidRef).then(function (node) {
+ if (!node) {
+ return null;
+ }
+ parentRef = node.getRaw('Parent');
+ return node.getAsync('Parent');
+ }).then(function (parent) {
+ if (!parent) {
+ return null;
+ }
+ return parent.getAsync('Kids');
+ }).then(function (kids) {
+ if (!kids) {
+ return null;
+ }
+ var kidPromises = [];
+ var found = false;
+ for (var i = 0; i < kids.length; i++) {
+ var kid = kids[i];
+ assert(isRef(kid), 'kids must be an ref');
+ if (kid.num == kidRef.num) {
+ found = true;
+ break;
+ }
+ kidPromises.push(xref.fetchAsync(kid).then(function (kid) {
+ if (kid.has('Count')) {
+ var count = kid.get('Count');
+ total += count;
+ } else { // page leaf node
+ total++;
+ }
+ }));
+ }
+ if (!found) {
+ error('kid ref not found in parents kids');
+ }
+ return Promise.all(kidPromises).then(function () {
+ return [total, parentRef];
+ });
+ });
+ }
+
+ var total = 0;
+ function next(ref) {
+ return pagesBeforeRef(ref).then(function (args) {
+ if (!args) {
+ return total;
+ }
+ var count = args[0];
+ var parentRef = args[1];
+ total += count;
+ return next(parentRef);
+ });
}
+
+ return next(ref);
}
};
@@ -5258,6 +6486,8 @@ var XRef = (function XRefClosure() {
if (!dict)
error('Failed to read XRef stream');
+ } else {
+ error('Invalid XRef stream header');
}
// Recursively get previous dictionary, if any
@@ -5278,7 +6508,7 @@ var XRef = (function XRefClosure() {
if (e instanceof MissingDataException) {
throw e;
}
- log('(while reading XRef): ' + e);
+ info('(while reading XRef): ' + e);
}
if (recoveryMode)
@@ -5399,14 +6629,14 @@ var XRef = (function XRefClosure() {
},
fetchIfRefAsync: function XRef_fetchIfRefAsync(obj) {
if (!isRef(obj)) {
- var promise = new Promise();
+ var promise = new LegacyPromise();
promise.resolve(obj);
return promise;
}
return this.fetchAsync(obj);
},
fetchAsync: function XRef_fetchAsync(ref, suppressEncryption) {
- var promise = new Promise();
+ var promise = new LegacyPromise();
var tryFetch = function (promise) {
try {
promise.resolve(this.fetch(ref, suppressEncryption));
@@ -5533,7 +6763,7 @@ var ObjectLoader = (function() {
load: function ObjectLoader_load() {
var keys = this.keys;
- this.promise = new Promise();
+ this.promise = new LegacyPromise();
// Don't walk the graph if all the data is already loaded.
if (!(this.xref.stream instanceof ChunkedStream) ||
this.xref.stream.getMissingChunks().length === 0) {
@@ -12218,1196 +13448,446 @@ var CIDToUnicodeMaps = {
{f: 2, c: 31026}, {f: 5, c: 31029}, 31037, 31039, {f: 4, c: 31042}, 31047,
{f: 9, c: 31050}, {f: 2, c: 31060}, {f: 2, c: 31064}, 31073,
{f: 2, c: 31075}, 31078, {f: 4, c: 31081}, 31086, {f: 7, c: 31088}, 31097,
- {f: 5, c: 31099}, {f: 2, c: 31106}, {f: 4, c: 31110}, {f: 2, c: 31115},
- {f: 10, c: 31120}, {f: 11, c: 31131}, {f: 2, c: 31144}, {f: 3, c: 31147},
- 31151, 31154, {f: 4, c: 31156}, [12145, 31160], 31164, 31167, 31170,
- {f: 2, c: 31172}, {f: 2, c: 31175}, 31178, 31180, {f: 3, c: 31182},
- {f: 2, c: 31187}, {f: 2, c: 31190}, {f: 6, c: 31193}, {f: 3, c: 31200},
- 31205, 31208, 31210, 31212, 31214, {f: 7, c: 31217}, {f: 2, c: 31225},
- 31228, {f: 2, c: 31230}, 31233, {f: 2, c: 31236}, {f: 4, c: 31239}, 31244,
- {f: 5, c: 31247}, {f: 2, c: 31253}, {f: 2, c: 31256}, {f: 3, c: 31259},
- 31263, {f: 2, c: 31265}, {f: 10, c: 31268}, {f: 2, c: 31279}, 31282,
- {f: 3, c: 31284}, 31288, 31290, 31294, {f: 5, c: 31297}, {f: 5, c: 31303},
- {f: 2, c: 31311}, {f: 5, c: 31314}, {f: 9, c: 31320}, {f: 6, c: 31331},
- 31338, {f: 4, c: 31340}, {f: 3, c: 31345}, 31349, {f: 4, c: 31355}, 31362,
- 31365, 31367, {f: 4, c: 31369}, {f: 3, c: 31374}, {f: 2, c: 31379},
- {f: 3, c: 31385}, 31390, {f: 4, c: 31393}, 31399, 31403, {f: 4, c: 31407},
- {f: 2, c: 31412}, {f: 3, c: 31415}, {f: 4, c: 31419}, {f: 4, c: 31424},
- 31430, 31433, {f: 10, c: 31436}, {f: 2, c: 31447}, {f: 4, c: 31450},
- {f: 2, c: 31457}, 31460, {f: 3, c: 31463}, {f: 2, c: 31467}, 31470,
- {f: 6, c: 31472}, {f: 2, c: 31479}, {f: 2, c: 31483}, 31486,
- {f: 3, c: 31488}, 31493, 31495, 31497, {f: 3, c: 31500}, 31504,
- {f: 2, c: 31506}, {f: 3, c: 31510}, 31514, {f: 2, c: 31516}, 31519,
- {f: 3, c: 31521}, 31527, 31529, 31533, {f: 2, c: 31535}, 31538,
- {f: 4, c: 31540}, 31545, 31547, 31549, {f: 6, c: 31551}, 31560, 31562,
- {f: 2, c: 31565}, 31571, 31573, 31575, 31577, 31580, {f: 2, c: 31582},
- 31585, {f: 4, c: 31587}, {f: 6, c: 31592}, {f: 2, c: 31599},
- {f: 2, c: 31603}, 31606, 31608, 31610, {f: 2, c: 31612}, 31615,
- {f: 4, c: 31617}, {f: 5, c: 31622}, 31628, {f: 2, c: 31630},
- {f: 3, c: 31633}, 31638, {f: 4, c: 31640}, {f: 3, c: 31646},
- {f: 3, c: 31651}, {f: 3, c: 31662}, {f: 2, c: 31666}, {f: 3, c: 31669},
- {f: 7, c: 31673}, {f: 2, c: 31682}, 31685, 31688, 31690, {f: 4, c: 31693},
- 31698, {f: 5, c: 31700}, {f: 2, c: 31707}, {f: 3, c: 31710},
- {f: 2, c: 31714}, {f: 2, c: 31719}, {f: 3, c: 31723}, {f: 2, c: 31727},
- 31730, {f: 3, c: 31732}, {f: 4, c: 31736}, 31741, 31743, {f: 6, c: 31745},
- {f: 3, c: 31752}, 31758, {f: 6, c: 31760}, {f: 7, c: 31767}, 31776, 31778,
- {f: 2, c: 31780}, {f: 2, c: 31784}, {f: 12, c: 31788}, {f: 4, c: 31801},
- 31810, {f: 8, c: 31812}, {f: 14, c: 31822}, {f: 2, c: 31837},
- {f: 3, c: 31841}, {f: 4, c: 31845}, 31851, 31853, {f: 3, c: 31855},
- {f: 6, c: 31861}, {f: 11, c: 31870}, {f: 7, c: 31882}, {f: 2, c: 31891},
- 31894, {f: 3, c: 31897}, {f: 2, c: 31904}, 31907, {f: 4, c: 31910},
- {f: 3, c: 31915}, {f: 2, c: 31919}, {f: 5, c: 31924}, {f: 2, c: 31930},
- {f: 2, c: 31935}, {f: 3, c: 31938}, 31942, 31945, 31947, {f: 7, c: 31950},
- 31960, {f: 2, c: 31962}, {f: 6, c: 31969}, {f: 6, c: 31977}, 31985, 31987,
- 31989, 31991, 31994, {f: 2, c: 31996}, 31999, 32001, 32003, 32012,
- {f: 2, c: 32014}, {f: 2, c: 32017}, 32022, 32024, {f: 3, c: 32029},
- {f: 4, c: 32035}, {f: 3, c: 32040}, {f: 3, c: 32044}, {f: 5, c: 32052},
- 32059, {f: 2, c: 32061}, 32065, 32067, 32069, {f: 7, c: 32071}, 32079,
- {f: 12, c: 32081}, {f: 2, c: 32095}, {f: 3, c: 32099}, 32103,
- {f: 5, c: 32105}, {f: 2, c: 32111}, {f: 2, c: 32116}, 32120,
- {f: 7, c: 32122}, 32130, {f: 2, c: 32132}, 32135, {f: 5, c: 32138},
- {f: 3, c: 32144}, {f: 8, c: 32148}, 32157, {f: 3, c: 32159},
- {f: 2, c: 32164}, {f: 4, c: 32167}, 32175, {f: 3, c: 32181}, 32188,
- {f: 4, c: 32192}, {f: 2, c: 32197}, {f: 2, c: 32200}, {f: 5, c: 32204},
- 32211, {f: 2, c: 32213}, {f: 3, c: 32218}, 32223, 32226, {f: 2, c: 32228},
- 32231, {f: 2, c: 32234}, {f: 2, c: 32237}, 32240, 32243, 32245,
- {f: 2, c: 32247}, 32250, {f: 12, c: 32252}, {f: 4, c: 32268},
- {f: 9, c: 32274}, 32284, {f: 3, c: 32288}, {f: 3, c: 32292},
- {f: 3, c: 32296}, 32300, {f: 2, c: 32303}, 32307, 32312, 32314, 32316,
- {f: 2, c: 32319}, {f: 3, c: 32322}, {f: 10, c: 32328}, 32339,
- {f: 4, c: 32342}, {f: 3, c: 32347}, {f: 3, c: 32351}, {f: 6, c: 32355},
- 32364, {f: 2, c: 32369}, {f: 5, c: 32372}, {f: 2, c: 32378},
- {f: 3, c: 32383}, {f: 5, c: 32387}, 32393, 32395, 32398, {f: 3, c: 32400},
- 32405, 32407, {f: 2, c: 32409}, {f: 2, c: 32413}, 32430, 32436,
- {f: 2, c: 32443}, 32470, 32484, 32492, 32505, 32522, 32528, 32542, 32567,
- 32569, {f: 7, c: 32571}, 32579, {f: 6, c: 32582}, 32589, 32591,
- {f: 2, c: 32594}, 32598, 32601, {f: 4, c: 32603}, 32608, {f: 5, c: 32611},
- {f: 3, c: 32619}, 32623, 32627, {f: 2, c: 32629}, 32632, {f: 4, c: 32634},
- {f: 2, c: 32639}, {f: 3, c: 32642}, 32647, 32649, 32651, 32653,
- {f: 5, c: 32655}, {f: 5, c: 32661}, {f: 2, c: 32667}, 32672,
- {f: 2, c: 32674}, 32678, 32680, {f: 5, c: 32682}, 32689, {f: 5, c: 32691},
- {f: 2, c: 32698}, 32702, 32704, {f: 3, c: 32706}, {f: 4, c: 32710}, 32715,
- 32717, {f: 3, c: 32719}, 32723, {f: 2, c: 32726}, {f: 6, c: 32729},
- {f: 3, c: 32738}, {f: 2, c: 32743}, {f: 4, c: 32746}, 32751, 32754,
- {f: 5, c: 32756}, 32762, {f: 3, c: 32765}, 32770, {f: 4, c: 32775},
- {f: 2, c: 32782}, 32785, 32787, {f: 2, c: 32794}, {f: 3, c: 32797}, 32801,
- {f: 2, c: 32803}, 32811, 32813, {f: 2, c: 32815}, 32818, 32820,
- {f: 2, c: 32825}, 32828, 32830, {f: 2, c: 32832}, {f: 2, c: 32836},
- {f: 3, c: 32839}, {f: 4, c: 32846}, 32851, 32853, 32855, 32857,
- {f: 3, c: 32859}, {f: 10, c: 32863}, {f: 4, c: 32875}, 32884, 32888,
- {f: 3, c: 32890}, {f: 2, c: 32897}, 32904, 32906, {f: 6, c: 32909},
- {f: 2, c: 32916}, 32919, 32921, 32926, 32931, {f: 3, c: 32934}, 32940,
- 32944, 32947, {f: 2, c: 32949}, {f: 2, c: 32952}, 32955, 32965,
- {f: 5, c: 32967}, {f: 7, c: 32975}, 32984, {f: 2, c: 32991},
- {f: 2, c: 32994}, 32998, 33006, 33013, 33015, 33017, 33019,
- {f: 4, c: 33022}, {f: 2, c: 33027}, {f: 2, c: 33031}, {f: 2, c: 33035},
- 33045, 33047, 33049, {f: 2, c: 33052}, {f: 13, c: 33055}, {f: 2, c: 33069},
- 33072, {f: 3, c: 33075}, 33079, {f: 4, c: 33082}, {f: 7, c: 33087}, 33095,
- 33097, 33101, 33103, 33106, {f: 2, c: 33111}, {f: 5, c: 33115},
- {f: 3, c: 33122}, 33128, 33130, 33132, 33135, {f: 2, c: 33138},
- {f: 3, c: 33141}, 33153, {f: 5, c: 33155}, 33161, {f: 4, c: 33163}, 33168,
- {f: 6, c: 33170}, 33177, {f: 2, c: 33182}, {f: 2, c: 33185},
- {f: 2, c: 33188}, 33191, {f: 8, c: 33195}, {f: 6, c: 33204}, 33212,
- {f: 2, c: 33220}, {f: 2, c: 33223}, 33227, 33230, {f: 8, c: 33232}, 33241,
- {f: 4, c: 33243}, {f: 2, c: 33249}, {f: 3, c: 33252}, 33257, 33259,
- {f: 5, c: 33262}, {f: 5, c: 33269}, 33277, 33279, 33283, 33291,
- {f: 2, c: 33294}, 33297, 33299, {f: 6, c: 33301}, 33309, 33312,
- {f: 4, c: 33316}, 33321, 33326, 33330, 33338, {f: 2, c: 33340},
- {f: 5, c: 33343}, {f: 2, c: 33349}, 33352, 33354, {f: 3, c: 33356},
- {f: 8, c: 33360}, {f: 4, c: 33371}, {f: 4, c: 33376}, 33381, 33383,
- {f: 2, c: 33385}, {f: 2, c: 33388}, {f: 2, c: 33397}, [12171, 33400],
- {f: 2, c: 33403}, {f: 2, c: 33408}, 33411, {f: 3, c: 33413}, 33417, 33420,
- 33424, {f: 4, c: 33427}, {f: 2, c: 33434}, 33438, 33440, {f: 2, c: 33442},
- 33447, 33458, {f: 2, c: 33461}, 33466, 33468, {f: 2, c: 33471},
- {f: 2, c: 33474}, {f: 2, c: 33477}, 33481, 33488, 33494, {f: 2, c: 33497},
- 33501, 33506, {f: 3, c: 33512}, {f: 3, c: 33516}, 33520, {f: 2, c: 33522},
- {f: 2, c: 33525}, 33528, 33530, {f: 5, c: 33532}, {f: 2, c: 33546}, 33549,
- 33552, {f: 2, c: 33554}, 33558, {f: 2, c: 33560}, {f: 10, c: 33565},
- {f: 2, c: 33577}, 33582, 33584, 33586, 33591, 33595, {f: 3, c: 33597},
- {f: 2, c: 33601}, {f: 2, c: 33604}, 33608, {f: 5, c: 33610}, 33619,
- {f: 5, c: 33621}, 33629, 33634, {f: 7, c: 33648}, {f: 2, c: 33657},
- {f: 7, c: 33662}, {f: 2, c: 33671}, {f: 3, c: 33675}, {f: 3, c: 33679},
- {f: 2, c: 33684}, 33687, {f: 2, c: 33689}, 33693, 33695, 33697,
- {f: 4, c: 33699}, {f: 4, c: 33708}, 33717, 33723, {f: 2, c: 33726},
- {f: 3, c: 33730}, 33734, {f: 2, c: 33736}, 33739, {f: 2, c: 33741},
- {f: 4, c: 33744}, 33749, 33751, {f: 3, c: 33753}, 33758, {f: 3, c: 33762},
- {f: 3, c: 33766}, {f: 4, c: 33771}, {f: 5, c: 33779}, {f: 3, c: 33786},
- {f: 3, c: 33790}, 33794, 33797, {f: 2, c: 33800}, 33808, {f: 6, c: 33810},
- {f: 3, c: 33817}, {f: 6, c: 33822}, {f: 3, c: 33833}, {f: 4, c: 33837},
- {f: 3, c: 33842}, {f: 2, c: 33846}, {f: 3, c: 33849}, {f: 8, c: 33854},
- {f: 2, c: 33863}, {f: 7, c: 33866}, {f: 4, c: 33875}, 33880,
- {f: 4, c: 33885}, 33890, 33893, {f: 2, c: 33895}, 33898, 33902, 33904,
- 33906, 33908, 33913, {f: 7, c: 33915}, {f: 4, c: 33923}, 33930, 33933,
- {f: 4, c: 33935}, {f: 2, c: 33941}, 33944, {f: 2, c: 33946},
- {f: 4, c: 33949}, {f: 13, c: 33954}, {f: 2, c: 33968}, 33971,
- {f: 3, c: 33973}, 33979, 33982, {f: 2, c: 33986}, {f: 4, c: 33989}, 33996,
- {f: 2, c: 33998}, 34002, {f: 2, c: 34004}, {f: 6, c: 34007}, 34014,
- {f: 2, c: 34017}, 34020, {f: 5, c: 34023}, 34029, {f: 11, c: 34033}, 34046,
- {f: 12, c: 34048}, {f: 4, c: 34061}, 34066, {f: 2, c: 34069},
- {f: 2, c: 34072}, {f: 3, c: 34075}, 34080, 34082, {f: 2, c: 34084},
- {f: 4, c: 34087}, {f: 9, c: 34094}, {f: 3, c: 34110}, 34114,
- {f: 2, c: 34116}, 34119, {f: 3, c: 34123}, {f: 3, c: 34127}, 34132, 34135,
- {f: 4, c: 34138}, {f: 3, c: 34143}, 34147, {f: 3, c: 34149},
- {f: 2, c: 34155}, {f: 4, c: 34158}, 34163, {f: 2, c: 34165}, 34168,
- {f: 2, c: 34172}, {f: 5, c: 34175}, 34182, 34185, 34187, {f: 2, c: 34189},
- 34192, {f: 2, c: 34194}, {f: 6, c: 34197}, {f: 2, c: 34205},
- {f: 4, c: 34208}, 34213, 34215, {f: 3, c: 34219}, {f: 6, c: 34225}, 34232,
- {f: 6, c: 34235}, {f: 7, c: 34242}, {f: 3, c: 34250}, {f: 2, c: 34257},
- 34260, {f: 6, c: 34262}, {f: 6, c: 34270}, {f: 3, c: 34278},
- {f: 9, c: 34283}, 34293, {f: 2, c: 34295}, {f: 3, c: 34300},
- {f: 4, c: 34304}, {f: 3, c: 34312}, {f: 5, c: 34316}, {f: 4, c: 34322},
- {f: 3, c: 34327}, {f: 3, c: 34331}, {f: 3, c: 34335}, {f: 4, c: 34339},
- 34344, {f: 3, c: 34346}, {f: 10, c: 34350}, 34361, 34363, {f: 2, c: 34365},
- {f: 13, c: 34368}, {f: 2, c: 34386}, {f: 4, c: 34390}, 34395, 34397,
- {f: 2, c: 34400}, {f: 4, c: 34403}, {f: 3, c: 34408}, 34413,
- {f: 2, c: 34415}, {f: 7, c: 34418}, {f: 7, c: 34435}, {f: 5, c: 34446},
- 34452, {f: 6, c: 34454}, {f: 5, c: 34462}, {f: 2, c: 34469}, 34475,
- {f: 2, c: 34477}, {f: 2, c: 34482}, {f: 3, c: 34487}, {f: 5, c: 34491},
- {f: 3, c: 34497}, 34501, 34504, {f: 2, c: 34508}, {f: 2, c: 34514},
- {f: 3, c: 34517}, 34522, {f: 2, c: 34524}, {f: 4, c: 34528},
- {f: 4, c: 34533}, {f: 3, c: 34538}, 34543, {f: 3, c: 34549},
- {f: 3, c: 34555}, 34559, 34561, {f: 2, c: 34564}, {f: 2, c: 34571},
- {f: 4, c: 34574}, 34580, 34582, 34585, 34587, 34589, {f: 2, c: 34591},
- 34596, {f: 3, c: 34598}, {f: 4, c: 34602}, {f: 2, c: 34607},
- {f: 2, c: 34610}, {f: 2, c: 34613}, {f: 3, c: 34616}, {f: 2, c: 34620},
- {f: 7, c: 34624}, {f: 2, c: 34634}, 34637, {f: 4, c: 34639}, 34644, 34646,
- 34648, {f: 6, c: 34650}, {f: 2, c: 34657}, {f: 7, c: 34663}, 34671,
- {f: 3, c: 34673}, 34677, 34679, {f: 2, c: 34681}, {f: 3, c: 34687},
- {f: 2, c: 34694}, {f: 2, c: 34697}, 34700, {f: 5, c: 34702},
- {f: 3, c: 34708}, {f: 6, c: 34712}, {f: 2, c: 34720}, {f: 5, c: 34723},
- {f: 2, c: 34729}, 34734, {f: 3, c: 34736}, 34740, {f: 4, c: 34742}, 34748,
- {f: 2, c: 34750}, {f: 3, c: 34753}, 34757, 34759, 34761, {f: 2, c: 34764},
- {f: 2, c: 34767}, {f: 7, c: 34772}, {f: 4, c: 34780}, {f: 2, c: 34785},
- 34788, {f: 4, c: 34790}, 34795, 34797, {f: 2, c: 34800}, {f: 3, c: 34803},
- {f: 2, c: 34807}, 34810, {f: 2, c: 34812}, {f: 4, c: 34815}, 34820,
- {f: 3, c: 34823}, {f: 5, c: 34827}, 34834, 34836, {f: 4, c: 34839},
- {f: 3, c: 34844}, 34848, {f: 13, c: 34852}, {f: 3, c: 34867},
- {f: 2, c: 34871}, 34874, {f: 3, c: 34877}, {f: 3, c: 34881},
- {f: 3, c: 34887}, 34891, {f: 5, c: 34894}, {f: 2, c: 34901}, 34904, 34906,
- 34908, {f: 3, c: 34910}, {f: 2, c: 34918}, 34922, 34925, 34927, 34929,
- {f: 4, c: 34931}, 34936, {f: 3, c: 34938}, 34944, 34947, {f: 2, c: 34950},
- {f: 2, c: 34953}, 34956, {f: 4, c: 34958}, {f: 3, c: 34963},
- {f: 5, c: 34967}, {f: 5, c: 34973}, 34979, {f: 6, c: 34981}, 34988,
- {f: 3, c: 34990}, {f: 5, c: 34994}, {f: 4, c: 35000}, {f: 4, c: 35005},
- {f: 2, c: 35011}, {f: 2, c: 35015}, {f: 3, c: 35019}, {f: 2, c: 35024},
- 35027, {f: 2, c: 35030}, {f: 2, c: 35034}, 35038, {f: 2, c: 35040},
- {f: 2, c: 35046}, {f: 7, c: 35049}, 35058, {f: 3, c: 35061},
- {f: 2, c: 35066}, {f: 3, c: 35071}, {f: 4, c: 35075}, {f: 2, c: 35080},
- {f: 5, c: 35083}, 35089, {f: 5, c: 35092}, {f: 5, c: 35100},
- {f: 3, c: 35106}, {f: 4, c: 35110}, {f: 4, c: 35116}, 35121, 35125, 35127,
- {f: 2, c: 35129}, {f: 5, c: 35132}, {f: 2, c: 35138}, {f: 2, c: 35141},
- {f: 14, c: 35144}, {f: 6, c: 35159}, {f: 3, c: 35169}, 35173,
- {f: 3, c: 35175}, 35179, {f: 2, c: 35181}, {f: 2, c: 35184},
- {f: 8, c: 35187}, {f: 2, c: 35196}, [12177, 35198], 35200, 35202,
- {f: 2, c: 35204}, {f: 4, c: 35207}, {f: 3, c: 35212}, {f: 3, c: 35216},
- {f: 2, c: 35220}, 35223, {f: 8, c: 35225}, {f: 4, c: 35234},
- {f: 3, c: 35239}, 35243, {f: 2, c: 35245}, {f: 2, c: 35248},
- {f: 4, c: 35251}, {f: 2, c: 35256}, {f: 2, c: 35259}, 35262, 35267, 35277,
- {f: 3, c: 35283}, {f: 3, c: 35287}, 35291, 35293, {f: 4, c: 35295}, 35300,
- {f: 4, c: 35303}, {f: 3, c: 35308}, {f: 3, c: 35312}, 35317, 35319,
- {f: 7, c: 35321}, {f: 3, c: 35332}, 35337, 35339, 35341, 35343,
- {f: 2, c: 35345}, 35348, 35351, {f: 2, c: 35353}, 35356, 35358,
- {f: 3, c: 35360}, 35364, {f: 4, c: 35366}, {f: 2, c: 35371},
- {f: 3, c: 35374}, {f: 2, c: 35378}, 35381, {f: 3, c: 35383},
- {f: 3, c: 35387}, {f: 2, c: 35391}, {f: 4, c: 35394}, 35399,
- {f: 5, c: 35401}, 35407, 35409, 35411, {f: 2, c: 35414}, {f: 2, c: 35417},
- {f: 2, c: 35420}, {f: 2, c: 35423}, {f: 2, c: 35428}, {f: 2, c: 35431},
- 35434, 35439, 35444, {f: 3, c: 35446}, {f: 2, c: 35450}, {f: 2, c: 35453},
- {f: 4, c: 35456}, 35464, {f: 2, c: 35467}, {f: 3, c: 35470}, 35476,
- {f: 2, c: 35478}, 35481, {f: 3, c: 35483}, 35487, 35490, 35495,
- {f: 3, c: 35497}, {f: 3, c: 35501}, 35505, {f: 3, c: 35507},
- {f: 2, c: 35511}, {f: 2, c: 35514}, {f: 2, c: 35517}, {f: 2, c: 35520},
- 35523, {f: 2, c: 35525}, 35528, 35530, 35532, 35534, 35536,
- {f: 3, c: 35539}, {f: 3, c: 35544}, 35549, {f: 3, c: 35551}, 35555, 35557,
- {f: 3, c: 35560}, 35564, {f: 2, c: 35567}, 35570, {f: 2, c: 35572}, 35577,
- 35579, 35581, 35583, 35587, 35590, {f: 2, c: 35592}, {f: 3, c: 35595},
- 35599, {f: 3, c: 35601}, 35605, 35608, 35612, {f: 3, c: 35614},
- {f: 4, c: 35618}, 35623, {f: 2, c: 35625}, {f: 5, c: 35630},
- {f: 5, c: 35636}, {f: 4, c: 35642}, {f: 10, c: 35647}, {f: 4, c: 35658},
- {f: 6, c: 35664}, 35671, 35675, {f: 9, c: 35677}, {f: 4, c: 35687},
- {f: 2, c: 35693}, {f: 3, c: 35697}, {f: 2, c: 35701}, {f: 5, c: 35704},
- {f: 2, c: 35710}, {f: 9, c: 35713}, {f: 3, c: 35723}, {f: 3, c: 35727},
- 35732, {f: 5, c: 35735}, 35741, 35743, 35756, 35761, 35771, 35783, 35792,
- 35818, 35849, 35870, {f: 9, c: 35896}, {f: 4, c: 35906}, {f: 2, c: 35914},
- {f: 3, c: 35917}, {f: 4, c: 35921}, {f: 4, c: 35926}, {f: 6, c: 35931},
- {f: 7, c: 35939}, {f: 7, c: 35948}, {f: 4, c: 35956}, {f: 7, c: 35963},
- {f: 2, c: 35971}, {f: 3, c: 35974}, 35979, {f: 7, c: 35981},
- {f: 3, c: 35989}, {f: 4, c: 35993}, 35999, {f: 4, c: 36003},
- {f: 2, c: 36013}, 36017, 36021, 36025, 36030, 36038, 36041,
- {f: 6, c: 36043}, 36052, {f: 4, c: 36054}, 36059, 36061, 36063, 36069,
- {f: 2, c: 36072}, {f: 6, c: 36078}, {f: 5, c: 36085}, {f: 5, c: 36095},
- {f: 2, c: 36102}, 36105, 36108, 36110, {f: 5, c: 36113}, {f: 4, c: 36119},
- 36128, {f: 2, c: 36177}, 36183, 36191, 36197, {f: 3, c: 36200}, 36204,
- {f: 2, c: 36206}, {f: 2, c: 36209}, {f: 9, c: 36216}, {f: 2, c: 36226},
- {f: 4, c: 36230}, {f: 5, c: 36236}, {f: 2, c: 36242}, {f: 3, c: 36246},
- {f: 5, c: 36250}, {f: 3, c: 36256}, {f: 4, c: 36260}, {f: 8, c: 36265},
- {f: 2, c: 36278}, 36281, 36283, 36285, {f: 3, c: 36288}, 36293,
- {f: 4, c: 36295}, 36301, 36304, {f: 4, c: 36306}, {f: 2, c: 36312}, 36316,
- {f: 3, c: 36320}, {f: 3, c: 36325}, 36329, {f: 2, c: 36333},
- {f: 3, c: 36336}, 36340, 36342, 36348, {f: 7, c: 36350}, {f: 3, c: 36358},
- 36363, {f: 2, c: 36365}, {f: 3, c: 36369}, {f: 8, c: 36373},
- {f: 2, c: 36384}, {f: 5, c: 36388}, 36395, 36397, 36400, {f: 2, c: 36402},
- {f: 3, c: 36406}, {f: 2, c: 36411}, {f: 2, c: 36414}, 36419,
- {f: 2, c: 36421}, {f: 4, c: 36429}, {f: 2, c: 36435}, {f: 3, c: 36438},
- {f: 9, c: 36442}, {f: 2, c: 36452}, {f: 2, c: 36455}, {f: 2, c: 36458},
- 36462, 36465, 36467, 36469, {f: 3, c: 36471}, 36475, {f: 2, c: 36477},
- 36480, {f: 3, c: 36482}, 36486, 36488, 36492, 36494, {f: 5, c: 36501},
- 36507, 36509, {f: 2, c: 36511}, {f: 3, c: 36514}, {f: 3, c: 36519},
- {f: 2, c: 36525}, {f: 2, c: 36528}, {f: 7, c: 36531}, {f: 5, c: 36539},
- {f: 9, c: 36545}, {f: 3, c: 36559}, 36563, {f: 6, c: 36565},
- {f: 3, c: 36572}, {f: 4, c: 36576}, {f: 6, c: 36581}, {f: 6, c: 36588},
- {f: 5, c: 36595}, 36605, {f: 4, c: 36607}, 36612, 36614, 36616,
- {f: 7, c: 36619}, 36627, {f: 5, c: 36630}, {f: 5, c: 36640},
- {f: 2, c: 36647}, {f: 4, c: 36651}, {f: 3, c: 36656}, {f: 4, c: 36660},
- {f: 2, c: 36665}, {f: 2, c: 36668}, {f: 2, c: 36672}, 36675,
- {f: 2, c: 36679}, {f: 3, c: 36682}, {f: 5, c: 36687}, {f: 10, c: 36693},
- 36704, 36707, 36709, 36714, 36736, 36748, 36754, 36765, {f: 3, c: 36768},
- {f: 2, c: 36772}, 36775, 36778, 36780, {f: 2, c: 36787}, [12193, 36789],
- {f: 2, c: 36791}, {f: 3, c: 36794}, {f: 2, c: 36799}, 36803, 36806,
- {f: 5, c: 36809}, 36815, 36818, {f: 2, c: 36822}, 36826, {f: 2, c: 36832},
- 36835, 36839, 36844, 36847, {f: 2, c: 36849}, {f: 2, c: 36853},
- {f: 3, c: 36858}, {f: 2, c: 36862}, {f: 2, c: 36871}, 36876, 36878, 36883,
- 36888, 36892, {f: 2, c: 36900}, {f: 6, c: 36903}, {f: 2, c: 36912},
- {f: 2, c: 36915}, 36919, {f: 2, c: 36921}, 36925, {f: 2, c: 36927}, 36931,
- {f: 2, c: 36933}, {f: 3, c: 36936}, 36940, 36950, {f: 2, c: 36953}, 36957,
- 36959, 36961, 36964, {f: 2, c: 36966}, {f: 3, c: 36970}, {f: 3, c: 36975},
- 36979, 36982, 36985, 36987, 36990, {f: 2, c: 36997}, 37001,
- {f: 3, c: 37004}, 37010, 37012, 37014, 37016, 37018, 37020,
- {f: 3, c: 37022}, {f: 2, c: 37028}, {f: 3, c: 37031}, 37035, 37037, 37042,
- 37047, {f: 2, c: 37052}, {f: 2, c: 37055}, {f: 2, c: 37058}, 37062,
- {f: 2, c: 37064}, {f: 3, c: 37067}, 37074, {f: 3, c: 37076},
- {f: 3, c: 37080}, 37086, 37088, {f: 3, c: 37091}, {f: 2, c: 37097}, 37100,
- 37102, {f: 4, c: 37104}, {f: 2, c: 37110}, {f: 4, c: 37113},
- {f: 3, c: 37119}, 37123, 37125, {f: 2, c: 37127}, {f: 8, c: 37130}, 37139,
- 37141, {f: 2, c: 37143}, {f: 4, c: 37146}, {f: 3, c: 37151},
- {f: 3, c: 37156}, {f: 5, c: 37160}, 37166, 37171, 37173, {f: 2, c: 37175},
- {f: 8, c: 37179}, {f: 2, c: 37188}, 37191, 37201, {f: 4, c: 37203},
- {f: 2, c: 37208}, {f: 2, c: 37211}, {f: 2, c: 37215}, {f: 3, c: 37222},
- 37227, 37229, 37235, {f: 3, c: 37242}, {f: 5, c: 37248}, 37254, 37256,
- 37258, {f: 2, c: 37262}, {f: 3, c: 37267}, {f: 3, c: 37271},
- {f: 5, c: 37277}, {f: 6, c: 37284}, {f: 4, c: 37296}, {f: 4, c: 37302},
- {f: 5, c: 37307}, 37314, 37316, [12196, 37318], 37320, 37328, 37334,
- {f: 2, c: 37338}, {f: 5, c: 37342}, {f: 2, c: 37349}, 37352,
- {f: 11, c: 37354}, 37366, 37368, {f: 5, c: 37371}, {f: 2, c: 37378},
- {f: 3, c: 37381}, {f: 3, c: 37386}, 37391, {f: 2, c: 37394},
- {f: 8, c: 37398}, {f: 4, c: 37407}, 37412, {f: 6, c: 37416}, 37423,
- {f: 2, c: 37425}, {f: 2, c: 37429}, {f: 2, c: 37435}, {f: 4, c: 37441},
- {f: 2, c: 37446}, {f: 3, c: 37450}, {f: 3, c: 37454}, {f: 3, c: 37458},
- 37462, {f: 2, c: 37464}, {f: 2, c: 37468}, {f: 3, c: 37471},
- {f: 3, c: 37475}, {f: 5, c: 37479}, {f: 6, c: 37486}, {f: 3, c: 37493},
- 37497, {f: 3, c: 37500}, {f: 2, c: 37505}, 37508, {f: 8, c: 37510},
- {f: 2, c: 37519}, 37522, {f: 2, c: 37524}, 37527, 37529, 37531,
- {f: 3, c: 37533}, {f: 2, c: 37537}, 37540, 37543, 37549, {f: 2, c: 37551},
- {f: 5, c: 37554}, 37560, 37562, {f: 4, c: 37565}, 37570, 37572, 37574,
- {f: 3, c: 37577}, {f: 2, c: 37581}, {f: 2, c: 37584}, {f: 10, c: 37587},
- 37598, {f: 3, c: 37600}, 37607, 37609, {f: 2, c: 37611}, {f: 4, c: 37618},
- 37623, {f: 3, c: 37625}, {f: 4, c: 37629}, {f: 4, c: 37634},
- {f: 7, c: 37641}, 37649, {f: 2, c: 37651}, {f: 2, c: 37654},
- {f: 3, c: 37660}, 37665, {f: 3, c: 37667}, 37671, {f: 2, c: 37673},
- {f: 2, c: 37676}, {f: 2, c: 37680}, {f: 2, c: 37684}, 37687,
- {f: 5, c: 37689}, 37695, 37698, {f: 2, c: 37700}, {f: 3, c: 37704}, 37708,
- {f: 6, c: 37710}, {f: 3, c: 37717}, {f: 2, c: 37721}, {f: 8, c: 37724},
- {f: 3, c: 37734}, 37739, {f: 3, c: 37741}, {f: 4, c: 37745},
- {f: 3, c: 37751}, {f: 3, c: 37755}, {f: 3, c: 37759}, 37763,
- {f: 2, c: 37765}, {f: 2, c: 37768}, {f: 4, c: 37771}, {f: 6, c: 37776},
- 37783, {f: 9, c: 37785}, {f: 2, c: 37796}, 37800, 37803, 37805, 37807,
- {f: 2, c: 37809}, 37812, {f: 2, c: 37814}, {f: 6, c: 37817},
- {f: 3, c: 37824}, {f: 3, c: 37828}, 37833, 37835, {f: 3, c: 37838},
- {f: 4, c: 37842}, {f: 3, c: 37849}, 37856, 37859, {f: 3, c: 37861},
- {f: 12, c: 37865}, 37878, 37880, {f: 9, c: 37882}, {f: 7, c: 37892},
- {f: 4, c: 37900}, 37905, {f: 3, c: 37909}, {f: 3, c: 37914},
- {f: 2, c: 37918}, {f: 5, c: 37921}, {f: 5, c: 37929}, {f: 3, c: 37935},
- 37940, {f: 2, c: 37942}, 37945, {f: 3, c: 37947}, {f: 4, c: 37952},
- {f: 5, c: 37957}, 37963, {f: 5, c: 37965}, 37971, {f: 11, c: 37973},
- {f: 2, c: 37985}, 37988, {f: 5, c: 37990}, 37996, {f: 2, c: 37998}, 38001,
- {f: 4, c: 38003}, 38008, {f: 2, c: 38010}, {f: 5, c: 38016}, 38033, 38038,
- 38040, 38087, 38095, {f: 2, c: 38099}, 38106, 38118, 38139, 38172, 38176,
- 38183, 38195, 38205, 38211, 38216, 38219, 38229, 38234, 38240, 38254,
- {f: 2, c: 38260}, {f: 7, c: 38264}, 38273, {f: 2, c: 38276},
- {f: 2, c: 38279}, 38282, 38285, 38288, 38290, {f: 3, c: 38293},
- {f: 8, c: 38297}, 38306, {f: 2, c: 38310}, 38314, {f: 4, c: 38318},
- {f: 3, c: 38323}, {f: 2, c: 38327}, 38330, {f: 3, c: 38336},
- {f: 2, c: 38340}, 38343, 38345, {f: 3, c: 38349}, {f: 3, c: 38353},
- {f: 5, c: 38359}, 38365, {f: 2, c: 38367}, {f: 2, c: 38371},
- {f: 2, c: 38374}, 38380, 38399, 38407, 38419, 38424, 38427, 38430, 38432,
- {f: 7, c: 38435}, {f: 3, c: 38443}, {f: 2, c: 38447}, {f: 4, c: 38455},
- 38462, 38465, 38467, 38474, {f: 2, c: 38478}, {f: 3, c: 38481},
- {f: 2, c: 38486}, {f: 2, c: 38489}, 38492, 38494, 38496, {f: 2, c: 38501},
- 38507, {f: 3, c: 38509}, 38513, {f: 4, c: 38521}, {f: 7, c: 38526}, 38535,
- 38537, 38540, {f: 3, c: 38545}, 38550, 38554, {f: 10, c: 38557}, 38569,
- {f: 5, c: 38571}, 38578, 38581, 38583, 38586, 38591, {f: 2, c: 38594},
- 38600, {f: 2, c: 38602}, {f: 2, c: 38608}, {f: 2, c: 38611},
- {f: 2, c: 38615}, 38618, {f: 3, c: 38621}, 38625, {f: 4, c: 38628},
- {f: 4, c: 38635}, {f: 2, c: 38640}, {f: 2, c: 38644}, 38648, 38650,
- {f: 2, c: 38652}, 38655, {f: 2, c: 38658}, 38661, {f: 3, c: 38666},
- {f: 3, c: 38672}, {f: 2, c: 38676}, {f: 5, c: 38679}, 38685,
- {f: 8, c: 38687}, {f: 2, c: 38696}, {f: 2, c: 38699}, {f: 2, c: 38702},
- 38705, {f: 5, c: 38707}, {f: 3, c: 38714}, {f: 3, c: 38719}, 38723,
- {f: 3, c: 38725}, {f: 8, c: 38729}, [12205, 38737], {f: 2, c: 38740},
- {f: 2, c: 38743}, {f: 2, c: 38748}, 38751, {f: 2, c: 38755},
- {f: 2, c: 38758}, {f: 9, c: 38762}, 38773, {f: 5, c: 38775},
- {f: 8, c: 38781}, {f: 5, c: 38790}, 38796, 38798, 38800, 38803,
- {f: 3, c: 38805}, {f: 7, c: 38809}, {f: 2, c: 38817}, {f: 2, c: 38820},
- {f: 4, c: 38823}, 38828, 38830, {f: 2, c: 38832}, 38835, {f: 8, c: 38837},
- {f: 5, c: 38846}, {f: 2, c: 38852}, {f: 2, c: 38855}, 38858,
- {f: 6, c: 38861}, {f: 5, c: 38868}, {f: 2, c: 38874}, 38877,
- {f: 7, c: 38879}, 38888, {f: 5, c: 38894}, 38900, {f: 8, c: 38903}, 38912,
- 38916, 38921, 38923, 38925, {f: 3, c: 38932}, {f: 3, c: 38937},
- {f: 4, c: 38941}, {f: 2, c: 38946}, 38949, {f: 6, c: 38951},
- {f: 2, c: 38958}, {f: 6, c: 38961}, {f: 2, c: 38969}, 38972,
- {f: 8, c: 38974}, {f: 5, c: 38983}, {f: 4, c: 38991}, {f: 3, c: 38997},
- 39002, {f: 2, c: 39004}, {f: 3, c: 39007}, {f: 2, c: 39011}, 39014,
- {f: 3, c: 39016}, {f: 2, c: 39021}, 39026, 39051, 39054, 39058, 39061,
- 39065, 39075, {f: 5, c: 39081}, 39088, 39090, {f: 2, c: 39092},
- {f: 5, c: 39095}, {f: 7, c: 39101}, 39109, 39111, {f: 5, c: 39113},
- {f: 2, c: 39119}, 39124, {f: 2, c: 39126}, {f: 2, c: 39132}, 39137,
- {f: 4, c: 39139}, 39148, 39150, {f: 2, c: 39152}, 39155, {f: 7, c: 39157},
- {f: 4, c: 39167}, 39172, {f: 3, c: 39174}, 39179, {f: 2, c: 39182},
- {f: 4, c: 39188}, {f: 2, c: 39193}, {f: 2, c: 39196}, {f: 2, c: 39199},
- {f: 6, c: 39202}, {f: 5, c: 39209}, {f: 4, c: 39215}, {f: 3, c: 39220},
- {f: 4, c: 39224}, 39229, {f: 3, c: 39232}, 39236, {f: 2, c: 39238},
- {f: 4, c: 39245}, 39251, 39254, {f: 4, c: 39256}, 39261, {f: 3, c: 39263},
- 39268, 39270, 39283, {f: 2, c: 39288}, 39291, 39294, {f: 2, c: 39298},
- 39305, 39308, 39310, {f: 11, c: 39322}, {f: 2, c: 39334}, {f: 3, c: 39337},
- {f: 2, c: 39343}, 39346, {f: 12, c: 39349}, {f: 14, c: 39362}, 39379,
- {f: 2, c: 39382}, 39386, 39388, 39390, 39392, {f: 10, c: 39395},
- {f: 3, c: 39406}, {f: 13, c: 39410}, 39424, {f: 3, c: 39426},
- {f: 7, c: 39430}, {f: 6, c: 39440}, {f: 2, c: 39447}, {f: 17, c: 39450},
- 39468, 39471, {f: 5, c: 39473}, {f: 5, c: 39481}, 39487, {f: 4, c: 39494},
- {f: 2, c: 39499}, 39502, {f: 5, c: 39504}, 39510, {f: 2, c: 39512},
- {f: 3, c: 39516}, {f: 2, c: 39520}, 39523, {f: 4, c: 39526}, 39531, 39538,
- 39555, 39561, {f: 2, c: 39565}, {f: 2, c: 39572}, 39577, 39590,
- {f: 6, c: 39593}, {f: 4, c: 39602}, 39609, 39611, {f: 3, c: 39613},
- {f: 2, c: 39619}, {f: 5, c: 39622}, {f: 2, c: 39629}, 39632, 39639,
- {f: 6, c: 39641}, 39648, {f: 4, c: 39650}, {f: 4, c: 39655}, 39660,
- {f: 9, c: 39664}, 39674, {f: 7, c: 39676}, {f: 2, c: 39684}, 39687,
- {f: 4, c: 39689}, 39694, {f: 3, c: 39696}, {f: 6, c: 39700},
- {f: 4, c: 39707}, {f: 2, c: 39712}, 39716, 39718, 39720, {f: 4, c: 39722},
- 39728, {f: 8, c: 39731}, {f: 4, c: 39741}, 39750, {f: 3, c: 39754}, 39760,
- {f: 2, c: 39762}, {f: 3, c: 39765}, 39769, {f: 20, c: 39771},
- {f: 4, c: 39792}, {f: 2, c: 39797}, {f: 9, c: 39800}, 39810,
- {f: 10, c: 39812}, 39823, {f: 7, c: 39827}, {f: 2, c: 39835},
- {f: 11, c: 39839}, 39852, {f: 17, c: 39855}, {f: 5, c: 39874}, 39880,
- {f: 9, c: 39883}, 39893, {f: 4, c: 39895}, 39900, {f: 3, c: 39902}, 39907,
- {f: 2, c: 39909}, 39913, {f: 4, c: 39916}, {f: 3, c: 39921},
- {f: 8, c: 39925}, 39934, {f: 8, c: 39936}, {f: 3, c: 39946},
- {f: 2, c: 39950}, 39953, {f: 12, c: 39956}, {f: 2, c: 39969}, 39972,
- {f: 2, c: 39974}, {f: 3, c: 39978}, {f: 3, c: 39982}, 39988, 39990, 39992,
- 39994, {f: 2, c: 39996}, {f: 6, c: 39999}, {f: 2, c: 40006},
- {f: 8, c: 40010}, 40019, 40021, {f: 4, c: 40025}, 40030, {f: 7, c: 40032},
- {f: 5, c: 40040}, {f: 10, c: 40046}, 40057, 40059, {f: 2, c: 40061}, 40064,
- {f: 2, c: 40067}, {f: 2, c: 40073}, 40076, 40079, 40083, {f: 4, c: 40086},
- 40093, 40106, 40108, 40111, 40121, {f: 5, c: 40126}, {f: 2, c: 40136},
- {f: 2, c: 40145}, {f: 2, c: 40154}, {f: 2, c: 40160}, {f: 2, c: 40163},
- {f: 3, c: 40166}, {f: 2, c: 40170}, {f: 6, c: 40173}, 40181,
- {f: 15, c: 40183}, 40200, {f: 11, c: 40202}, {f: 5, c: 40214}, 40220,
- 40222, {f: 3, c: 40224}, {f: 2, c: 40228}, 40231, {f: 6, c: 40233},
- {f: 10, c: 40241}, {f: 3, c: 40252}, {f: 2, c: 40256}, {f: 14, c: 40259},
- {f: 8, c: 40276}, {f: 2, c: 40286}, {f: 8, c: 40290}, 40299,
- {f: 2, c: 40301}, {f: 2, c: 40304}, {f: 20, c: 40307}, 40328,
- {f: 9, c: 40330}, {f: 4, c: 40340}, 40345, {f: 10, c: 40347},
- {f: 3, c: 40358}, {f: 5, c: 40362}, {f: 4, c: 40368}, {f: 6, c: 40373},
- {f: 3, c: 40381}, 40385, 40387, {f: 14, c: 40389}, {f: 3, c: 40404}, 40408,
- {f: 10, c: 40411}, {f: 8, c: 40423}, {f: 2, c: 40432}, {f: 4, c: 40436},
- {f: 17, c: 40443}, {f: 8, c: 40461}, {f: 4, c: 40470}, 40476, 40484, 40487,
- 40494, 40496, 40500, {f: 2, c: 40507}, 40512, 40525, 40528,
- {f: 3, c: 40530}, 40534, 40537, 40541, {f: 4, c: 40543}, 40549,
- {f: 2, c: 40558}, 40562, 40564, {f: 3, c: 40566}, 40571, {f: 2, c: 40576},
- {f: 4, c: 40579}, {f: 2, c: 40585}, {f: 6, c: 40588}, {f: 3, c: 40596},
- {f: 5, c: 40600}, 40606, {f: 5, c: 40608}, {f: 2, c: 40615},
- {f: 5, c: 40618}, {f: 4, c: 40624}, {f: 2, c: 40630}, {f: 2, c: 40633},
- 40636, {f: 4, c: 40639}, [12232, 40643], {f: 4, c: 40645},
- {f: 2, c: 40650}, 40656, {f: 2, c: 40658}, {f: 3, c: 40661},
- {f: 2, c: 40665}, 40673, {f: 2, c: 40675}, 40678, {f: 4, c: 40683},
- {f: 2, c: 40688}, 40691, {f: 2, c: 40693}, 40696, 40698, {f: 9, c: 40704},
- 40714, 40716, 40719, {f: 2, c: 40721}, 40724, 40726, 40728,
- {f: 6, c: 40730}, 40737, {f: 9, c: 40739}, {f: 2, c: 40749},
- {f: 7, c: 40752}, 40760, 40762, 40764, {f: 5, c: 40767}, {f: 5, c: 40773},
- {f: 3, c: 40780}, 40787, {f: 4, c: 40789}, {f: 2, c: 40794},
- {f: 2, c: 40797}, 40802, {f: 2, c: 40804}, {f: 3, c: 40807}, 40811,
- {f: 5, c: 40813}, {f: 4, c: 40819}, {f: 7, c: 40824}, {f: 2, c: 40833},
- {f: 2, c: 40846}, {f: 3, c: 40849}, {f: 3, c: 40854}, {f: 2, c: 40861},
- {f: 5, c: 40865}, 63788, {f: 3, c: 64013}, 64017, {f: 2, c: 64019}, 64024,
- {f: 3, c: 64031}, {f: 2, c: 64035}, {f: 3, c: 64039}, 11905,
- [59414, 131207], [59415, 131209], [59416, 131276], 11908, 13427, 13383,
- 11912, 11915, 59422, 13726, 13850, 13838, 11916, 11927, 14702, 14616,
- 59430, 14799, 14815, 14963, 14800, {f: 2, c: 59435}, 15182, 15470, 15584,
- 11943, [59441, 136663], 59442, 11946, 16470, 16735, 11950, 17207, 11955,
- {f: 2, c: 11958}, [59451, 141711], 17329, 17324, 11963, 17373, 17622,
- 18017, 17996, [59459, 132361], 18211, 18217, 18300, 18317, 11978, 18759,
- 18810, 18813, {f: 2, c: 18818}, {f: 2, c: 18821}, 18847, 18843, 18871,
- 18870, [59476, 133533], [59477, 147966], 19619, {f: 3, c: 19615}, 19575,
- 19618, {f: 7, c: 19731}, 19886, 59492, {s: 226}, 8364, 165, 0, 0, 12351,
- {s: 17}, 12436, {s: 14}, 12535, 12537, 12536, 12538, 0, {f: 3, c: 12339},
- {f: 3, c: 12344}, {f: 3, c: 12586}, {f: 24, c: 12704}, 11904,
- {f: 2, c: 11906}, {f: 3, c: 11909}, {f: 2, c: 11913}, {f: 10, c: 11917},
- {f: 2, c: 11928}, {f: 12, c: 11931}, {f: 2, c: 11944}, {f: 3, c: 11947},
- {f: 4, c: 11951}, {f: 2, c: 11956}, {f: 3, c: 11960}, {f: 14, c: 11964},
- {f: 41, c: 11979}, {f: 71, c: 13312}, {f: 43, c: 13384},
- {f: 298, c: 13428}, {f: 111, c: 13727}, {f: 11, c: 13839},
- {f: 765, c: 13851}, {f: 85, c: 14617}, {f: 96, c: 14703},
- {f: 14, c: 14801}, {f: 147, c: 14816}, {f: 218, c: 14964},
- {f: 287, c: 15183}, {f: 113, c: 15471}, {f: 885, c: 15585},
- {f: 264, c: 16471}, {f: 471, c: 16736}, {f: 116, c: 17208},
- {f: 4, c: 17325}, {f: 43, c: 17330}, {f: 248, c: 17374},
- {f: 373, c: 17623}, {f: 20, c: 17997}, {f: 193, c: 18018},
- {f: 5, c: 18212}, {f: 82, c: 18218}, {f: 16, c: 18301}, {f: 441, c: 18318},
- {f: 50, c: 18760}, {f: 2, c: 18811}, {f: 4, c: 18814}, 18820,
- {f: 20, c: 18823}, {f: 3, c: 18844}, {f: 22, c: 18848}, {f: 703, c: 18872},
- {f: 39, c: 19576}, {f: 111, c: 19620}, {f: 148, c: 19738},
- {f: 7, c: 19887}]
-};
-
-
-
-var ColorSpace = (function ColorSpaceClosure() {
- // Constructor should define this.numComps, this.defaultColor, this.name
- function ColorSpace() {
- error('should not call ColorSpace constructor');
- }
-
- ColorSpace.prototype = {
- /**
- * Converts the color value to the RGB color. The color components are
- * located in the src array starting from the srcOffset. Returns the array
- * of the rgb components, each value ranging from [0,255].
- */
- getRgb: function ColorSpace_getRgb(src, srcOffset) {
- error('Should not call ColorSpace.getRgb');
- },
- /**
- * Converts the color value to the RGB color, similar to the getRgb method.
- * The result placed into the dest array starting from the destOffset.
- */
- getRgbItem: function ColorSpace_getRgb(src, srcOffset, dest, destOffset) {
- error('Should not call ColorSpace.getRgbItem');
- },
- /**
- * Converts the specified number of the color values to the RGB colors.
- * The colors are located in the src array starting from the srcOffset.
- * The result is placed into the dest array starting from the destOffset.
- * The src array items shall be in [0,2^bits) range, the dest array items
- * will be in [0,255] range.
- */
- getRgbBuffer: function ColorSpace_getRgbBuffer(src, srcOffset, count,
- dest, destOffset, bits) {
- error('Should not call ColorSpace.getRgbBuffer');
- },
- /**
- * Determines amount of the bytes is required to store the reslut of the
- * conversion that done by the getRgbBuffer method.
- */
- getOutputLength: function ColorSpace_getOutputLength(inputLength) {
- error('Should not call ColorSpace.getOutputLength');
- },
- /**
- * Returns true if source data will be equal the result/output data.
- */
- isPassthrough: function ColorSpace_isPassthrough(bits) {
- return false;
- },
- /**
- * Creates the output buffer and converts the specified number of the color
- * values to the RGB colors, similar to the getRgbBuffer.
- */
- createRgbBuffer: function ColorSpace_createRgbBuffer(src, srcOffset,
- count, bits) {
- if (this.isPassthrough(bits)) {
- return src.subarray(srcOffset);
- }
- var dest = new Uint8Array(count * 3);
- var numComponentColors = 1 << bits;
- // Optimization: create a color map when there is just one component and
- // we are converting more colors than the size of the color map. We
- // don't build the map if the colorspace is gray or rgb since those
- // methods are faster than building a map. This mainly offers big speed
- // ups for indexed and alternate colorspaces.
- if (this.numComps === 1 && count > numComponentColors &&
- this.name !== 'DeviceGray' && this.name !== 'DeviceRGB') {
- // TODO it may be worth while to cache the color map. While running
- // testing I never hit a cache so I will leave that out for now (perhaps
- // we are reparsing colorspaces too much?).
- var allColors = bits <= 8 ? new Uint8Array(numComponentColors) :
- new Uint16Array(numComponentColors);
- for (var i = 0; i < numComponentColors; i++) {
- allColors[i] = i;
- }
- var colorMap = new Uint8Array(numComponentColors * 3);
- this.getRgbBuffer(allColors, 0, numComponentColors, colorMap, 0, bits);
-
- var destOffset = 0;
- for (var i = 0; i < count; ++i) {
- var key = src[srcOffset++] * 3;
- dest[destOffset++] = colorMap[key];
- dest[destOffset++] = colorMap[key + 1];
- dest[destOffset++] = colorMap[key + 2];
- }
- return dest;
- }
- this.getRgbBuffer(src, srcOffset, count, dest, 0, bits);
- return dest;
- },
- /**
- * True if the colorspace has components in the default range of [0, 1].
- * This should be true for all colorspaces except for lab color spaces
- * which are [0,100], [-128, 127], [-128, 127].
- */
- usesZeroToOneRange: true
- };
-
- ColorSpace.parse = function ColorSpace_parse(cs, xref, res) {
- var IR = ColorSpace.parseToIR(cs, xref, res);
- if (IR instanceof AlternateCS)
- return IR;
-
- return ColorSpace.fromIR(IR);
- };
-
- ColorSpace.fromIR = function ColorSpace_fromIR(IR) {
- var name = isArray(IR) ? IR[0] : IR;
-
- switch (name) {
- case 'DeviceGrayCS':
- return this.singletons.gray;
- case 'DeviceRgbCS':
- return this.singletons.rgb;
- case 'DeviceCmykCS':
- return this.singletons.cmyk;
- case 'PatternCS':
- var basePatternCS = IR[1];
- if (basePatternCS)
- basePatternCS = ColorSpace.fromIR(basePatternCS);
- return new PatternCS(basePatternCS);
- case 'IndexedCS':
- var baseIndexedCS = IR[1];
- var hiVal = IR[2];
- var lookup = IR[3];
- return new IndexedCS(ColorSpace.fromIR(baseIndexedCS), hiVal, lookup);
- case 'AlternateCS':
- var numComps = IR[1];
- var alt = IR[2];
- var tintFnIR = IR[3];
-
- return new AlternateCS(numComps, ColorSpace.fromIR(alt),
- PDFFunction.fromIR(tintFnIR));
- case 'LabCS':
- var whitePoint = IR[1].WhitePoint;
- var blackPoint = IR[1].BlackPoint;
- var range = IR[1].Range;
- return new LabCS(whitePoint, blackPoint, range);
- default:
- error('Unkown name ' + name);
- }
- return null;
- };
-
- ColorSpace.parseToIR = function ColorSpace_parseToIR(cs, xref, res) {
- if (isName(cs)) {
- var colorSpaces = res.get('ColorSpace');
- if (isDict(colorSpaces)) {
- var refcs = colorSpaces.get(cs.name);
- if (refcs)
- cs = refcs;
- }
- }
-
- cs = xref.fetchIfRef(cs);
- var mode;
-
- if (isName(cs)) {
- mode = cs.name;
- this.mode = mode;
-
- switch (mode) {
- case 'DeviceGray':
- case 'G':
- return 'DeviceGrayCS';
- case 'DeviceRGB':
- case 'RGB':
- return 'DeviceRgbCS';
- case 'DeviceCMYK':
- case 'CMYK':
- return 'DeviceCmykCS';
- case 'Pattern':
- return ['PatternCS', null];
- default:
- error('unrecognized colorspace ' + mode);
- }
- } else if (isArray(cs)) {
- mode = cs[0].name;
- this.mode = mode;
-
- switch (mode) {
- case 'DeviceGray':
- case 'G':
- return 'DeviceGrayCS';
- case 'DeviceRGB':
- case 'RGB':
- return 'DeviceRgbCS';
- case 'DeviceCMYK':
- case 'CMYK':
- return 'DeviceCmykCS';
- case 'CalGray':
- return 'DeviceGrayCS';
- case 'CalRGB':
- return 'DeviceRgbCS';
- case 'ICCBased':
- var stream = xref.fetchIfRef(cs[1]);
- var dict = stream.dict;
- var numComps = dict.get('N');
- if (numComps == 1)
- return 'DeviceGrayCS';
- if (numComps == 3)
- return 'DeviceRgbCS';
- if (numComps == 4)
- return 'DeviceCmykCS';
- break;
- case 'Pattern':
- var basePatternCS = cs[1];
- if (basePatternCS)
- basePatternCS = ColorSpace.parseToIR(basePatternCS, xref, res);
- return ['PatternCS', basePatternCS];
- case 'Indexed':
- case 'I':
- var baseIndexedCS = ColorSpace.parseToIR(cs[1], xref, res);
- var hiVal = cs[2] + 1;
- var lookup = xref.fetchIfRef(cs[3]);
- if (isStream(lookup)) {
- lookup = lookup.getBytes();
- }
- return ['IndexedCS', baseIndexedCS, hiVal, lookup];
- case 'Separation':
- case 'DeviceN':
- var name = cs[1];
- var numComps = 1;
- if (isName(name))
- numComps = 1;
- else if (isArray(name))
- numComps = name.length;
- var alt = ColorSpace.parseToIR(cs[2], xref, res);
- var tintFnIR = PDFFunction.getIR(xref, xref.fetchIfRef(cs[3]));
- return ['AlternateCS', numComps, alt, tintFnIR];
- case 'Lab':
- var params = cs[1].getAll();
- return ['LabCS', params];
- default:
- error('unimplemented color space object "' + mode + '"');
- }
- } else {
- error('unrecognized color space object: "' + cs + '"');
- }
- return null;
- };
- /**
- * Checks if a decode map matches the default decode map for a color space.
- * This handles the general decode maps where there are two values per
- * component. e.g. [0, 1, 0, 1, 0, 1] for a RGB color.
- * This does not handle Lab, Indexed, or Pattern decode maps since they are
- * slightly different.
- * @param {Array} decode Decode map (usually from an image).
- * @param {Number} n Number of components the color space has.
- */
- ColorSpace.isDefaultDecode = function ColorSpace_isDefaultDecode(decode, n) {
- if (!decode)
- return true;
-
- if (n * 2 !== decode.length) {
- warn('The decode map is not the correct length');
- return true;
- }
- for (var i = 0, ii = decode.length; i < ii; i += 2) {
- if (decode[i] !== 0 || decode[i + 1] != 1)
- return false;
- }
- return true;
- };
-
- ColorSpace.singletons = {
- get gray() {
- return shadow(this, 'gray', new DeviceGrayCS());
- },
- get rgb() {
- return shadow(this, 'rgb', new DeviceRgbCS());
- },
- get cmyk() {
- return shadow(this, 'cmyk', new DeviceCmykCS());
- }
- };
-
- return ColorSpace;
-})();
-
-/**
- * Alternate color space handles both Separation and DeviceN color spaces. A
- * Separation color space is actually just a DeviceN with one color component.
- * Both color spaces use a tinting function to convert colors to a base color
- * space.
- */
-var AlternateCS = (function AlternateCSClosure() {
- function AlternateCS(numComps, base, tintFn) {
- this.name = 'Alternate';
- this.numComps = numComps;
- this.defaultColor = new Float32Array(numComps);
- for (var i = 0; i < numComps; ++i) {
- this.defaultColor[i] = 1;
- }
- this.base = base;
- this.tintFn = tintFn;
- }
-
- AlternateCS.prototype = {
- getRgb: function AlternateCS_getRgb(src, srcOffset) {
- var rgb = new Uint8Array(3);
- this.getRgbItem(src, srcOffset, rgb, 0);
- return rgb;
- },
- getRgbItem: function AlternateCS_getRgbItem(src, srcOffset,
- dest, destOffset) {
- var baseNumComps = this.base.numComps;
- var input = 'subarray' in src ?
- src.subarray(srcOffset, srcOffset + this.numComps) :
- Array.prototype.slice.call(src, srcOffset, srcOffset + this.numComps);
- var tinted = this.tintFn(input);
- this.base.getRgbItem(tinted, 0, dest, destOffset);
- },
- getRgbBuffer: function AlternateCS_getRgbBuffer(src, srcOffset, count,
- dest, destOffset, bits) {
- var tintFn = this.tintFn;
- var base = this.base;
- var scale = 1 / ((1 << bits) - 1);
- var baseNumComps = base.numComps;
- var usesZeroToOneRange = base.usesZeroToOneRange;
- var isPassthrough = base.isPassthrough(8) || !usesZeroToOneRange;
- var pos = isPassthrough ? destOffset : 0;
- var baseBuf = isPassthrough ? dest : new Uint8Array(baseNumComps * count);
- var numComps = this.numComps;
-
- var scaled = new Float32Array(numComps);
- for (var i = 0; i < count; i++) {
- for (var j = 0; j < numComps; j++) {
- scaled[j] = src[srcOffset++] * scale;
- }
- var tinted = tintFn(scaled);
- if (usesZeroToOneRange) {
- for (var j = 0; j < baseNumComps; j++) {
- baseBuf[pos++] = tinted[j] * 255;
- }
- } else {
- base.getRgbItem(tinted, 0, baseBuf, pos);
- pos += baseNumComps;
- }
- }
- if (!isPassthrough) {
- base.getRgbBuffer(baseBuf, 0, count, dest, destOffset, 8);
- }
- },
- getOutputLength: function AlternateCS_getOutputLength(inputLength) {
- return this.base.getOutputLength(inputLength *
- this.base.numComps / this.numComps);
- },
- isPassthrough: ColorSpace.prototype.isPassthrough,
- createRgbBuffer: ColorSpace.prototype.createRgbBuffer,
- isDefaultDecode: function AlternateCS_isDefaultDecode(decodeMap) {
- return ColorSpace.isDefaultDecode(decodeMap, this.numComps);
- },
- usesZeroToOneRange: true
- };
-
- return AlternateCS;
-})();
-
-var PatternCS = (function PatternCSClosure() {
- function PatternCS(baseCS) {
- this.name = 'Pattern';
- this.base = baseCS;
- }
- PatternCS.prototype = {};
-
- return PatternCS;
-})();
-
-var IndexedCS = (function IndexedCSClosure() {
- function IndexedCS(base, highVal, lookup) {
- this.name = 'Indexed';
- this.numComps = 1;
- this.defaultColor = new Uint8Array([0]);
- this.base = base;
- this.highVal = highVal;
-
- var baseNumComps = base.numComps;
- var length = baseNumComps * highVal;
- var lookupArray;
-
- if (isStream(lookup)) {
- lookupArray = new Uint8Array(length);
- var bytes = lookup.getBytes(length);
- lookupArray.set(bytes);
- } else if (isString(lookup)) {
- lookupArray = new Uint8Array(length);
- for (var i = 0; i < length; ++i)
- lookupArray[i] = lookup.charCodeAt(i);
- } else if (lookup instanceof Uint8Array || lookup instanceof Array) {
- lookupArray = lookup;
- } else {
- error('Unrecognized lookup table: ' + lookup);
- }
- this.lookup = lookupArray;
- }
-
- IndexedCS.prototype = {
- getRgb: function IndexedCS_getRgb(src, srcOffset) {
- var numComps = this.base.numComps;
- var start = src[srcOffset] * numComps;
- return this.base.getRgb(this.lookup, start);
- },
- getRgbItem: function IndexedCS_getRgbItem(src, srcOffset,
- dest, destOffset) {
- var numComps = this.base.numComps;
- var start = src[srcOffset] * numComps;
- this.base.getRgbItem(this.lookup, start, dest, destOffset);
- },
- getRgbBuffer: function IndexedCS_getRgbBuffer(src, srcOffset, count,
- dest, destOffset) {
- var base = this.base;
- var numComps = base.numComps;
- var outputDelta = base.getOutputLength(numComps);
- var lookup = this.lookup;
-
- for (var i = 0; i < count; ++i) {
- var lookupPos = src[srcOffset++] * numComps;
- base.getRgbBuffer(lookup, lookupPos, 1, dest, destOffset, 8);
- destOffset += outputDelta;
- }
- },
- getOutputLength: function IndexedCS_getOutputLength(inputLength) {
- return this.base.getOutputLength(inputLength * this.base.numComps);
- },
- isPassthrough: ColorSpace.prototype.isPassthrough,
- createRgbBuffer: ColorSpace.prototype.createRgbBuffer,
- isDefaultDecode: function IndexedCS_isDefaultDecode(decodeMap) {
- // indexed color maps shouldn't be changed
- return true;
- },
- usesZeroToOneRange: true
- };
- return IndexedCS;
-})();
-
-var DeviceGrayCS = (function DeviceGrayCSClosure() {
- function DeviceGrayCS() {
- this.name = 'DeviceGray';
- this.numComps = 1;
- this.defaultColor = new Float32Array([0]);
- }
-
- DeviceGrayCS.prototype = {
- getRgb: function DeviceGrayCS_getRgb(src, srcOffset) {
- var rgb = new Uint8Array(3);
- this.getRgbItem(src, srcOffset, rgb, 0);
- return rgb;
- },
- getRgbItem: function DeviceGrayCS_getRgbItem(src, srcOffset,
- dest, destOffset) {
- var c = (src[srcOffset] * 255) | 0;
- c = c < 0 ? 0 : c > 255 ? 255 : c;
- dest[destOffset] = dest[destOffset + 1] = dest[destOffset + 2] = c;
- },
- getRgbBuffer: function DeviceGrayCS_getRgbBuffer(src, srcOffset, count,
- dest, destOffset, bits) {
- var scale = 255 / ((1 << bits) - 1);
- var j = srcOffset, q = destOffset;
- for (var i = 0; i < count; ++i) {
- var c = (scale * src[j++]) | 0;
- dest[q++] = c;
- dest[q++] = c;
- dest[q++] = c;
- }
- },
- getOutputLength: function DeviceGrayCS_getOutputLength(inputLength) {
- return inputLength * 3;
- },
- isPassthrough: ColorSpace.prototype.isPassthrough,
- createRgbBuffer: ColorSpace.prototype.createRgbBuffer,
- isDefaultDecode: function DeviceGrayCS_isDefaultDecode(decodeMap) {
- return ColorSpace.isDefaultDecode(decodeMap, this.numComps);
- },
- usesZeroToOneRange: true
- };
- return DeviceGrayCS;
-})();
-
-var DeviceRgbCS = (function DeviceRgbCSClosure() {
- function DeviceRgbCS() {
- this.name = 'DeviceRGB';
- this.numComps = 3;
- this.defaultColor = new Float32Array([0, 0, 0]);
- }
- DeviceRgbCS.prototype = {
- getRgb: function DeviceRgbCS_getRgb(src, srcOffset) {
- var rgb = new Uint8Array(3);
- this.getRgbItem(src, srcOffset, rgb, 0);
- return rgb;
- },
- getRgbItem: function DeviceRgbCS_getRgbItem(src, srcOffset,
- dest, destOffset) {
- var r = (src[srcOffset] * 255) | 0;
- var g = (src[srcOffset + 1] * 255) | 0;
- var b = (src[srcOffset + 2] * 255) | 0;
- dest[destOffset] = r < 0 ? 0 : r > 255 ? 255 : r;
- dest[destOffset + 1] = g < 0 ? 0 : g > 255 ? 255 : g;
- dest[destOffset + 2] = b < 0 ? 0 : b > 255 ? 255 : b;
- },
- getRgbBuffer: function DeviceRgbCS_getRgbBuffer(src, srcOffset, count,
- dest, destOffset, bits) {
- var length = count * 3;
- if (bits == 8) {
- dest.set(src.subarray(srcOffset, srcOffset + length), destOffset);
- return;
- }
- var scale = 255 / ((1 << bits) - 1);
- var j = srcOffset, q = destOffset;
- for (var i = 0; i < length; ++i) {
- dest[q++] = (scale * src[j++]) | 0;
- }
- },
- getOutputLength: function DeviceRgbCS_getOutputLength(inputLength) {
- return inputLength;
- },
- isPassthrough: function DeviceRgbCS_isPassthrough(bits) {
- return bits == 8;
- },
- createRgbBuffer: ColorSpace.prototype.createRgbBuffer,
- isDefaultDecode: function DeviceRgbCS_isDefaultDecode(decodeMap) {
- return ColorSpace.isDefaultDecode(decodeMap, this.numComps);
- },
- usesZeroToOneRange: true
- };
- return DeviceRgbCS;
-})();
-
-var DeviceCmykCS = (function DeviceCmykCSClosure() {
- // The coefficients below was found using numerical analysis: the method of
- // steepest descent for the sum((f_i - color_value_i)^2) for r/g/b colors,
- // where color_value is the tabular value from the table of sampled RGB colors
- // from CMYK US Web Coated (SWOP) colorspace, and f_i is the corresponding
- // CMYK color conversion using the estimation below:
- // f(A, B,.. N) = Acc+Bcm+Ccy+Dck+c+Fmm+Gmy+Hmk+Im+Jyy+Kyk+Ly+Mkk+Nk+255
- function convertToRgb(src, srcOffset, srcScale, dest, destOffset) {
- var c = src[srcOffset + 0] * srcScale;
- var m = src[srcOffset + 1] * srcScale;
- var y = src[srcOffset + 2] * srcScale;
- var k = src[srcOffset + 3] * srcScale;
-
- var r =
- c * (-4.387332384609988 * c + 54.48615194189176 * m +
- 18.82290502165302 * y + 212.25662451639585 * k +
- -285.2331026137004) +
- m * (1.7149763477362134 * m - 5.6096736904047315 * y +
- -17.873870861415444 * k - 5.497006427196366) +
- y * (-2.5217340131683033 * y - 21.248923337353073 * k +
- 17.5119270841813) +
- k * (-21.86122147463605 * k - 189.48180835922747) + 255;
- var g =
- c * (8.841041422036149 * c + 60.118027045597366 * m +
- 6.871425592049007 * y + 31.159100130055922 * k +
- -79.2970844816548) +
- m * (-15.310361306967817 * m + 17.575251261109482 * y +
- 131.35250912493976 * k - 190.9453302588951) +
- y * (4.444339102852739 * y + 9.8632861493405 * k - 24.86741582555878) +
- k * (-20.737325471181034 * k - 187.80453709719578) + 255;
- var b =
- c * (0.8842522430003296 * c + 8.078677503112928 * m +
- 30.89978309703729 * y - 0.23883238689178934 * k +
- -14.183576799673286) +
- m * (10.49593273432072 * m + 63.02378494754052 * y +
- 50.606957656360734 * k - 112.23884253719248) +
- y * (0.03296041114873217 * y + 115.60384449646641 * k +
- -193.58209356861505) +
- k * (-22.33816807309886 * k - 180.12613974708367) + 255;
-
- dest[destOffset] = r > 255 ? 255 : r < 0 ? 0 : r;
- dest[destOffset + 1] = g > 255 ? 255 : g < 0 ? 0 : g;
- dest[destOffset + 2] = b > 255 ? 255 : b < 0 ? 0 : b;
- }
-
- function DeviceCmykCS() {
- this.name = 'DeviceCMYK';
- this.numComps = 4;
- this.defaultColor = new Float32Array([0, 0, 0, 1]);
- }
- DeviceCmykCS.prototype = {
- getRgb: function DeviceCmykCS_getRgb(src, srcOffset) {
- var rgb = new Uint8Array(3);
- convertToRgb(src, srcOffset, 1, rgb, 0);
- return rgb;
- },
- getRgbItem: function DeviceCmykCS_getRgbItem(src, srcOffset,
- dest, destOffset) {
- convertToRgb(src, srcOffset, 1, dest, destOffset);
- },
- getRgbBuffer: function DeviceCmykCS_getRgbBuffer(src, srcOffset, count,
- dest, destOffset, bits) {
- var scale = 1 / ((1 << bits) - 1);
- for (var i = 0; i < count; i++) {
- convertToRgb(src, srcOffset, scale, dest, destOffset);
- srcOffset += 4;
- destOffset += 3;
- }
- },
- getOutputLength: function DeviceCmykCS_getOutputLength(inputLength) {
- return (inputLength >> 2) * 3;
- },
- isPassthrough: ColorSpace.prototype.isPassthrough,
- createRgbBuffer: ColorSpace.prototype.createRgbBuffer,
- isDefaultDecode: function DeviceCmykCS_isDefaultDecode(decodeMap) {
- return ColorSpace.isDefaultDecode(decodeMap, this.numComps);
- },
- usesZeroToOneRange: true
- };
-
- return DeviceCmykCS;
-})();
-
-//
-// LabCS: Based on "PDF Reference, Sixth Ed", p.250
-//
-var LabCS = (function LabCSClosure() {
- function LabCS(whitePoint, blackPoint, range) {
- this.name = 'Lab';
- this.numComps = 3;
- this.defaultColor = new Float32Array([0, 0, 0]);
-
- if (!whitePoint)
- error('WhitePoint missing - required for color space Lab');
- blackPoint = blackPoint || [0, 0, 0];
- range = range || [-100, 100, -100, 100];
-
- // Translate args to spec variables
- this.XW = whitePoint[0];
- this.YW = whitePoint[1];
- this.ZW = whitePoint[2];
- this.amin = range[0];
- this.amax = range[1];
- this.bmin = range[2];
- this.bmax = range[3];
-
- // These are here just for completeness - the spec doesn't offer any
- // formulas that use BlackPoint in Lab
- this.XB = blackPoint[0];
- this.YB = blackPoint[1];
- this.ZB = blackPoint[2];
-
- // Validate vars as per spec
- if (this.XW < 0 || this.ZW < 0 || this.YW !== 1)
- error('Invalid WhitePoint components, no fallback available');
-
- if (this.XB < 0 || this.YB < 0 || this.ZB < 0) {
- info('Invalid BlackPoint, falling back to default');
- this.XB = this.YB = this.ZB = 0;
- }
-
- if (this.amin > this.amax || this.bmin > this.bmax) {
- info('Invalid Range, falling back to defaults');
- this.amin = -100;
- this.amax = 100;
- this.bmin = -100;
- this.bmax = 100;
- }
- }
-
- // Function g(x) from spec
- function fn_g(x) {
- if (x >= 6 / 29)
- return x * x * x;
- else
- return (108 / 841) * (x - 4 / 29);
- }
-
- function decode(value, high1, low2, high2) {
- return low2 + (value) * (high2 - low2) / (high1);
- }
-
- // If decoding is needed maxVal should be 2^bits per component - 1.
- function convertToRgb(cs, src, srcOffset, maxVal, dest, destOffset) {
- // XXX: Lab input is in the range of [0, 100], [amin, amax], [bmin, bmax]
- // not the usual [0, 1]. If a command like setFillColor is used the src
- // values will already be within the correct range. However, if we are
- // converting an image we have to map the values to the correct range given
- // above.
- // Ls,as,bs <---> L*,a*,b* in the spec
- var Ls = src[srcOffset];
- var as = src[srcOffset + 1];
- var bs = src[srcOffset + 2];
- if (maxVal !== false) {
- Ls = decode(Ls, maxVal, 0, 100);
- as = decode(as, maxVal, cs.amin, cs.amax);
- bs = decode(bs, maxVal, cs.bmin, cs.bmax);
- }
-
- // Adjust limits of 'as' and 'bs'
- as = as > cs.amax ? cs.amax : as < cs.amin ? cs.amin : as;
- bs = bs > cs.bmax ? cs.bmax : bs < cs.bmin ? cs.bmin : bs;
-
- // Computes intermediate variables X,Y,Z as per spec
- var M = (Ls + 16) / 116;
- var L = M + (as / 500);
- var N = M - (bs / 200);
-
- var X = cs.XW * fn_g(L);
- var Y = cs.YW * fn_g(M);
- var Z = cs.ZW * fn_g(N);
-
- var r, g, b;
- // Using different conversions for D50 and D65 white points,
- // per http://www.color.org/srgb.pdf
- if (cs.ZW < 1) {
- // Assuming D50 (X=0.9642, Y=1.00, Z=0.8249)
- r = X * 3.1339 + Y * -1.6170 + Z * -0.4906;
- g = X * -0.9785 + Y * 1.9160 + Z * 0.0333;
- b = X * 0.0720 + Y * -0.2290 + Z * 1.4057;
- } else {
- // Assuming D65 (X=0.9505, Y=1.00, Z=1.0888)
- r = X * 3.2406 + Y * -1.5372 + Z * -0.4986;
- g = X * -0.9689 + Y * 1.8758 + Z * 0.0415;
- b = X * 0.0557 + Y * -0.2040 + Z * 1.0570;
- }
- // clamp color values to [0,1] range then convert to [0,255] range.
- dest[destOffset] = Math.sqrt(r < 0 ? 0 : r > 1 ? 1 : r) * 255;
- dest[destOffset + 1] = Math.sqrt(g < 0 ? 0 : g > 1 ? 1 : g) * 255;
- dest[destOffset + 2] = Math.sqrt(b < 0 ? 0 : b > 1 ? 1 : b) * 255;
- }
+ {f: 5, c: 31099}, {f: 2, c: 31106}, {f: 4, c: 31110}, {f: 2, c: 31115},
+ {f: 10, c: 31120}, {f: 11, c: 31131}, {f: 2, c: 31144}, {f: 3, c: 31147},
+ 31151, 31154, {f: 4, c: 31156}, [12145, 31160], 31164, 31167, 31170,
+ {f: 2, c: 31172}, {f: 2, c: 31175}, 31178, 31180, {f: 3, c: 31182},
+ {f: 2, c: 31187}, {f: 2, c: 31190}, {f: 6, c: 31193}, {f: 3, c: 31200},
+ 31205, 31208, 31210, 31212, 31214, {f: 7, c: 31217}, {f: 2, c: 31225},
+ 31228, {f: 2, c: 31230}, 31233, {f: 2, c: 31236}, {f: 4, c: 31239}, 31244,
+ {f: 5, c: 31247}, {f: 2, c: 31253}, {f: 2, c: 31256}, {f: 3, c: 31259},
+ 31263, {f: 2, c: 31265}, {f: 10, c: 31268}, {f: 2, c: 31279}, 31282,
+ {f: 3, c: 31284}, 31288, 31290, 31294, {f: 5, c: 31297}, {f: 5, c: 31303},
+ {f: 2, c: 31311}, {f: 5, c: 31314}, {f: 9, c: 31320}, {f: 6, c: 31331},
+ 31338, {f: 4, c: 31340}, {f: 3, c: 31345}, 31349, {f: 4, c: 31355}, 31362,
+ 31365, 31367, {f: 4, c: 31369}, {f: 3, c: 31374}, {f: 2, c: 31379},
+ {f: 3, c: 31385}, 31390, {f: 4, c: 31393}, 31399, 31403, {f: 4, c: 31407},
+ {f: 2, c: 31412}, {f: 3, c: 31415}, {f: 4, c: 31419}, {f: 4, c: 31424},
+ 31430, 31433, {f: 10, c: 31436}, {f: 2, c: 31447}, {f: 4, c: 31450},
+ {f: 2, c: 31457}, 31460, {f: 3, c: 31463}, {f: 2, c: 31467}, 31470,
+ {f: 6, c: 31472}, {f: 2, c: 31479}, {f: 2, c: 31483}, 31486,
+ {f: 3, c: 31488}, 31493, 31495, 31497, {f: 3, c: 31500}, 31504,
+ {f: 2, c: 31506}, {f: 3, c: 31510}, 31514, {f: 2, c: 31516}, 31519,
+ {f: 3, c: 31521}, 31527, 31529, 31533, {f: 2, c: 31535}, 31538,
+ {f: 4, c: 31540}, 31545, 31547, 31549, {f: 6, c: 31551}, 31560, 31562,
+ {f: 2, c: 31565}, 31571, 31573, 31575, 31577, 31580, {f: 2, c: 31582},
+ 31585, {f: 4, c: 31587}, {f: 6, c: 31592}, {f: 2, c: 31599},
+ {f: 2, c: 31603}, 31606, 31608, 31610, {f: 2, c: 31612}, 31615,
+ {f: 4, c: 31617}, {f: 5, c: 31622}, 31628, {f: 2, c: 31630},
+ {f: 3, c: 31633}, 31638, {f: 4, c: 31640}, {f: 3, c: 31646},
+ {f: 3, c: 31651}, {f: 3, c: 31662}, {f: 2, c: 31666}, {f: 3, c: 31669},
+ {f: 7, c: 31673}, {f: 2, c: 31682}, 31685, 31688, 31690, {f: 4, c: 31693},
+ 31698, {f: 5, c: 31700}, {f: 2, c: 31707}, {f: 3, c: 31710},
+ {f: 2, c: 31714}, {f: 2, c: 31719}, {f: 3, c: 31723}, {f: 2, c: 31727},
+ 31730, {f: 3, c: 31732}, {f: 4, c: 31736}, 31741, 31743, {f: 6, c: 31745},
+ {f: 3, c: 31752}, 31758, {f: 6, c: 31760}, {f: 7, c: 31767}, 31776, 31778,
+ {f: 2, c: 31780}, {f: 2, c: 31784}, {f: 12, c: 31788}, {f: 4, c: 31801},
+ 31810, {f: 8, c: 31812}, {f: 14, c: 31822}, {f: 2, c: 31837},
+ {f: 3, c: 31841}, {f: 4, c: 31845}, 31851, 31853, {f: 3, c: 31855},
+ {f: 6, c: 31861}, {f: 11, c: 31870}, {f: 7, c: 31882}, {f: 2, c: 31891},
+ 31894, {f: 3, c: 31897}, {f: 2, c: 31904}, 31907, {f: 4, c: 31910},
+ {f: 3, c: 31915}, {f: 2, c: 31919}, {f: 5, c: 31924}, {f: 2, c: 31930},
+ {f: 2, c: 31935}, {f: 3, c: 31938}, 31942, 31945, 31947, {f: 7, c: 31950},
+ 31960, {f: 2, c: 31962}, {f: 6, c: 31969}, {f: 6, c: 31977}, 31985, 31987,
+ 31989, 31991, 31994, {f: 2, c: 31996}, 31999, 32001, 32003, 32012,
+ {f: 2, c: 32014}, {f: 2, c: 32017}, 32022, 32024, {f: 3, c: 32029},
+ {f: 4, c: 32035}, {f: 3, c: 32040}, {f: 3, c: 32044}, {f: 5, c: 32052},
+ 32059, {f: 2, c: 32061}, 32065, 32067, 32069, {f: 7, c: 32071}, 32079,
+ {f: 12, c: 32081}, {f: 2, c: 32095}, {f: 3, c: 32099}, 32103,
+ {f: 5, c: 32105}, {f: 2, c: 32111}, {f: 2, c: 32116}, 32120,
+ {f: 7, c: 32122}, 32130, {f: 2, c: 32132}, 32135, {f: 5, c: 32138},
+ {f: 3, c: 32144}, {f: 8, c: 32148}, 32157, {f: 3, c: 32159},
+ {f: 2, c: 32164}, {f: 4, c: 32167}, 32175, {f: 3, c: 32181}, 32188,
+ {f: 4, c: 32192}, {f: 2, c: 32197}, {f: 2, c: 32200}, {f: 5, c: 32204},
+ 32211, {f: 2, c: 32213}, {f: 3, c: 32218}, 32223, 32226, {f: 2, c: 32228},
+ 32231, {f: 2, c: 32234}, {f: 2, c: 32237}, 32240, 32243, 32245,
+ {f: 2, c: 32247}, 32250, {f: 12, c: 32252}, {f: 4, c: 32268},
+ {f: 9, c: 32274}, 32284, {f: 3, c: 32288}, {f: 3, c: 32292},
+ {f: 3, c: 32296}, 32300, {f: 2, c: 32303}, 32307, 32312, 32314, 32316,
+ {f: 2, c: 32319}, {f: 3, c: 32322}, {f: 10, c: 32328}, 32339,
+ {f: 4, c: 32342}, {f: 3, c: 32347}, {f: 3, c: 32351}, {f: 6, c: 32355},
+ 32364, {f: 2, c: 32369}, {f: 5, c: 32372}, {f: 2, c: 32378},
+ {f: 3, c: 32383}, {f: 5, c: 32387}, 32393, 32395, 32398, {f: 3, c: 32400},
+ 32405, 32407, {f: 2, c: 32409}, {f: 2, c: 32413}, 32430, 32436,
+ {f: 2, c: 32443}, 32470, 32484, 32492, 32505, 32522, 32528, 32542, 32567,
+ 32569, {f: 7, c: 32571}, 32579, {f: 6, c: 32582}, 32589, 32591,
+ {f: 2, c: 32594}, 32598, 32601, {f: 4, c: 32603}, 32608, {f: 5, c: 32611},
+ {f: 3, c: 32619}, 32623, 32627, {f: 2, c: 32629}, 32632, {f: 4, c: 32634},
+ {f: 2, c: 32639}, {f: 3, c: 32642}, 32647, 32649, 32651, 32653,
+ {f: 5, c: 32655}, {f: 5, c: 32661}, {f: 2, c: 32667}, 32672,
+ {f: 2, c: 32674}, 32678, 32680, {f: 5, c: 32682}, 32689, {f: 5, c: 32691},
+ {f: 2, c: 32698}, 32702, 32704, {f: 3, c: 32706}, {f: 4, c: 32710}, 32715,
+ 32717, {f: 3, c: 32719}, 32723, {f: 2, c: 32726}, {f: 6, c: 32729},
+ {f: 3, c: 32738}, {f: 2, c: 32743}, {f: 4, c: 32746}, 32751, 32754,
+ {f: 5, c: 32756}, 32762, {f: 3, c: 32765}, 32770, {f: 4, c: 32775},
+ {f: 2, c: 32782}, 32785, 32787, {f: 2, c: 32794}, {f: 3, c: 32797}, 32801,
+ {f: 2, c: 32803}, 32811, 32813, {f: 2, c: 32815}, 32818, 32820,
+ {f: 2, c: 32825}, 32828, 32830, {f: 2, c: 32832}, {f: 2, c: 32836},
+ {f: 3, c: 32839}, {f: 4, c: 32846}, 32851, 32853, 32855, 32857,
+ {f: 3, c: 32859}, {f: 10, c: 32863}, {f: 4, c: 32875}, 32884, 32888,
+ {f: 3, c: 32890}, {f: 2, c: 32897}, 32904, 32906, {f: 6, c: 32909},
+ {f: 2, c: 32916}, 32919, 32921, 32926, 32931, {f: 3, c: 32934}, 32940,
+ 32944, 32947, {f: 2, c: 32949}, {f: 2, c: 32952}, 32955, 32965,
+ {f: 5, c: 32967}, {f: 7, c: 32975}, 32984, {f: 2, c: 32991},
+ {f: 2, c: 32994}, 32998, 33006, 33013, 33015, 33017, 33019,
+ {f: 4, c: 33022}, {f: 2, c: 33027}, {f: 2, c: 33031}, {f: 2, c: 33035},
+ 33045, 33047, 33049, {f: 2, c: 33052}, {f: 13, c: 33055}, {f: 2, c: 33069},
+ 33072, {f: 3, c: 33075}, 33079, {f: 4, c: 33082}, {f: 7, c: 33087}, 33095,
+ 33097, 33101, 33103, 33106, {f: 2, c: 33111}, {f: 5, c: 33115},
+ {f: 3, c: 33122}, 33128, 33130, 33132, 33135, {f: 2, c: 33138},
+ {f: 3, c: 33141}, 33153, {f: 5, c: 33155}, 33161, {f: 4, c: 33163}, 33168,
+ {f: 6, c: 33170}, 33177, {f: 2, c: 33182}, {f: 2, c: 33185},
+ {f: 2, c: 33188}, 33191, {f: 8, c: 33195}, {f: 6, c: 33204}, 33212,
+ {f: 2, c: 33220}, {f: 2, c: 33223}, 33227, 33230, {f: 8, c: 33232}, 33241,
+ {f: 4, c: 33243}, {f: 2, c: 33249}, {f: 3, c: 33252}, 33257, 33259,
+ {f: 5, c: 33262}, {f: 5, c: 33269}, 33277, 33279, 33283, 33291,
+ {f: 2, c: 33294}, 33297, 33299, {f: 6, c: 33301}, 33309, 33312,
+ {f: 4, c: 33316}, 33321, 33326, 33330, 33338, {f: 2, c: 33340},
+ {f: 5, c: 33343}, {f: 2, c: 33349}, 33352, 33354, {f: 3, c: 33356},
+ {f: 8, c: 33360}, {f: 4, c: 33371}, {f: 4, c: 33376}, 33381, 33383,
+ {f: 2, c: 33385}, {f: 2, c: 33388}, {f: 2, c: 33397}, [12171, 33400],
+ {f: 2, c: 33403}, {f: 2, c: 33408}, 33411, {f: 3, c: 33413}, 33417, 33420,
+ 33424, {f: 4, c: 33427}, {f: 2, c: 33434}, 33438, 33440, {f: 2, c: 33442},
+ 33447, 33458, {f: 2, c: 33461}, 33466, 33468, {f: 2, c: 33471},
+ {f: 2, c: 33474}, {f: 2, c: 33477}, 33481, 33488, 33494, {f: 2, c: 33497},
+ 33501, 33506, {f: 3, c: 33512}, {f: 3, c: 33516}, 33520, {f: 2, c: 33522},
+ {f: 2, c: 33525}, 33528, 33530, {f: 5, c: 33532}, {f: 2, c: 33546}, 33549,
+ 33552, {f: 2, c: 33554}, 33558, {f: 2, c: 33560}, {f: 10, c: 33565},
+ {f: 2, c: 33577}, 33582, 33584, 33586, 33591, 33595, {f: 3, c: 33597},
+ {f: 2, c: 33601}, {f: 2, c: 33604}, 33608, {f: 5, c: 33610}, 33619,
+ {f: 5, c: 33621}, 33629, 33634, {f: 7, c: 33648}, {f: 2, c: 33657},
+ {f: 7, c: 33662}, {f: 2, c: 33671}, {f: 3, c: 33675}, {f: 3, c: 33679},
+ {f: 2, c: 33684}, 33687, {f: 2, c: 33689}, 33693, 33695, 33697,
+ {f: 4, c: 33699}, {f: 4, c: 33708}, 33717, 33723, {f: 2, c: 33726},
+ {f: 3, c: 33730}, 33734, {f: 2, c: 33736}, 33739, {f: 2, c: 33741},
+ {f: 4, c: 33744}, 33749, 33751, {f: 3, c: 33753}, 33758, {f: 3, c: 33762},
+ {f: 3, c: 33766}, {f: 4, c: 33771}, {f: 5, c: 33779}, {f: 3, c: 33786},
+ {f: 3, c: 33790}, 33794, 33797, {f: 2, c: 33800}, 33808, {f: 6, c: 33810},
+ {f: 3, c: 33817}, {f: 6, c: 33822}, {f: 3, c: 33833}, {f: 4, c: 33837},
+ {f: 3, c: 33842}, {f: 2, c: 33846}, {f: 3, c: 33849}, {f: 8, c: 33854},
+ {f: 2, c: 33863}, {f: 7, c: 33866}, {f: 4, c: 33875}, 33880,
+ {f: 4, c: 33885}, 33890, 33893, {f: 2, c: 33895}, 33898, 33902, 33904,
+ 33906, 33908, 33913, {f: 7, c: 33915}, {f: 4, c: 33923}, 33930, 33933,
+ {f: 4, c: 33935}, {f: 2, c: 33941}, 33944, {f: 2, c: 33946},
+ {f: 4, c: 33949}, {f: 13, c: 33954}, {f: 2, c: 33968}, 33971,
+ {f: 3, c: 33973}, 33979, 33982, {f: 2, c: 33986}, {f: 4, c: 33989}, 33996,
+ {f: 2, c: 33998}, 34002, {f: 2, c: 34004}, {f: 6, c: 34007}, 34014,
+ {f: 2, c: 34017}, 34020, {f: 5, c: 34023}, 34029, {f: 11, c: 34033}, 34046,
+ {f: 12, c: 34048}, {f: 4, c: 34061}, 34066, {f: 2, c: 34069},
+ {f: 2, c: 34072}, {f: 3, c: 34075}, 34080, 34082, {f: 2, c: 34084},
+ {f: 4, c: 34087}, {f: 9, c: 34094}, {f: 3, c: 34110}, 34114,
+ {f: 2, c: 34116}, 34119, {f: 3, c: 34123}, {f: 3, c: 34127}, 34132, 34135,
+ {f: 4, c: 34138}, {f: 3, c: 34143}, 34147, {f: 3, c: 34149},
+ {f: 2, c: 34155}, {f: 4, c: 34158}, 34163, {f: 2, c: 34165}, 34168,
+ {f: 2, c: 34172}, {f: 5, c: 34175}, 34182, 34185, 34187, {f: 2, c: 34189},
+ 34192, {f: 2, c: 34194}, {f: 6, c: 34197}, {f: 2, c: 34205},
+ {f: 4, c: 34208}, 34213, 34215, {f: 3, c: 34219}, {f: 6, c: 34225}, 34232,
+ {f: 6, c: 34235}, {f: 7, c: 34242}, {f: 3, c: 34250}, {f: 2, c: 34257},
+ 34260, {f: 6, c: 34262}, {f: 6, c: 34270}, {f: 3, c: 34278},
+ {f: 9, c: 34283}, 34293, {f: 2, c: 34295}, {f: 3, c: 34300},
+ {f: 4, c: 34304}, {f: 3, c: 34312}, {f: 5, c: 34316}, {f: 4, c: 34322},
+ {f: 3, c: 34327}, {f: 3, c: 34331}, {f: 3, c: 34335}, {f: 4, c: 34339},
+ 34344, {f: 3, c: 34346}, {f: 10, c: 34350}, 34361, 34363, {f: 2, c: 34365},
+ {f: 13, c: 34368}, {f: 2, c: 34386}, {f: 4, c: 34390}, 34395, 34397,
+ {f: 2, c: 34400}, {f: 4, c: 34403}, {f: 3, c: 34408}, 34413,
+ {f: 2, c: 34415}, {f: 7, c: 34418}, {f: 7, c: 34435}, {f: 5, c: 34446},
+ 34452, {f: 6, c: 34454}, {f: 5, c: 34462}, {f: 2, c: 34469}, 34475,
+ {f: 2, c: 34477}, {f: 2, c: 34482}, {f: 3, c: 34487}, {f: 5, c: 34491},
+ {f: 3, c: 34497}, 34501, 34504, {f: 2, c: 34508}, {f: 2, c: 34514},
+ {f: 3, c: 34517}, 34522, {f: 2, c: 34524}, {f: 4, c: 34528},
+ {f: 4, c: 34533}, {f: 3, c: 34538}, 34543, {f: 3, c: 34549},
+ {f: 3, c: 34555}, 34559, 34561, {f: 2, c: 34564}, {f: 2, c: 34571},
+ {f: 4, c: 34574}, 34580, 34582, 34585, 34587, 34589, {f: 2, c: 34591},
+ 34596, {f: 3, c: 34598}, {f: 4, c: 34602}, {f: 2, c: 34607},
+ {f: 2, c: 34610}, {f: 2, c: 34613}, {f: 3, c: 34616}, {f: 2, c: 34620},
+ {f: 7, c: 34624}, {f: 2, c: 34634}, 34637, {f: 4, c: 34639}, 34644, 34646,
+ 34648, {f: 6, c: 34650}, {f: 2, c: 34657}, {f: 7, c: 34663}, 34671,
+ {f: 3, c: 34673}, 34677, 34679, {f: 2, c: 34681}, {f: 3, c: 34687},
+ {f: 2, c: 34694}, {f: 2, c: 34697}, 34700, {f: 5, c: 34702},
+ {f: 3, c: 34708}, {f: 6, c: 34712}, {f: 2, c: 34720}, {f: 5, c: 34723},
+ {f: 2, c: 34729}, 34734, {f: 3, c: 34736}, 34740, {f: 4, c: 34742}, 34748,
+ {f: 2, c: 34750}, {f: 3, c: 34753}, 34757, 34759, 34761, {f: 2, c: 34764},
+ {f: 2, c: 34767}, {f: 7, c: 34772}, {f: 4, c: 34780}, {f: 2, c: 34785},
+ 34788, {f: 4, c: 34790}, 34795, 34797, {f: 2, c: 34800}, {f: 3, c: 34803},
+ {f: 2, c: 34807}, 34810, {f: 2, c: 34812}, {f: 4, c: 34815}, 34820,
+ {f: 3, c: 34823}, {f: 5, c: 34827}, 34834, 34836, {f: 4, c: 34839},
+ {f: 3, c: 34844}, 34848, {f: 13, c: 34852}, {f: 3, c: 34867},
+ {f: 2, c: 34871}, 34874, {f: 3, c: 34877}, {f: 3, c: 34881},
+ {f: 3, c: 34887}, 34891, {f: 5, c: 34894}, {f: 2, c: 34901}, 34904, 34906,
+ 34908, {f: 3, c: 34910}, {f: 2, c: 34918}, 34922, 34925, 34927, 34929,
+ {f: 4, c: 34931}, 34936, {f: 3, c: 34938}, 34944, 34947, {f: 2, c: 34950},
+ {f: 2, c: 34953}, 34956, {f: 4, c: 34958}, {f: 3, c: 34963},
+ {f: 5, c: 34967}, {f: 5, c: 34973}, 34979, {f: 6, c: 34981}, 34988,
+ {f: 3, c: 34990}, {f: 5, c: 34994}, {f: 4, c: 35000}, {f: 4, c: 35005},
+ {f: 2, c: 35011}, {f: 2, c: 35015}, {f: 3, c: 35019}, {f: 2, c: 35024},
+ 35027, {f: 2, c: 35030}, {f: 2, c: 35034}, 35038, {f: 2, c: 35040},
+ {f: 2, c: 35046}, {f: 7, c: 35049}, 35058, {f: 3, c: 35061},
+ {f: 2, c: 35066}, {f: 3, c: 35071}, {f: 4, c: 35075}, {f: 2, c: 35080},
+ {f: 5, c: 35083}, 35089, {f: 5, c: 35092}, {f: 5, c: 35100},
+ {f: 3, c: 35106}, {f: 4, c: 35110}, {f: 4, c: 35116}, 35121, 35125, 35127,
+ {f: 2, c: 35129}, {f: 5, c: 35132}, {f: 2, c: 35138}, {f: 2, c: 35141},
+ {f: 14, c: 35144}, {f: 6, c: 35159}, {f: 3, c: 35169}, 35173,
+ {f: 3, c: 35175}, 35179, {f: 2, c: 35181}, {f: 2, c: 35184},
+ {f: 8, c: 35187}, {f: 2, c: 35196}, [12177, 35198], 35200, 35202,
+ {f: 2, c: 35204}, {f: 4, c: 35207}, {f: 3, c: 35212}, {f: 3, c: 35216},
+ {f: 2, c: 35220}, 35223, {f: 8, c: 35225}, {f: 4, c: 35234},
+ {f: 3, c: 35239}, 35243, {f: 2, c: 35245}, {f: 2, c: 35248},
+ {f: 4, c: 35251}, {f: 2, c: 35256}, {f: 2, c: 35259}, 35262, 35267, 35277,
+ {f: 3, c: 35283}, {f: 3, c: 35287}, 35291, 35293, {f: 4, c: 35295}, 35300,
+ {f: 4, c: 35303}, {f: 3, c: 35308}, {f: 3, c: 35312}, 35317, 35319,
+ {f: 7, c: 35321}, {f: 3, c: 35332}, 35337, 35339, 35341, 35343,
+ {f: 2, c: 35345}, 35348, 35351, {f: 2, c: 35353}, 35356, 35358,
+ {f: 3, c: 35360}, 35364, {f: 4, c: 35366}, {f: 2, c: 35371},
+ {f: 3, c: 35374}, {f: 2, c: 35378}, 35381, {f: 3, c: 35383},
+ {f: 3, c: 35387}, {f: 2, c: 35391}, {f: 4, c: 35394}, 35399,
+ {f: 5, c: 35401}, 35407, 35409, 35411, {f: 2, c: 35414}, {f: 2, c: 35417},
+ {f: 2, c: 35420}, {f: 2, c: 35423}, {f: 2, c: 35428}, {f: 2, c: 35431},
+ 35434, 35439, 35444, {f: 3, c: 35446}, {f: 2, c: 35450}, {f: 2, c: 35453},
+ {f: 4, c: 35456}, 35464, {f: 2, c: 35467}, {f: 3, c: 35470}, 35476,
+ {f: 2, c: 35478}, 35481, {f: 3, c: 35483}, 35487, 35490, 35495,
+ {f: 3, c: 35497}, {f: 3, c: 35501}, 35505, {f: 3, c: 35507},
+ {f: 2, c: 35511}, {f: 2, c: 35514}, {f: 2, c: 35517}, {f: 2, c: 35520},
+ 35523, {f: 2, c: 35525}, 35528, 35530, 35532, 35534, 35536,
+ {f: 3, c: 35539}, {f: 3, c: 35544}, 35549, {f: 3, c: 35551}, 35555, 35557,
+ {f: 3, c: 35560}, 35564, {f: 2, c: 35567}, 35570, {f: 2, c: 35572}, 35577,
+ 35579, 35581, 35583, 35587, 35590, {f: 2, c: 35592}, {f: 3, c: 35595},
+ 35599, {f: 3, c: 35601}, 35605, 35608, 35612, {f: 3, c: 35614},
+ {f: 4, c: 35618}, 35623, {f: 2, c: 35625}, {f: 5, c: 35630},
+ {f: 5, c: 35636}, {f: 4, c: 35642}, {f: 10, c: 35647}, {f: 4, c: 35658},
+ {f: 6, c: 35664}, 35671, 35675, {f: 9, c: 35677}, {f: 4, c: 35687},
+ {f: 2, c: 35693}, {f: 3, c: 35697}, {f: 2, c: 35701}, {f: 5, c: 35704},
+ {f: 2, c: 35710}, {f: 9, c: 35713}, {f: 3, c: 35723}, {f: 3, c: 35727},
+ 35732, {f: 5, c: 35735}, 35741, 35743, 35756, 35761, 35771, 35783, 35792,
+ 35818, 35849, 35870, {f: 9, c: 35896}, {f: 4, c: 35906}, {f: 2, c: 35914},
+ {f: 3, c: 35917}, {f: 4, c: 35921}, {f: 4, c: 35926}, {f: 6, c: 35931},
+ {f: 7, c: 35939}, {f: 7, c: 35948}, {f: 4, c: 35956}, {f: 7, c: 35963},
+ {f: 2, c: 35971}, {f: 3, c: 35974}, 35979, {f: 7, c: 35981},
+ {f: 3, c: 35989}, {f: 4, c: 35993}, 35999, {f: 4, c: 36003},
+ {f: 2, c: 36013}, 36017, 36021, 36025, 36030, 36038, 36041,
+ {f: 6, c: 36043}, 36052, {f: 4, c: 36054}, 36059, 36061, 36063, 36069,
+ {f: 2, c: 36072}, {f: 6, c: 36078}, {f: 5, c: 36085}, {f: 5, c: 36095},
+ {f: 2, c: 36102}, 36105, 36108, 36110, {f: 5, c: 36113}, {f: 4, c: 36119},
+ 36128, {f: 2, c: 36177}, 36183, 36191, 36197, {f: 3, c: 36200}, 36204,
+ {f: 2, c: 36206}, {f: 2, c: 36209}, {f: 9, c: 36216}, {f: 2, c: 36226},
+ {f: 4, c: 36230}, {f: 5, c: 36236}, {f: 2, c: 36242}, {f: 3, c: 36246},
+ {f: 5, c: 36250}, {f: 3, c: 36256}, {f: 4, c: 36260}, {f: 8, c: 36265},
+ {f: 2, c: 36278}, 36281, 36283, 36285, {f: 3, c: 36288}, 36293,
+ {f: 4, c: 36295}, 36301, 36304, {f: 4, c: 36306}, {f: 2, c: 36312}, 36316,
+ {f: 3, c: 36320}, {f: 3, c: 36325}, 36329, {f: 2, c: 36333},
+ {f: 3, c: 36336}, 36340, 36342, 36348, {f: 7, c: 36350}, {f: 3, c: 36358},
+ 36363, {f: 2, c: 36365}, {f: 3, c: 36369}, {f: 8, c: 36373},
+ {f: 2, c: 36384}, {f: 5, c: 36388}, 36395, 36397, 36400, {f: 2, c: 36402},
+ {f: 3, c: 36406}, {f: 2, c: 36411}, {f: 2, c: 36414}, 36419,
+ {f: 2, c: 36421}, {f: 4, c: 36429}, {f: 2, c: 36435}, {f: 3, c: 36438},
+ {f: 9, c: 36442}, {f: 2, c: 36452}, {f: 2, c: 36455}, {f: 2, c: 36458},
+ 36462, 36465, 36467, 36469, {f: 3, c: 36471}, 36475, {f: 2, c: 36477},
+ 36480, {f: 3, c: 36482}, 36486, 36488, 36492, 36494, {f: 5, c: 36501},
+ 36507, 36509, {f: 2, c: 36511}, {f: 3, c: 36514}, {f: 3, c: 36519},
+ {f: 2, c: 36525}, {f: 2, c: 36528}, {f: 7, c: 36531}, {f: 5, c: 36539},
+ {f: 9, c: 36545}, {f: 3, c: 36559}, 36563, {f: 6, c: 36565},
+ {f: 3, c: 36572}, {f: 4, c: 36576}, {f: 6, c: 36581}, {f: 6, c: 36588},
+ {f: 5, c: 36595}, 36605, {f: 4, c: 36607}, 36612, 36614, 36616,
+ {f: 7, c: 36619}, 36627, {f: 5, c: 36630}, {f: 5, c: 36640},
+ {f: 2, c: 36647}, {f: 4, c: 36651}, {f: 3, c: 36656}, {f: 4, c: 36660},
+ {f: 2, c: 36665}, {f: 2, c: 36668}, {f: 2, c: 36672}, 36675,
+ {f: 2, c: 36679}, {f: 3, c: 36682}, {f: 5, c: 36687}, {f: 10, c: 36693},
+ 36704, 36707, 36709, 36714, 36736, 36748, 36754, 36765, {f: 3, c: 36768},
+ {f: 2, c: 36772}, 36775, 36778, 36780, {f: 2, c: 36787}, [12193, 36789],
+ {f: 2, c: 36791}, {f: 3, c: 36794}, {f: 2, c: 36799}, 36803, 36806,
+ {f: 5, c: 36809}, 36815, 36818, {f: 2, c: 36822}, 36826, {f: 2, c: 36832},
+ 36835, 36839, 36844, 36847, {f: 2, c: 36849}, {f: 2, c: 36853},
+ {f: 3, c: 36858}, {f: 2, c: 36862}, {f: 2, c: 36871}, 36876, 36878, 36883,
+ 36888, 36892, {f: 2, c: 36900}, {f: 6, c: 36903}, {f: 2, c: 36912},
+ {f: 2, c: 36915}, 36919, {f: 2, c: 36921}, 36925, {f: 2, c: 36927}, 36931,
+ {f: 2, c: 36933}, {f: 3, c: 36936}, 36940, 36950, {f: 2, c: 36953}, 36957,
+ 36959, 36961, 36964, {f: 2, c: 36966}, {f: 3, c: 36970}, {f: 3, c: 36975},
+ 36979, 36982, 36985, 36987, 36990, {f: 2, c: 36997}, 37001,
+ {f: 3, c: 37004}, 37010, 37012, 37014, 37016, 37018, 37020,
+ {f: 3, c: 37022}, {f: 2, c: 37028}, {f: 3, c: 37031}, 37035, 37037, 37042,
+ 37047, {f: 2, c: 37052}, {f: 2, c: 37055}, {f: 2, c: 37058}, 37062,
+ {f: 2, c: 37064}, {f: 3, c: 37067}, 37074, {f: 3, c: 37076},
+ {f: 3, c: 37080}, 37086, 37088, {f: 3, c: 37091}, {f: 2, c: 37097}, 37100,
+ 37102, {f: 4, c: 37104}, {f: 2, c: 37110}, {f: 4, c: 37113},
+ {f: 3, c: 37119}, 37123, 37125, {f: 2, c: 37127}, {f: 8, c: 37130}, 37139,
+ 37141, {f: 2, c: 37143}, {f: 4, c: 37146}, {f: 3, c: 37151},
+ {f: 3, c: 37156}, {f: 5, c: 37160}, 37166, 37171, 37173, {f: 2, c: 37175},
+ {f: 8, c: 37179}, {f: 2, c: 37188}, 37191, 37201, {f: 4, c: 37203},
+ {f: 2, c: 37208}, {f: 2, c: 37211}, {f: 2, c: 37215}, {f: 3, c: 37222},
+ 37227, 37229, 37235, {f: 3, c: 37242}, {f: 5, c: 37248}, 37254, 37256,
+ 37258, {f: 2, c: 37262}, {f: 3, c: 37267}, {f: 3, c: 37271},
+ {f: 5, c: 37277}, {f: 6, c: 37284}, {f: 4, c: 37296}, {f: 4, c: 37302},
+ {f: 5, c: 37307}, 37314, 37316, [12196, 37318], 37320, 37328, 37334,
+ {f: 2, c: 37338}, {f: 5, c: 37342}, {f: 2, c: 37349}, 37352,
+ {f: 11, c: 37354}, 37366, 37368, {f: 5, c: 37371}, {f: 2, c: 37378},
+ {f: 3, c: 37381}, {f: 3, c: 37386}, 37391, {f: 2, c: 37394},
+ {f: 8, c: 37398}, {f: 4, c: 37407}, 37412, {f: 6, c: 37416}, 37423,
+ {f: 2, c: 37425}, {f: 2, c: 37429}, {f: 2, c: 37435}, {f: 4, c: 37441},
+ {f: 2, c: 37446}, {f: 3, c: 37450}, {f: 3, c: 37454}, {f: 3, c: 37458},
+ 37462, {f: 2, c: 37464}, {f: 2, c: 37468}, {f: 3, c: 37471},
+ {f: 3, c: 37475}, {f: 5, c: 37479}, {f: 6, c: 37486}, {f: 3, c: 37493},
+ 37497, {f: 3, c: 37500}, {f: 2, c: 37505}, 37508, {f: 8, c: 37510},
+ {f: 2, c: 37519}, 37522, {f: 2, c: 37524}, 37527, 37529, 37531,
+ {f: 3, c: 37533}, {f: 2, c: 37537}, 37540, 37543, 37549, {f: 2, c: 37551},
+ {f: 5, c: 37554}, 37560, 37562, {f: 4, c: 37565}, 37570, 37572, 37574,
+ {f: 3, c: 37577}, {f: 2, c: 37581}, {f: 2, c: 37584}, {f: 10, c: 37587},
+ 37598, {f: 3, c: 37600}, 37607, 37609, {f: 2, c: 37611}, {f: 4, c: 37618},
+ 37623, {f: 3, c: 37625}, {f: 4, c: 37629}, {f: 4, c: 37634},
+ {f: 7, c: 37641}, 37649, {f: 2, c: 37651}, {f: 2, c: 37654},
+ {f: 3, c: 37660}, 37665, {f: 3, c: 37667}, 37671, {f: 2, c: 37673},
+ {f: 2, c: 37676}, {f: 2, c: 37680}, {f: 2, c: 37684}, 37687,
+ {f: 5, c: 37689}, 37695, 37698, {f: 2, c: 37700}, {f: 3, c: 37704}, 37708,
+ {f: 6, c: 37710}, {f: 3, c: 37717}, {f: 2, c: 37721}, {f: 8, c: 37724},
+ {f: 3, c: 37734}, 37739, {f: 3, c: 37741}, {f: 4, c: 37745},
+ {f: 3, c: 37751}, {f: 3, c: 37755}, {f: 3, c: 37759}, 37763,
+ {f: 2, c: 37765}, {f: 2, c: 37768}, {f: 4, c: 37771}, {f: 6, c: 37776},
+ 37783, {f: 9, c: 37785}, {f: 2, c: 37796}, 37800, 37803, 37805, 37807,
+ {f: 2, c: 37809}, 37812, {f: 2, c: 37814}, {f: 6, c: 37817},
+ {f: 3, c: 37824}, {f: 3, c: 37828}, 37833, 37835, {f: 3, c: 37838},
+ {f: 4, c: 37842}, {f: 3, c: 37849}, 37856, 37859, {f: 3, c: 37861},
+ {f: 12, c: 37865}, 37878, 37880, {f: 9, c: 37882}, {f: 7, c: 37892},
+ {f: 4, c: 37900}, 37905, {f: 3, c: 37909}, {f: 3, c: 37914},
+ {f: 2, c: 37918}, {f: 5, c: 37921}, {f: 5, c: 37929}, {f: 3, c: 37935},
+ 37940, {f: 2, c: 37942}, 37945, {f: 3, c: 37947}, {f: 4, c: 37952},
+ {f: 5, c: 37957}, 37963, {f: 5, c: 37965}, 37971, {f: 11, c: 37973},
+ {f: 2, c: 37985}, 37988, {f: 5, c: 37990}, 37996, {f: 2, c: 37998}, 38001,
+ {f: 4, c: 38003}, 38008, {f: 2, c: 38010}, {f: 5, c: 38016}, 38033, 38038,
+ 38040, 38087, 38095, {f: 2, c: 38099}, 38106, 38118, 38139, 38172, 38176,
+ 38183, 38195, 38205, 38211, 38216, 38219, 38229, 38234, 38240, 38254,
+ {f: 2, c: 38260}, {f: 7, c: 38264}, 38273, {f: 2, c: 38276},
+ {f: 2, c: 38279}, 38282, 38285, 38288, 38290, {f: 3, c: 38293},
+ {f: 8, c: 38297}, 38306, {f: 2, c: 38310}, 38314, {f: 4, c: 38318},
+ {f: 3, c: 38323}, {f: 2, c: 38327}, 38330, {f: 3, c: 38336},
+ {f: 2, c: 38340}, 38343, 38345, {f: 3, c: 38349}, {f: 3, c: 38353},
+ {f: 5, c: 38359}, 38365, {f: 2, c: 38367}, {f: 2, c: 38371},
+ {f: 2, c: 38374}, 38380, 38399, 38407, 38419, 38424, 38427, 38430, 38432,
+ {f: 7, c: 38435}, {f: 3, c: 38443}, {f: 2, c: 38447}, {f: 4, c: 38455},
+ 38462, 38465, 38467, 38474, {f: 2, c: 38478}, {f: 3, c: 38481},
+ {f: 2, c: 38486}, {f: 2, c: 38489}, 38492, 38494, 38496, {f: 2, c: 38501},
+ 38507, {f: 3, c: 38509}, 38513, {f: 4, c: 38521}, {f: 7, c: 38526}, 38535,
+ 38537, 38540, {f: 3, c: 38545}, 38550, 38554, {f: 10, c: 38557}, 38569,
+ {f: 5, c: 38571}, 38578, 38581, 38583, 38586, 38591, {f: 2, c: 38594},
+ 38600, {f: 2, c: 38602}, {f: 2, c: 38608}, {f: 2, c: 38611},
+ {f: 2, c: 38615}, 38618, {f: 3, c: 38621}, 38625, {f: 4, c: 38628},
+ {f: 4, c: 38635}, {f: 2, c: 38640}, {f: 2, c: 38644}, 38648, 38650,
+ {f: 2, c: 38652}, 38655, {f: 2, c: 38658}, 38661, {f: 3, c: 38666},
+ {f: 3, c: 38672}, {f: 2, c: 38676}, {f: 5, c: 38679}, 38685,
+ {f: 8, c: 38687}, {f: 2, c: 38696}, {f: 2, c: 38699}, {f: 2, c: 38702},
+ 38705, {f: 5, c: 38707}, {f: 3, c: 38714}, {f: 3, c: 38719}, 38723,
+ {f: 3, c: 38725}, {f: 8, c: 38729}, [12205, 38737], {f: 2, c: 38740},
+ {f: 2, c: 38743}, {f: 2, c: 38748}, 38751, {f: 2, c: 38755},
+ {f: 2, c: 38758}, {f: 9, c: 38762}, 38773, {f: 5, c: 38775},
+ {f: 8, c: 38781}, {f: 5, c: 38790}, 38796, 38798, 38800, 38803,
+ {f: 3, c: 38805}, {f: 7, c: 38809}, {f: 2, c: 38817}, {f: 2, c: 38820},
+ {f: 4, c: 38823}, 38828, 38830, {f: 2, c: 38832}, 38835, {f: 8, c: 38837},
+ {f: 5, c: 38846}, {f: 2, c: 38852}, {f: 2, c: 38855}, 38858,
+ {f: 6, c: 38861}, {f: 5, c: 38868}, {f: 2, c: 38874}, 38877,
+ {f: 7, c: 38879}, 38888, {f: 5, c: 38894}, 38900, {f: 8, c: 38903}, 38912,
+ 38916, 38921, 38923, 38925, {f: 3, c: 38932}, {f: 3, c: 38937},
+ {f: 4, c: 38941}, {f: 2, c: 38946}, 38949, {f: 6, c: 38951},
+ {f: 2, c: 38958}, {f: 6, c: 38961}, {f: 2, c: 38969}, 38972,
+ {f: 8, c: 38974}, {f: 5, c: 38983}, {f: 4, c: 38991}, {f: 3, c: 38997},
+ 39002, {f: 2, c: 39004}, {f: 3, c: 39007}, {f: 2, c: 39011}, 39014,
+ {f: 3, c: 39016}, {f: 2, c: 39021}, 39026, 39051, 39054, 39058, 39061,
+ 39065, 39075, {f: 5, c: 39081}, 39088, 39090, {f: 2, c: 39092},
+ {f: 5, c: 39095}, {f: 7, c: 39101}, 39109, 39111, {f: 5, c: 39113},
+ {f: 2, c: 39119}, 39124, {f: 2, c: 39126}, {f: 2, c: 39132}, 39137,
+ {f: 4, c: 39139}, 39148, 39150, {f: 2, c: 39152}, 39155, {f: 7, c: 39157},
+ {f: 4, c: 39167}, 39172, {f: 3, c: 39174}, 39179, {f: 2, c: 39182},
+ {f: 4, c: 39188}, {f: 2, c: 39193}, {f: 2, c: 39196}, {f: 2, c: 39199},
+ {f: 6, c: 39202}, {f: 5, c: 39209}, {f: 4, c: 39215}, {f: 3, c: 39220},
+ {f: 4, c: 39224}, 39229, {f: 3, c: 39232}, 39236, {f: 2, c: 39238},
+ {f: 4, c: 39245}, 39251, 39254, {f: 4, c: 39256}, 39261, {f: 3, c: 39263},
+ 39268, 39270, 39283, {f: 2, c: 39288}, 39291, 39294, {f: 2, c: 39298},
+ 39305, 39308, 39310, {f: 11, c: 39322}, {f: 2, c: 39334}, {f: 3, c: 39337},
+ {f: 2, c: 39343}, 39346, {f: 12, c: 39349}, {f: 14, c: 39362}, 39379,
+ {f: 2, c: 39382}, 39386, 39388, 39390, 39392, {f: 10, c: 39395},
+ {f: 3, c: 39406}, {f: 13, c: 39410}, 39424, {f: 3, c: 39426},
+ {f: 7, c: 39430}, {f: 6, c: 39440}, {f: 2, c: 39447}, {f: 17, c: 39450},
+ 39468, 39471, {f: 5, c: 39473}, {f: 5, c: 39481}, 39487, {f: 4, c: 39494},
+ {f: 2, c: 39499}, 39502, {f: 5, c: 39504}, 39510, {f: 2, c: 39512},
+ {f: 3, c: 39516}, {f: 2, c: 39520}, 39523, {f: 4, c: 39526}, 39531, 39538,
+ 39555, 39561, {f: 2, c: 39565}, {f: 2, c: 39572}, 39577, 39590,
+ {f: 6, c: 39593}, {f: 4, c: 39602}, 39609, 39611, {f: 3, c: 39613},
+ {f: 2, c: 39619}, {f: 5, c: 39622}, {f: 2, c: 39629}, 39632, 39639,
+ {f: 6, c: 39641}, 39648, {f: 4, c: 39650}, {f: 4, c: 39655}, 39660,
+ {f: 9, c: 39664}, 39674, {f: 7, c: 39676}, {f: 2, c: 39684}, 39687,
+ {f: 4, c: 39689}, 39694, {f: 3, c: 39696}, {f: 6, c: 39700},
+ {f: 4, c: 39707}, {f: 2, c: 39712}, 39716, 39718, 39720, {f: 4, c: 39722},
+ 39728, {f: 8, c: 39731}, {f: 4, c: 39741}, 39750, {f: 3, c: 39754}, 39760,
+ {f: 2, c: 39762}, {f: 3, c: 39765}, 39769, {f: 20, c: 39771},
+ {f: 4, c: 39792}, {f: 2, c: 39797}, {f: 9, c: 39800}, 39810,
+ {f: 10, c: 39812}, 39823, {f: 7, c: 39827}, {f: 2, c: 39835},
+ {f: 11, c: 39839}, 39852, {f: 17, c: 39855}, {f: 5, c: 39874}, 39880,
+ {f: 9, c: 39883}, 39893, {f: 4, c: 39895}, 39900, {f: 3, c: 39902}, 39907,
+ {f: 2, c: 39909}, 39913, {f: 4, c: 39916}, {f: 3, c: 39921},
+ {f: 8, c: 39925}, 39934, {f: 8, c: 39936}, {f: 3, c: 39946},
+ {f: 2, c: 39950}, 39953, {f: 12, c: 39956}, {f: 2, c: 39969}, 39972,
+ {f: 2, c: 39974}, {f: 3, c: 39978}, {f: 3, c: 39982}, 39988, 39990, 39992,
+ 39994, {f: 2, c: 39996}, {f: 6, c: 39999}, {f: 2, c: 40006},
+ {f: 8, c: 40010}, 40019, 40021, {f: 4, c: 40025}, 40030, {f: 7, c: 40032},
+ {f: 5, c: 40040}, {f: 10, c: 40046}, 40057, 40059, {f: 2, c: 40061}, 40064,
+ {f: 2, c: 40067}, {f: 2, c: 40073}, 40076, 40079, 40083, {f: 4, c: 40086},
+ 40093, 40106, 40108, 40111, 40121, {f: 5, c: 40126}, {f: 2, c: 40136},
+ {f: 2, c: 40145}, {f: 2, c: 40154}, {f: 2, c: 40160}, {f: 2, c: 40163},
+ {f: 3, c: 40166}, {f: 2, c: 40170}, {f: 6, c: 40173}, 40181,
+ {f: 15, c: 40183}, 40200, {f: 11, c: 40202}, {f: 5, c: 40214}, 40220,
+ 40222, {f: 3, c: 40224}, {f: 2, c: 40228}, 40231, {f: 6, c: 40233},
+ {f: 10, c: 40241}, {f: 3, c: 40252}, {f: 2, c: 40256}, {f: 14, c: 40259},
+ {f: 8, c: 40276}, {f: 2, c: 40286}, {f: 8, c: 40290}, 40299,
+ {f: 2, c: 40301}, {f: 2, c: 40304}, {f: 20, c: 40307}, 40328,
+ {f: 9, c: 40330}, {f: 4, c: 40340}, 40345, {f: 10, c: 40347},
+ {f: 3, c: 40358}, {f: 5, c: 40362}, {f: 4, c: 40368}, {f: 6, c: 40373},
+ {f: 3, c: 40381}, 40385, 40387, {f: 14, c: 40389}, {f: 3, c: 40404}, 40408,
+ {f: 10, c: 40411}, {f: 8, c: 40423}, {f: 2, c: 40432}, {f: 4, c: 40436},
+ {f: 17, c: 40443}, {f: 8, c: 40461}, {f: 4, c: 40470}, 40476, 40484, 40487,
+ 40494, 40496, 40500, {f: 2, c: 40507}, 40512, 40525, 40528,
+ {f: 3, c: 40530}, 40534, 40537, 40541, {f: 4, c: 40543}, 40549,
+ {f: 2, c: 40558}, 40562, 40564, {f: 3, c: 40566}, 40571, {f: 2, c: 40576},
+ {f: 4, c: 40579}, {f: 2, c: 40585}, {f: 6, c: 40588}, {f: 3, c: 40596},
+ {f: 5, c: 40600}, 40606, {f: 5, c: 40608}, {f: 2, c: 40615},
+ {f: 5, c: 40618}, {f: 4, c: 40624}, {f: 2, c: 40630}, {f: 2, c: 40633},
+ 40636, {f: 4, c: 40639}, [12232, 40643], {f: 4, c: 40645},
+ {f: 2, c: 40650}, 40656, {f: 2, c: 40658}, {f: 3, c: 40661},
+ {f: 2, c: 40665}, 40673, {f: 2, c: 40675}, 40678, {f: 4, c: 40683},
+ {f: 2, c: 40688}, 40691, {f: 2, c: 40693}, 40696, 40698, {f: 9, c: 40704},
+ 40714, 40716, 40719, {f: 2, c: 40721}, 40724, 40726, 40728,
+ {f: 6, c: 40730}, 40737, {f: 9, c: 40739}, {f: 2, c: 40749},
+ {f: 7, c: 40752}, 40760, 40762, 40764, {f: 5, c: 40767}, {f: 5, c: 40773},
+ {f: 3, c: 40780}, 40787, {f: 4, c: 40789}, {f: 2, c: 40794},
+ {f: 2, c: 40797}, 40802, {f: 2, c: 40804}, {f: 3, c: 40807}, 40811,
+ {f: 5, c: 40813}, {f: 4, c: 40819}, {f: 7, c: 40824}, {f: 2, c: 40833},
+ {f: 2, c: 40846}, {f: 3, c: 40849}, {f: 3, c: 40854}, {f: 2, c: 40861},
+ {f: 5, c: 40865}, 63788, {f: 3, c: 64013}, 64017, {f: 2, c: 64019}, 64024,
+ {f: 3, c: 64031}, {f: 2, c: 64035}, {f: 3, c: 64039}, 11905,
+ [59414, 131207], [59415, 131209], [59416, 131276], 11908, 13427, 13383,
+ 11912, 11915, 59422, 13726, 13850, 13838, 11916, 11927, 14702, 14616,
+ 59430, 14799, 14815, 14963, 14800, {f: 2, c: 59435}, 15182, 15470, 15584,
+ 11943, [59441, 136663], 59442, 11946, 16470, 16735, 11950, 17207, 11955,
+ {f: 2, c: 11958}, [59451, 141711], 17329, 17324, 11963, 17373, 17622,
+ 18017, 17996, [59459, 132361], 18211, 18217, 18300, 18317, 11978, 18759,
+ 18810, 18813, {f: 2, c: 18818}, {f: 2, c: 18821}, 18847, 18843, 18871,
+ 18870, [59476, 133533], [59477, 147966], 19619, {f: 3, c: 19615}, 19575,
+ 19618, {f: 7, c: 19731}, 19886, 59492, {s: 226}, 8364, 165, 0, 0, 12351,
+ {s: 17}, 12436, {s: 14}, 12535, 12537, 12536, 12538, 0, {f: 3, c: 12339},
+ {f: 3, c: 12344}, {f: 3, c: 12586}, {f: 24, c: 12704}, 11904,
+ {f: 2, c: 11906}, {f: 3, c: 11909}, {f: 2, c: 11913}, {f: 10, c: 11917},
+ {f: 2, c: 11928}, {f: 12, c: 11931}, {f: 2, c: 11944}, {f: 3, c: 11947},
+ {f: 4, c: 11951}, {f: 2, c: 11956}, {f: 3, c: 11960}, {f: 14, c: 11964},
+ {f: 41, c: 11979}, {f: 71, c: 13312}, {f: 43, c: 13384},
+ {f: 298, c: 13428}, {f: 111, c: 13727}, {f: 11, c: 13839},
+ {f: 765, c: 13851}, {f: 85, c: 14617}, {f: 96, c: 14703},
+ {f: 14, c: 14801}, {f: 147, c: 14816}, {f: 218, c: 14964},
+ {f: 287, c: 15183}, {f: 113, c: 15471}, {f: 885, c: 15585},
+ {f: 264, c: 16471}, {f: 471, c: 16736}, {f: 116, c: 17208},
+ {f: 4, c: 17325}, {f: 43, c: 17330}, {f: 248, c: 17374},
+ {f: 373, c: 17623}, {f: 20, c: 17997}, {f: 193, c: 18018},
+ {f: 5, c: 18212}, {f: 82, c: 18218}, {f: 16, c: 18301}, {f: 441, c: 18318},
+ {f: 50, c: 18760}, {f: 2, c: 18811}, {f: 4, c: 18814}, 18820,
+ {f: 20, c: 18823}, {f: 3, c: 18844}, {f: 22, c: 18848}, {f: 703, c: 18872},
+ {f: 39, c: 19576}, {f: 111, c: 19620}, {f: 148, c: 19738},
+ {f: 7, c: 19887}]
+};
- LabCS.prototype = {
- getRgb: function LabCS_getRgb(src, srcOffset) {
- var rgb = new Uint8Array(3);
- convertToRgb(this, src, srcOffset, false, rgb, 0);
- return rgb;
- },
- getRgbItem: function LabCS_getRgbItem(src, srcOffset, dest, destOffset) {
- convertToRgb(this, src, srcOffset, false, dest, destOffset);
- },
- getRgbBuffer: function LabCS_getRgbBuffer(src, srcOffset, count,
- dest, destOffset, bits) {
- var maxVal = (1 << bits) - 1;
- for (var i = 0; i < count; i++) {
- convertToRgb(this, src, srcOffset, maxVal, dest, destOffset);
- srcOffset += 3;
- destOffset += 3;
- }
- },
- getOutputLength: function LabCS_getOutputLength(inputLength) {
- return inputLength;
- },
- isPassthrough: ColorSpace.prototype.isPassthrough,
- isDefaultDecode: function LabCS_isDefaultDecode(decodeMap) {
- // XXX: Decoding is handled with the lab conversion because of the strange
- // ranges that are used.
- return true;
- },
- usesZeroToOneRange: false
- };
- return LabCS;
-})();
var ARCFourCipher = (function ARCFourCipherClosure() {
@@ -13840,7 +14320,8 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
function prepareKeyData(fileId, password, ownerPassword, userPassword,
flags, revision, keyLength, encryptMetadata) {
- var hashData = new Uint8Array(100), i = 0, j, n;
+ var hashDataSize = 40 + ownerPassword.length + fileId.length;
+ var hashData = new Uint8Array(hashDataSize), i = 0, j, n;
if (password) {
n = Math.min(32, password.length);
for (; i < n; ++i)
@@ -13955,8 +14436,8 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
keyLength < 40 || (keyLength % 8) !== 0)
error('invalid key length');
// prepare keys
- var ownerPassword = stringToBytes(dict.get('O'));
- var userPassword = stringToBytes(dict.get('U'));
+ var ownerPassword = stringToBytes(dict.get('O')).subarray(0, 32);
+ var userPassword = stringToBytes(dict.get('U')).subarray(0, 32);
var flags = dict.get('P');
var revision = dict.get('R');
var encryptMetadata = algorithm == 4 && // meaningful when V is 4
@@ -14067,7 +14548,7 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
var PartialEvaluator = (function PartialEvaluatorClosure() {
function PartialEvaluator(pdfManager, xref, handler, pageIndex,
- uniquePrefix, idCounters) {
+ uniquePrefix, idCounters, fontCache) {
this.state = new EvalState();
this.stateStack = [];
@@ -14077,121 +14558,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
this.pageIndex = pageIndex;
this.uniquePrefix = uniquePrefix;
this.idCounters = idCounters;
- this.fontCache = new RefSetCache();
+ this.fontCache = fontCache;
}
- // Specifies properties for each command
- //
- // If variableArgs === true: [0, `numArgs`] expected
- // If variableArgs === false: exactly `numArgs` expected
- var OP_MAP = {
- // Graphic state
- w: { fnName: 'setLineWidth', numArgs: 1, variableArgs: false },
- J: { fnName: 'setLineCap', numArgs: 1, variableArgs: false },
- j: { fnName: 'setLineJoin', numArgs: 1, variableArgs: false },
- M: { fnName: 'setMiterLimit', numArgs: 1, variableArgs: false },
- d: { fnName: 'setDash', numArgs: 2, variableArgs: false },
- ri: { fnName: 'setRenderingIntent', numArgs: 1, variableArgs: false },
- i: { fnName: 'setFlatness', numArgs: 1, variableArgs: false },
- gs: { fnName: 'setGState', numArgs: 1, variableArgs: false },
- q: { fnName: 'save', numArgs: 0, variableArgs: false },
- Q: { fnName: 'restore', numArgs: 0, variableArgs: false },
- cm: { fnName: 'transform', numArgs: 6, variableArgs: false },
-
- // Path
- m: { fnName: 'moveTo', numArgs: 2, variableArgs: false },
- l: { fnName: 'lineTo', numArgs: 2, variableArgs: false },
- c: { fnName: 'curveTo', numArgs: 6, variableArgs: false },
- v: { fnName: 'curveTo2', numArgs: 4, variableArgs: false },
- y: { fnName: 'curveTo3', numArgs: 4, variableArgs: false },
- h: { fnName: 'closePath', numArgs: 0, variableArgs: false },
- re: { fnName: 'rectangle', numArgs: 4, variableArgs: false },
- S: { fnName: 'stroke', numArgs: 0, variableArgs: false },
- s: { fnName: 'closeStroke', numArgs: 0, variableArgs: false },
- f: { fnName: 'fill', numArgs: 0, variableArgs: false },
- F: { fnName: 'fill', numArgs: 0, variableArgs: false },
- 'f*': { fnName: 'eoFill', numArgs: 0, variableArgs: false },
- B: { fnName: 'fillStroke', numArgs: 0, variableArgs: false },
- 'B*': { fnName: 'eoFillStroke', numArgs: 0, variableArgs: false },
- b: { fnName: 'closeFillStroke', numArgs: 0, variableArgs: false },
- 'b*': { fnName: 'closeEOFillStroke', numArgs: 0, variableArgs: false },
- n: { fnName: 'endPath', numArgs: 0, variableArgs: false },
-
- // Clipping
- W: { fnName: 'clip', numArgs: 0, variableArgs: false },
- 'W*': { fnName: 'eoClip', numArgs: 0, variableArgs: false },
-
- // Text
- BT: { fnName: 'beginText', numArgs: 0, variableArgs: false },
- ET: { fnName: 'endText', numArgs: 0, variableArgs: false },
- Tc: { fnName: 'setCharSpacing', numArgs: 1, variableArgs: false },
- Tw: { fnName: 'setWordSpacing', numArgs: 1, variableArgs: false },
- Tz: { fnName: 'setHScale', numArgs: 1, variableArgs: false },
- TL: { fnName: 'setLeading', numArgs: 1, variableArgs: false },
- Tf: { fnName: 'setFont', numArgs: 2, variableArgs: false },
- Tr: { fnName: 'setTextRenderingMode', numArgs: 1, variableArgs: false },
- Ts: { fnName: 'setTextRise', numArgs: 1, variableArgs: false },
- Td: { fnName: 'moveText', numArgs: 2, variableArgs: false },
- TD: { fnName: 'setLeadingMoveText', numArgs: 2, variableArgs: false },
- Tm: { fnName: 'setTextMatrix', numArgs: 6, variableArgs: false },
- 'T*': { fnName: 'nextLine', numArgs: 0, variableArgs: false },
- Tj: { fnName: 'showText', numArgs: 1, variableArgs: false },
- TJ: { fnName: 'showSpacedText', numArgs: 1, variableArgs: false },
- '\'': { fnName: 'nextLineShowText', numArgs: 1, variableArgs: false },
- '"': { fnName: 'nextLineSetSpacingShowText', numArgs: 3,
- variableArgs: false },
-
- // Type3 fonts
- d0: { fnName: 'setCharWidth', numArgs: 2, variableArgs: false },
- d1: { fnName: 'setCharWidthAndBounds', numArgs: 6, variableArgs: false },
-
- // Color
- CS: { fnName: 'setStrokeColorSpace', numArgs: 1, variableArgs: false },
- cs: { fnName: 'setFillColorSpace', numArgs: 1, variableArgs: false },
- SC: { fnName: 'setStrokeColor', numArgs: 4, variableArgs: true },
- SCN: { fnName: 'setStrokeColorN', numArgs: 33, variableArgs: true },
- sc: { fnName: 'setFillColor', numArgs: 4, variableArgs: true },
- scn: { fnName: 'setFillColorN', numArgs: 33, variableArgs: true },
- G: { fnName: 'setStrokeGray', numArgs: 1, variableArgs: false },
- g: { fnName: 'setFillGray', numArgs: 1, variableArgs: false },
- RG: { fnName: 'setStrokeRGBColor', numArgs: 3, variableArgs: false },
- rg: { fnName: 'setFillRGBColor', numArgs: 3, variableArgs: false },
- K: { fnName: 'setStrokeCMYKColor', numArgs: 4, variableArgs: false },
- k: { fnName: 'setFillCMYKColor', numArgs: 4, variableArgs: false },
-
- // Shading
- sh: { fnName: 'shadingFill', numArgs: 1, variableArgs: false },
-
- // Images
- BI: { fnName: 'beginInlineImage', numArgs: 0, variableArgs: false },
- ID: { fnName: 'beginImageData', numArgs: 0, variableArgs: false },
- EI: { fnName: 'endInlineImage', numArgs: 1, variableArgs: false },
-
- // XObjects
- Do: { fnName: 'paintXObject', numArgs: 1, variableArgs: false },
- MP: { fnName: 'markPoint', numArgs: 1, variableArgs: false },
- DP: { fnName: 'markPointProps', numArgs: 2, variableArgs: false },
- BMC: { fnName: 'beginMarkedContent', numArgs: 1, variableArgs: false },
- BDC: { fnName: 'beginMarkedContentProps', numArgs: 2, variableArgs: false },
- EMC: { fnName: 'endMarkedContent', numArgs: 0, variableArgs: false },
-
- // Compatibility
- BX: { fnName: 'beginCompat', numArgs: 0, variableArgs: false },
- EX: { fnName: 'endCompat', numArgs: 0, variableArgs: false },
-
- // (reserved partial commands for the lexer)
- BM: null,
- BD: null,
- 'true': null,
- fa: null,
- fal: null,
- fals: null,
- 'false': null,
- nu: null,
- nul: null,
- 'null': null
- };
-
var TILING_PATTERN = 1, SHADING_PATTERN = 2;
PartialEvaluator.prototype = {
@@ -14237,7 +14606,8 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
buildFormXObject: function PartialEvaluator_buildFormXObject(resources,
xobj, smask,
- operatorList) {
+ operatorList,
+ state) {
var self = this;
var matrix = xobj.dict.get('Matrix');
@@ -14259,17 +14629,17 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
// There is also a group colorspace, but since we put everything in
// RGB I'm not sure we need it.
}
- operatorList.addOp('beginGroup', [groupOptions]);
+ operatorList.addOp(OPS.beginGroup, [groupOptions]);
}
- operatorList.addOp('paintFormXObjectBegin', [matrix, bbox]);
+ operatorList.addOp(OPS.paintFormXObjectBegin, [matrix, bbox]);
this.getOperatorList(xobj, xobj.dict.get('Resources') || resources,
- operatorList);
- operatorList.addOp('paintFormXObjectEnd', []);
+ operatorList, state);
+ operatorList.addOp(OPS.paintFormXObjectEnd, []);
if (group) {
- operatorList.addOp('endGroup', [groupOptions]);
+ operatorList.addOp(OPS.endGroup, [groupOptions]);
}
},
@@ -14300,9 +14670,8 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
var decode = dict.get('Decode', 'D');
var inverseDecode = !!decode && decode[0] > 0;
- operatorList.addOp('paintImageMaskXObject',
- [PDFImage.createMask(imgArray, width, height,
- inverseDecode)]
+ operatorList.addOp(OPS.paintImageMaskXObject,
+ [PDFImage.createMask(imgArray, width, height, inverseDecode)]
);
return;
}
@@ -14318,7 +14687,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
var imageObj = new PDFImage(this.xref, resources, image,
inline, null, null);
var imgData = imageObj.getImageData();
- operatorList.addOp('paintInlineImageXObject', [imgData]);
+ operatorList.addOp(OPS.paintInlineImageXObject, [imgData]);
return;
}
@@ -14332,7 +14701,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
if (!softMask && !mask && image instanceof JpegStream &&
image.isNativelySupported(this.xref, resources)) {
// These JPEGs don't need any more processing so we can just send it.
- operatorList.addOp('paintJpegXObject', args);
+ operatorList.addOp(OPS.paintJpegXObject, args);
this.handler.send(
'obj', [objId, this.pageIndex, 'JpegStream', image.getIR()]);
return;
@@ -14341,10 +14710,11 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
PDFImage.buildImage(function(imageObj) {
var imgData = imageObj.getImageData();
- self.handler.send('obj', [objId, self.pageIndex, 'Image', imgData]);
+ self.handler.send('obj', [objId, self.pageIndex, 'Image', imgData],
+ null, [imgData.data.buffer]);
}, self.handler, self.xref, resources, image, inline);
- operatorList.addOp('paintImageXObject', args);
+ operatorList.addOp(OPS.paintImageXObject, args);
},
handleTilingType: function PartialEvaluator_handleTilingType(
@@ -14446,9 +14816,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
gStateObj.push([key, value]);
break;
case 'SMask':
- // We support the default so don't trigger the TODO.
+ // We support the default so don't trigger a warning bar.
if (!isName(value) || value.name != 'None')
- TODO('graphic state operator ' + key);
+ UnsupportedManager.notify(UNSUPPORTED_FEATURES.smask);
break;
// Only generate info log messages for the following since
// they are unlikey to have a big impact on the rendering.
@@ -14483,7 +14853,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
setGStateForKey(gStateObj, key, value);
}
- operatorList.addOp('setGState', [gStateObj]);
+ operatorList.addOp(OPS.setGState, [gStateObj]);
},
loadFont: function PartialEvaluator_loadFont(fontName, font, xref,
@@ -14514,22 +14884,31 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
return this.fontCache.get(fontRef);
}
-
font = xref.fetchIfRef(fontRef);
if (!isDict(font)) {
return errorFont();
}
- this.fontCache.put(fontRef, font);
+ // Workaround for bad PDF generators that doesn't reference fonts
+ // properly, i.e. by not using an object identifier.
+ // Check if the fontRef is a Dict (as opposed to a standard object),
+ // in which case we don't cache the font and instead reference it by
+ // fontName in font.loadedName below.
+ var fontRefIsDict = isDict(fontRef);
+ if (!fontRefIsDict) {
+ this.fontCache.put(fontRef, font);
+ }
// keep track of each font we translated so the caller can
// load them asynchronously before calling display on a page
- font.loadedName = 'g_font_' + fontRef.num + '_' + fontRef.gen;
+ font.loadedName = 'g_font_' + (fontRefIsDict ?
+ fontName.replace(/\W/g, '') : (fontRef.num + '_' + fontRef.gen));
if (!font.translated) {
var translated;
try {
translated = this.translateFont(font, xref);
} catch (e) {
+ UnsupportedManager.notify(UNSUPPORTED_FEATURES.font);
translated = new ErrorFont(e instanceof Error ? e.message : e);
}
font.translated = translated;
@@ -14562,7 +14941,8 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
getOperatorList: function PartialEvaluator_getOperatorList(stream,
resources,
- operatorList) {
+ operatorList,
+ evaluatorState) {
var self = this;
var xref = this.xref;
@@ -14573,154 +14953,131 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
resources = resources || new Dict();
var xobjs = resources.get('XObject') || new Dict();
var patterns = resources.get('Pattern') || new Dict();
- // TODO(mduan): pass array of knownCommands rather than OP_MAP
- // dictionary
- var parser = new Parser(new Lexer(stream, OP_MAP), false, xref);
-
- var promise = new Promise();
- var args = [];
- nextOp:
- while (true) {
-
- var obj = parser.getObj();
-
- if (isEOF(obj)) {
- break;
- }
+ var preprocessor = new EvaluatorPreprocessor(stream, xref);
+ if (evaluatorState) {
+ preprocessor.setState(evaluatorState);
+ }
- if (isCmd(obj)) {
- var cmd = obj.cmd;
+ var promise = new LegacyPromise();
+ var operation;
+ while ((operation = preprocessor.read())) {
+ var args = operation.args;
+ var fn = operation.fn;
- // Check that the command is valid
- var opSpec = OP_MAP[cmd];
- if (!opSpec) {
- warn('Unknown command "' + cmd + '"');
- continue;
- }
-
- var fn = opSpec.fnName;
+ switch (fn) {
+ case OPS.setStrokeColorN:
+ case OPS.setFillColorN:
+ if (args[args.length - 1].code) {
+ break;
+ }
+ // compile tiling patterns
+ var patternName = args[args.length - 1];
+ // SCN/scn applies patterns along with normal colors
+ var pattern;
+ if (isName(patternName) &&
+ (pattern = patterns.get(patternName.name))) {
+
+ var dict = isStream(pattern) ? pattern.dict : pattern;
+ var typeNum = dict.get('PatternType');
+
+ if (typeNum == TILING_PATTERN) {
+ self.handleTilingType(fn, args, resources, pattern, dict,
+ operatorList);
+ args = [];
+ continue;
+ } else if (typeNum == SHADING_PATTERN) {
+ var shading = dict.get('Shading');
+ var matrix = dict.get('Matrix');
+ var pattern = Pattern.parseShading(shading, matrix, xref,
+ resources);
+ args = pattern.getIR();
+ } else {
+ error('Unkown PatternType ' + typeNum);
+ }
+ }
+ break;
+ case OPS.paintXObject:
+ if (args[0].code) {
+ break;
+ }
+ // eagerly compile XForm objects
+ var name = args[0].name;
+ var xobj = xobjs.get(name);
+ if (xobj) {
+ assertWellFormed(
+ isStream(xobj), 'XObject should be a stream');
+
+ var type = xobj.dict.get('Subtype');
+ assertWellFormed(
+ isName(type),
+ 'XObject should have a Name subtype'
+ );
- // Validate the number of arguments for the command
- if (opSpec.variableArgs) {
- if (args.length > opSpec.numArgs) {
- info('Command ' + fn + ': expected [0,' + opSpec.numArgs +
- '] args, but received ' + args.length + ' args');
- }
- } else {
- if (args.length < opSpec.numArgs) {
- // If we receive too few args, it's not possible to possible
- // to execute the command, so skip the command
- info('Command ' + fn + ': because expected ' +
- opSpec.numArgs + ' args, but received ' + args.length +
- ' args; skipping');
+ if ('Form' == type.name) {
+ self.buildFormXObject(resources, xobj, null, operatorList,
+ preprocessor.getState());
+ args = [];
+ continue;
+ } else if ('Image' == type.name) {
+ self.buildPaintImageXObject(resources, xobj, false,
+ operatorList);
+ args = [];
+ continue;
+ } else {
+ error('Unhandled XObject subtype ' + type.name);
+ }
+ }
+ break;
+ case OPS.setFont:
+ // eagerly collect all fonts
+ var loadedName = self.handleSetFont(resources, args, null,
+ operatorList);
+ operatorList.addDependency(loadedName);
+ args[0] = loadedName;
+ break;
+ case OPS.endInlineImage:
+ self.buildPaintImageXObject(resources, args[0], true,
+ operatorList);
args = [];
continue;
- } else if (args.length > opSpec.numArgs) {
- info('Command ' + fn + ': expected ' + opSpec.numArgs +
- ' args, but received ' + args.length + ' args');
- }
- }
-
- // TODO figure out how to type-check vararg functions
-
- if ((cmd == 'SCN' || cmd == 'scn') &&
- !args[args.length - 1].code) {
- // compile tiling patterns
- var patternName = args[args.length - 1];
- // SCN/scn applies patterns along with normal colors
- var pattern;
- if (isName(patternName) &&
- (pattern = patterns.get(patternName.name))) {
-
- var dict = isStream(pattern) ? pattern.dict : pattern;
- var typeNum = dict.get('PatternType');
-
- if (typeNum == TILING_PATTERN) {
- self.handleTilingType(fn, args, resources, pattern, dict,
- operatorList);
- args = [];
- continue;
- } else if (typeNum == SHADING_PATTERN) {
- var shading = dict.get('Shading');
- var matrix = dict.get('Matrix');
- var pattern = Pattern.parseShading(shading, matrix, xref,
- resources);
- args = pattern.getIR();
- } else {
- error('Unkown PatternType ' + typeNum);
- }
- }
- } else if (cmd == 'Do' && !args[0].code) {
- // eagerly compile XForm objects
- var name = args[0].name;
- var xobj = xobjs.get(name);
- if (xobj) {
- assertWellFormed(
- isStream(xobj), 'XObject should be a stream');
-
- var type = xobj.dict.get('Subtype');
- assertWellFormed(
- isName(type),
- 'XObject should have a Name subtype'
- );
-
- if ('Form' == type.name) {
- self.buildFormXObject(resources, xobj, null, operatorList);
- args = [];
- continue;
- } else if ('Image' == type.name) {
- self.buildPaintImageXObject(resources, xobj, false,
- operatorList);
- args = [];
- continue;
- } else {
- error('Unhandled XObject subtype ' + type.name);
+ case OPS.save:
+ var old = this.state;
+ this.stateStack.push(this.state);
+ this.state = old.clone();
+ break;
+ case OPS.restore:
+ var prev = this.stateStack.pop();
+ if (prev) {
+ this.state = prev;
}
- }
- } else if (cmd == 'Tf') { // eagerly collect all fonts
- var loadedName = self.handleSetFont(resources, args, null,
- operatorList);
- operatorList.addDependency(loadedName);
- fn = 'setFont';
- args[0] = loadedName;
- } else if (cmd == 'EI') {
- self.buildPaintImageXObject(resources, args[0], true, operatorList);
- args = [];
- continue;
- } else if (cmd === 'q') { // save
- var old = this.state;
- this.stateStack.push(this.state);
- this.state = old.clone();
- } else if (cmd === 'Q') { // restore
- var prev = this.stateStack.pop();
- if (prev) {
- this.state = prev;
- }
- } else if (cmd === 'Tj') { // showText
- args[0] = this.handleText(args[0]);
- } else if (cmd === 'TJ') { // showSpacedText
- var arr = args[0];
- var arrLength = arr.length;
- for (var i = 0; i < arrLength; ++i) {
- if (isString(arr[i])) {
- arr[i] = this.handleText(arr[i]);
+ break;
+ case OPS.showText:
+ args[0] = this.handleText(args[0]);
+ break;
+ case OPS.showSpacedText:
+ var arr = args[0];
+ var arrLength = arr.length;
+ for (var i = 0; i < arrLength; ++i) {
+ if (isString(arr[i])) {
+ arr[i] = this.handleText(arr[i]);
+ }
}
- }
- } else if (cmd === '\'') { // nextLineShowText
- args[0] = this.handleText(args[0]);
- } else if (cmd === '"') { // nextLineSetSpacingShowText
- args[2] = this.handleText(args[2]);
- } else if (cmd === 'Tr') { // setTextRenderingMode
- this.state.textRenderingMode = args[0];
- }
-
- switch (fn) {
+ break;
+ case OPS.nextLineShowText:
+ args[0] = this.handleText(args[0]);
+ break;
+ case OPS.nextLineSetSpacingShowText:
+ args[2] = this.handleText(args[2]);
+ break;
+ case OPS.setTextRenderingMode:
+ this.state.textRenderingMode = args[0];
+ break;
// Parse the ColorSpace data to a raw format.
- case 'setFillColorSpace':
- case 'setStrokeColorSpace':
+ case OPS.setFillColorSpace:
+ case OPS.setStrokeColorSpace:
args = [ColorSpace.parseToIR(args[0], xref, resources)];
break;
- case 'shadingFill':
+ case OPS.shadingFill:
var shadingRes = resources.get('Shading');
if (!shadingRes)
error('No shading resource found');
@@ -14733,9 +15090,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
shading, null, xref, resources);
var patternIR = shadingFill.getIR();
args = [patternIR];
- fn = 'shadingFill';
+ fn = OPS.shadingFill;
break;
- case 'setGState':
+ case OPS.setGState:
var dictName = args[0];
var extGState = resources.get('ExtGState');
@@ -14745,16 +15102,16 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
var gState = extGState.get(dictName.name);
self.setGState(resources, gState, operatorList);
args = [];
- continue nextOp;
+ continue;
} // switch
operatorList.addOp(fn, args);
- args = [];
- parser.saveState();
- } else if (obj !== null && obj !== undefined) {
- args.push(obj instanceof Dict ? obj.getAll() : obj);
- assertWellFormed(args.length <= 33, 'Too many arguments');
- }
+ }
+
+ // some pdf don't close all restores inside object/form
+ // closing those for them
+ for (var i = 0, ii = preprocessor.savedStatesDepth; i < ii; i++) {
+ operatorList.addOp(OPS.restore, []);
}
return operatorList;
@@ -14791,65 +15148,55 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
// The xobj is parsed iff it's needed, e.g. if there is a `DO` cmd.
var xobjs = null;
- var parser = new Parser(new Lexer(stream), false);
+ var preprocessor = new EvaluatorPreprocessor(stream, xref);
var res = resources;
- var args = [], obj;
var chunk = '';
var font = null;
var charSpace = 0, wordSpace = 0;
- while (!isEOF(obj = parser.getObj())) {
- if (isCmd(obj)) {
- var cmd = obj.cmd;
- switch (cmd) {
+ var operation;
+ while ((operation = preprocessor.read())) {
+ var fn = operation.fn;
+ var args = operation.args;
+ switch (fn) {
// TODO: Add support for SAVE/RESTORE and XFORM here.
- case 'Tf':
+ case OPS.setFont:
font = handleSetFont(args[0].name).translated;
textState.fontSize = args[1];
break;
- case 'Ts':
+ case OPS.setTextRise:
textState.textRise = args[0];
break;
- case 'Tz':
+ case OPS.setHScale:
textState.textHScale = args[0] / 100;
break;
- case 'TL':
+ case OPS.setLeading:
textState.leading = args[0];
break;
- case 'Td':
+ case OPS.moveText:
textState.translateTextMatrix(args[0], args[1]);
break;
- case 'TD':
+ case OPS.setLeadingMoveText:
textState.leading = -args[1];
textState.translateTextMatrix(args[0], args[1]);
break;
- case 'T*':
+ case OPS.nextLine:
textState.translateTextMatrix(0, -textState.leading);
break;
- case 'Tm':
+ case OPS.setTextMatrix:
textState.setTextMatrix(args[0], args[1],
args[2], args[3], args[4], args[5]);
break;
- case 'Tc':
+ case OPS.setCharSpacing:
charSpace = args[0];
break;
- case 'Tw':
+ case OPS.setWordSpacing:
wordSpace = args[0];
break;
- case 'q':
- textState.push();
- break;
- case 'Q':
- textState.pop();
- break;
- case 'BT':
+ case OPS.beginText:
textState.initialiseTextObj();
break;
- case 'cm':
- textState.transformCTM(args[0], args[1], args[2],
- args[3], args[4], args[5]);
- break;
- case 'TJ':
+ case OPS.showSpacedText:
var items = args[0];
for (var j = 0, jj = items.length; j < jj; j++) {
if (typeof items[j] === 'string') {
@@ -14867,20 +15214,20 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
}
}
break;
- case 'Tj':
+ case OPS.showText:
chunk += fontCharsToUnicode(args[0], font);
break;
- case '\'':
+ case OPS.nextLineShowText:
// For search, adding a extra white space for line breaks would be
// better here, but that causes too much spaces in the
// text-selection divs.
chunk += fontCharsToUnicode(args[0], font);
break;
- case '"':
+ case OPS.nextLineSetSpacingShowText:
// Note comment in "'"
chunk += fontCharsToUnicode(args[2], font);
break;
- case 'Do':
+ case OPS.paintXObject:
// Set the chunk such that the following if won't add something
// to the state.
chunk = '';
@@ -14914,7 +15261,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
state
);
break;
- case 'gs':
+ case OPS.setGState:
var dictName = args[0];
var extGState = resources.get('ExtGState');
@@ -14933,11 +15280,18 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
if (chunk !== '') {
var bidiText = PDFJS.bidi(chunk, -1, font.vertical);
- var renderParams = textState.calcRenderParams();
+ var renderParams = textState.calcRenderParams(preprocessor.ctm);
bidiText.x = renderParams.renderMatrix[4] - (textState.fontSize *
renderParams.vScale * Math.sin(renderParams.angle));
bidiText.y = renderParams.renderMatrix[5] + (textState.fontSize *
renderParams.vScale * Math.cos(renderParams.angle));
+ var fontHeight = textState.fontSize * renderParams.vScale;
+ var fontAscent = font.ascent ? font.ascent * fontHeight :
+ font.descent ? (1 + font.descent) * fontHeight : fontHeight;
+ bidiText.x = renderParams.renderMatrix[4] - (fontAscent *
+ Math.sin(renderParams.angle));
+ bidiText.y = renderParams.renderMatrix[5] + (fontAscent *
+ Math.cos(renderParams.angle));
if (bidiText.dir == 'ttb') {
bidiText.x += renderParams.vScale / 2;
bidiText.y -= renderParams.vScale;
@@ -14946,12 +15300,6 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
chunk = '';
}
-
- args = [];
- } else if (obj !== null && obj !== undefined) {
- assertWellFormed(args.length <= 33, 'Too many arguments');
- args.push(obj);
- }
} // while
return state;
@@ -14999,10 +15347,11 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
Encodings.WinAnsiEncoding :
Encodings.StandardEncoding;
// The Symbolic attribute can be misused for regular fonts
- // Heuristic: we have to check if the font is a standard one also
+ // Heuristic: we have to check if the font is a standard one and has
+ // Symbolic font name
if (!!(flags & FontFlags.Symbolic)) {
- baseEncoding = !properties.file ? Encodings.symbolsEncoding :
- Encodings.MacRomanEncoding;
+ baseEncoding = !properties.file && /Symbol/i.test(properties.name) ?
+ Encodings.SymbolSetEncoding : Encodings.MacRomanEncoding;
}
if (dict.has('Encoding')) {
var encoding = dict.get('Encoding');
@@ -15270,6 +15619,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
var properties = {
type: type.name,
+ name: baseFontName,
widths: metrics.widths,
defaultWidth: metrics.defaultWidth,
flags: flags,
@@ -15328,6 +15678,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
var properties = {
type: type.name,
+ name: fontName.name,
subtype: subtype,
file: fontFile,
length1: length1,
@@ -15371,6 +15722,18 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
PartialEvaluator.optimizeQueue =
function PartialEvaluator_optimizeQueue(queue) {
+ function squash(array, index, howMany, element) {
+ if (isArray(array)) {
+ array.splice(index, howMany, element);
+ } else {
+ // Replace the element.
+ array[index] = element;
+ // Shift everything after the element up.
+ var sub = array.subarray(index + howMany);
+ array.set(sub, index + 1);
+ }
+ }
+
var fnArray = queue.fnArray, argsArray = queue.argsArray;
// grouping paintInlineImageXObject's into paintInlineImageXObjectGroup
// searching for (save, transform, paintInlineImageXObject, restore)+
@@ -15378,10 +15741,10 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
var MAX_IMAGES_IN_INLINE_IMAGES_BLOCK = 200;
var MAX_WIDTH = 1000;
var IMAGE_PADDING = 1;
- for (var i = 0, ii = fnArray.length; i < ii; i++) {
- if (fnArray[i] === 'paintInlineImageXObject' &&
- fnArray[i - 2] === 'save' && fnArray[i - 1] === 'transform' &&
- fnArray[i + 1] === 'restore') {
+ for (var i = 0, ii = argsArray.length; i < ii; i++) {
+ if (fnArray[i] === OPS.paintInlineImageXObject &&
+ fnArray[i - 2] === OPS.save && fnArray[i - 1] === OPS.transform &&
+ fnArray[i + 1] === OPS.restore) {
var j = i - 2;
for (i += 2; i < ii && fnArray[i - 4] === fnArray[i]; i++) {
}
@@ -15446,21 +15809,21 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
}
}
// replacing queue items
- fnArray.splice(j, count * 4, ['paintInlineImageXObjectGroup']);
+ squash(fnArray, j, count * 4, OPS.paintInlineImageXObjectGroup);
argsArray.splice(j, count * 4,
[{width: imgWidth, height: imgHeight, data: imgData}, map]);
i = j;
- ii = fnArray.length;
+ ii = argsArray.length;
}
}
// grouping paintImageMaskXObject's into paintImageMaskXObjectGroup
// searching for (save, transform, paintImageMaskXObject, restore)+
var MIN_IMAGES_IN_MASKS_BLOCK = 10;
var MAX_IMAGES_IN_MASKS_BLOCK = 100;
- for (var i = 0, ii = fnArray.length; i < ii; i++) {
- if (fnArray[i] === 'paintImageMaskXObject' &&
- fnArray[i - 2] === 'save' && fnArray[i - 1] === 'transform' &&
- fnArray[i + 1] === 'restore') {
+ for (var i = 0, ii = argsArray.length; i < ii; i++) {
+ if (fnArray[i] === OPS.paintImageMaskXObject &&
+ fnArray[i - 2] === OPS.save && fnArray[i - 1] === OPS.transform &&
+ fnArray[i + 1] === OPS.restore) {
var j = i - 2;
for (i += 2; i < ii && fnArray[i - 4] === fnArray[i]; i++) {
}
@@ -15477,37 +15840,68 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
height: maskParams.height, transform: transform});
}
// replacing queue items
- fnArray.splice(j, count * 4, ['paintImageMaskXObjectGroup']);
+ squash(fnArray, j, count * 4, OPS.paintImageMaskXObjectGroup);
argsArray.splice(j, count * 4, [images]);
i = j;
- ii = fnArray.length;
+ ii = argsArray.length;
}
}
};
-
return PartialEvaluator;
})();
-
var OperatorList = (function OperatorListClosure() {
var CHUNK_SIZE = 100;
- function OperatorList(messageHandler, pageIndex) {
+ function getTransfers(queue) {
+ var transfers = [];
+ var fnArray = queue.fnArray, argsArray = queue.argsArray;
+ for (var i = 0, ii = queue.length; i < ii; i++) {
+ switch (fnArray[i]) {
+ case OPS.paintInlineImageXObject:
+ case OPS.paintInlineImageXObjectGroup:
+ case OPS.paintImageMaskXObject:
+ var arg = argsArray[i][0]; // first param in imgData
+ transfers.push(arg.data.buffer);
+ break;
+ }
+ }
+ return transfers;
+ }
+
+
+ function OperatorList(messageHandler, pageIndex) {
this.messageHandler = messageHandler;
- this.fnArray = [];
+ // When there isn't a message handler the fn array needs to be able to grow
+ // since we can't flush the operators.
+ if (messageHandler) {
+ this.fnArray = new Uint8Array(CHUNK_SIZE);
+ } else {
+ this.fnArray = [];
+ }
this.argsArray = [];
this.dependencies = {},
this.pageIndex = pageIndex;
+ this.fnIndex = 0;
}
OperatorList.prototype = {
+ get length() {
+ return this.argsArray.length;
+ },
+
addOp: function(fn, args) {
- this.fnArray.push(fn);
- this.argsArray.push(args);
- if (this.messageHandler && this.fnArray.length >= CHUNK_SIZE) {
- this.flush();
+ if (this.messageHandler) {
+ this.fnArray[this.fnIndex++] = fn;
+ this.argsArray.push(args);
+ if (this.fnIndex >= CHUNK_SIZE) {
+ this.flush();
+ }
+ } else {
+ this.fnArray.push(fn);
+ this.argsArray.push(args);
}
},
@@ -15516,7 +15910,7 @@ var OperatorList = (function OperatorListClosure() {
return;
}
this.dependencies[dependency] = true;
- this.addOp('dependency', [dependency]);
+ this.addOp(OPS.dependency, [dependency]);
},
addDependencies: function(dependencies) {
@@ -15526,40 +15920,44 @@ var OperatorList = (function OperatorListClosure() {
},
addOpList: function(opList) {
- Util.concatenateToArray(this.fnArray, opList.fnArray);
- Util.concatenateToArray(this.argsArray, opList.argsArray);
Util.extendObj(this.dependencies, opList.dependencies);
+ for (var i = 0, ii = opList.length; i < ii; i++) {
+ this.addOp(opList.fnArray[i], opList.argsArray[i]);
+ }
},
getIR: function() {
return {
fnArray: this.fnArray,
- argsArray: this.argsArray
+ argsArray: this.argsArray,
+ length: this.length
};
},
flush: function(lastChunk) {
PartialEvaluator.optimizeQueue(this);
+ var transfers = getTransfers(this);
this.messageHandler.send('RenderPageChunk', {
operatorList: {
fnArray: this.fnArray,
argsArray: this.argsArray,
- lastChunk: lastChunk
+ lastChunk: lastChunk,
+ length: this.length
},
pageIndex: this.pageIndex
- });
+ }, null, transfers);
this.dependencies = [];
- this.fnArray = [];
+ this.fnIndex = 0;
this.argsArray = [];
}
};
return OperatorList;
})();
+
var TextState = (function TextStateClosure() {
function TextState() {
this.fontSize = 0;
- this.ctm = [1, 0, 0, 1, 0, 0];
this.textMatrix = [1, 0, 0, 1, 0, 0];
this.stateStack = [];
//textState variables
@@ -15568,12 +15966,6 @@ var TextState = (function TextStateClosure() {
this.textRise = 0;
}
TextState.prototype = {
- push: function TextState_push() {
- this.stateStack.push(this.ctm.slice());
- },
- pop: function TextStae_pop() {
- this.ctm = this.stateStack.pop();
- },
initialiseTextObj: function TextState_initialiseTextObj() {
var m = this.textMatrix;
m[0] = 1, m[1] = 0, m[2] = 0, m[3] = 1, m[4] = 0, m[5] = 0;
@@ -15582,24 +15974,13 @@ var TextState = (function TextStateClosure() {
var m = this.textMatrix;
m[0] = a, m[1] = b, m[2] = c, m[3] = d, m[4] = e, m[5] = f;
},
- transformCTM: function TextState_transformCTM(a, b, c, d, e, f) {
- var m = this.ctm;
- var m0 = m[0], m1 = m[1], m2 = m[2], m3 = m[3], m4 = m[4], m5 = m[5];
- m[0] = m0 * a + m2 * b;
- m[1] = m1 * a + m3 * b;
- m[2] = m0 * c + m2 * d;
- m[3] = m1 * c + m3 * d;
- m[4] = m0 * e + m2 * f + m4;
- m[5] = m1 * e + m3 * f + m5;
- },
translateTextMatrix: function TextState_translateTextMatrix(x, y) {
var m = this.textMatrix;
m[4] = m[0] * x + m[2] * y + m[4];
m[5] = m[1] * x + m[3] * y + m[5];
},
- calcRenderParams: function TextState_calcRenderingParams() {
+ calcRenderParams: function TextState_calcRenderingParams(cm) {
var tm = this.textMatrix;
- var cm = this.ctm;
var a = this.fontSize;
var b = a * this.textHScale;
var c = this.textRise;
@@ -15642,6 +16023,221 @@ var EvalState = (function EvalStateClosure() {
return EvalState;
})();
+var EvaluatorPreprocessor = (function EvaluatorPreprocessor() {
+ // Specifies properties for each command
+ //
+ // If variableArgs === true: [0, `numArgs`] expected
+ // If variableArgs === false: exactly `numArgs` expected
+ var OP_MAP = {
+ // Graphic state
+ w: { id: OPS.setLineWidth, numArgs: 1, variableArgs: false },
+ J: { id: OPS.setLineCap, numArgs: 1, variableArgs: false },
+ j: { id: OPS.setLineJoin, numArgs: 1, variableArgs: false },
+ M: { id: OPS.setMiterLimit, numArgs: 1, variableArgs: false },
+ d: { id: OPS.setDash, numArgs: 2, variableArgs: false },
+ ri: { id: OPS.setRenderingIntent, numArgs: 1, variableArgs: false },
+ i: { id: OPS.setFlatness, numArgs: 1, variableArgs: false },
+ gs: { id: OPS.setGState, numArgs: 1, variableArgs: false },
+ q: { id: OPS.save, numArgs: 0, variableArgs: false },
+ Q: { id: OPS.restore, numArgs: 0, variableArgs: false },
+ cm: { id: OPS.transform, numArgs: 6, variableArgs: false },
+
+ // Path
+ m: { id: OPS.moveTo, numArgs: 2, variableArgs: false },
+ l: { id: OPS.lineTo, numArgs: 2, variableArgs: false },
+ c: { id: OPS.curveTo, numArgs: 6, variableArgs: false },
+ v: { id: OPS.curveTo2, numArgs: 4, variableArgs: false },
+ y: { id: OPS.curveTo3, numArgs: 4, variableArgs: false },
+ h: { id: OPS.closePath, numArgs: 0, variableArgs: false },
+ re: { id: OPS.rectangle, numArgs: 4, variableArgs: false },
+ S: { id: OPS.stroke, numArgs: 0, variableArgs: false },
+ s: { id: OPS.closeStroke, numArgs: 0, variableArgs: false },
+ f: { id: OPS.fill, numArgs: 0, variableArgs: false },
+ F: { id: OPS.fill, numArgs: 0, variableArgs: false },
+ 'f*': { id: OPS.eoFill, numArgs: 0, variableArgs: false },
+ B: { id: OPS.fillStroke, numArgs: 0, variableArgs: false },
+ 'B*': { id: OPS.eoFillStroke, numArgs: 0, variableArgs: false },
+ b: { id: OPS.closeFillStroke, numArgs: 0, variableArgs: false },
+ 'b*': { id: OPS.closeEOFillStroke, numArgs: 0, variableArgs: false },
+ n: { id: OPS.endPath, numArgs: 0, variableArgs: false },
+
+ // Clipping
+ W: { id: OPS.clip, numArgs: 0, variableArgs: false },
+ 'W*': { id: OPS.eoClip, numArgs: 0, variableArgs: false },
+
+ // Text
+ BT: { id: OPS.beginText, numArgs: 0, variableArgs: false },
+ ET: { id: OPS.endText, numArgs: 0, variableArgs: false },
+ Tc: { id: OPS.setCharSpacing, numArgs: 1, variableArgs: false },
+ Tw: { id: OPS.setWordSpacing, numArgs: 1, variableArgs: false },
+ Tz: { id: OPS.setHScale, numArgs: 1, variableArgs: false },
+ TL: { id: OPS.setLeading, numArgs: 1, variableArgs: false },
+ Tf: { id: OPS.setFont, numArgs: 2, variableArgs: false },
+ Tr: { id: OPS.setTextRenderingMode, numArgs: 1, variableArgs: false },
+ Ts: { id: OPS.setTextRise, numArgs: 1, variableArgs: false },
+ Td: { id: OPS.moveText, numArgs: 2, variableArgs: false },
+ TD: { id: OPS.setLeadingMoveText, numArgs: 2, variableArgs: false },
+ Tm: { id: OPS.setTextMatrix, numArgs: 6, variableArgs: false },
+ 'T*': { id: OPS.nextLine, numArgs: 0, variableArgs: false },
+ Tj: { id: OPS.showText, numArgs: 1, variableArgs: false },
+ TJ: { id: OPS.showSpacedText, numArgs: 1, variableArgs: false },
+ '\'': { id: OPS.nextLineShowText, numArgs: 1, variableArgs: false },
+ '"': { id: OPS.nextLineSetSpacingShowText, numArgs: 3,
+ variableArgs: false },
+
+ // Type3 fonts
+ d0: { id: OPS.setCharWidth, numArgs: 2, variableArgs: false },
+ d1: { id: OPS.setCharWidthAndBounds, numArgs: 6, variableArgs: false },
+
+ // Color
+ CS: { id: OPS.setStrokeColorSpace, numArgs: 1, variableArgs: false },
+ cs: { id: OPS.setFillColorSpace, numArgs: 1, variableArgs: false },
+ SC: { id: OPS.setStrokeColor, numArgs: 4, variableArgs: true },
+ SCN: { id: OPS.setStrokeColorN, numArgs: 33, variableArgs: true },
+ sc: { id: OPS.setFillColor, numArgs: 4, variableArgs: true },
+ scn: { id: OPS.setFillColorN, numArgs: 33, variableArgs: true },
+ G: { id: OPS.setStrokeGray, numArgs: 1, variableArgs: false },
+ g: { id: OPS.setFillGray, numArgs: 1, variableArgs: false },
+ RG: { id: OPS.setStrokeRGBColor, numArgs: 3, variableArgs: false },
+ rg: { id: OPS.setFillRGBColor, numArgs: 3, variableArgs: false },
+ K: { id: OPS.setStrokeCMYKColor, numArgs: 4, variableArgs: false },
+ k: { id: OPS.setFillCMYKColor, numArgs: 4, variableArgs: false },
+
+ // Shading
+ sh: { id: OPS.shadingFill, numArgs: 1, variableArgs: false },
+
+ // Images
+ BI: { id: OPS.beginInlineImage, numArgs: 0, variableArgs: false },
+ ID: { id: OPS.beginImageData, numArgs: 0, variableArgs: false },
+ EI: { id: OPS.endInlineImage, numArgs: 1, variableArgs: false },
+
+ // XObjects
+ Do: { id: OPS.paintXObject, numArgs: 1, variableArgs: false },
+ MP: { id: OPS.markPoint, numArgs: 1, variableArgs: false },
+ DP: { id: OPS.markPointProps, numArgs: 2, variableArgs: false },
+ BMC: { id: OPS.beginMarkedContent, numArgs: 1, variableArgs: false },
+ BDC: { id: OPS.beginMarkedContentProps, numArgs: 2,
+ variableArgs: false },
+ EMC: { id: OPS.endMarkedContent, numArgs: 0, variableArgs: false },
+
+ // Compatibility
+ BX: { id: OPS.beginCompat, numArgs: 0, variableArgs: false },
+ EX: { id: OPS.endCompat, numArgs: 0, variableArgs: false },
+
+ // (reserved partial commands for the lexer)
+ BM: null,
+ BD: null,
+ 'true': null,
+ fa: null,
+ fal: null,
+ fals: null,
+ 'false': null,
+ nu: null,
+ nul: null,
+ 'null': null
+ };
+
+ function EvaluatorPreprocessor(stream, xref) {
+ // TODO(mduan): pass array of knownCommands rather than OP_MAP
+ // dictionary
+ this.parser = new Parser(new Lexer(stream, OP_MAP), false, xref);
+ this.ctm = new Float32Array([1, 0, 0, 1, 0, 0]);
+ this.savedStates = [];
+ }
+ EvaluatorPreprocessor.prototype = {
+ get savedStatesDepth() {
+ return this.savedStates.length;
+ },
+ read: function EvaluatorPreprocessor_read() {
+ var args = [];
+ while (true) {
+ var obj = this.parser.getObj();
+ if (isEOF(obj)) {
+ return null; // no more commands
+ }
+ if (!isCmd(obj)) {
+ // argument
+ if (obj !== null && obj !== undefined) {
+ args.push(obj instanceof Dict ? obj.getAll() : obj);
+ assertWellFormed(args.length <= 33, 'Too many arguments');
+ }
+ continue;
+ }
+
+ var cmd = obj.cmd;
+ // Check that the command is valid
+ var opSpec = OP_MAP[cmd];
+ if (!opSpec) {
+ warn('Unknown command "' + cmd + '"');
+ continue;
+ }
+
+ var fn = opSpec.id;
+
+ // Validate the number of arguments for the command
+ if (opSpec.variableArgs) {
+ if (args.length > opSpec.numArgs) {
+ info('Command ' + fn + ': expected [0,' + opSpec.numArgs +
+ '] args, but received ' + args.length + ' args');
+ }
+ } else {
+ if (args.length < opSpec.numArgs) {
+ // If we receive too few args, it's not possible to possible
+ // to execute the command, so skip the command
+ info('Command ' + fn + ': because expected ' +
+ opSpec.numArgs + ' args, but received ' + args.length +
+ ' args; skipping');
+ args = [];
+ continue;
+ } else if (args.length > opSpec.numArgs) {
+ info('Command ' + fn + ': expected ' + opSpec.numArgs +
+ ' args, but received ' + args.length + ' args');
+ }
+ }
+
+ // TODO figure out how to type-check vararg functions
+
+ this.preprocessCommand(fn, args);
+
+ return {fn: fn, args: args};
+ }
+ },
+ getState: function EvaluatorPreprocessor_getState() {
+ return {
+ ctm: this.ctm
+ };
+ },
+ setState: function EvaluatorPreprocessor_setState(state) {
+ this.ctm = state.ctm;
+ },
+ preprocessCommand: function EvaluatorPreprocessor_preprocessCommand(fn,
+ args) {
+ switch (fn | 0) {
+ case OPS.save:
+ this.savedStates.push(this.getState());
+ break;
+ case OPS.restore:
+ var previousState = this.savedStates.pop();
+ if (previousState) {
+ this.setState(previousState);
+ }
+ break;
+ case OPS.transform:
+ var ctm = this.ctm;
+ var m = new Float32Array(6);
+ m[0] = ctm[0] * args[0] + ctm[2] * args[1];
+ m[1] = ctm[1] * args[0] + ctm[3] * args[1];
+ m[2] = ctm[0] * args[2] + ctm[2] * args[3];
+ m[3] = ctm[1] * args[2] + ctm[3] * args[3];
+ m[4] = ctm[0] * args[4] + ctm[2] * args[5] + ctm[4];
+ m[5] = ctm[1] * args[4] + ctm[3] * args[5] + ctm[5];
+ this.ctm = m;
+ break;
+ }
+ }
+ };
+ return EvaluatorPreprocessor;
+})();
// Unicode Private Use Area
@@ -15848,8 +16444,8 @@ var Encodings = {
'oacute', 'ocircumflex', 'otilde', 'odieresis', 'divide', 'oslash',
'ugrave', 'uacute', 'ucircumflex', 'udieresis', 'yacute', 'thorn',
'ydieresis'],
- symbolsEncoding: ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
- '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
+ SymbolSetEncoding: ['', '', '', '', '', '', '', '', '', '', '', '', '', '',
+ '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
'space', 'exclam', 'universal', 'numbersign', 'existential', 'percent',
'ampersand', 'suchthat', 'parenleft', 'parenright', 'asteriskmath', 'plus',
'comma', 'minus', 'period', 'slash', 'zero', 'one', 'two', 'three', 'four',
@@ -16078,6 +16674,76 @@ var HalfwidthCMaps = {
'UniJIS-UCS2-HW-V': true
};
+// Glyph map for well-known standard fonts. Sometimes Ghostscript uses CID fonts
+// but does not embed the CID to GID mapping. The mapping is incomplete for all
+// glyphs, but common for some set of the standard fonts.
+var GlyphMapForStandardFonts = {
+ '2': 10, '3': 32, '4': 33, '5': 34, '6': 35, '7': 36, '8': 37, '9': 38,
+ '10': 39, '11': 40, '12': 41, '13': 42, '14': 43, '15': 44, '16': 173,
+ '17': 46, '18': 47, '19': 48, '20': 49, '21': 50, '22': 51, '23': 52,
+ '24': 53, '25': 54, '26': 55, '27': 56, '28': 57, '29': 58, '30': 894,
+ '31': 60, '32': 61, '33': 62, '34': 63, '35': 64, '36': 65, '37': 66,
+ '38': 67, '39': 68, '40': 69, '41': 70, '42': 71, '43': 72, '44': 73,
+ '45': 74, '46': 75, '47': 76, '48': 77, '49': 78, '50': 79, '51': 80,
+ '52': 81, '53': 82, '54': 83, '55': 84, '56': 85, '57': 86, '58': 87,
+ '59': 88, '60': 89, '61': 90, '62': 91, '63': 92, '64': 93, '65': 94,
+ '66': 95, '67': 96, '68': 97, '69': 98, '70': 99, '71': 100, '72': 101,
+ '73': 102, '74': 103, '75': 104, '76': 105, '77': 106, '78': 107, '79': 108,
+ '80': 109, '81': 110, '82': 111, '83': 112, '84': 113, '85': 114, '86': 115,
+ '87': 116, '88': 117, '89': 118, '90': 119, '91': 120, '92': 121, '93': 122,
+ '94': 123, '95': 124, '96': 125, '97': 126, '98': 196, '99': 197, '100': 199,
+ '101': 201, '102': 209, '103': 214, '104': 220, '105': 225, '106': 224,
+ '107': 226, '108': 228, '109': 227, '110': 229, '111': 231, '112': 233,
+ '113': 232, '114': 234, '115': 235, '116': 237, '117': 236, '118': 238,
+ '119': 239, '120': 241, '121': 243, '122': 242, '123': 244, '124': 246,
+ '125': 245, '126': 250, '127': 249, '128': 251, '129': 252, '130': 8224,
+ '131': 176, '132': 162, '133': 163, '134': 167, '135': 8226, '136': 182,
+ '137': 223, '138': 174, '139': 169, '140': 8482, '141': 180, '142': 168,
+ '143': 8800, '144': 198, '145': 216, '146': 8734, '147': 177, '148': 8804,
+ '149': 8805, '150': 165, '151': 181, '152': 8706, '153': 8721, '154': 8719,
+ '156': 8747, '157': 170, '158': 186, '159': 8486, '160': 230, '161': 248,
+ '162': 191, '163': 161, '164': 172, '165': 8730, '166': 402, '167': 8776,
+ '168': 8710, '169': 171, '170': 187, '171': 8230, '210': 218, '305': 963,
+ '306': 964, '307': 966, '308': 8215, '309': 8252, '310': 8319, '311': 8359,
+ '312': 8592, '313': 8593, '337': 9552, '493': 1039, '494': 1040, '705': 1524,
+ '706': 8362, '710': 64288, '711': 64298, '759': 1617, '761': 1776,
+ '763': 1778, '775': 1652, '777': 1764, '778': 1780, '779': 1781, '780': 1782,
+ '782': 771, '783': 64726, '786': 8363, '788': 8532, '790': 768, '791': 769,
+ '792': 768, '795': 803, '797': 64336, '798': 64337, '799': 64342,
+ '800': 64343, '801': 64344, '802': 64345, '803': 64362, '804': 64363,
+ '805': 64364, '2424': 7821, '2425': 7822, '2426': 7823, '2427': 7824,
+ '2428': 7825, '2429': 7826, '2430': 7827, '2433': 7682, '2678': 8045,
+ '2679': 8046, '2830': 1552, '2838': 686, '2840': 751, '2842': 753,
+ '2843': 754, '2844': 755, '2846': 757, '2856': 767, '2857': 848, '2858': 849,
+ '2862': 853, '2863': 854, '2864': 855, '2865': 861, '2866': 862, '2906': 7460,
+ '2908': 7462, '2909': 7463, '2910': 7464, '2912': 7466, '2913': 7467,
+ '2914': 7468, '2916': 7470, '2917': 7471, '2918': 7472, '2920': 7474,
+ '2921': 7475, '2922': 7476, '2924': 7478, '2925': 7479, '2926': 7480,
+ '2928': 7482, '2929': 7483, '2930': 7484, '2932': 7486, '2933': 7487,
+ '2934': 7488, '2936': 7490, '2937': 7491, '2938': 7492, '2940': 7494,
+ '2941': 7495, '2942': 7496, '2944': 7498, '2946': 7500, '2948': 7502,
+ '2950': 7504, '2951': 7505, '2952': 7506, '2954': 7508, '2955': 7509,
+ '2956': 7510, '2958': 7512, '2959': 7513, '2960': 7514, '2962': 7516,
+ '2963': 7517, '2964': 7518, '2966': 7520, '2967': 7521, '2968': 7522,
+ '2970': 7524, '2971': 7525, '2972': 7526, '2974': 7528, '2975': 7529,
+ '2976': 7530, '2978': 1537, '2979': 1538, '2980': 1539, '2982': 1549,
+ '2983': 1551, '2984': 1552, '2986': 1554, '2987': 1555, '2988': 1556,
+ '2990': 1623, '2991': 1624, '2995': 1775, '2999': 1791, '3002': 64290,
+ '3003': 64291, '3004': 64292, '3006': 64294, '3007': 64295, '3008': 64296,
+ '3011': 1900, '3014': 8223, '3015': 8244, '3017': 7532, '3018': 7533,
+ '3019': 7534, '3075': 7590, '3076': 7591, '3079': 7594, '3080': 7595,
+ '3083': 7598, '3084': 7599, '3087': 7602, '3088': 7603, '3091': 7606,
+ '3092': 7607, '3095': 7610, '3096': 7611, '3099': 7614, '3100': 7615,
+ '3103': 7618, '3104': 7619, '3107': 8337, '3108': 8338, '3116': 1884,
+ '3119': 1885, '3120': 1885, '3123': 1886, '3124': 1886, '3127': 1887,
+ '3128': 1887, '3131': 1888, '3132': 1888, '3135': 1889, '3136': 1889,
+ '3139': 1890, '3140': 1890, '3143': 1891, '3144': 1891, '3147': 1892,
+ '3148': 1892, '3153': 580, '3154': 581, '3157': 584, '3158': 585, '3161': 588,
+ '3162': 589, '3165': 891, '3166': 892, '3169': 1274, '3170': 1275,
+ '3173': 1278, '3174': 1279, '3181': 7622, '3182': 7623, '3282': 11799,
+ '3316': 578, '3379': 42785, '3393': 1159, '3416': 8377
+};
+
var decodeBytes;
if (typeof TextDecoder !== 'undefined') {
// The encodings supported by TextDecoder can be found at:
@@ -16117,7 +16783,7 @@ function sjis83pvToUnicode(str) {
// TODO: 83pv has incompatible mappings in ed40..ee9c range.
return decodeBytes(bytes, 'shift_jis', true);
} catch (e) {
- TODO('Unsupported 83pv character found');
+ warn('Unsupported 83pv character found');
// Just retry without checking errors for now.
return decodeBytes(bytes, 'shift_jis');
}
@@ -16129,7 +16795,7 @@ function sjis90pvToUnicode(str) {
// TODO: 90pv has incompatible mappings in 8740..879c and eb41..ee9c.
return decodeBytes(bytes, 'shift_jis', true);
} catch (e) {
- TODO('Unsupported 90pv character found');
+ warn('Unsupported 90pv character found');
// Just retry without checking errors for now.
return decodeBytes(bytes, 'shift_jis');
}
@@ -17805,6 +18471,8 @@ var Font = (function FontClosure() {
this.wideChars = properties.wideChars;
this.hasEncoding = properties.hasEncoding;
this.cmap = properties.cmap;
+ this.ascent = properties.ascent / PDF_GLYPH_SPACE_UNITS;
+ this.descent = properties.descent / PDF_GLYPH_SPACE_UNITS;
this.fontMatrix = properties.fontMatrix;
if (properties.type == 'Type3') {
@@ -17832,6 +18500,7 @@ var Font = (function FontClosure() {
// The file data is not specified. Trying to fix the font name
// to be used with the canvas.font.
var fontName = name.replace(/[,_]/g, '-');
+ var isStandardFont = fontName in stdFontMap;
fontName = stdFontMap[fontName] || nonStdFontMap[fontName] || fontName;
this.bold = (fontName.search(/bold/gi) != -1);
@@ -17847,6 +18516,17 @@ var Font = (function FontClosure() {
this.encoding = properties.baseEncoding;
this.noUnicodeAdaptation = true;
+ if (isStandardFont && type === 'CIDFontType2' &&
+ properties.cidEncoding.indexOf('Identity-') === 0) {
+ // Standard fonts might be embedded as CID font without glyph mapping.
+ // Building one based on GlyphMapForStandardFonts.
+ var map = [];
+ for (var code in GlyphMapForStandardFonts) {
+ map[+code] = GlyphMapForStandardFonts[code];
+ }
+ this.toFontChar = map;
+ this.toUnicode = map;
+ }
this.loadedName = fontName.split('-')[0];
this.loading = false;
return;
@@ -18699,6 +19379,17 @@ var Font = (function FontClosure() {
error('cmap table has unsupported format: ' + format);
}
+ // removing duplicate entries
+ mappings.sort(function (a, b) {
+ return a.charcode - b.charcode;
+ });
+ for (var i = 1; i < mappings.length; i++) {
+ if (mappings[i - 1].charcode === mappings[i].charcode) {
+ mappings.splice(i, 1);
+ i--;
+ }
+ }
+
return {
platformId: potentialTable.platformId,
encodingId: potentialTable.encodingId,
@@ -18774,8 +19465,8 @@ var Font = (function FontClosure() {
for (var i = 0; i < flagsCount; i++) {
var flag = glyf[j++];
if (flag & 0xC0) {
- // reserved flags must be zero, rejecting
- return 0;
+ // reserved flags must be zero, cleaning up
+ glyf[j - 1] = flag & 0x3F;
}
var xyLength = ((flag & 2) ? 1 : (flag & 16) ? 0 : 2) +
((flag & 4) ? 1 : (flag & 32) ? 0 : 2);
@@ -18786,6 +19477,10 @@ var Font = (function FontClosure() {
coordinatesLength += repeat * xyLength;
}
}
+ // glyph without coordinates will be rejected
+ if (coordinatesLength === 0) {
+ return 0;
+ }
var glyphDataLength = j + coordinatesLength;
if (glyphDataLength > glyf.length) {
// not enough data for coordinates
@@ -18884,6 +19579,13 @@ var Font = (function FontClosure() {
};
}
var locaData = loca.data;
+ var locaDataSize = itemSize * (1 + numGlyphs);
+ // is loca.data too short or long?
+ if (locaData.length !== locaDataSize) {
+ locaData = new Uint8Array(locaDataSize);
+ locaData.set(loca.data.subarray(0, locaDataSize));
+ loca.data = locaData;
+ }
// removing the invalid glyphs
var oldGlyfData = glyf.data;
var oldGlyfDataLength = oldGlyfData.length;
@@ -18927,9 +19629,7 @@ var Font = (function FontClosure() {
glyf.data.set(newGlyfData.subarray(0, writeOffset));
}
glyf.data.set(newGlyfData.subarray(0, firstEntryLength), writeOffset);
- loca.data = new Uint8Array(locaData.length + itemSize);
- loca.data.set(locaData);
- itemEncode(loca.data, locaData.length,
+ itemEncode(loca.data, locaData.length - itemSize,
writeOffset + firstEntryLength);
} else {
glyf.data = newGlyfData.subarray(0, writeOffset);
@@ -19129,6 +19829,11 @@ var Font = (function FontClosure() {
callstack.push({data: data, i: i, stackTop: stack.length - 1});
functionsCalled.push(funcId);
var pc = ttContext.functionsDefined[funcId];
+ if (!pc) {
+ warn('TT: CALL non-existent function');
+ ttContext.hintsValid = false;
+ return;
+ }
data = pc.data;
i = pc.i;
}
@@ -19149,6 +19854,11 @@ var Font = (function FontClosure() {
lastEndf = i;
} else {
var pc = callstack.pop();
+ if (!pc) {
+ warn('TT: ENDF bad stack');
+ ttContext.hintsValid = false;
+ return;
+ }
var funcId = functionsCalled.pop();
data = pc.data;
i = pc.i;
@@ -19248,7 +19958,7 @@ var Font = (function FontClosure() {
}
}
- function sanitizeTTPrograms(fpgm, prep) {
+ function sanitizeTTPrograms(fpgm, prep, cvt) {
var ttContext = {
functionsDefined: [],
functionsUsed: [],
@@ -19265,6 +19975,11 @@ var Font = (function FontClosure() {
if (fpgm) {
checkInvalidFunctions(ttContext, maxFunctionDefs);
}
+ if (cvt && (cvt.length & 1)) {
+ var cvtData = new Uint8Array(cvt.length + 1);
+ cvtData.set(cvt.data);
+ cvt.data = cvtData;
+ }
return ttContext.hintsValid;
}
@@ -19284,6 +19999,9 @@ var Font = (function FontClosure() {
if (VALID_TABLES.indexOf(table.tag) < 0) {
continue; // skipping table if it's not a required or optional table
}
+ if (table.length === 0) {
+ continue; // skipping empty tables
+ }
tables[table.tag] = table;
}
@@ -19318,7 +20036,14 @@ var Font = (function FontClosure() {
var numGlyphs = int16(font.getBytes(2));
var maxFunctionDefs = 0;
if (version >= 0x00010000 && tables.maxp.length >= 22) {
- font.pos += 14;
+ // maxZones can be invalid
+ font.pos += 8;
+ var maxZones = int16(font.getBytes(2));
+ if (maxZones > 2) { // reset to 2 if font has invalid maxZones
+ tables.maxp.data[14] = 0;
+ tables.maxp.data[15] = 2;
+ }
+ font.pos += 4;
maxFunctionDefs = int16(font.getBytes(2));
}
@@ -19333,10 +20058,11 @@ var Font = (function FontClosure() {
}
var hintsValid = sanitizeTTPrograms(tables.fpgm, tables.prep,
- maxFunctionDefs);
+ tables['cvt '], maxFunctionDefs);
if (!hintsValid) {
delete tables.fpgm;
delete tables.prep;
+ delete tables['cvt '];
}
// Tables needs to be written by ascendant alphabetic order
@@ -19370,7 +20096,6 @@ var Font = (function FontClosure() {
if (isTrueType) {
var isGlyphLocationsLong = int16([tables.head.data[50],
tables.head.data[51]]);
-
sanitizeGlyphLocations(tables.loca, tables.glyf, numGlyphs,
isGlyphLocationsLong, hintsValid, dupFirstEntry);
}
@@ -19916,7 +20641,7 @@ var Font = (function FontClosure() {
var cidEncoding = properties.cidEncoding;
if (properties.toUnicode) {
if (cidEncoding && cidEncoding.indexOf('Identity-') !== 0) {
- TODO('Need to create a reverse mapping from \'ToUnicode\' CMap');
+ warn('Need to create a reverse mapping from \'ToUnicode\' CMap');
}
return; // 'ToUnicode' CMap will be used
}
@@ -20174,8 +20899,10 @@ var Font = (function FontClosure() {
var glyph = this.charToGlyph(charcode);
glyphs.push(glyph);
// placing null after each word break charcode (ASCII SPACE)
- if (charcode == 0x20)
+ // Ignore occurences of 0x20 in multiple-byte codes.
+ if (length === 1 && chars.charCodeAt(i - 1) === 0x20) {
glyphs.push(null);
+ }
}
}
else {
@@ -20817,13 +21544,21 @@ var Type1Parser = (function Type1ParserClosure() {
for (var j = 0; j < size; j++) {
var token = this.getToken();
- if (token === 'dup') {
- var index = this.readInt();
- this.getToken(); // read in '/'
- var glyph = this.getToken();
- encoding[index] = glyph;
- this.getToken(); // read the in 'put'
+ // skipping till first dup or def (e.g. ignoring for statement)
+ while (token !== 'dup' && token !== 'def') {
+ token = this.getToken();
+ if (token === null) {
+ return; // invalid header
+ }
+ }
+ if (token === 'def') {
+ break; // read all array data
}
+ var index = this.readInt();
+ this.getToken(); // read in '/'
+ var glyph = this.getToken();
+ encoding[index] = glyph;
+ this.getToken(); // read the in 'put'
}
}
if (properties.overridableEncoding && encoding) {
@@ -20831,6 +21566,13 @@ var Type1Parser = (function Type1ParserClosure() {
break;
}
break;
+ case 'FontBBox':
+ var fontBBox = this.readNumberArray();
+ // adjusting ascent/descent
+ properties.ascent = fontBBox[3];
+ properties.descent = fontBBox[1];
+ properties.ascentScaled = true;
+ break;
}
}
}
@@ -20913,13 +21655,33 @@ var CFFStandardStrings = [
// Type1Font is also a CIDFontType0.
var Type1Font = function Type1Font(name, file, properties) {
+ // Some bad generators embed pfb file as is, we have to strip 6-byte headers.
+ // Also, length1 and length2 might be off by 6 bytes as well.
+ // http://www.math.ubc.ca/~cass/piscript/type1.pdf
+ var PFB_HEADER_SIZE = 6;
+ var headerBlockLength = properties.length1;
+ var eexecBlockLength = properties.length2;
+ var pfbHeader = file.peekBytes(PFB_HEADER_SIZE);
+ var pfbHeaderPresent = pfbHeader[0] == 0x80 && pfbHeader[1] == 0x01;
+ if (pfbHeaderPresent) {
+ file.skip(PFB_HEADER_SIZE);
+ headerBlockLength = (pfbHeader[5] << 24) | (pfbHeader[4] << 16) |
+ (pfbHeader[3] << 8) | pfbHeader[2];
+ }
+
// Get the data block containing glyphs and subrs informations
- var headerBlock = new Stream(file.getBytes(properties.length1));
+ var headerBlock = new Stream(file.getBytes(headerBlockLength));
var headerBlockParser = new Type1Parser(headerBlock);
headerBlockParser.extractFontHeader(properties);
+ if (pfbHeaderPresent) {
+ pfbHeader = file.getBytes(PFB_HEADER_SIZE);
+ eexecBlockLength = (pfbHeader[5] << 24) | (pfbHeader[4] << 16) |
+ (pfbHeader[3] << 8) | pfbHeader[2];
+ }
+
// Decrypt the data blocks and retrieve it's content
- var eexecBlock = new Stream(file.getBytes(properties.length2));
+ var eexecBlock = new Stream(file.getBytes(eexecBlockLength));
var eexecBlockParser = new Type1Parser(eexecBlock, true);
var data = eexecBlockParser.extractFontProgram();
for (var info in data.properties)
@@ -21151,6 +21913,9 @@ var CFFFont = (function CFFFontClosure() {
var unassignedUnicodeItems = [];
var inverseEncoding = [];
var gidStart = 0;
+ if (charsets[0] === '.notdef') {
+ gidStart = 1;
+ }
// According to section 9.7.4.2 CIDFontType0C glyph selection should be
// handled differently.
if (this.properties.subtype === 'CIDFontType0C') {
@@ -21183,9 +21948,6 @@ var CFFFont = (function CFFFontClosure() {
inverseEncoding[gid] = charcode | 0;
}
}
- if (charsets[0] === '.notdef') {
- gidStart = 1;
- }
}
for (var i = gidStart, ii = charsets.length; i < ii; i++) {
@@ -27560,7 +28322,7 @@ var PDFImage = (function PDFImageClosure() {
if (image.getParams) {
// JPX/JPEG2000 streams directly contain bits per component
// and color space mode information.
- TODO('get params from actual stream');
+ warn('get params from actual stream');
// var bits = ...
// var colorspace = ...
}
@@ -27593,7 +28355,7 @@ var PDFImage = (function PDFImageClosure() {
if (!this.imageMask) {
var colorSpace = dict.get('ColorSpace', 'CS');
if (!colorSpace) {
- TODO('JPX images (which don"t require color spaces');
+ warn('JPX images (which don"t require color spaces');
colorSpace = new Name('DeviceRGB');
}
this.colorSpace = ColorSpace.parse(colorSpace, xref, res);
@@ -27635,9 +28397,9 @@ var PDFImage = (function PDFImageClosure() {
*/
PDFImage.buildImage = function PDFImage_buildImage(callback, handler, xref,
res, image, inline) {
- var imageDataPromise = new Promise();
- var smaskPromise = new Promise();
- var maskPromise = new Promise();
+ var imageDataPromise = new LegacyPromise();
+ var smaskPromise = new LegacyPromise();
+ var maskPromise = new LegacyPromise();
// The image data and smask data may not be ready yet, wait till both are
// resolved.
Promise.all([imageDataPromise, smaskPromise, maskPromise]).then(
@@ -27715,26 +28477,21 @@ var PDFImage = (function PDFImageClosure() {
PDFImage.createMask = function PDFImage_createMask(imgArray, width, height,
inverseDecode) {
- var buffer = new Uint8Array(width * height * 4);
- var imgArrayPos = 0;
- var i, j, mask, buf;
- // removing making non-masked pixels transparent
- var bufferPos = 3; // alpha component offset
- for (i = 0; i < height; i++) {
- mask = 0;
- for (j = 0; j < width; j++) {
- if (!mask) {
- buf = imgArray[imgArrayPos++];
- mask = 128;
- }
- if (!(buf & mask) !== inverseDecode) {
- buffer[bufferPos] = 255;
- }
- bufferPos += 4;
- mask >>= 1;
- }
- }
- return {data: buffer, width: width, height: height};
+ // Copy imgArray into a typed array (inverting if necessary) so it can be
+ // transferred to the main thread.
+ var length = ((width + 7) >> 3) * height;
+ var data = new Uint8Array(length);
+ if (inverseDecode) {
+ for (var i = 0; i < length; i++) {
+ data[i] = ~imgArray[i];
+ }
+ } else {
+ for (var i = 0; i < length; i++) {
+ data[i] = imgArray[i];
+ }
+ }
+
+ return {data: data, width: width, height: height};
};
PDFImage.prototype = {
@@ -30963,21 +31720,6 @@ var Parser = (function ParserClosure() {
}
Parser.prototype = {
- saveState: function Parser_saveState() {
- this.state = {
- buf1: this.buf1,
- buf2: this.buf2,
- streamPos: this.lexer.stream.pos
- };
- },
-
- restoreState: function Parser_restoreState() {
- var state = this.state;
- this.buf1 = state.buf1;
- this.buf2 = state.buf2;
- this.lexer.stream.pos = state.streamPos;
- },
-
refill: function Parser_refill() {
this.buf1 = this.lexer.getObj();
this.buf2 = this.lexer.getObj();
@@ -32182,12 +32924,18 @@ var FlateStream = (function FlateStreamClosure() {
var buffer = this.ensureBuffer(bufferLength + blockLen);
var end = bufferLength + blockLen;
this.bufferLength = end;
- for (var n = bufferLength; n < end; ++n) {
- if (typeof (b = bytes[bytesPos++]) == 'undefined') {
+ if (blockLen === 0) {
+ if (typeof bytes[bytesPos] == 'undefined') {
this.eof = true;
- break;
}
- buffer[n] = b;
+ } else {
+ for (var n = bufferLength; n < end; ++n) {
+ if (typeof (b = bytes[bytesPos++]) == 'undefined') {
+ this.eof = true;
+ break;
+ }
+ buffer[n] = b;
+ }
}
this.bytesPos = bytesPos;
return;
@@ -32506,7 +33254,7 @@ var JpegStream = (function JpegStreamClosure() {
}
};
JpegStream.prototype.getIR = function JpegStream_getIR() {
- return bytesToString(this.bytes);
+ return PDFJS.createObjectURL(this.bytes, 'image/jpeg');
};
/**
* Checks if the image can be decoded and displayed by the browser without any
@@ -32650,6 +33398,16 @@ var Jbig2Stream = (function Jbig2StreamClosure() {
var jbig2Image = new Jbig2Image();
var chunks = [], decodeParams = this.dict.get('DecodeParms');
+
+ // According to the PDF specification, DecodeParms can be either
+ // a dictionary, or an array whose elements are dictionaries.
+ if (isArray(decodeParams)) {
+ if (decodeParams.length > 1) {
+ warn('JBIG2 - \'DecodeParms\' array with multiple elements ' +
+ 'not supported.');
+ }
+ decodeParams = decodeParams[0];
+ }
if (decodeParams && decodeParams.has('JBIG2Globals')) {
var globalsStream = decodeParams.get('JBIG2Globals');
var globals = globalsStream.getBytes();
@@ -34002,7 +34760,7 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {
var pdfManager;
function loadDocument(recoveryMode) {
- var loadDocumentPromise = new Promise();
+ var loadDocumentPromise = new LegacyPromise();
var parseSuccess = function parseSuccess() {
var numPagesPromise = pdfManager.ensureModel('numPages');
@@ -34046,7 +34804,7 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {
}
function getPdfManager(data) {
- var pdfManagerPromise = new Promise();
+ var pdfManagerPromise = new LegacyPromise();
var source = data.source;
var disableRange = data.disableRange;
@@ -34069,7 +34827,8 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {
}
var networkManager = new NetworkManager(source.url, {
- httpHeaders: source.httpHeaders
+ httpHeaders: source.httpHeaders,
+ withCredentials: source.withCredentials
});
var fullRequestXhrId = networkManager.requestFull({
onHeadersReceived: function onHeadersReceived() {
@@ -34148,6 +34907,9 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {
handler.send('test', false);
return;
}
+ // making sure postMessage transfers are working
+ var supportTransfers = data[0] === 255;
+ handler.postMessageTransfers = supportTransfers;
// check if the response property is supported by xhr
var xhr = new XMLHttpRequest();
var responseExists = 'response' in xhr;
@@ -34161,14 +34923,16 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {
handler.send('test', false);
return;
}
- handler.send('test', true);
+ handler.send('test', {
+ supportTypedArray: true,
+ supportTransfers: supportTransfers
+ });
});
handler.on('GetDocRequest', function wphSetupDoc(data) {
var onSuccess = function(doc) {
handler.send('GetDoc', { pdfInfo: doc });
- pdfManager.ensureModel('traversePages', []).then(null, onFailure);
};
var onFailure = function(e) {
@@ -34200,6 +34964,8 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {
PDFJS.maxImageSize = data.maxImageSize === undefined ?
-1 : data.maxImageSize;
PDFJS.disableFontFace = data.disableFontFace;
+ PDFJS.disableCreateObjectURL = data.disableCreateObjectURL;
+ PDFJS.verbosity = data.verbosity;
getPdfManager(data).then(function pdfManagerReady() {
loadDocument(false).then(onSuccess, function loadFailure(ex) {
@@ -34208,7 +34974,8 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {
if (ex instanceof PasswordException) {
// after password exception prepare to receive a new password
// to repeat loading
- pdfManager.passwordChangedPromise = new Promise();
+ pdfManager.passwordChangedPromise =
+ new LegacyPromise();
pdfManager.passwordChangedPromise.then(pdfManagerReady);
}
@@ -34245,24 +35012,31 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {
});
});
+ handler.on('GetPageIndex', function wphSetupGetPageIndex(data, deferred) {
+ var ref = new Ref(data.ref.num, data.ref.gen);
+ pdfManager.pdfModel.catalog.getPageIndex(ref).then(function (pageIndex) {
+ deferred.resolve(pageIndex);
+ }, deferred.reject);
+ });
+
handler.on('GetDestinations',
- function wphSetupGetDestinations(data, promise) {
+ function wphSetupGetDestinations(data, deferred) {
pdfManager.ensureCatalog('destinations').then(function(destinations) {
- promise.resolve(destinations);
+ deferred.resolve(destinations);
});
}
);
- handler.on('GetData', function wphSetupGetData(data, promise) {
+ handler.on('GetData', function wphSetupGetData(data, deferred) {
pdfManager.requestLoadedStream();
pdfManager.onLoadedStream().then(function(stream) {
- promise.resolve(stream.bytes);
+ deferred.resolve(stream.bytes);
});
});
- handler.on('DataLoaded', function wphSetupDataLoaded(data, promise) {
+ handler.on('DataLoaded', function wphSetupDataLoaded(data, deferred) {
pdfManager.onLoadedStream().then(function(stream) {
- promise.resolve({ length: stream.bytes.byteLength });
+ deferred.resolve({ length: stream.bytes.byteLength });
});
});
@@ -34291,7 +35065,7 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {
// Pre compile the pdf page and fetch the fonts/images.
page.getOperatorList(handler).then(function(operatorList) {
- log('page=%d - getOperatorList: time=%dms, len=%d', pageNum,
+ info('page=%d - getOperatorList: time=%dms, len=%d', pageNum,
Date.now() - start, operatorList.fnArray.length);
}, function(e) {
@@ -34327,24 +35101,29 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {
});
}, this);
- handler.on('GetTextContent', function wphExtractText(data, promise) {
+ handler.on('GetTextContent', function wphExtractText(data, deferred) {
pdfManager.getPage(data.pageIndex).then(function(page) {
var pageNum = data.pageIndex + 1;
var start = Date.now();
page.extractTextContent().then(function(textContent) {
- promise.resolve(textContent);
- log('text indexing: page=%d - time=%dms', pageNum,
+ deferred.resolve(textContent);
+ info('text indexing: page=%d - time=%dms', pageNum,
Date.now() - start);
}, function (e) {
// Skip errored pages
- promise.reject(e);
+ deferred.reject(e);
});
});
});
- handler.on('Terminate', function wphTerminate(data, promise) {
+ handler.on('Cleanup', function wphCleanup(data, deferred) {
+ pdfManager.cleanup();
+ deferred.resolve(true);
+ });
+
+ handler.on('Terminate', function wphTerminate(data, deferred) {
pdfManager.terminate();
- promise.resolve();
+ deferred.resolve();
});
}
};
@@ -34376,25 +35155,25 @@ var workerConsole = {
timeEnd: function timeEnd(name) {
var time = consoleTimer[name];
if (!time) {
- error('Unkown timer name ' + name);
+ error('Unknown timer name ' + name);
}
this.log('Timer:', name, Date.now() - time);
}
};
+
// Worker thread?
if (typeof window === 'undefined') {
- globalScope.console = workerConsole;
-
- // Add a logger so we can pass warnings on to the main thread, errors will
- // throw an exception which will be forwarded on automatically.
- PDFJS.LogManager.addLogger({
- warn: function(msg) {
- globalScope.postMessage({
- action: '_warn',
- data: msg
- });
- }
+ if (!('console' in globalScope)) {
+ globalScope.console = workerConsole;
+ }
+
+ // Listen for unsupported features so we can pass them on to the main thread.
+ PDFJS.UnsupportedManager.listen(function (msg) {
+ globalScope.postMessage({
+ action: '_unsupported_feature',
+ data: msg
+ });
});
var handler = new MessageHandler('worker_processor', this);
@@ -36076,6 +36855,19 @@ var JpxImage = (function JpxImageClosure() {
}
return ll;
};
+ Transform.prototype.expand = function expand(buffer, bufferPadding, step) {
+ // Section F.3.7 extending... using max extension of 4
+ var i1 = bufferPadding - 1, j1 = bufferPadding + 1;
+ var i2 = bufferPadding + step - 2, j2 = bufferPadding + step;
+ buffer[i1--] = buffer[j1++];
+ buffer[j2++] = buffer[i2--];
+ buffer[i1--] = buffer[j1++];
+ buffer[j2++] = buffer[i2--];
+ buffer[i1--] = buffer[j1++];
+ buffer[j2++] = buffer[i2--];
+ buffer[i1--] = buffer[j1++];
+ buffer[j2++] = buffer[i2--];
+ };
Transform.prototype.iterate = function Transform_iterate(ll, hl, lh, hh,
u0, v0) {
var llWidth = ll.width, llHeight = ll.height, llItems = ll.items;
@@ -36129,18 +36921,7 @@ var JpxImage = (function JpxImageClosure() {
for (var u = 0; u < width; u++, k++, l++)
buffer[l] = items[k];
- // Section F.3.7 extending... using max extension of 4
- var i1 = bufferPadding - 1, j1 = bufferPadding + 1;
- var i2 = bufferPadding + width - 2, j2 = bufferPadding + width;
- buffer[i1--] = buffer[j1++];
- buffer[j2++] = buffer[i2--];
- buffer[i1--] = buffer[j1++];
- buffer[j2++] = buffer[i2--];
- buffer[i1--] = buffer[j1++];
- buffer[j2++] = buffer[i2--];
- buffer[i1--] = buffer[j1++];
- buffer[j2++] = buffer[i2--];
-
+ this.expand(buffer, bufferPadding, width);
this.filter(buffer, bufferPadding, width, u0, bufferOut);
k = v * width;
@@ -36164,18 +36945,7 @@ var JpxImage = (function JpxImageClosure() {
for (var v = 0; v < height; v++, k += width, l++)
buffer[l] = items[k];
- // Section F.3.7 extending... using max extension of 4
- var i1 = bufferPadding - 1, j1 = bufferPadding + 1;
- var i2 = bufferPadding + height - 2, j2 = bufferPadding + height;
- buffer[i1--] = buffer[j1++];
- buffer[j2++] = buffer[i2--];
- buffer[i1--] = buffer[j1++];
- buffer[j2++] = buffer[i2--];
- buffer[i1--] = buffer[j1++];
- buffer[j2++] = buffer[i2--];
- buffer[i1--] = buffer[j1++];
- buffer[j2++] = buffer[i2--];
-
+ this.expand(buffer, bufferPadding, height);
this.filter(buffer, bufferPadding, height, v0, bufferOut);
k = u;
diff --git a/plugins/pdfviewer/viewer/viewer.css b/plugins/pdfviewer/viewer/viewer.css
index 1b36776..9c31d6a 100644
--- a/plugins/pdfviewer/viewer/viewer.css
+++ b/plugins/pdfviewer/viewer/viewer.css
@@ -20,6 +20,8 @@
html {
height: 100%;
+ /* Font size is needed to make the activity bar the correct size. */
+ font-size: 10px;
}
body {
@@ -45,8 +47,7 @@ select {
#viewerContainer:-webkit-full-screen {
top: 0px;
border-top: 2px solid transparent;
- background-color: #404040;
- background-image: url(images/texture.png);
+ background-color: #000;
width: 100%;
height: 100%;
overflow: hidden;
@@ -56,8 +57,7 @@ select {
#viewerContainer:-moz-full-screen {
top: 0px;
border-top: 2px solid transparent;
- background-color: #404040;
- background-image: url(images/texture.png);
+ background-color: #000;
width: 100%;
height: 100%;
overflow: hidden;
@@ -74,15 +74,13 @@ select {
}
#viewerContainer:-ms-fullscreen::-ms-backdrop {
- background-color: #404040;
- background-image: url(images/texture.png);
+ background-color: #000;
}
#viewerContainer:fullscreen {
top: 0px;
border-top: 2px solid transparent;
- background-color: #404040;
- background-image: url(images/texture.png);
+ background-color: #000;
width: 100%;
height: 100%;
overflow: hidden;
@@ -167,6 +165,7 @@ html[dir='rtl'] .innerCenter {
#outerContainer {
width: 100%;
height: 100%;
+ position: relative;
}
#sidebarContainer {
@@ -400,6 +399,7 @@ html[dir='rtl'] .secondaryToolbar {
max-width: 200px;
max-height: 400px;
overflow-y: auto;
+ margin-bottom: -4px;
}
.doorHanger,
@@ -894,20 +894,25 @@ html[dir="rtl"] .secondaryToolbarButton.print::before {
content: url(images/toolbarButton-download.png);
}
-.toolbarButton.bookmark {
+.toolbarButton.bookmark,
+.secondaryToolbarButton.bookmark {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
- margin-top: 3px;
padding-top: 4px;
+ text-decoration: none;
+}
+.secondaryToolbarButton.bookmark {
+ padding-top: 5px;
}
-#viewBookmark[href='#'] {
+.bookmark[href='#'] {
opacity: .5;
pointer-events: none;
}
-.toolbarButton.bookmark::before {
+.toolbarButton.bookmark::before,
+.secondaryToolbarButton.bookmark::before {
content: url(images/toolbarButton-bookmark.png);
}
@@ -944,9 +949,11 @@ html[dir="rtl"] .secondaryToolbarButton {
padding-right: 24px;
text-align: right;
}
-
-#secondaryToolbarButtonContainer :last-child {
- margin-bottom: 0;
+html[dir="ltr"] .secondaryToolbarButton.bookmark {
+ padding-left: 27px;
+}
+html[dir="rtl"] .secondaryToolbarButton.bookmark {
+ padding-right: 27px;
}
html[dir="ltr"] .secondaryToolbarButton > span {
@@ -972,6 +979,10 @@ html[dir="rtl"] .secondaryToolbarButton > span {
content: url(images/secondaryToolbarButton-rotateCw.png);
}
+.secondaryToolbarButton.handTool::before {
+ content: url(images/secondaryToolbarButton-handTool.png);
+}
+
.verticalToolbarSeparator {
display: block;
padding: 8px 0;
@@ -1023,6 +1034,7 @@ html[dir='rtl'] .verticalToolbarSeparator {
}
.toolbarField.pageNumber {
+ -moz-appearance: textfield; /* hides the spinner in moz */
min-width: 16px;
text-align: right;
width: 40px;
@@ -1070,6 +1082,11 @@ html[dir='rtl'] .verticalToolbarSeparator {
.thumbnail {
float: left;
+ margin-bottom: 5px;
+}
+
+#thumbnailView > a:last-of-type > .thumbnail {
+ margin-bottom: 10px;
}
.thumbnail:not([data-loaded]) {
@@ -1190,22 +1207,6 @@ html[dir='rtl'] .outlineItem > a {
cursor: default;
}
-#findScrollView {
- position: absolute;
- top: 10px;
- bottom: 10px;
- left: 10px;
- width: 280px;
-}
-
-#sidebarControls {
- position:absolute;
- width: 180px;
- height: 32px;
- left: 15px;
- bottom: 35px;
-}
-
.canvasWrapper {
overflow: hidden;
}
@@ -1417,6 +1418,10 @@ canvas {
background: white;
color: black;
margin-top: 5px;
+ visibility: hidden;
+ position: fixed;
+ right: 0;
+ top: 0;
}
#PDFBug {
@@ -1478,6 +1483,32 @@ canvas {
color: black;
}
+.grab-to-pan-grab * {
+ cursor: url("images/grab.cur"), move !important;
+ cursor: -webkit-grab !important;
+ cursor: -moz-grab !important;
+ cursor: grab !important;
+}
+.grab-to-pan-grabbing,
+.grab-to-pan-grabbing * {
+ cursor: url("images/grabbing.cur"), move !important;
+ cursor: -webkit-grabbing !important;
+ cursor: -moz-grabbing !important;
+ cursor: grabbing !important;
+}
+.grab-to-pan-grab input,
+.grab-to-pan-grab textarea,
+.grab-to-pan-grab button,
+.grab-to-pan-grab button *,
+.grab-to-pan-grab select,
+.grab-to-pan-grab option {
+ cursor: auto !important;
+}
+.grab-to-pan-grab a[href],
+.grab-to-pan-grab a[href] * {
+ cursor: pointer !important;
+}
+
@page {
margin: 0;
}
diff --git a/plugins/pdfviewer/viewer/viewer.html b/plugins/pdfviewer/viewer/viewer.html
index 7608f1a..f91077a 100644
--- a/plugins/pdfviewer/viewer/viewer.html
+++ b/plugins/pdfviewer/viewer/viewer.html
@@ -1,4 +1,4 @@
-<!DOCTYPE html>
+<!DOCTYPE html>
<!--
Copyright 2012 Mozilla Foundation
@@ -31,12 +31,12 @@ limitations under the License.
<!-- This snippet is used in production, see Makefile -->
<link rel="resource" type="application/l10n" href="locale/locale.properties"/>
<script type="text/javascript" src="l10n.js"></script>
-<script type="text/javascript" src="pdf.js"></script>
+<script type="text/javascript" src="pdf.min.js"></script>
<script type="text/javascript" src="debugger.js"></script>
- <script type="text/javascript" src="viewer.js"></script>
+ <script type="text/javascript" src="viewer.min.js"></script>
</head>
@@ -88,27 +88,45 @@ limitations under the License.
<span data-l10n-id="presentation_mode_label">Presentation Mode</span>
</button>
+ <button id="secondaryOpenFile" class="secondaryToolbarButton openFile hidden" title="Open File" tabindex="19" data-l10n-id="open_file">
+ <span data-l10n-id="open_file_label">Open</span>
+ </button>
+
<button id="secondaryPrint" class="secondaryToolbarButton print visibleMediumView" title="Print" tabindex="20" data-l10n-id="print">
<span data-l10n-id="print_label">Print</span>
</button>
+ <button id="secondaryDownload" class="secondaryToolbarButton download hidden" title="Download" tabindex="21" data-l10n-id="download">
+ <span data-l10n-id="download_label">Download</span>
+ </button>
+
+ <a href="#" id="secondaryViewBookmark" class="secondaryToolbarButton bookmark hidden" title="Current view (copy or open in new window)" tabindex="22" data-l10n-id="bookmark">
+ <span data-l10n-id="bookmark_label">Current View</span>
+ </a>
+
<div class="horizontalToolbarSeparator visibleLargeView"></div>
- <button id="firstPage" class="secondaryToolbarButton firstPage" title="Go to First Page" tabindex="22" data-l10n-id="first_page">
+ <button id="firstPage" class="secondaryToolbarButton firstPage" title="Go to First Page" tabindex="23" data-l10n-id="first_page">
<span data-l10n-id="first_page_label">Go to First Page</span>
</button>
- <button id="lastPage" class="secondaryToolbarButton lastPage" title="Go to Last Page" tabindex="23" data-l10n-id="last_page">
+ <button id="lastPage" class="secondaryToolbarButton lastPage" title="Go to Last Page" tabindex="24" data-l10n-id="last_page">
<span data-l10n-id="last_page_label">Go to Last Page</span>
</button>
<div class="horizontalToolbarSeparator"></div>
- <button id="pageRotateCw" class="secondaryToolbarButton rotateCw" title="Rotate Clockwise" tabindex="24" data-l10n-id="page_rotate_cw">
+ <button id="pageRotateCw" class="secondaryToolbarButton rotateCw" title="Rotate Clockwise" tabindex="25" data-l10n-id="page_rotate_cw">
<span data-l10n-id="page_rotate_cw_label">Rotate Clockwise</span>
</button>
- <button id="pageRotateCcw" class="secondaryToolbarButton rotateCcw" title="Rotate Counterclockwise" tabindex="25" data-l10n-id="page_rotate_ccw">
+ <button id="pageRotateCcw" class="secondaryToolbarButton rotateCcw" title="Rotate Counterclockwise" tabindex="26" data-l10n-id="page_rotate_ccw">
<span data-l10n-id="page_rotate_ccw_label">Rotate Counterclockwise</span>
</button>
+
+ <div class="horizontalToolbarSeparator"></div>
+
+ <button id="toggleHandTool" class="secondaryToolbarButton handTool" title="Enable hand tool" tabindex="27" data-l10n-id="hand_tool_enable">
+ <span data-l10n-id="hand_tool_enable_label">Enable hand tool</span>
+ </button>
</div>
</div> <!-- secondaryToolbar -->
@@ -134,7 +152,6 @@ limitations under the License.
</div>
<label id="pageNumberLabel" class="toolbarLabel" for="pageNumber" data-l10n-id="page_label">Page: </label>
<input type="number" id="pageNumber" class="toolbarField pageNumber" value="1" size="4" min="1" tabindex="8">
- </input>
<span id="numPages" class="toolbarLabel"></span>
</div>
<div id="toolbarViewerRight">
@@ -142,10 +159,22 @@ limitations under the License.
<span data-l10n-id="presentation_mode_label">Presentation Mode</span>
</button>
+ <button id="openFile" class="toolbarButton openFile hidden" title="Open File" tabindex="13" data-l10n-id="open_file">
+ <span data-l10n-id="open_file_label">Open</span>
+ </button>
+
<button id="print" class="toolbarButton print hiddenMediumView" title="Print" tabindex="14" data-l10n-id="print">
<span data-l10n-id="print_label">Print</span>
</button>
+ <button id="download" class="toolbarButton download hidden" title="Download" tabindex="15" data-l10n-id="download">
+ <span data-l10n-id="download_label">Download</span>
+ </button>
+ <!-- <div class="toolbarButtonSpacer"></div> -->
+ <a href="#" id="viewBookmark" class="toolbarButton bookmark hidden" title="Current view (copy or open in new window)" tabindex="16" data-l10n-id="bookmark">
+ <span data-l10n-id="bookmark_label">Current View</span>
+ </a>
+
<div class="verticalToolbarSeparator hiddenSmallView"></div>
<button id="secondaryToolbarToggle" class="toolbarButton" title="Tools" tabindex="17" data-l10n-id="tools">
@@ -244,6 +273,78 @@ limitations under the License.
</div> <!-- outerContainer -->
<div id="printContainer"></div>
+<div id="mozPrintCallback-shim" hidden>
+ <style scoped>
+#mozPrintCallback-shim {
+ position: fixed;
+ top: 0;
+ left: 0;
+ height: 100%;
+ width: 100%;
+ z-index: 9999999;
+
+ display: block;
+ text-align: center;
+ background-color: rgba(0, 0, 0, 0.5);
+}
+#mozPrintCallback-shim[hidden] {
+ display: none;
+}
+ at media print {
+ #mozPrintCallback-shim {
+ display: none;
+ }
+}
+
+#mozPrintCallback-shim .mozPrintCallback-dialog-box {
+ display: inline-block;
+ margin: -50px auto 0;
+ position: relative;
+ top: 45%;
+ left: 0;
+ min-width: 220px;
+ max-width: 400px;
+
+ padding: 9px;
+
+ border: 1px solid hsla(0, 0%, 0%, .5);
+ border-radius: 2px;
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
+
+ background-color: #474747;
+
+ color: hsl(0, 0%, 85%);
+ font-size: 16px;
+ line-height: 20px;
+}
+#mozPrintCallback-shim .progress-row {
+ clear: both;
+ padding: 1em 0;
+}
+#mozPrintCallback-shim progress {
+ width: 100%;
+}
+#mozPrintCallback-shim .relative-progress {
+ clear: both;
+ float: right;
+}
+#mozPrintCallback-shim .progress-actions {
+ clear: both;
+}
+ </style>
+ <div class="mozPrintCallback-dialog-box">
+ <!-- TODO: Localise the following strings -->
+ Preparing document for printing...
+ <div class="progress-row">
+ <progress value="0" max="100"></progress>
+ <span class="relative-progress">0%</span>
+ </div>
+ <div class="progress-actions">
+ <input type="button" value="Cancel" class="mozPrintCallback-cancel">
+ </div>
+ </div>
+</div>
+
</body>
</html>
diff --git a/plugins/pdfviewer/viewer/viewer.js b/plugins/pdfviewer/viewer/viewer.js
index 8500af4..b94a444 100644
--- a/plugins/pdfviewer/viewer/viewer.js
+++ b/plugins/pdfviewer/viewer/viewer.js
@@ -1,93 +1,5449 @@
-var DEFAULT_URL=null,DEFAULT_SCALE="auto",DEFAULT_SCALE_DELTA=1.1,UNKNOWN_SCALE=0,CACHE_SIZE=20,CSS_UNITS=96/72,SCROLLBAR_PADDING=40,VERTICAL_PADDING=5,MIN_SCALE=0.25,MAX_SCALE=4,IMAGE_DIR="./images/",SETTINGS_MEMORY=20,ANNOT_MIN_SIZE=10,RenderingStates={INITIAL:0,RUNNING:1,PAUSED:2,FINISHED:3},FindStates={FIND_FOUND:0,FIND_NOTFOUND:1,FIND_WRAPPED:2,FIND_PENDING:3};PDFJS.workerSrc="pdf.js";var mozL10n=document.mozL10n||document.webL10n;
-function getFileName(a){var b=a.indexOf("#"),c=a.indexOf("?"),b=Math.min(0<b?b:a.length,0<c?c:a.length);return a.substring(a.lastIndexOf("/",b)+1,b)}function scrollIntoView(a,b){for(var c=a.offsetParent,d=a.offsetTop;c.clientHeight==c.scrollHeight;)if(d+=c.offsetTop,c=c.offsetParent,!c)return;b&&(d+=b.top);c.scrollTop=d}
-var Cache=function(a){var b=[];this.push=function(c){var d=b.indexOf(c);0<=d&&b.splice(d);b.push(c);b.length>a&&b.shift().destroy()}},ProgressBar=function(){function a(a,c){this.div=document.querySelector(a+" .progress");this.height=c.height||100;this.width=c.width||100;this.units=c.units||"%";this.div.style.height=this.height+this.units}a.prototype={updateBar:function(){if(this._indeterminate)this.div.classList.add("indeterminate");else{var a=this.width*this._percent/100;95<this._percent?this.div.classList.add("full"):
-this.div.classList.remove("full");this.div.classList.remove("indeterminate");this.div.style.width=a+this.units}},get percent(){return this._percent},set percent(a){this._indeterminate=isNaN(a);this._percent=Math.min(Math.max(a,0),100);this.updateBar()}};return a}(),Settings=function(){function a(a){this.fingerprint=a;this.initializedPromise=new PDFJS.Promise;a=function(a){this.initialize(a||"{}");this.initializedPromise.resolve()}.bind(this);b&&a(localStorage.getItem("database"))}var b;try{b="localStorage"in
-window&&null!==window.localStorage&&localStorage}catch(c){b=!1}a.prototype={initialize:function(a){a=JSON.parse(a);"files"in a||(a.files=[]);a.files.length>=SETTINGS_MEMORY&&a.files.shift();for(var b,c=0,e=a.files.length;c<e;c++)if(a.files[c].fingerprint==this.fingerprint){b=c;break}"number"!=typeof b&&(b=a.files.push({fingerprint:this.fingerprint})-1);this.file=a.files[b];this.database=a},set:function(a,c){if(this.initializedPromise.isResolved){this.file[a]=c;var h=JSON.stringify(this.database);
-b&&localStorage.setItem("database",h)}},get:function(a,b){return this.initializedPromise.isResolved?this.file[a]||b:b}};return a}(),cache=new Cache(CACHE_SIZE),currentPageNumber=1,PDFFindController={startedTextExtraction:!1,extractTextPromises:[],active:!1,pageContents:[],pageMatches:[],selected:{pageIdx:-1,matchIdx:-1},offset:{pageIdx:null,matchIdx:null},resumePageIdx:null,resumeCallback:null,state:null,dirtyMatch:!1,findTimeout:null,initialize:function(){var a=["find","findagain","findhighlightallchange",
-"findcasesensitivitychange"];this.handleEvent=this.handleEvent.bind(this);for(var b=0;b<a.length;b++)window.addEventListener(a[b],this.handleEvent)},calcFindMatch:function(a){var b=this.pageContents[a],c=this.state.query,d=this.state.caseSensitive,f=c.length;if(0!==f){d||(b=b.toLowerCase(),c=c.toLowerCase());for(var d=[],h=-f;;){h=b.indexOf(c,h+f);if(-1===h)break;d.push(h)}this.pageMatches[a]=d;this.updatePage(a);this.resumePageIdx===a&&(a=this.resumeCallback,this.resumeCallback=this.resumePageIdx=
-null,a())}},extractText:function(){function a(b){PDFView.pages[b].getTextContent().then(function(c){c=c.bidiTexts;for(var e="",g=0;g<c.length;g++)e+=c[g].str;d.pageContents.push(e);d.extractTextPromises[b].resolve(b);b+1<PDFView.pages.length&&a(b+1)})}if(!this.startedTextExtraction){this.startedTextExtraction=!0;this.pageContents=[];for(var b=0,c=PDFView.pdfDocument.numPages;b<c;b++)this.extractTextPromises.push(new PDFJS.Promise);var d=this;a(0);return this.extractTextPromise}},handleEvent:function(a){if(null===
-this.state||"findagain"!==a.type)this.dirtyMatch=!0;this.state=a.detail;this.updateUIState(FindStates.FIND_PENDING);this.extractText();clearTimeout(this.findTimeout);"find"===a.type?this.findTimeout=setTimeout(this.nextMatch.bind(this),250):this.nextMatch()},updatePage:function(a){var b=PDFView.pages[a];this.selected.pageIdx===a&&b.scrollIntoView();b.textLayer&&b.textLayer.updateMatches()},nextMatch:function(){var a=this.state.findPrevious,b=PDFView.pages.length;this.active=!0;if(this.dirtyMatch){this.dirtyMatch=
-!1;this.selected.pageIdx=this.selected.matchIdx=-1;this.offset.pageIdx=a?b-1:0;this.offset.matchIdx=null;this.hadMatch=!1;this.resumePageIdx=this.resumeCallback=null;this.pageMatches=[];for(var c=this,d=0;d<b;d++)this.updatePage(d),this.extractTextPromises[d].onData(function(a){setTimeout(function(){c.calcFindMatch(a)})})}if(""===this.state.query)this.updateUIState(FindStates.FIND_FOUND);else if(!this.resumeCallback){b=this.offset;if(null!==b.matchIdx){d=this.pageMatches[b.pageIdx].length;if(!a&&
-b.matchIdx+1<d||a&&0<b.matchIdx){this.hadMatch=!0;b.matchIdx=a?b.matchIdx-1:b.matchIdx+1;this.updateMatch(!0);return}this.advanceOffsetPage(a)}this.nextPageMatch()}},nextPageMatch:function(){null!==this.resumePageIdx&&console.error("There can only be one pending page.");var a=function(a){var b=this.offset;a=a.length;var c=this.state.findPrevious;if(a)this.hadMatch=!0,b.matchIdx=c?a-1:0,this.updateMatch(!0);else{this.advanceOffsetPage(c);if(b.wrapped&&(b.matchIdx=null,!this.hadMatch)){this.updateMatch(!1);
-return}this.nextPageMatch()}}.bind(this),b=this.offset.pageIdx,c=this.pageMatches;c[b]?a(c[b]):(this.resumeCallback=function(){a(c[b])},this.resumePageIdx=b)},advanceOffsetPage:function(a){var b=this.offset,c=this.extractTextPromises.length;b.pageIdx=a?b.pageIdx-1:b.pageIdx+1;b.matchIdx=null;if(b.pageIdx>=c||0>b.pageIdx)b.pageIdx=a?c-1:0,b.wrapped=!0},updateMatch:function(a){var b=FindStates.FIND_NOTFOUND,c=this.offset.wrapped;this.offset.wrapped=!1;a&&(a=this.selected.pageIdx,this.selected.pageIdx=
-this.offset.pageIdx,this.selected.matchIdx=this.offset.matchIdx,b=c?FindStates.FIND_WRAPPED:FindStates.FIND_FOUND,-1!==a&&a!==this.selected.pageIdx&&this.updatePage(a));this.updateUIState(b,this.state.findPrevious);-1!==this.selected.pageIdx&&this.updatePage(this.selected.pageIdx,!0)},updateUIState:function(a,b){PDFView.supportsIntegratedFind?FirefoxCom.request("updateFindControlState",{result:a,findPrevious:b}):PDFFindBar.updateUIState(a,b)}},PDFFindBar={opened:!1,initialize:function(){this.bar=
-document.getElementById("findbar");this.toggleButton=document.getElementById("viewFind");this.findField=document.getElementById("findInput");this.highlightAll=document.getElementById("findHighlightAll");this.caseSensitive=document.getElementById("findMatchCase");this.findMsg=document.getElementById("findMsg");this.findStatusIcon=document.getElementById("findStatusIcon");var a=this;this.toggleButton.addEventListener("click",function(){a.toggle()});this.findField.addEventListener("input",function(){a.dispatchEvent("")});
-this.bar.addEventListener("keydown",function(b){switch(b.keyCode){case 13:b.target===a.findField&&a.dispatchEvent("again",b.shiftKey);break;case 27:a.close()}});document.getElementById("findPrevious").addEventListener("click",function(){a.dispatchEvent("again",!0)});document.getElementById("findNext").addEventListener("click",function(){a.dispatchEvent("again",!1)});this.highlightAll.addEventListener("click",function(){a.dispatchEvent("highlightallchange")});this.caseSensitive.addEventListener("click",
-function(){a.dispatchEvent("casesensitivitychange")})},dispatchEvent:function(a,b){var c=document.createEvent("CustomEvent");c.initCustomEvent("find"+a,!0,!0,{query:this.findField.value,caseSensitive:this.caseSensitive.checked,highlightAll:this.highlightAll.checked,findPrevious:b});return window.dispatchEvent(c)},updateUIState:function(a,b){var c=!1,d="",f="";switch(a){case FindStates.FIND_PENDING:f="pending";break;case FindStates.FIND_NOTFOUND:d=mozL10n.get("find_not_found",null,"Phrase not found");
-c=!0;break;case FindStates.FIND_WRAPPED:d=b?mozL10n.get("find_reached_top",null,"Reached top of document, continued from bottom"):mozL10n.get("find_reached_bottom",null,"Reached end of document, continued from top")}c?this.findField.classList.add("notFound"):this.findField.classList.remove("notFound");this.findField.setAttribute("data-status",f);this.findMsg.textContent=d},open:function(){this.opened||(this.opened=!0,this.toggleButton.classList.add("toggled"),this.bar.classList.remove("hidden"),this.findField.select(),
-this.findField.focus())},close:function(){this.opened&&(this.opened=!1,this.toggleButton.classList.remove("toggled"),this.bar.classList.add("hidden"),PDFFindController.active=!1)},toggle:function(){this.opened?this.close():this.open()}},PDFView={pages:[],thumbnails:[],currentScale:UNKNOWN_SCALE,currentScaleValue:null,initialBookmark:document.location.hash.substring(1),startedTextExtraction:!1,pageText:[],container:null,thumbnailContainer:null,initialized:!1,fellback:!1,pdfDocument:null,sidebarOpen:!1,
-pageViewScroll:null,thumbnailViewScroll:null,isFullscreen:!1,previousScale:null,pageRotation:0,mouseScrollTimeStamp:0,mouseScrollDelta:0,lastScroll:0,previousPageNumber:1,initialize:function(){var a=this,b=this.container=document.getElementById("viewerContainer");this.pageViewScroll={};this.watchScroll(b,this.pageViewScroll,updateViewarea);var c=this.thumbnailContainer=document.getElementById("thumbnailView");this.thumbnailViewScroll={};this.watchScroll(c,this.thumbnailViewScroll,this.renderHighestPriority.bind(this));
-PDFFindBar.initialize();PDFFindController.initialize();this.initialized=!0;b.addEventListener("scroll",function(){a.lastScroll=Date.now()},!1)},watchScroll:function(a,b,c){b.down=!0;b.lastY=a.scrollTop;a.addEventListener("scroll",function(d){d=a.scrollTop;var f=b.lastY;d>f?b.down=!0:d<f&&(b.down=!1);b.lastY=d;c()},!0)},setScale:function(a,b,c){if(a!=this.currentScale){for(var d=this.pages,f=0;f<d.length;f++)d[f].update(a*CSS_UNITS);c||this.currentScale==a||this.pages[this.page-1].scrollIntoView();
-this.currentScale=a;c=document.createEvent("UIEvents");c.initUIEvent("scalechange",!1,!1,window,0);c.scale=a;c.resetAutoSettings=b;window.dispatchEvent(c)}},parseScale:function(a,b,c){if("custom"!=a){var d=parseFloat(a);this.currentScaleValue=a;if(d)this.setScale(d,!0,c);else{var f=this.container,h=this.pages[this.page-1];if(h){var e=(f.clientWidth-SCROLLBAR_PADDING)/h.width*h.scale/CSS_UNITS,f=(f.clientHeight-VERTICAL_PADDING)/h.height*h.scale/CSS_UNITS;switch(a){case "page-actual":d=1;break;case "page-width":d=
-e;break;case "page-height":d=f;break;case "page-fit":d=Math.min(e,f);break;case "auto":d=Math.min(1,e)}this.setScale(d,b,c);selectScaleOption(a)}}}},zoomIn:function(){var a=(this.currentScale*DEFAULT_SCALE_DELTA).toFixed(2),a=Math.min(MAX_SCALE,a);this.parseScale(a,!0)},zoomOut:function(){var a=(this.currentScale/DEFAULT_SCALE_DELTA).toFixed(2),a=Math.max(MIN_SCALE,a);this.parseScale(a,!0)},set page(a){var b=this.pages;document.getElementById("pageNumber");var c=document.createEvent("UIEvents");c.initUIEvent("pagechange",
-!1,!1,window,0);0<a&&a<=b.length?(b[a-1].updateStats(),this.previousPageNumber=currentPageNumber,currentPageNumber=a,c.pageNumber=a,window.dispatchEvent(c),updateViewarea.inProgress||this.loading&&1==a||b[a-1].scrollIntoView()):(this.previousPageNumber=a,c.pageNumber=this.page,window.dispatchEvent(c))},get page(){return currentPageNumber},get supportsPrinting(){var a="mozPrintCallback"in document.createElement("canvas");Object.defineProperty(this,"supportsPrinting",{value:a,enumerable:!0,configurable:!0,
-writable:!1});return a},get supportsFullscreen(){var a=document.documentElement,a=a.requestFullscreen||a.mozRequestFullScreen||a.webkitRequestFullScreen;window.frameElement&&(a=!1);Object.defineProperty(this,"supportsFullScreen",{value:a,enumerable:!0,configurable:!0,writable:!1});return a},get supportsIntegratedFind(){Object.defineProperty(this,"supportsIntegratedFind",{value:!1,enumerable:!0,configurable:!0,writable:!1});return!1},get supportsDocumentFonts(){Object.defineProperty(this,"supportsDocumentFonts",
-{value:!0,enumerable:!0,configurable:!0,writable:!1});return!0},get isHorizontalScrollbarEnabled(){var a=document.getElementById("viewerContainer");return a.scrollWidth>a.clientWidth},initPassiveLoading:function(){PDFView.loadingBar||(PDFView.loadingBar=new ProgressBar("#loadingBar",{}));window.addEventListener("message",function(a){var b=a.data;if("object"===typeof b&&"pdfjsLoadAction"in b)switch(b.pdfjsLoadAction){case "progress":PDFView.progress(b.loaded/b.total);break;case "complete":if(!b.data){PDFView.error(mozL10n.get("loading_error",
-null,"An error occurred while loading the PDF."),a);break}PDFView.open(b.data,0)}});FirefoxCom.requestSync("initPassiveLoading",null)},setTitleUsingUrl:function(a){this.url=a;try{this.setTitle(decodeURIComponent(getFileName(a))||a)}catch(b){this.setTitle(a)}},setTitle:function(a){document.title=a},open:function(a,b,c){var d={password:c};"string"===typeof a?(this.setTitleUsingUrl(a),d.url=a):a&&"byteLength"in a&&(d.data=a);PDFView.loadingBar||(PDFView.loadingBar=new ProgressBar("#loadingBar",{}));
-this.pdfDocument=null;var f=this;f.loading=!0;PDFJS.getDocument(d).then(function(a){f.load(a,b);f.loading=!1},function(d,e){if(e&&"PasswordException"===e.name&&"needpassword"===e.code){var g=mozL10n.get("request_password",null,"PDF is protected by a password:");if((c=prompt(g))&&0<c.length)return PDFView.open(a,b,c)}g=mozL10n.get("loading_error",null,"An error occurred while loading the PDF.");e&&"InvalidPDFException"===e.name&&(g=mozL10n.get("invalid_file_error",null,"Invalid or corrupted PDF file."));
-document.getElementById("loading").textContent=mozL10n.get("loading_error_indicator",null,"Error");f.error(g,{message:d});f.loading=!1},function(a){f.progress(a.loaded/a.total)})},download:function(){var a=this.url.split("#")[0];window.open(a+"#pdfjs.action=download","_parent")},fallback:function(){},navigateTo:function(a){"string"===typeof a&&(a=this.destinations[a]);if(a instanceof Array){var b=a[0],b=b instanceof Object?this.pagesRefMap[b.num+" "+b.gen+" R"]:b+1;b>this.pages.length&&(b=this.pages.length);
-b&&(this.page=b,this.pages[b-1].scrollIntoView(a))}},getDestinationHash:function(a){if("string"===typeof a)return PDFView.getAnchorUrl("#"+escape(a));if(a instanceof Array){var b=a[0];if(b=b instanceof Object?this.pagesRefMap[b.num+" "+b.gen+" R"]:b+1){var b=PDFView.getAnchorUrl("#page="+b),c=a[1];"object"===typeof c&&"name"in c&&"XYZ"==c.name&&(b+="&zoom="+100*(a[4]||this.currentScale),a[2]||a[3])&&(b+=","+(a[2]||0)+","+(a[3]||0));return b}}return""},getAnchorUrl:function(a){return a},getOutputScale:function(){var a=
-"devicePixelRatio"in window?window.devicePixelRatio:1;return{sx:a,sy:a,scaled:1!=a}},error:function(a,b){var c=mozL10n.get("error_version_info",{version:PDFJS.version||"?",build:PDFJS.build||"?"},"PDF.js v{{version}} (build: {{build}})")+"\n";b&&(c+=mozL10n.get("error_message",{message:b.message},"Message: {{message}}"),b.stack?c+="\n"+mozL10n.get("error_stack",{stack:b.stack},"Stack: {{stack}}"):(b.filename&&(c+="\n"+mozL10n.get("error_file",{file:b.filename},"File: {{file}}")),b.lineNumber&&(c+=
-"\n"+mozL10n.get("error_line",{line:b.lineNumber},"Line: {{line}}"))));document.getElementById("loadingBox").setAttribute("hidden","true");var d=document.getElementById("errorWrapper");d.removeAttribute("hidden");document.getElementById("errorMessage").textContent=a;document.getElementById("errorClose").onclick=function(){d.setAttribute("hidden","true")};var f=document.getElementById("errorMoreInfo"),h=document.getElementById("errorShowMore"),e=document.getElementById("errorShowLess");h.onclick=function(){f.removeAttribute("hidden");
-h.setAttribute("hidden","true");e.removeAttribute("hidden")};e.onclick=function(){f.setAttribute("hidden","true");h.removeAttribute("hidden");e.setAttribute("hidden","true")};h.removeAttribute("hidden");e.setAttribute("hidden","true");f.value=c;f.rows=c.split("\n").length-1},progress:function(a){a=Math.round(100*a);PDFView.loadingBar.percent=a},load:function(a,b){function c(a,b){a.onAfterDraw=function(){b.setImage(a.canvas)}}this.pdfDocument=a;document.getElementById("errorWrapper").setAttribute("hidden",
-"true");document.getElementById("loadingBox").setAttribute("hidden","true");document.getElementById("loading").textContent="";var d=document.getElementById("thumbnailView");for(d.parentNode.scrollTop=0;d.hasChildNodes();)d.removeChild(d.lastChild);"_loadingInterval"in d&&clearInterval(d._loadingInterval);for(var f=document.getElementById("viewer");f.hasChildNodes();)f.removeChild(f.lastChild);var h=a.numPages,e=a.fingerprint;document.getElementById("numPages").textContent=mozL10n.get("page_of",{pageCount:h},
-"of {{pageCount}}");document.getElementById("pageNumber").max=h;PDFView.documentFingerprint=e;var g=PDFView.store=new Settings(e),e=g.initializedPromise;this.pageRotation=0;var k=this.pages=[];this.pageText=[];this.startedTextExtraction=!1;for(var n={},l=this.thumbnails=[],m=[],s=1;s<=h;s++)m.push(a.getPage(s));var r=this,m=PDFJS.Promise.all(m);m.then(function(a){for(var p=1;p<=h;p++){var e=a[p-1],g=new PageView(f,e,p,b,e.stats,r.navigateTo.bind(r)),m=new ThumbnailView(d,e,p);c(g,m);k.push(g);l.push(m);
-e=e.ref;n[e.num+" "+e.gen+" R"]=p}r.pagesRefMap=n});s=a.getDestinations();s.then(function(a){r.destinations=a});PDFJS.Promise.all([m,s,e]).then(function(){a.getOutline().then(function(a){r.outline=new DocumentOutlineView(a)});var c=null;if(g.get("exists",!1))var c=g.get("page","1"),d=g.get("zoom",PDFView.currentScale),f=g.get("scrollLeft","0"),e=g.get("scrollTop","0"),c="page="+c+"&zoom="+d+","+f+","+e;r.setInitialView(c,b)});a.getMetadata().then(function(b){var c=b.info;b=b.metadata;r.documentInfo=
-c;r.metadata=b;console.log("PDF "+a.fingerprint+" ["+c.PDFFormatVersion+" "+(c.Producer||"-")+" / "+(c.Creator||"-")+"]"+(PDFJS.version?" (PDF.js: "+PDFJS.version+")":""));var d;b&&b.has("dc:title")&&(d=b.get("dc:title"));!d&&c&&c.Title&&(d=c.Title);d&&r.setTitle(d+" - "+document.title)})},setInitialView:function(a,b){this.currentScale=0;this.currentScaleValue=null;this.initialBookmark?(this.setHash(this.initialBookmark),this.initialBookmark=null):a?this.setHash(a):b&&(this.parseScale(b,!0),this.page=
-1);PDFView.currentScale===UNKNOWN_SCALE&&this.parseScale(DEFAULT_SCALE,!0)},renderHighestPriority:function(){var a=this.getVisiblePages();(a=this.getHighestPriority(a,this.pages,this.pageViewScroll.down))?this.renderView(a,"page"):this.sidebarOpen&&(a=this.getVisibleThumbs(),(a=this.getHighestPriority(a,this.thumbnails,this.thumbnailViewScroll.down))&&this.renderView(a,"thumbnail"))},getHighestPriority:function(a,b,c){var d=a.views,f=d.length;if(0===f)return!1;for(var h=0;h<f;++h){var e=d[h].view;
-if(!this.isViewFinished(e))return e}a=c?a.last.id:a.first.id-2;return b[a]&&!this.isViewFinished(b[a])?b[a]:!1},isViewFinished:function(a){return a.renderingState===RenderingStates.FINISHED},renderView:function(a,b){switch(a.renderingState){case RenderingStates.FINISHED:return!1;case RenderingStates.PAUSED:PDFView.highestPriorityPage=b+a.id;a.resume();break;case RenderingStates.RUNNING:PDFView.highestPriorityPage=b+a.id;break;case RenderingStates.INITIAL:PDFView.highestPriorityPage=b+a.id,a.draw(this.renderHighestPriority.bind(this))}return!0},
-setHash:function(a){if(a)if(0<=a.indexOf("=")){var b=PDFView.parseQueryString(a);if("nameddest"in b)PDFView.navigateTo(b.nameddest);else if("page"in b)if(a=b.page|0||1,"zoom"in b){var b=b.zoom.split(","),c=b[0],d=parseFloat(c);d&&(c=d/100);this.pages[a-1].scrollIntoView([null,{name:"XYZ"},b[1]|0,b[2]|0,c])}else this.page=a}else/^\d+$/.test(a)?this.page=a:PDFView.navigateTo(unescape(a))},switchSidebarView:function(a){var b=document.getElementById("thumbnailView"),c=document.getElementById("outlineView"),
-d=document.getElementById("viewThumbnail"),f=document.getElementById("viewOutline");switch(a){case "thumbs":a=b.classList.contains("hidden");d.classList.add("toggled");f.classList.remove("toggled");b.classList.remove("hidden");c.classList.add("hidden");PDFView.renderHighestPriority();a&&scrollIntoView(document.getElementById("thumbnailContainer"+this.page));break;case "outline":d.classList.remove("toggled"),f.classList.add("toggled"),b.classList.add("hidden"),c.classList.remove("hidden"),f.getAttribute("disabled")}},
-getVisiblePages:function(){return this.getVisibleElements(this.container,this.pages,!0)},getVisibleThumbs:function(){return this.getVisibleElements(this.thumbnailContainer,this.thumbnails)},getVisibleElements:function(a,b,c){for(var d=0,f,h=a.scrollTop,e=1,g=b.length;e<=g;++e){f=b[e-1];d=f.el.offsetTop;if(d+f.el.clientHeight>h)break;d+=f.el.clientHeight}var k=[];if(this.isFullscreen)return c=this.pages[this.page-1],k.push({id:c.id,view:c}),{first:c,last:c,views:k};a=h+a.clientHeight;for(var n,l,m;e<=
-g&&d<a;++e)f=b[e-1],m=f.el.clientHeight,d=f.el.offsetTop,n=d+m,l=Math.max(0,h-d)+Math.max(0,n-a),l=Math.floor(100*(m-l)/m),k.push({id:f.id,y:d,view:f,percent:l}),d=n;b=k[0];d=k[k.length-1];c&&k.sort(function(a,b){var c=a.percent-b.percent;return 0.0010<Math.abs(c)?-c:a.id-b.id});return{first:b,last:d,views:k}},parseQueryString:function(a){a=a.split("&");for(var b={},c=0;c<a.length;++c){var d=a[c].split("="),f=1<d.length?d[1]:null;b[unescape(d[0])]=unescape(f)}return b},beforePrint:function(){if(this.supportsPrinting){document.querySelector("body").setAttribute("data-mozPrintCallback",
-!0);for(var a=0,b=this.pages.length;a<b;++a)this.pages[a].beforePrint()}else a=mozL10n.get("printing_not_supported",null,"Warning: Printing is not fully supported by this browser."),this.error(a)},afterPrint:function(){for(var a=document.getElementById("printContainer");a.hasChildNodes();)a.removeChild(a.lastChild)},fullscreen:function(){if(document.fullscreenElement||document.mozFullScreen||document.webkitIsFullScreen)return!1;var a=document.getElementById("viewerContainer");if(document.documentElement.requestFullscreen)a.requestFullscreen();
-else if(document.documentElement.mozRequestFullScreen)a.mozRequestFullScreen();else if(document.documentElement.webkitRequestFullScreen)a.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);else return!1;this.isFullscreen=!0;var b=this.pages[this.page-1];this.previousScale=this.currentScaleValue;this.parseScale("page-fit",!0);setTimeout(function(){b.scrollIntoView()},0);this.showPresentationControls();return!0},exitFullscreen:function(){this.isFullscreen=!1;this.parseScale(this.previousScale);this.page=
-this.page;this.clearMouseScrollState();this.hidePresentationControls()},showPresentationControls:function(){var a=document.getElementById("viewerContainer");this.presentationControlsTimeout?clearTimeout(this.presentationControlsTimeout):a.classList.add("presentationControls");this.presentationControlsTimeout=setTimeout(function(){a.classList.remove("presentationControls");delete PDFView.presentationControlsTimeout},3E3)},hidePresentationControls:function(){this.presentationControlsTimeout&&(clearTimeout(this.presentationControlsTimeout),
-delete this.presentationControlsTimeout,document.getElementById("viewerContainer").classList.remove("presentationControls"))},rotatePages:function(a){this.pageRotation=(this.pageRotation+360+a)%360;a=0;for(var b=this.pages.length;a<b;a++){var c=this.pages[a];c.update(c.scale,this.pageRotation)}a=0;for(b=this.thumbnails.length;a<b;a++)this.thumbnails[a].updateRotation(this.pageRotation);var d=this.pages[this.page-1];this.parseScale(this.currentScaleValue,!0);this.renderHighestPriority();setTimeout(function(){d.scrollIntoView()},
-0)},mouseScroll:function(a){var b=(new Date).getTime(),c=this.mouseScrollTimeStamp;b>c&&50>b-c||((0<this.mouseScrollDelta&&0>a||0>this.mouseScrollDelta&&0<a)&&this.clearMouseScrollState(),this.mouseScrollDelta+=a,120<=Math.abs(this.mouseScrollDelta)&&(a=0<this.mouseScrollDelta?-1:1,this.clearMouseScrollState(),c=this.page,1==c&&-1==a||c==this.pages.length&&1==a||(this.page+=a,this.mouseScrollTimeStamp=b)))},clearMouseScrollState:function(){this.mouseScrollDelta=this.mouseScrollTimeStamp=0}},PageView=
-function(a,b,c,d,f,h){function e(a,b){function c(a,b){a.href=PDFView.getDestinationHash(b);a.onclick=function(){b&&PDFView.navigateTo(b);return!1}}function d(a,c,f){f||(f=b.convertToViewportRectangle(c.rect),f=PDFJS.Util.normalizeRect(f));a=document.createElement(a);a.style.left=Math.floor(f[0])+"px";a.style.top=Math.floor(f[1])+"px";a.style.width=Math.ceil(f[2]-f[0])+"px";a.style.height=Math.ceil(f[3]-f[1])+"px";return a}function f(a){var c=document.createElement("section");c.className="annotText";
-var e=b.convertToViewportRectangle(a.rect),e=PDFJS.Util.normalizeRect(e);e[3]-e[1]<ANNOT_MIN_SIZE&&(e[3]=e[1]+ANNOT_MIN_SIZE);e[2]-e[0]<ANNOT_MIN_SIZE&&(e[2]=e[0]+(e[3]-e[1]));var h=d("img",a,e),g=a.name;h.src=IMAGE_DIR+"annotation-"+g.toLowerCase()+".svg";h.alt=mozL10n.get("text_annotation_type",{type:g},"[{{type}} Annotation]");var k=document.createElement("div");k.setAttribute("hidden",!0);var g=document.createElement("h1"),l=document.createElement("p");k.style.left=Math.floor(e[2])+"px";k.style.top=
-Math.floor(e[1])+"px";g.textContent=a.title;if(a.content||a.title){e=document.createElement("span");a=a.content.split(/(?:\r\n?|\n)/);for(var s=0,v=a.length;s<v;++s)e.appendChild(document.createTextNode(a[s])),s<v-1&&e.appendChild(document.createElement("br"));l.appendChild(e);h.addEventListener("mouseover",function(){k.removeAttribute("hidden")},!1);h.addEventListener("mouseout",function(){k.setAttribute("hidden",!0)},!1)}else k.setAttribute("hidden",!0);k.appendChild(g);k.appendChild(l);c.appendChild(h);
-c.appendChild(k);return c}a.getAnnotations().then(function(a){for(var b=0;b<a.length;b++){var e=a[b];switch(e.type){case "Link":var h=d("a",e);h.href=e.url||"";e.url||c(h,"dest"in e?e.dest:null);g.appendChild(h);break;case "Text":(e=f(e))&&g.appendChild(e);break;case "Widget":PDFView.fallback()}}})}this.id=c;this.pdfPage=b;this.rotation=0;this.scale=d||1;this.viewport=this.pdfPage.getViewport(this.scale,this.pdfPage.rotate);this.renderingState=RenderingStates.INITIAL;this.textLayer=this.textContent=
-this.resume=null;c=document.createElement("a");c.name=""+this.id;var g=this.el=document.createElement("div");g.id="pageContainer"+this.id;g.className="page";g.style.width=Math.floor(this.viewport.width)+"px";g.style.height=Math.floor(this.viewport.height)+"px";a.appendChild(c);a.appendChild(g);this.destroy=function(){this.update();this.pdfPage.destroy()};this.update=function(a,b){this.renderingState=RenderingStates.INITIAL;this.resume=null;"undefined"!==typeof b&&(this.rotation=b);this.scale=a||this.scale;
-var c=this.pdfPage.getViewport(this.scale,(this.rotation+this.pdfPage.rotate)%360);this.viewport=c;g.style.width=Math.floor(c.width)+"px";for(g.style.height=Math.floor(c.height)+"px";g.hasChildNodes();)g.removeChild(g.lastChild);g.removeAttribute("data-loaded");delete this.canvas;this.loadingIconDiv=document.createElement("div");this.loadingIconDiv.className="loadingIcon";g.appendChild(this.loadingIconDiv)};Object.defineProperty(this,"width",{get:function(){return this.viewport.width},enumerable:!0});
-Object.defineProperty(this,"height",{get:function(){return this.viewport.height},enumerable:!0});this.getPagePoint=function(a,b){return this.viewport.convertToPdfPoint(a,b)};this.scrollIntoView=function(a){if(a){var b=0,c=0,d=0,f=0,e;e=0;switch(a[1].name){case "XYZ":b=a[2];c=a[3];e=a[4];break;case "Fit":case "FitB":e="page-fit";break;case "FitH":case "FitBH":c=a[2];e="page-width";break;case "FitV":case "FitBV":b=a[2];e="page-height";break;case "FitR":b=a[2];c=a[3];d=a[4]-b;f=a[5]-c;a=(this.container.clientWidth-
-SCROLLBAR_PADDING)/d/CSS_UNITS;e=(this.container.clientHeight-SCROLLBAR_PADDING)/f/CSS_UNITS;e=Math.min(a,e);break;default:return}e&&e!==PDFView.currentScale?PDFView.parseScale(e,!0,!0):PDFView.currentScale===UNKNOWN_SCALE&&PDFView.parseScale(DEFAULT_SCALE,!0,!0);var h=[this.viewport.convertToViewportPoint(b,c),this.viewport.convertToViewportPoint(b+d,c+f)];setTimeout(function(){var a=Math.min(h[0][0],h[1][0]),b=Math.min(h[0][1],h[1][1]),c=Math.abs(h[0][0]-h[1][0]),d=Math.abs(h[0][1]-h[1][1]);scrollIntoView(g,
-{left:a,top:b,width:c,height:d})},0)}else scrollIntoView(g)};this.getTextContent=function(){this.textContent||(this.textContent=this.pdfPage.getTextContent());return this.textContent};this.draw=function(a){function c(d){p.renderingState=RenderingStates.FINISHED;p.loadingIconDiv&&(g.removeChild(p.loadingIconDiv),delete p.loadingIconDiv);d&&PDFView.error(mozL10n.get("rendering_error",null,"An error occurred while rendering the page."),d);p.stats=b.stats;p.updateStats();if(p.onAfterDraw)p.onAfterDraw();
-cache.push(p);a()}this.renderingState!==RenderingStates.INITIAL&&error("Must be in new state before drawing");this.renderingState=RenderingStates.RUNNING;var d=document.createElement("canvas");d.id="page"+this.id;d.mozOpaque=!0;g.appendChild(d);this.canvas=d;var f=null;PDFJS.disableTextLayer||(f=document.createElement("div"),f.className="textLayer",g.appendChild(f));var h=this.textLayer=f?new TextLayerBuilder(f,this.id-1):null,r=this.viewport,q=PDFView.getOutputScale();d.width=Math.floor(r.width)*
-q.sx;d.height=Math.floor(r.height)*q.sy;q.scaled&&(r="scale("+1/q.sx+", "+1/q.sy+")",CustomStyle.setProp("transform",d,r),CustomStyle.setProp("transformOrigin",d,"0% 0%"),f&&(CustomStyle.setProp("transform",f,r),CustomStyle.setProp("transformOrigin",f,"0% 0%")));f=d.getContext("2d");f.save();f.fillStyle="rgb(255, 255, 255)";f.fillRect(0,0,d.width,d.height);f.restore();q.scaled&&f.scale(q.sx,q.sy);var p=this;this.pdfPage.render({canvasContext:f,viewport:this.viewport,textLayer:h,continueCallback:function(a){PDFView.highestPriorityPage!==
-"page"+p.id?(p.renderingState=RenderingStates.PAUSED,p.resume=function(){p.renderingState=RenderingStates.RUNNING;a()}):a()}}).then(function(){c(null)},function(a){c(a)});h&&this.getTextContent().then(function(a){h.setTextContent(a)});e(this.pdfPage,this.viewport);g.setAttribute("data-loaded",!0)};this.beforePrint=function(){var a=this.pdfPage,b=a.getViewport(1),c=this.canvas=document.createElement("canvas");c.width=2*Math.floor(b.width);c.height=2*Math.floor(b.height);c.style.width=2*b.width+"pt";
-c.style.height=2*b.height+"pt";CustomStyle.setProp("transform",c,"scale(0.5, 0.5)");CustomStyle.setProp("transformOrigin",c,"0% 0%");document.getElementById("printContainer").appendChild(c);var d=this;c.mozPrintCallback=function(f){var e=f.context;e.save();e.fillStyle="rgb(255, 255, 255)";e.fillRect(0,0,c.width,c.height);e.restore();e.scale(2,2);a.render({canvasContext:e,viewport:b}).then(function(){f.done();d.pdfPage.destroy()},function(a){console.error(a);"abort"in object?f.abort():f.done();d.pdfPage.destroy()})}};
-this.updateStats=function(){PDFJS.pdfBug&&Stats.enabled&&Stats.add(this.id,this.stats)}},ThumbnailView=function(a,b,c){function d(){var a=document.createElement("canvas");a.id="thumbnail"+c;a.mozOpaque=!0;a.width=l;a.height=m;a.className="thumbnailImage";a.setAttribute("aria-label",mozL10n.get("thumb_page_canvas",{page:c},"Thumbnail of Page {{page}}"));r.setAttribute("data-loaded",!0);q.appendChild(a);a=a.getContext("2d");a.save();a.fillStyle="rgb(255, 255, 255)";a.fillRect(0,0,l,m);a.restore();return a}
-var f=document.createElement("a");f.href=PDFView.getAnchorUrl("#page="+c);f.title=mozL10n.get("thumb_page_title",{page:c},"Page {{page}}");f.onclick=function(){PDFView.page=c;return!1};var h=0,e=(h+b.rotate)%360,g=b.getViewport(1,e),k=this.width=g.width,n=this.height=g.height;this.id=c;var l=98,m=l/this.width*this.height,s=this.scaleX=l/k;this.scaleY=m/n;var r=this.el=document.createElement("div");r.id="thumbnailContainer"+c;r.className="thumbnail";1===c&&r.classList.add("selected");var q=document.createElement("div");
-q.className="thumbnailSelectionRing";q.style.width=l+"px";q.style.height=m+"px";r.appendChild(q);f.appendChild(r);a.appendChild(f);this.hasImage=!1;this.renderingState=RenderingStates.INITIAL;this.updateRotation=function(a){h=a;e=(h+b.rotate)%360;g=b.getViewport(1,e);k=this.width=g.width;n=this.height=g.height;m=l/this.width*this.height;s=this.scaleX=l/k;this.scaleY=m/n;r.removeAttribute("data-loaded");q.textContent="";q.style.width=l+"px";q.style.height=m+"px";this.hasImage=!1;this.renderingState=
-RenderingStates.INITIAL;this.resume=null};this.drawingRequired=function(){return!this.hasImage};this.draw=function(a){this.renderingState!==RenderingStates.INITIAL&&error("Must be in new state before drawing");this.renderingState=RenderingStates.RUNNING;if(this.hasImage)a();else{var c=this,f=d(),h=b.getViewport(s,e);b.render({canvasContext:f,viewport:h,continueCallback:function(a){PDFView.highestPriorityPage!=="thumbnail"+c.id?(c.renderingState=RenderingStates.PAUSED,c.resume=function(){c.renderingState=
-RenderingStates.RUNNING;a()}):a()}}).then(function(){c.renderingState=RenderingStates.FINISHED;a()},function(b){c.renderingState=RenderingStates.FINISHED;a()});this.hasImage=!0}};this.setImage=function(a){if(!this.hasImage&&a){this.renderingState=RenderingStates.FINISHED;var b=d();b.drawImage(a,0,0,a.width,a.height,0,0,b.canvas.width,b.canvas.height);this.hasImage=!0}}},DocumentOutlineView=function(a){function b(a,b){a.href=PDFView.getDestinationHash(b.dest);a.onclick=function(a){PDFView.navigateTo(b.dest);
-return!1}}for(var c=document.getElementById("outlineView");c.firstChild;)c.removeChild(c.firstChild);if(a)for(c=[{parent:c,items:a}];0<c.length;){a=c.shift();var d,f=a.items.length;for(d=0;d<f;d++){var h=a.items[d],e=document.createElement("div");e.className="outlineItem";var g=document.createElement("a");b(g,h);g.textContent=h.title;e.appendChild(g);0<h.items.length&&(g=document.createElement("div"),g.className="outlineItems",e.appendChild(g),c.push({parent:g,items:h.items}));a.parent.appendChild(e)}}else a=
-document.createElement("div"),a.classList.add("noOutline"),a.textContent=mozL10n.get("no_outline",null,"No Outline Available"),c.appendChild(a)},CustomStyle=function(){function a(){}var b=["ms","Moz","Webkit","O"],c={};a.getProp=function(a,f){if(1==arguments.length&&"string"==typeof c[a])return c[a];f=f||document.documentElement;var h=f.style,e,g;if("string"==typeof h[a])return c[a]=a;g=a.charAt(0).toUpperCase()+a.slice(1);for(var k=0,n=b.length;k<n;k++)if(e=b[k]+g,"string"==typeof h[e])return c[a]=
-e;return c[a]="undefined"};a.setProp=function(a,b,c){a=this.getProp(a);"undefined"!=a&&(b.style[a]=c)};return a}(),TextLayerBuilder=function(a,b){var c=document.createDocumentFragment();this.textLayerDiv=a;this.divContentDone=this.layoutDone=!1;this.pageIdx=b;this.matches=[];this.beginLayout=function(){this.textDivs=[];this.textLayerQueue=[];this.renderingDone=!1};this.endLayout=function(){this.layoutDone=!0;this.insertDivContent()};this.renderLayer=function(){var a=this.textDivs,b=this.textLayerDiv,
-h=document.createElement("canvas").getContext("2d");if(!(1E5<a.length)){for(var e=0,g=a.length;e<g;e++){var k=a[e];c.appendChild(k);h.font=k.style.fontSize+" "+k.style.fontFamily;var n=h.measureText(k.textContent).width;0<n&&(CustomStyle.setProp("transform",k,"scale("+k.dataset.canvasWidth/n+", 1)"),CustomStyle.setProp("transformOrigin",k,"0% 0%"),b.appendChild(k))}this.renderingDone=!0;this.updateMatches();b.appendChild(c)}};this.setupRenderLayoutTimer=function(){var a=this;200<Date.now()-PDFView.lastScroll?
-this.renderLayer():(this.renderTimer&&clearTimeout(this.renderTimer),this.renderTimer=setTimeout(function(){a.setupRenderLayoutTimer()},200))};this.appendText=function(a){var b=document.createElement("div"),c=a.fontSize*a.vScale;b.dataset.canvasWidth=a.canvasWidth*a.hScale;b.dataset.fontName=a.fontName;b.style.fontSize=c+"px";b.style.fontFamily=a.fontFamily;b.style.left=a.x+"px";b.style.top=a.y-c+"px";this.textDivs.push(b)};this.insertDivContent=function(){if(this.layoutDone&&!this.divContentDone&&
-this.textContent){this.divContentDone=!0;for(var a=this.textDivs,b=this.textContent.bidiTexts,c=0;c<b.length;c++){var e=b[c],g=a[c];g.textContent=e.str;g.dir=e.ltr?"ltr":"rtl"}this.setupRenderLayoutTimer()}};this.setTextContent=function(a){this.textContent=a;this.insertDivContent()};this.convertMatches=function(a){for(var b=0,c=0,e=this.textContent.bidiTexts,g=e.length-1,k=PDFFindController.state.query.length,n=[],l=0;l<a.length;l++){for(var m=a[l];b!==g&&m>=c+e[b].str.length;)c+=e[b].str.length,
-b++;b==e.length&&console.error("Could not find matching mapping");for(var s={begin:{divIdx:b,offset:m-c}},m=m+k;b!==g&&m>c+e[b].str.length;)c+=e[b].str.length,b++;s.end={divIdx:b,offset:m-c};n.push(s)}return n};this.renderMatches=function(a){function b(a,c){var d=a.divIdx,f=g[d];f.textContent="";var h=e[d].str.substring(0,a.offset),h=document.createTextNode(h);if(c){var d=n&&d===l,k=document.createElement("span");k.className=c+(d?" selected":"");k.appendChild(h);f.appendChild(k)}else f.appendChild(h)}
-function c(a,b,d){var f=a.divIdx,h=g[f];a=e[f].str.substring(a.offset,b.offset);a=document.createTextNode(a);d?(b=document.createElement("span"),b.className=d,b.appendChild(a),h.appendChild(b)):h.appendChild(a)}if(0!==a.length){var e=this.textContent.bidiTexts,g=this.textDivs,k=null,n=this.pageIdx===PDFFindController.selected.pageIdx,l=PDFFindController.selected.matchIdx,m={divIdx:-1,offset:void 0},s=l,r=s+1;if(PDFFindController.state.highlightAll)s=0,r=a.length;else if(!n)return;for(;s<r;s++){var q=
-a[s],p=q.begin,q=q.end,u=n&&s===l,t=u?" selected":"";u&&scrollIntoView(g[p.divIdx],{top:-50});k&&p.divIdx===k.divIdx?c(k,p):(null!==k&&c(k,m),b(p));if(p.divIdx===q.divIdx)c(p,q,"highlight"+t);else{c(p,m,"highlight begin"+t);for(k=p.divIdx+1;k<q.divIdx;k++)g[k].className="highlight middle"+t;b(q,"highlight end"+t)}k=q}k&&c(k,m)}};this.updateMatches=function(){if(this.renderingDone){for(var a=this.matches,b=this.textDivs,c=this.textContent.bidiTexts,e=-1,g=0;g<a.length;g++){for(var k=a[g],e=Math.max(e,
-k.begin.divIdx);e<=k.end.divIdx;e++){var n=b[e];n.textContent=c[e].str;n.className=""}e=k.end.divIdx+1}PDFFindController.active&&(this.matches=this.convertMatches(PDFFindController.pageMatches[this.pageIdx]||[]),this.renderMatches(this.matches))}}};
-document.addEventListener("DOMContentLoaded",function(a){PDFView.initialize();a=PDFView.parseQueryString(document.location.search.substring(1)).file||DEFAULT_URL;window.File&&window.FileReader&&window.FileList&&window.Blob&&(document.getElementById("fileInput").value=null);var b=document.location.hash.substring(1),b=PDFView.parseQueryString(b);"disableWorker"in b&&(PDFJS.disableWorker="true"===b.disableWorker);var c=navigator.language;"locale"in b&&(c=b.locale);mozL10n.setLanguage(c);if("textLayer"in
-b)switch(b.textLayer){case "off":PDFJS.disableTextLayer=!0;break;case "visible":case "shadow":case "hover":document.getElementById("viewer").classList.add("textLayer-"+b.textLayer)}"pdfBug"in b&&(PDFJS.pdfBug=!0,b=b.pdfBug.split(","),PDFBug.enable(b),PDFBug.init());PDFView.supportsPrinting||document.getElementById("print").classList.add("hidden");PDFView.supportsFullscreen||document.getElementById("fullscreen").classList.add("hidden");PDFView.supportsIntegratedFind&&document.querySelector("#viewFind").classList.add("hidden");
-PDFJS.LogManager.addLogger({warn:function(){PDFView.fallback()}});var d=document.getElementById("mainContainer"),f=document.getElementById("outerContainer");d.addEventListener("transitionend",function(a){a.target==d&&(a=document.createEvent("UIEvents"),a.initUIEvent("resize",!1,!1,window,0),window.dispatchEvent(a),f.classList.remove("sidebarMoving"))},!0);document.getElementById("sidebarToggle").addEventListener("click",function(){this.classList.toggle("toggled");f.classList.add("sidebarMoving");
-f.classList.toggle("sidebarOpen");PDFView.sidebarOpen=f.classList.contains("sidebarOpen");PDFView.renderHighestPriority()});document.getElementById("viewThumbnail").addEventListener("click",function(){PDFView.switchSidebarView("thumbs")});document.getElementById("viewOutline").addEventListener("click",function(){PDFView.switchSidebarView("outline")});document.getElementById("previous").addEventListener("click",function(){PDFView.page--});document.getElementById("next").addEventListener("click",function(){PDFView.page++});
-document.querySelector(".zoomIn").addEventListener("click",function(){PDFView.zoomIn()});document.querySelector(".zoomOut").addEventListener("click",function(){PDFView.zoomOut()});document.getElementById("fullscreen").addEventListener("click",function(){PDFView.fullscreen()});document.getElementById("print").addEventListener("click",function(){window.print()});document.getElementById("pageNumber").addEventListener("change",function(){PDFView.page=this.value});document.getElementById("scaleSelect").addEventListener("change",
-function(){PDFView.parseScale(this.value)});document.getElementById("first_page").addEventListener("click",function(){PDFView.page=1});document.getElementById("last_page").addEventListener("click",function(){PDFView.page=PDFView.pdfDocument.numPages});document.getElementById("page_rotate_ccw").addEventListener("click",function(){PDFView.rotatePages(-90)});document.getElementById("page_rotate_cw").addEventListener("click",function(){PDFView.rotatePages(90)});PDFView.open(a,0)},!0);
-function updateViewarea(){if(PDFView.initialized){var a=PDFView.getVisiblePages(),b=a.views;if(0!==b.length){PDFView.renderHighestPriority();for(var c=PDFView.page,a=a.first,d=0,f=b.length,h=!1;d<f;++d){var e=b[d];if(100>e.percent)break;if(e.id===PDFView.page){h=!0;break}}h||(c=b[0].id);PDFView.isFullscreen||(updateViewarea.inProgress=!0,PDFView.page=c,updateViewarea.inProgress=!1);var b=PDFView.currentScale,c=PDFView.currentScaleValue,g=c==b?100*b:c,k=a.id,b="#page="+k+("&zoom="+g),n=PDFView.pages[k-
-1].getPagePoint(PDFView.container.scrollLeft,PDFView.container.scrollTop-a.y),b=b+(","+Math.round(n[0])+","+Math.round(n[1])),l=PDFView.store;l.initializedPromise.then(function(){l.set("exists",!0);l.set("page",k);l.set("zoom",g);l.set("scrollLeft",Math.round(n[0]));l.set("scrollTop",Math.round(n[1]))});PDFView.getAnchorUrl(b)}}}
-window.addEventListener("resize",function(a){PDFView.initialized&&(document.getElementById("pageWidthOption").selected||document.getElementById("pageFitOption").selected||document.getElementById("pageAutoOption").selected)&&PDFView.parseScale(document.getElementById("scaleSelect").value);updateViewarea()});window.addEventListener("hashchange",function(a){PDFView.setHash(document.location.hash.substring(1))});
-window.addEventListener("change",function(a){var b=a.target.files;b&&0!=b.length&&(a=new FileReader,a.onload=function(a){a=new Uint8Array(a.target.result);PDFView.open(a,0)},b=b[0],a.readAsArrayBuffer(b),PDFView.setTitleUsingUrl(b.name))},!0);function selectScaleOption(a){for(var b=document.getElementById("scaleSelect").options,c=!1,d=0;d<b.length;d++){var f=b[d];f.value!=a?f.selected=!1:c=f.selected=!0}return c}
-window.addEventListener("localized",function(a){document.getElementsByTagName("html")[0].dir=mozL10n.getDirection()},!0);
-window.addEventListener("scalechange",function(a){var b=document.getElementById("customScaleOption");b.selected=!1;!a.resetAutoSettings&&(document.getElementById("pageWidthOption").selected||document.getElementById("pageFitOption").selected||document.getElementById("pageAutoOption").selected)||selectScaleOption(""+a.scale)||(b.textContent=Math.round(1E4*a.scale)/100+"%",b.selected=!0);updateViewarea()},!0);
-window.addEventListener("pagechange",function(a){a=a.pageNumber;if(PDFView.previousPageNumber!==a){document.getElementById("pageNumber").value=a;var b=document.querySelector(".thumbnail.selected");b&&b.classList.remove("selected");b=document.getElementById("thumbnailContainer"+a);b.classList.add("selected");var c=PDFView.getVisibleThumbs(),d=c.views.length;if(0<d){var f=c.first.id,c=1<d?c.last.id:f;(a<=f||a>=c)&&scrollIntoView(b)}}document.getElementById("previous").disabled=1>=a;document.getElementById("next").disabled=
-a>=PDFView.pages.length},!0);window.addEventListener("DOMMouseScroll",function(a){if(a.ctrlKey){a.preventDefault();var b=a.detail;a=0<b?"zoomOut":"zoomIn";for(var c=0,b=Math.abs(b);c<b;c++)PDFView[a]()}else PDFView.isFullscreen&&PDFView.mouseScroll(-40*a.detail)},!1);window.addEventListener("mousemove",function(a){PDFView.isFullscreen&&PDFView.showPresentationControls()},!1);window.addEventListener("mousedown",function(a){PDFView.isFullscreen&&0===a.button&&(a.preventDefault(),PDFView.page++)},!1);
-window.addEventListener("keydown",function(a){var b=!1,c=(a.ctrlKey?1:0)|(a.altKey?2:0)|(a.shiftKey?4:0)|(a.metaKey?8:0);if(1==c||8==c)switch(a.keyCode){case 70:PDFView.supportsIntegratedFind||(PDFFindBar.toggle(),b=!0);break;case 61:case 107:case 187:case 171:PDFView.zoomIn();b=!0;break;case 173:case 109:case 189:PDFView.zoomOut();b=!0;break;case 48:case 96:PDFView.parseScale(DEFAULT_SCALE,!0),b=!0}if(1==c||8==c||5==c||12==c)switch(a.keyCode){case 71:PDFView.supportsIntegratedFind||(PDFFindBar.dispatchEvent("again",
-5==c||12==c),b=!0)}if(b)a.preventDefault();else{var d=document.activeElement;if(!d||"INPUT"!=d.tagName&&"SELECT"!=d.tagName){for(var f=document.getElementById("toolbar");d;){if(d===f&&!PDFView.isFullscreen)return;d=d.parentNode}if(0==c)switch(a.keyCode){case 38:case 33:case 8:if(!PDFView.isFullscreen&&"page-fit"!==PDFView.currentScaleValue)break;case 37:if(PDFView.isHorizontalScrollbarEnabled)break;case 75:case 80:PDFView.page--;b=!0;break;case 40:case 34:case 32:if(!PDFView.isFullscreen&&"page-fit"!==
-PDFView.currentScaleValue)break;case 39:if(PDFView.isHorizontalScrollbarEnabled)break;case 74:case 78:PDFView.page++;b=!0;break;case 36:PDFView.isFullscreen&&(PDFView.page=1,b=!0);break;case 35:PDFView.isFullscreen&&(PDFView.page=PDFView.pdfDocument.numPages,b=!0);break;case 82:PDFView.rotatePages(90)}if(4==c)switch(a.keyCode){case 82:PDFView.rotatePages(-90)}b&&(a.preventDefault(),PDFView.clearMouseScrollState())}}});window.addEventListener("beforeprint",function(a){PDFView.beforePrint()});
-window.addEventListener("afterprint",function(a){PDFView.afterPrint()});(function(){function a(a){document.fullscreenElement||document.mozFullScreen||document.webkitIsFullScreen||PDFView.exitFullscreen()}window.addEventListener("fullscreenchange",a,!1);window.addEventListener("mozfullscreenchange",a,!1);window.addEventListener("webkitfullscreenchange",a,!1)})();
+/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
+/* Copyright 2012 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/* globals PDFJS, PDFBug, FirefoxCom, Stats, Cache, PDFFindBar, CustomStyle,
+ PDFFindController, ProgressBar, TextLayerBuilder, DownloadManager,
+ getFileName, scrollIntoView, getPDFFileNameFromURL, PDFHistory,
+ Preferences, ViewHistory, PageView, ThumbnailView,
+ noContextMenuHandler, SecondaryToolbar, PasswordPrompt,
+ PresentationMode, HandTool, Promise */
+
+'use strict';
+
+var DEFAULT_URL = null;
+var DEFAULT_SCALE = 'auto';
+var DEFAULT_SCALE_DELTA = 1.1;
+var UNKNOWN_SCALE = 0;
+var CACHE_SIZE = 20;
+var CSS_UNITS = 96.0 / 72.0;
+var SCROLLBAR_PADDING = 40;
+var VERTICAL_PADDING = 5;
+var MAX_AUTO_SCALE = 1.25;
+var MIN_SCALE = 0.25;
+var MAX_SCALE = 4.0;
+var VIEW_HISTORY_MEMORY = 20;
+var SCALE_SELECT_CONTAINER_PADDING = 8;
+var SCALE_SELECT_PADDING = 22;
+var THUMBNAIL_SCROLL_MARGIN = -19;
+var USE_ONLY_CSS_ZOOM = false;
+var CLEANUP_TIMEOUT = 30000;
+var IGNORE_CURRENT_POSITION_ON_ZOOM = false;
+var RenderingStates = {
+ INITIAL: 0,
+ RUNNING: 1,
+ PAUSED: 2,
+ FINISHED: 3
+};
+var FindStates = {
+ FIND_FOUND: 0,
+ FIND_NOTFOUND: 1,
+ FIND_WRAPPED: 2,
+ FIND_PENDING: 3
+};
+
+PDFJS.imageResourcesPath = './images/';
+ PDFJS.workerSrc = 'pdf.worker.js';
+
+var mozL10n = document.mozL10n || document.webL10n;
+
+
+// optimised CSS custom property getter/setter
+var CustomStyle = (function CustomStyleClosure() {
+
+ // As noted on: http://www.zachstronaut.com/posts/2009/02/17/
+ // animate-css-transforms-firefox-webkit.html
+ // in some versions of IE9 it is critical that ms appear in this list
+ // before Moz
+ var prefixes = ['ms', 'Moz', 'Webkit', 'O'];
+ var _cache = { };
+
+ function CustomStyle() {
+ }
+
+ CustomStyle.getProp = function get(propName, element) {
+ // check cache only when no element is given
+ if (arguments.length == 1 && typeof _cache[propName] == 'string') {
+ return _cache[propName];
+ }
+
+ element = element || document.documentElement;
+ var style = element.style, prefixed, uPropName;
+
+ // test standard property first
+ if (typeof style[propName] == 'string') {
+ return (_cache[propName] = propName);
+ }
+
+ // capitalize
+ uPropName = propName.charAt(0).toUpperCase() + propName.slice(1);
+
+ // test vendor specific properties
+ for (var i = 0, l = prefixes.length; i < l; i++) {
+ prefixed = prefixes[i] + uPropName;
+ if (typeof style[prefixed] == 'string') {
+ return (_cache[propName] = prefixed);
+ }
+ }
+
+ //if all fails then set to undefined
+ return (_cache[propName] = 'undefined');
+ };
+
+ CustomStyle.setProp = function set(propName, element, str) {
+ var prop = this.getProp(propName);
+ if (prop != 'undefined')
+ element.style[prop] = str;
+ };
+
+ return CustomStyle;
+})();
+
+function getFileName(url) {
+ var anchor = url.indexOf('#');
+ var query = url.indexOf('?');
+ var end = Math.min(
+ anchor > 0 ? anchor : url.length,
+ query > 0 ? query : url.length);
+ return url.substring(url.lastIndexOf('/', end) + 1, end);
+}
+
+/**
+ * Returns scale factor for the canvas. It makes sense for the HiDPI displays.
+ * @return {Object} The object with horizontal (sx) and vertical (sy)
+ scales. The scaled property is set to false if scaling is
+ not required, true otherwise.
+ */
+function getOutputScale(ctx) {
+ var devicePixelRatio = window.devicePixelRatio || 1;
+ var backingStoreRatio = ctx.webkitBackingStorePixelRatio ||
+ ctx.mozBackingStorePixelRatio ||
+ ctx.msBackingStorePixelRatio ||
+ ctx.oBackingStorePixelRatio ||
+ ctx.backingStorePixelRatio || 1;
+ var pixelRatio = devicePixelRatio / backingStoreRatio;
+ return {
+ sx: pixelRatio,
+ sy: pixelRatio,
+ scaled: pixelRatio != 1
+ };
+}
+
+/**
+ * Scrolls specified element into view of its parent.
+ * element {Object} The element to be visible.
+ * spot {Object} An object with optional top and left properties,
+ * specifying the offset from the top left edge.
+ */
+function scrollIntoView(element, spot) {
+ // Assuming offsetParent is available (it's not available when viewer is in
+ // hidden iframe or object). We have to scroll: if the offsetParent is not set
+ // producing the error. See also animationStartedClosure.
+ var parent = element.offsetParent;
+ var offsetY = element.offsetTop + element.clientTop;
+ var offsetX = element.offsetLeft + element.clientLeft;
+ if (!parent) {
+ console.error('offsetParent is not set -- cannot scroll');
+ return;
+ }
+ while (parent.clientHeight === parent.scrollHeight) {
+ if (parent.dataset._scaleY) {
+ offsetY /= parent.dataset._scaleY;
+ offsetX /= parent.dataset._scaleX;
+ }
+ offsetY += parent.offsetTop;
+ offsetX += parent.offsetLeft;
+ parent = parent.offsetParent;
+ if (!parent) {
+ return; // no need to scroll
+ }
+ }
+ if (spot) {
+ if (spot.top !== undefined) {
+ offsetY += spot.top;
+ }
+ if (spot.left !== undefined) {
+ offsetX += spot.left;
+ parent.scrollLeft = offsetX;
+ }
+ }
+ parent.scrollTop = offsetY;
+}
+
+/**
+ * Event handler to suppress context menu.
+ */
+function noContextMenuHandler(e) {
+ e.preventDefault();
+}
+
+/**
+ * Returns the filename or guessed filename from the url (see issue 3455).
+ * url {String} The original PDF location.
+ * @return {String} Guessed PDF file name.
+ */
+function getPDFFileNameFromURL(url) {
+ var reURI = /^(?:([^:]+:)?\/\/[^\/]+)?([^?#]*)(\?[^#]*)?(#.*)?$/;
+ // SCHEME HOST 1.PATH 2.QUERY 3.REF
+ // Pattern to get last matching NAME.pdf
+ var reFilename = /[^\/?#=]+\.pdf\b(?!.*\.pdf\b)/i;
+ var splitURI = reURI.exec(url);
+ var suggestedFilename = reFilename.exec(splitURI[1]) ||
+ reFilename.exec(splitURI[2]) ||
+ reFilename.exec(splitURI[3]);
+ if (suggestedFilename) {
+ suggestedFilename = suggestedFilename[0];
+ if (suggestedFilename.indexOf('%') != -1) {
+ // URL-encoded %2Fpath%2Fto%2Ffile.pdf should be file.pdf
+ try {
+ suggestedFilename =
+ reFilename.exec(decodeURIComponent(suggestedFilename))[0];
+ } catch(e) { // Possible (extremely rare) errors:
+ // URIError "Malformed URI", e.g. for "%AA.pdf"
+ // TypeError "null has no properties", e.g. for "%2F.pdf"
+ }
+ }
+ }
+ return suggestedFilename || 'document.pdf';
+}
+
+var ProgressBar = (function ProgressBarClosure() {
+
+ function clamp(v, min, max) {
+ return Math.min(Math.max(v, min), max);
+ }
+
+ function ProgressBar(id, opts) {
+
+ // Fetch the sub-elements for later.
+ this.div = document.querySelector(id + ' .progress');
+
+ // Get the loading bar element, so it can be resized to fit the viewer.
+ this.bar = this.div.parentNode;
+
+ // Get options, with sensible defaults.
+ this.height = opts.height || 100;
+ this.width = opts.width || 100;
+ this.units = opts.units || '%';
+
+ // Initialize heights.
+ this.div.style.height = this.height + this.units;
+ this.percent = 0;
+ }
+
+ ProgressBar.prototype = {
+
+ updateBar: function ProgressBar_updateBar() {
+ if (this._indeterminate) {
+ this.div.classList.add('indeterminate');
+ this.div.style.width = this.width + this.units;
+ return;
+ }
+
+ this.div.classList.remove('indeterminate');
+ var progressSize = this.width * this._percent / 100;
+ this.div.style.width = progressSize + this.units;
+ },
+
+ get percent() {
+ return this._percent;
+ },
+
+ set percent(val) {
+ this._indeterminate = isNaN(val);
+ this._percent = clamp(val, 0, 100);
+ this.updateBar();
+ },
+
+ setWidth: function ProgressBar_setWidth(viewer) {
+ if (viewer) {
+ var container = viewer.parentNode;
+ var scrollbarWidth = container.offsetWidth - viewer.offsetWidth;
+ if (scrollbarWidth > 0) {
+ this.bar.setAttribute('style', 'width: calc(100% - ' +
+ scrollbarWidth + 'px);');
+ }
+ }
+ },
+
+ hide: function ProgressBar_hide() {
+ this.bar.classList.add('hidden');
+ this.bar.removeAttribute('style');
+ }
+ };
+
+ return ProgressBar;
+})();
+
+var Cache = function cacheCache(size) {
+ var data = [];
+ this.push = function cachePush(view) {
+ var i = data.indexOf(view);
+ if (i >= 0)
+ data.splice(i);
+ data.push(view);
+ if (data.length > size)
+ data.shift().destroy();
+ };
+};
+
+var isLocalStorageEnabled = (function isLocalStorageEnabledClosure() {
+ // Feature test as per http://diveintohtml5.info/storage.html
+ // The additional localStorage call is to get around a FF quirk, see
+ // bug #495747 in bugzilla
+ try {
+ return ('localStorage' in window && window['localStorage'] !== null &&
+ localStorage);
+ } catch (e) {
+ return false;
+ }
+})();
+
+
+
+var EXPORTED_SYMBOLS = ['DEFAULT_PREFERENCES'];
+
+var DEFAULT_PREFERENCES = {
+ showPreviousViewOnLoad: true,
+ defaultZoomValue: '',
+ ifAvailableShowOutlineOnLoad: false
+};
+
+
+var Preferences = (function PreferencesClosure() {
+ function Preferences() {
+ this.prefs = {};
+ this.isInitializedPromiseResolved = false;
+ this.initializedPromise = this.readFromStorage().then(function(prefObj) {
+ this.isInitializedPromiseResolved = true;
+ if (prefObj) {
+ this.prefs = prefObj;
+ }
+ }.bind(this));
+ }
+
+ Preferences.prototype = {
+ writeToStorage: function Preferences_writeToStorage(prefObj) {
+ return;
+ },
+
+ readFromStorage: function Preferences_readFromStorage() {
+ var readFromStoragePromise = Promise.resolve();
+ return readFromStoragePromise;
+ },
+
+ reset: function Preferences_reset() {
+ if (this.isInitializedPromiseResolved) {
+ this.prefs = {};
+ this.writeToStorage(this.prefs);
+ }
+ },
+
+ set: function Preferences_set(name, value) {
+ if (!this.isInitializedPromiseResolved) {
+ return;
+ } else if (DEFAULT_PREFERENCES[name] === undefined) {
+ console.error('Preferences_set: \'' + name + '\' is undefined.');
+ return;
+ } else if (value === undefined) {
+ console.error('Preferences_set: no value is specified.');
+ return;
+ }
+ var valueType = typeof value;
+ var defaultType = typeof DEFAULT_PREFERENCES[name];
+
+ if (valueType !== defaultType) {
+ if (valueType === 'number' && defaultType === 'string') {
+ value = value.toString();
+ } else {
+ console.error('Preferences_set: \'' + value + '\' is a \"' +
+ valueType + '\", expected a \"' + defaultType + '\".');
+ return;
+ }
+ }
+ this.prefs[name] = value;
+ this.writeToStorage(this.prefs);
+ },
+
+ get: function Preferences_get(name) {
+ var defaultPref = DEFAULT_PREFERENCES[name];
+
+ if (defaultPref === undefined) {
+ console.error('Preferences_get: \'' + name + '\' is undefined.');
+ return;
+ } else if (this.isInitializedPromiseResolved) {
+ var pref = this.prefs[name];
+
+ if (pref !== undefined) {
+ return pref;
+ }
+ }
+ return defaultPref;
+ }
+ };
+
+ return Preferences;
+})();
+
+
+Preferences.prototype.writeToStorage = function(prefObj) {
+ if (isLocalStorageEnabled) {
+ localStorage.setItem('preferences', JSON.stringify(prefObj));
+ }
+};
+
+Preferences.prototype.readFromStorage = function() {
+ var readFromStoragePromise = new Promise(function (resolve) {
+ if (isLocalStorageEnabled) {
+ var readPrefs = JSON.parse(localStorage.getItem('preferences'));
+ resolve(readPrefs);
+ }
+ });
+ return readFromStoragePromise;
+};
+
+
+(function mozPrintCallbackPolyfillClosure() {
+ if ('mozPrintCallback' in document.createElement('canvas')) {
+ return;
+ }
+ // Cause positive result on feature-detection:
+ HTMLCanvasElement.prototype.mozPrintCallback = undefined;
+
+ var canvases; // During print task: non-live NodeList of <canvas> elements
+ var index; // Index of <canvas> element that is being processed
+
+ var print = window.print;
+ window.print = function print() {
+ if (canvases) {
+ console.warn('Ignored window.print() because of a pending print job.');
+ return;
+ }
+ try {
+ dispatchEvent('beforeprint');
+ } finally {
+ canvases = document.querySelectorAll('canvas');
+ index = -1;
+ next();
+ }
+ };
+
+ function dispatchEvent(eventType) {
+ var event = document.createEvent('CustomEvent');
+ event.initCustomEvent(eventType, false, false, 'custom');
+ window.dispatchEvent(event);
+ }
+
+ function next() {
+ if (!canvases) {
+ return; // Print task cancelled by user (state reset in abort())
+ }
+
+ renderProgress();
+ if (++index < canvases.length) {
+ var canvas = canvases[index];
+ if (typeof canvas.mozPrintCallback === 'function') {
+ canvas.mozPrintCallback({
+ context: canvas.getContext('2d'),
+ abort: abort,
+ done: next
+ });
+ } else {
+ next();
+ }
+ } else {
+ renderProgress();
+ print.call(window);
+ setTimeout(abort, 20); // Tidy-up
+ }
+ }
+
+ function abort() {
+ if (canvases) {
+ canvases = null;
+ renderProgress();
+ dispatchEvent('afterprint');
+ }
+ }
+
+ function renderProgress() {
+ var progressContainer = document.getElementById('mozPrintCallback-shim');
+ if (canvases) {
+ var progress = Math.round(100 * index / canvases.length);
+ var progressBar = progressContainer.querySelector('progress');
+ var progressPerc = progressContainer.querySelector('.relative-progress');
+ progressBar.value = progress;
+ progressPerc.textContent = progress + '%';
+ progressContainer.removeAttribute('hidden');
+ progressContainer.onclick = abort;
+ } else {
+ progressContainer.setAttribute('hidden', '');
+ }
+ }
+
+ var hasAttachEvent = !!document.attachEvent;
+
+ window.addEventListener('keydown', function(event) {
+ if (event.keyCode === 80/*P*/ && (event.ctrlKey || event.metaKey)) {
+ window.print();
+ if (hasAttachEvent) {
+ // Only attachEvent can cancel Ctrl + P dialog in IE <=10
+ // attachEvent is gone in IE11, so the dialog will re-appear in IE11.
+ return;
+ }
+ event.preventDefault();
+ if (event.stopImmediatePropagation) {
+ event.stopImmediatePropagation();
+ } else {
+ event.stopPropagation();
+ }
+ return;
+ }
+ if (event.keyCode === 27 && canvases) { // Esc
+ abort();
+ }
+ }, true);
+ if (hasAttachEvent) {
+ document.attachEvent('onkeydown', function(event) {
+ event = event || window.event;
+ if (event.keyCode === 80/*P*/ && event.ctrlKey) {
+ event.keyCode = 0;
+ return false;
+ }
+ });
+ }
+
+ if ('onbeforeprint' in window) {
+ // Do not propagate before/afterprint events when they are not triggered
+ // from within this polyfill. (FF/IE).
+ var stopPropagationIfNeeded = function(event) {
+ if (event.detail !== 'custom' && event.stopImmediatePropagation) {
+ event.stopImmediatePropagation();
+ }
+ };
+ window.addEventListener('beforeprint', stopPropagationIfNeeded, false);
+ window.addEventListener('afterprint', stopPropagationIfNeeded, false);
+ }
+})();
+
+
+
+var DownloadManager = (function DownloadManagerClosure() {
+
+ function download(blobUrl, filename) {
+ var a = document.createElement('a');
+ if (a.click) {
+ // Use a.click() if available. Otherwise, Chrome might show
+ // "Unsafe JavaScript attempt to initiate a navigation change
+ // for frame with URL" and not open the PDF at all.
+ // Supported by (not mentioned = untested):
+ // - Firefox 6 - 19 (4- does not support a.click, 5 ignores a.click)
+ // - Chrome 19 - 26 (18- does not support a.click)
+ // - Opera 9 - 12.15
+ // - Internet Explorer 6 - 10
+ // - Safari 6 (5.1- does not support a.click)
+ a.href = blobUrl;
+ a.target = '_parent';
+ // Use a.download if available. This increases the likelihood that
+ // the file is downloaded instead of opened by another PDF plugin.
+ if ('download' in a) {
+ a.download = filename;
+ }
+ // <a> must be in the document for IE and recent Firefox versions.
+ // (otherwise .click() is ignored)
+ (document.body || document.documentElement).appendChild(a);
+ a.click();
+ a.parentNode.removeChild(a);
+ } else {
+ if (window.top === window &&
+ blobUrl.split('#')[0] === window.location.href.split('#')[0]) {
+ // If _parent == self, then opening an identical URL with different
+ // location hash will only cause a navigation, not a download.
+ var padCharacter = blobUrl.indexOf('?') === -1 ? '?' : '&';
+ blobUrl = blobUrl.replace(/#|$/, padCharacter + '$&');
+ }
+ window.open(blobUrl, '_parent');
+ }
+ }
+
+ function DownloadManager() {}
+
+ DownloadManager.prototype = {
+ downloadUrl: function DownloadManager_downloadUrl(url, filename) {
+ if (!PDFJS.isValidUrl(url, true)) {
+ return; // restricted/invalid URL
+ }
+
+ download(url + '#pdfjs.action=download', filename);
+ },
+
+ download: function DownloadManager_download(blob, url, filename) {
+ if (!URL) {
+ // URL.createObjectURL is not supported
+ this.downloadUrl(url, filename);
+ return;
+ }
+
+ if (navigator.msSaveBlob) {
+ // IE10 / IE11
+ if (!navigator.msSaveBlob(blob, filename)) {
+ this.downloadUrl(url, filename);
+ }
+ return;
+ }
+
+ var blobUrl = URL.createObjectURL(blob);
+ download(blobUrl, filename);
+ }
+ };
+
+ return DownloadManager;
+})();
+
+
+
+var cache = new Cache(CACHE_SIZE);
+var currentPageNumber = 1;
+
+
+/**
+ * View History - This is a utility for saving various view parameters for
+ * recently opened files.
+ *
+ * The way that the view parameters are stored depends on how PDF.js is built,
+ * for 'node make <flag>' the following cases exist:
+ * - FIREFOX or MOZCENTRAL - uses about:config.
+ * - B2G - uses asyncStorage.
+ * - GENERIC or CHROME - uses localStorage, if it is available.
+ */
+var ViewHistory = (function ViewHistoryClosure() {
+ function ViewHistory(fingerprint) {
+ this.fingerprint = fingerprint;
+ var initializedPromiseResolve;
+ this.isInitializedPromiseResolved = false;
+ this.initializedPromise = new Promise(function (resolve) {
+ initializedPromiseResolve = resolve;
+ });
+
+ var resolvePromise = (function ViewHistoryResolvePromise(db) {
+ this.isInitializedPromiseResolved = true;
+ this.initialize(db || '{}');
+ initializedPromiseResolve();
+ }).bind(this);
+
+
+
+ if (isLocalStorageEnabled) {
+ resolvePromise(localStorage.getItem('database'));
+ }
+ }
+
+ ViewHistory.prototype = {
+ initialize: function ViewHistory_initialize(database) {
+ database = JSON.parse(database);
+ if (!('files' in database)) {
+ database.files = [];
+ }
+ if (database.files.length >= VIEW_HISTORY_MEMORY) {
+ database.files.shift();
+ }
+ var index;
+ for (var i = 0, length = database.files.length; i < length; i++) {
+ var branch = database.files[i];
+ if (branch.fingerprint === this.fingerprint) {
+ index = i;
+ break;
+ }
+ }
+ if (typeof index !== 'number') {
+ index = database.files.push({fingerprint: this.fingerprint}) - 1;
+ }
+ this.file = database.files[index];
+ this.database = database;
+ },
+
+ set: function ViewHistory_set(name, val) {
+ if (!this.isInitializedPromiseResolved) {
+ return;
+ }
+ var file = this.file;
+ file[name] = val;
+ var database = JSON.stringify(this.database);
+
+
+
+ if (isLocalStorageEnabled) {
+ localStorage.setItem('database', database);
+ }
+ },
+
+ get: function ViewHistory_get(name, defaultValue) {
+ if (!this.isInitializedPromiseResolved) {
+ return defaultValue;
+ }
+ return this.file[name] || defaultValue;
+ }
+ };
+
+ return ViewHistory;
+})();
+
+
+/* globals PDFFindController, FindStates, mozL10n */
+
+/**
+ * Creates a "search bar" given set of DOM elements
+ * that act as controls for searching, or for setting
+ * search preferences in the UI. This object also sets
+ * up the appropriate events for the controls. Actual
+ * searching is done by PDFFindController
+ */
+var PDFFindBar = {
+
+ opened: false,
+ bar: null,
+ toggleButton: null,
+ findField: null,
+ highlightAll: null,
+ caseSensitive: null,
+ findMsg: null,
+ findStatusIcon: null,
+ findPreviousButton: null,
+ findNextButton: null,
+
+ initialize: function(options) {
+ if(typeof PDFFindController === 'undefined' || PDFFindController === null) {
+ throw 'PDFFindBar cannot be initialized ' +
+ 'without a PDFFindController instance.';
+ }
+
+ this.bar = options.bar;
+ this.toggleButton = options.toggleButton;
+ this.findField = options.findField;
+ this.highlightAll = options.highlightAllCheckbox;
+ this.caseSensitive = options.caseSensitiveCheckbox;
+ this.findMsg = options.findMsg;
+ this.findStatusIcon = options.findStatusIcon;
+ this.findPreviousButton = options.findPreviousButton;
+ this.findNextButton = options.findNextButton;
+
+ var self = this;
+ this.toggleButton.addEventListener('click', function() {
+ self.toggle();
+ });
+
+ this.findField.addEventListener('input', function() {
+ self.dispatchEvent('');
+ });
+
+ this.bar.addEventListener('keydown', function(evt) {
+ switch (evt.keyCode) {
+ case 13: // Enter
+ if (evt.target === self.findField) {
+ self.dispatchEvent('again', evt.shiftKey);
+ }
+ break;
+ case 27: // Escape
+ self.close();
+ break;
+ }
+ });
+
+ this.findPreviousButton.addEventListener('click',
+ function() { self.dispatchEvent('again', true); }
+ );
+
+ this.findNextButton.addEventListener('click', function() {
+ self.dispatchEvent('again', false);
+ });
+
+ this.highlightAll.addEventListener('click', function() {
+ self.dispatchEvent('highlightallchange');
+ });
+
+ this.caseSensitive.addEventListener('click', function() {
+ self.dispatchEvent('casesensitivitychange');
+ });
+ },
+
+ dispatchEvent: function(aType, aFindPrevious) {
+ var event = document.createEvent('CustomEvent');
+ event.initCustomEvent('find' + aType, true, true, {
+ query: this.findField.value,
+ caseSensitive: this.caseSensitive.checked,
+ highlightAll: this.highlightAll.checked,
+ findPrevious: aFindPrevious
+ });
+ return window.dispatchEvent(event);
+ },
+
+ updateUIState: function(state, previous) {
+ var notFound = false;
+ var findMsg = '';
+ var status = '';
+
+ switch (state) {
+ case FindStates.FIND_FOUND:
+ break;
+
+ case FindStates.FIND_PENDING:
+ status = 'pending';
+ break;
+
+ case FindStates.FIND_NOTFOUND:
+ findMsg = mozL10n.get('find_not_found', null, 'Phrase not found');
+ notFound = true;
+ break;
+
+ case FindStates.FIND_WRAPPED:
+ if (previous) {
+ findMsg = mozL10n.get('find_reached_top', null,
+ 'Reached top of document, continued from bottom');
+ } else {
+ findMsg = mozL10n.get('find_reached_bottom', null,
+ 'Reached end of document, continued from top');
+ }
+ break;
+ }
+
+ if (notFound) {
+ this.findField.classList.add('notFound');
+ } else {
+ this.findField.classList.remove('notFound');
+ }
+
+ this.findField.setAttribute('data-status', status);
+ this.findMsg.textContent = findMsg;
+ },
+
+ open: function() {
+ if (!this.opened) {
+ this.opened = true;
+ this.toggleButton.classList.add('toggled');
+ this.bar.classList.remove('hidden');
+ }
+
+ this.findField.select();
+ this.findField.focus();
+ },
+
+ close: function() {
+ if (!this.opened) return;
+
+ this.opened = false;
+ this.toggleButton.classList.remove('toggled');
+ this.bar.classList.add('hidden');
+
+ PDFFindController.active = false;
+ },
+
+ toggle: function() {
+ if (this.opened) {
+ this.close();
+ } else {
+ this.open();
+ }
+ }
+};
+
+
+
+/* globals PDFFindBar, PDFJS, FindStates, FirefoxCom, Promise */
+
+/**
+ * Provides a "search" or "find" functionality for the PDF.
+ * This object actually performs the search for a given string.
+ */
+
+var PDFFindController = {
+ startedTextExtraction: false,
+
+ extractTextPromises: [],
+
+ pendingFindMatches: {},
+
+ // If active, find results will be highlighted.
+ active: false,
+
+ // Stores the text for each page.
+ pageContents: [],
+
+ pageMatches: [],
+
+ // Currently selected match.
+ selected: {
+ pageIdx: -1,
+ matchIdx: -1
+ },
+
+ // Where find algorithm currently is in the document.
+ offset: {
+ pageIdx: null,
+ matchIdx: null
+ },
+
+ resumePageIdx: null,
+
+ resumeCallback: null,
+
+ state: null,
+
+ dirtyMatch: false,
+
+ findTimeout: null,
+
+ pdfPageSource: null,
+
+ integratedFind: false,
+
+ initialize: function(options) {
+ if(typeof PDFFindBar === 'undefined' || PDFFindBar === null) {
+ throw 'PDFFindController cannot be initialized ' +
+ 'without a PDFFindController instance';
+ }
+
+ this.pdfPageSource = options.pdfPageSource;
+ this.integratedFind = options.integratedFind;
+
+ var events = [
+ 'find',
+ 'findagain',
+ 'findhighlightallchange',
+ 'findcasesensitivitychange'
+ ];
+
+ this.firstPagePromise = new Promise(function (resolve) {
+ this.resolveFirstPage = resolve;
+ }.bind(this));
+ this.handleEvent = this.handleEvent.bind(this);
+
+ for (var i = 0; i < events.length; i++) {
+ window.addEventListener(events[i], this.handleEvent);
+ }
+ },
+
+ reset: function pdfFindControllerReset() {
+ this.startedTextExtraction = false;
+ this.extractTextPromises = [];
+ this.active = false;
+ },
+
+ calcFindMatch: function(pageIndex) {
+ var pageContent = this.pageContents[pageIndex];
+ var query = this.state.query;
+ var caseSensitive = this.state.caseSensitive;
+ var queryLen = query.length;
+
+ if (queryLen === 0) {
+ // Do nothing the matches should be wiped out already.
+ return;
+ }
+
+ if (!caseSensitive) {
+ pageContent = pageContent.toLowerCase();
+ query = query.toLowerCase();
+ }
+
+ var matches = [];
+
+ var matchIdx = -queryLen;
+ while (true) {
+ matchIdx = pageContent.indexOf(query, matchIdx + queryLen);
+ if (matchIdx === -1) {
+ break;
+ }
+
+ matches.push(matchIdx);
+ }
+ this.pageMatches[pageIndex] = matches;
+ this.updatePage(pageIndex);
+ if (this.resumePageIdx === pageIndex) {
+ var callback = this.resumeCallback;
+ this.resumePageIdx = null;
+ this.resumeCallback = null;
+ callback();
+ }
+ },
+
+ extractText: function() {
+ if (this.startedTextExtraction) {
+ return;
+ }
+ this.startedTextExtraction = true;
+
+ this.pageContents = [];
+ var extractTextPromisesResolves = [];
+ for (var i = 0, ii = this.pdfPageSource.pdfDocument.numPages; i < ii; i++) {
+ this.extractTextPromises.push(new Promise(function (resolve) {
+ extractTextPromisesResolves.push(resolve);
+ }));
+ }
+
+ var self = this;
+ function extractPageText(pageIndex) {
+ self.pdfPageSource.pages[pageIndex].getTextContent().then(
+ function textContentResolved(data) {
+ // Build the find string.
+ var bidiTexts = data.bidiTexts;
+ var str = '';
+
+ for (var i = 0; i < bidiTexts.length; i++) {
+ str += bidiTexts[i].str;
+ }
+
+ // Store the pageContent as a string.
+ self.pageContents.push(str);
+
+ extractTextPromisesResolves[pageIndex](pageIndex);
+ if ((pageIndex + 1) < self.pdfPageSource.pages.length)
+ extractPageText(pageIndex + 1);
+ }
+ );
+ }
+ extractPageText(0);
+ },
+
+ handleEvent: function(e) {
+ if (this.state === null || e.type !== 'findagain') {
+ this.dirtyMatch = true;
+ }
+ this.state = e.detail;
+ this.updateUIState(FindStates.FIND_PENDING);
+
+ this.firstPagePromise.then(function() {
+ this.extractText();
+
+ clearTimeout(this.findTimeout);
+ if (e.type === 'find') {
+ // Only trigger the find action after 250ms of silence.
+ this.findTimeout = setTimeout(this.nextMatch.bind(this), 250);
+ } else {
+ this.nextMatch();
+ }
+ }.bind(this));
+ },
+
+ updatePage: function(idx) {
+ var page = this.pdfPageSource.pages[idx];
+
+ if (this.selected.pageIdx === idx) {
+ // If the page is selected, scroll the page into view, which triggers
+ // rendering the page, which adds the textLayer. Once the textLayer is
+ // build, it will scroll onto the selected match.
+ page.scrollIntoView();
+ }
+
+ if (page.textLayer) {
+ page.textLayer.updateMatches();
+ }
+ },
+
+ nextMatch: function() {
+ var previous = this.state.findPrevious;
+ var currentPageIndex = this.pdfPageSource.page - 1;
+ var numPages = this.pdfPageSource.pages.length;
+
+ this.active = true;
+
+ if (this.dirtyMatch) {
+ // Need to recalculate the matches, reset everything.
+ this.dirtyMatch = false;
+ this.selected.pageIdx = this.selected.matchIdx = -1;
+ this.offset.pageIdx = currentPageIndex;
+ this.offset.matchIdx = null;
+ this.hadMatch = false;
+ this.resumeCallback = null;
+ this.resumePageIdx = null;
+ this.pageMatches = [];
+ var self = this;
+
+ for (var i = 0; i < numPages; i++) {
+ // Wipe out any previous highlighted matches.
+ this.updatePage(i);
+
+ // As soon as the text is extracted start finding the matches.
+ if (!(i in this.pendingFindMatches)) {
+ this.pendingFindMatches[i] = true;
+ this.extractTextPromises[i].then(function(pageIdx) {
+ delete self.pendingFindMatches[pageIdx];
+ self.calcFindMatch(pageIdx);
+ });
+ }
+ }
+ }
+
+ // If there's no query there's no point in searching.
+ if (this.state.query === '') {
+ this.updateUIState(FindStates.FIND_FOUND);
+ return;
+ }
+
+ // If we're waiting on a page, we return since we can't do anything else.
+ if (this.resumeCallback) {
+ return;
+ }
+
+ var offset = this.offset;
+ // If there's already a matchIdx that means we are iterating through a
+ // page's matches.
+ if (offset.matchIdx !== null) {
+ var numPageMatches = this.pageMatches[offset.pageIdx].length;
+ if ((!previous && offset.matchIdx + 1 < numPageMatches) ||
+ (previous && offset.matchIdx > 0)) {
+ // The simple case, we just have advance the matchIdx to select the next
+ // match on the page.
+ this.hadMatch = true;
+ offset.matchIdx = previous ? offset.matchIdx - 1 : offset.matchIdx + 1;
+ this.updateMatch(true);
+ return;
+ }
+ // We went beyond the current page's matches, so we advance to the next
+ // page.
+ this.advanceOffsetPage(previous);
+ }
+ // Start searching through the page.
+ this.nextPageMatch();
+ },
+
+ nextPageMatch: function() {
+ if (this.resumePageIdx !== null)
+ console.error('There can only be one pending page.');
+
+ var matchesReady = function(matches) {
+ var offset = this.offset;
+ var numMatches = matches.length;
+ var previous = this.state.findPrevious;
+ if (numMatches) {
+ // There were matches for the page, so initialize the matchIdx.
+ this.hadMatch = true;
+ offset.matchIdx = previous ? numMatches - 1 : 0;
+ this.updateMatch(true);
+ } else {
+ // No matches attempt to search the next page.
+ this.advanceOffsetPage(previous);
+ if (offset.wrapped) {
+ offset.matchIdx = null;
+ if (!this.hadMatch) {
+ // No point in wrapping there were no matches.
+ this.updateMatch(false);
+ return;
+ }
+ }
+ // Search the next page.
+ this.nextPageMatch();
+ }
+ }.bind(this);
+
+ var pageIdx = this.offset.pageIdx;
+ var pageMatches = this.pageMatches;
+ if (!pageMatches[pageIdx]) {
+ // The matches aren't ready setup a callback so we can be notified,
+ // when they are ready.
+ this.resumeCallback = function() {
+ matchesReady(pageMatches[pageIdx]);
+ };
+ this.resumePageIdx = pageIdx;
+ return;
+ }
+ // The matches are finished already.
+ matchesReady(pageMatches[pageIdx]);
+ },
+
+ advanceOffsetPage: function(previous) {
+ var offset = this.offset;
+ var numPages = this.extractTextPromises.length;
+ offset.pageIdx = previous ? offset.pageIdx - 1 : offset.pageIdx + 1;
+ offset.matchIdx = null;
+ if (offset.pageIdx >= numPages || offset.pageIdx < 0) {
+ offset.pageIdx = previous ? numPages - 1 : 0;
+ offset.wrapped = true;
+ return;
+ }
+ },
+
+ updateMatch: function(found) {
+ var state = FindStates.FIND_NOTFOUND;
+ var wrapped = this.offset.wrapped;
+ this.offset.wrapped = false;
+ if (found) {
+ var previousPage = this.selected.pageIdx;
+ this.selected.pageIdx = this.offset.pageIdx;
+ this.selected.matchIdx = this.offset.matchIdx;
+ state = wrapped ? FindStates.FIND_WRAPPED : FindStates.FIND_FOUND;
+ // Update the currently selected page to wipe out any selected matches.
+ if (previousPage !== -1 && previousPage !== this.selected.pageIdx) {
+ this.updatePage(previousPage);
+ }
+ }
+ this.updateUIState(state, this.state.findPrevious);
+ if (this.selected.pageIdx !== -1) {
+ this.updatePage(this.selected.pageIdx, true);
+ }
+ },
+
+ updateUIState: function(state, previous) {
+ if (this.integratedFind) {
+ FirefoxCom.request('updateFindControlState',
+ {result: state, findPrevious: previous});
+ return;
+ }
+ PDFFindBar.updateUIState(state, previous);
+ }
+};
+
+
+
+var PDFHistory = {
+ initialized: false,
+ initialDestination: null,
+
+ initialize: function pdfHistoryInitialize(fingerprint) {
+ if (PDFJS.disableHistory || PDFView.isViewerEmbedded) {
+ // The browsing history is only enabled when the viewer is standalone,
+ // i.e. not when it is embedded in a web page.
+ return;
+ }
+ this.initialized = true;
+ this.reInitialized = false;
+ this.allowHashChange = true;
+ this.historyUnlocked = true;
+
+ this.previousHash = window.location.hash.substring(1);
+ this.currentBookmark = '';
+ this.currentPage = 0;
+ this.updatePreviousBookmark = false;
+ this.previousBookmark = '';
+ this.previousPage = 0;
+ this.nextHashParam = '';
+
+ this.fingerprint = fingerprint;
+ this.currentUid = this.uid = 0;
+ this.current = {};
+
+ var state = window.history.state;
+ if (this._isStateObjectDefined(state)) {
+ // This corresponds to navigating back to the document
+ // from another page in the browser history.
+ if (state.target.dest) {
+ this.initialDestination = state.target.dest;
+ } else {
+ PDFView.initialBookmark = state.target.hash;
+ }
+ this.currentUid = state.uid;
+ this.uid = state.uid + 1;
+ this.current = state.target;
+ } else {
+ // This corresponds to the loading of a new document.
+ if (state && state.fingerprint &&
+ this.fingerprint !== state.fingerprint) {
+ // Reinitialize the browsing history when a new document
+ // is opened in the web viewer.
+ this.reInitialized = true;
+ }
+ this._pushOrReplaceState({ fingerprint: this.fingerprint }, true);
+ }
+
+ var self = this;
+ window.addEventListener('popstate', function pdfHistoryPopstate(evt) {
+ evt.preventDefault();
+ evt.stopPropagation();
+
+ if (!self.historyUnlocked) {
+ return;
+ }
+ if (evt.state) {
+ // Move back/forward in the history.
+ self._goTo(evt.state);
+ } else {
+ // Handle the user modifying the hash of a loaded document.
+ self.previousHash = window.location.hash.substring(1);
+
+ // If the history is empty when the hash changes,
+ // update the previous entry in the browser history.
+ if (self.uid === 0) {
+ var previousParams = (self.previousHash && self.currentBookmark &&
+ self.previousHash !== self.currentBookmark) ?
+ { hash: self.currentBookmark, page: self.currentPage } :
+ { page: 1 };
+ self.historyUnlocked = false;
+ self.allowHashChange = false;
+ window.history.back();
+ self._pushToHistory(previousParams, false, true);
+ window.history.forward();
+ self.historyUnlocked = true;
+ }
+ self._pushToHistory({ hash: self.previousHash }, false, true);
+ self._updatePreviousBookmark();
+ }
+ }, false);
+
+ function pdfHistoryBeforeUnload() {
+ var previousParams = self._getPreviousParams(null, true);
+ if (previousParams) {
+ var replacePrevious = (!self.current.dest &&
+ self.current.hash !== self.previousHash);
+ self._pushToHistory(previousParams, false, replacePrevious);
+ self._updatePreviousBookmark();
+ }
+ // Remove the event listener when navigating away from the document,
+ // since 'beforeunload' prevents Firefox from caching the document.
+ window.removeEventListener('beforeunload', pdfHistoryBeforeUnload, false);
+ }
+ window.addEventListener('beforeunload', pdfHistoryBeforeUnload, false);
+
+ window.addEventListener('pageshow', function pdfHistoryPageShow(evt) {
+ // If the entire viewer (including the PDF file) is cached in the browser,
+ // we need to reattach the 'beforeunload' event listener since
+ // the 'DOMContentLoaded' event is not fired on 'pageshow'.
+ window.addEventListener('beforeunload', pdfHistoryBeforeUnload, false);
+ }, false);
+ },
+
+ _isStateObjectDefined: function pdfHistory_isStateObjectDefined(state) {
+ return (state && state.uid >= 0 &&
+ state.fingerprint && this.fingerprint === state.fingerprint &&
+ state.target && state.target.hash) ? true : false;
+ },
+
+ _pushOrReplaceState: function pdfHistory_pushOrReplaceState(stateObj,
+ replace) {
+ if (replace) {
+ window.history.replaceState(stateObj, '', document.URL);
+ } else {
+ window.history.pushState(stateObj, '', document.URL);
+ }
+ },
+
+ get isHashChangeUnlocked() {
+ if (!this.initialized) {
+ return true;
+ }
+ // If the current hash changes when moving back/forward in the history,
+ // this will trigger a 'popstate' event *as well* as a 'hashchange' event.
+ // Since the hash generally won't correspond to the exact the position
+ // stored in the history's state object, triggering the 'hashchange' event
+ // can thus corrupt the browser history.
+ //
+ // When the hash changes during a 'popstate' event, we *only* prevent the
+ // first 'hashchange' event and immediately reset allowHashChange.
+ // If it is not reset, the user would not be able to change the hash.
+
+ var temp = this.allowHashChange;
+ this.allowHashChange = true;
+ return temp;
+ },
+
+ _updatePreviousBookmark: function pdfHistory_updatePreviousBookmark() {
+ if (this.updatePreviousBookmark &&
+ this.currentBookmark && this.currentPage) {
+ this.previousBookmark = this.currentBookmark;
+ this.previousPage = this.currentPage;
+ this.updatePreviousBookmark = false;
+ }
+ },
+
+ updateCurrentBookmark: function pdfHistoryUpdateCurrentBookmark(bookmark,
+ pageNum) {
+ if (this.initialized) {
+ this.currentBookmark = bookmark.substring(1);
+ this.currentPage = pageNum | 0;
+ this._updatePreviousBookmark();
+ }
+ },
+
+ updateNextHashParam: function pdfHistoryUpdateNextHashParam(param) {
+ if (this.initialized) {
+ this.nextHashParam = param;
+ }
+ },
+
+ push: function pdfHistoryPush(params, isInitialBookmark) {
+ if (!(this.initialized && this.historyUnlocked)) {
+ return;
+ }
+ if (params.dest && !params.hash) {
+ params.hash = (this.current.hash && this.current.dest &&
+ this.current.dest === params.dest) ?
+ this.current.hash :
+ PDFView.getDestinationHash(params.dest).split('#')[1];
+ }
+ if (params.page) {
+ params.page |= 0;
+ }
+ if (isInitialBookmark) {
+ var target = window.history.state.target;
+ if (!target) {
+ // Invoked when the user specifies an initial bookmark,
+ // thus setting PDFView.initialBookmark, when the document is loaded.
+ this._pushToHistory(params, false);
+ this.previousHash = window.location.hash.substring(1);
+ }
+ this.updatePreviousBookmark = this.nextHashParam ? false : true;
+ if (target) {
+ // If the current document is reloaded,
+ // avoid creating duplicate entries in the history.
+ this._updatePreviousBookmark();
+ }
+ return;
+ }
+ if (this.nextHashParam) {
+ if (this.nextHashParam === params.hash) {
+ this.nextHashParam = null;
+ this.updatePreviousBookmark = true;
+ return;
+ } else {
+ this.nextHashParam = null;
+ }
+ }
+
+ if (params.hash) {
+ if (this.current.hash) {
+ if (this.current.hash !== params.hash) {
+ this._pushToHistory(params, true);
+ } else {
+ if (!this.current.page && params.page) {
+ this._pushToHistory(params, false, true);
+ }
+ this.updatePreviousBookmark = true;
+ }
+ } else {
+ this._pushToHistory(params, true);
+ }
+ } else if (this.current.page && params.page &&
+ this.current.page !== params.page) {
+ this._pushToHistory(params, true);
+ }
+ },
+
+ _getPreviousParams: function pdfHistory_getPreviousParams(onlyCheckPage,
+ beforeUnload) {
+ if (!(this.currentBookmark && this.currentPage)) {
+ return null;
+ } else if (this.updatePreviousBookmark) {
+ this.updatePreviousBookmark = false;
+ }
+ if (this.uid > 0 && !(this.previousBookmark && this.previousPage)) {
+ // Prevent the history from getting stuck in the current state,
+ // effectively preventing the user from going back/forward in the history.
+ //
+ // This happens if the current position in the document didn't change when
+ // the history was previously updated. The reasons for this are either:
+ // 1. The current zoom value is such that the document does not need to,
+ // or cannot, be scrolled to display the destination.
+ // 2. The previous destination is broken, and doesn't actally point to a
+ // position within the document.
+ // (This is either due to a bad PDF generator, or the user making a
+ // mistake when entering a destination in the hash parameters.)
+ return null;
+ }
+ if ((!this.current.dest && !onlyCheckPage) || beforeUnload) {
+ if (this.previousBookmark === this.currentBookmark) {
+ return null;
+ }
+ } else if (this.current.page || onlyCheckPage) {
+ if (this.previousPage === this.currentPage) {
+ return null;
+ }
+ } else {
+ return null;
+ }
+ var params = { hash: this.currentBookmark, page: this.currentPage };
+ if (PresentationMode.active) {
+ params.hash = null;
+ }
+ return params;
+ },
+
+ _stateObj: function pdfHistory_stateObj(params) {
+ return { fingerprint: this.fingerprint, uid: this.uid, target: params };
+ },
+
+ _pushToHistory: function pdfHistory_pushToHistory(params,
+ addPrevious, overwrite) {
+ if (!this.initialized) {
+ return;
+ }
+ if (!params.hash && params.page) {
+ params.hash = ('page=' + params.page);
+ }
+ if (addPrevious && !overwrite) {
+ var previousParams = this._getPreviousParams();
+ if (previousParams) {
+ var replacePrevious = (!this.current.dest &&
+ this.current.hash !== this.previousHash);
+ this._pushToHistory(previousParams, false, replacePrevious);
+ }
+ }
+ this._pushOrReplaceState(this._stateObj(params),
+ (overwrite || this.uid === 0));
+ this.currentUid = this.uid++;
+ this.current = params;
+ this.updatePreviousBookmark = true;
+ },
+
+ _goTo: function pdfHistory_goTo(state) {
+ if (!(this.initialized && this.historyUnlocked &&
+ this._isStateObjectDefined(state))) {
+ return;
+ }
+ if (!this.reInitialized && state.uid < this.currentUid) {
+ var previousParams = this._getPreviousParams(true);
+ if (previousParams) {
+ this._pushToHistory(this.current, false);
+ this._pushToHistory(previousParams, false);
+ this.currentUid = state.uid;
+ window.history.back();
+ return;
+ }
+ }
+ this.historyUnlocked = false;
+
+ if (state.target.dest) {
+ PDFView.navigateTo(state.target.dest);
+ } else {
+ PDFView.setHash(state.target.hash);
+ }
+ this.currentUid = state.uid;
+ if (state.uid > this.uid) {
+ this.uid = state.uid;
+ }
+ this.current = state.target;
+ this.updatePreviousBookmark = true;
+
+ var currentHash = window.location.hash.substring(1);
+ if (this.previousHash !== currentHash) {
+ this.allowHashChange = false;
+ }
+ this.previousHash = currentHash;
+
+ this.historyUnlocked = true;
+ },
+
+ back: function pdfHistoryBack() {
+ this.go(-1);
+ },
+
+ forward: function pdfHistoryForward() {
+ this.go(1);
+ },
+
+ go: function pdfHistoryGo(direction) {
+ if (this.initialized && this.historyUnlocked) {
+ var state = window.history.state;
+ if (direction === -1 && state && state.uid > 0) {
+ window.history.back();
+ } else if (direction === 1 && state && state.uid < (this.uid - 1)) {
+ window.history.forward();
+ }
+ }
+ }
+};
+
+
+var SecondaryToolbar = {
+ opened: false,
+ previousContainerHeight: null,
+ newContainerHeight: null,
+
+ initialize: function secondaryToolbarInitialize(options) {
+ this.toolbar = options.toolbar;
+ this.presentationMode = options.presentationMode;
+ this.buttonContainer = this.toolbar.firstElementChild;
+
+ // Define the toolbar buttons.
+ this.toggleButton = options.toggleButton;
+ this.presentationModeButton = options.presentationModeButton;
+ this.openFile = options.openFile;
+ this.print = options.print;
+ this.download = options.download;
+ this.firstPage = options.firstPage;
+ this.lastPage = options.lastPage;
+ this.pageRotateCw = options.pageRotateCw;
+ this.pageRotateCcw = options.pageRotateCcw;
+
+ // Attach the event listeners.
+ var elements = [
+ // Button to toggle the visibility of the secondary toolbar:
+ { element: this.toggleButton, handler: this.toggle },
+ // All items within the secondary toolbar
+ // (except for toggleHandTool, hand_tool.js is responsible for it):
+ { element: this.presentationModeButton,
+ handler: this.presentationModeClick },
+ //{ element: this.openFile, handler: this.openFileClick },
+ { element: this.print, handler: this.printClick },
+ //{ element: this.download, handler: this.downloadClick },
+ { element: this.firstPage, handler: this.firstPageClick },
+ { element: this.lastPage, handler: this.lastPageClick },
+ { element: this.pageRotateCw, handler: this.pageRotateCwClick },
+ { element: this.pageRotateCcw, handler: this.pageRotateCcwClick }
+ ];
+
+ for (var item in elements) {
+ var element = elements[item].element;
+ if (element) {
+ element.addEventListener('click', elements[item].handler.bind(this));
+ }
+ }
+ },
+
+ // Event handling functions.
+ presentationModeClick: function secondaryToolbarPresentationModeClick(evt) {
+ this.presentationMode.request();
+ this.close();
+ },
+
+ openFileClick: function secondaryToolbarOpenFileClick(evt) {
+ document.getElementById('fileInput').click();
+ this.close(evt.target);
+ },
+
+ printClick: function secondaryToolbarPrintClick(evt) {
+ window.print();
+ this.close(evt.target);
+ },
+
+ downloadClick: function secondaryToolbarDownloadClick(evt) {
+ PDFView.download();
+ this.close(evt.target);
+ },
+
+ firstPageClick: function secondaryToolbarFirstPageClick(evt) {
+ PDFView.page = 1;
+ },
+
+ lastPageClick: function secondaryToolbarLastPageClick(evt) {
+ PDFView.page = PDFView.pdfDocument.numPages;
+ },
+
+ pageRotateCwClick: function secondaryToolbarPageRotateCwClick(evt) {
+ PDFView.rotatePages(90);
+ },
+
+ pageRotateCcwClick: function secondaryToolbarPageRotateCcwClick(evt) {
+ PDFView.rotatePages(-90);
+ },
+
+ // Misc. functions for interacting with the toolbar.
+ setMaxHeight: function secondaryToolbarSetMaxHeight(container) {
+ if (!container || !this.buttonContainer) {
+ return;
+ }
+ this.newContainerHeight = container.clientHeight;
+ if (this.previousContainerHeight === this.newContainerHeight) {
+ return;
+ }
+ this.buttonContainer.setAttribute('style',
+ 'max-height: ' + (this.newContainerHeight - SCROLLBAR_PADDING) + 'px;');
+ this.previousContainerHeight = this.newContainerHeight;
+ },
+
+ open: function secondaryToolbarOpen() {
+ if (this.opened) {
+ return;
+ }
+ this.opened = true;
+ this.toggleButton.classList.add('toggled');
+ this.toolbar.classList.remove('hidden');
+ },
+
+ close: function secondaryToolbarClose(target) {
+ if (!this.opened) {
+ return;
+ } else if (target && !this.toolbar.contains(target)) {
+ return;
+ }
+ this.opened = false;
+ this.toolbar.classList.add('hidden');
+ this.toggleButton.classList.remove('toggled');
+ },
+
+ toggle: function secondaryToolbarToggle() {
+ if (this.opened) {
+ this.close();
+ } else {
+ this.open();
+ }
+ }
+};
+
+
+var PasswordPrompt = {
+ visible: false,
+ updatePassword: null,
+ reason: null,
+ overlayContainer: null,
+ passwordField: null,
+ passwordText: null,
+ passwordSubmit: null,
+ passwordCancel: null,
+
+ initialize: function secondaryToolbarInitialize(options) {
+ this.overlayContainer = options.overlayContainer;
+ this.passwordField = options.passwordField;
+ this.passwordText = options.passwordText;
+ this.passwordSubmit = options.passwordSubmit;
+ this.passwordCancel = options.passwordCancel;
+
+ // Attach the event listeners.
+ this.passwordSubmit.addEventListener('click',
+ this.verifyPassword.bind(this));
+
+ this.passwordCancel.addEventListener('click', this.hide.bind(this));
+
+ this.passwordField.addEventListener('keydown',
+ function (e) {
+ if (e.keyCode === 13) { // Enter key
+ this.verifyPassword();
+ }
+ }.bind(this));
+
+ this.overlayContainer.addEventListener('keydown',
+ function (e) {
+ if (e.keyCode === 27) { // Esc key
+ this.hide();
+ }
+ }.bind(this));
+ },
+
+ show: function passwordPromptShow() {
+ if (this.visible) {
+ return;
+ }
+ this.visible = true;
+ this.overlayContainer.classList.remove('hidden');
+ this.passwordField.focus();
+
+ var promptString = mozL10n.get('password_label', null,
+ 'Enter the password to open this PDF file.');
+
+ if (this.reason === PDFJS.PasswordResponses.INCORRECT_PASSWORD) {
+ promptString = mozL10n.get('password_invalid', null,
+ 'Invalid password. Please try again.');
+ }
+
+ this.passwordText.textContent = promptString;
+ },
+
+ hide: function passwordPromptClose() {
+ if (!this.visible) {
+ return;
+ }
+ this.visible = false;
+ this.passwordField.value = '';
+ this.overlayContainer.classList.add('hidden');
+ },
+
+ verifyPassword: function passwordPromptVerifyPassword() {
+ var password = this.passwordField.value;
+ if (password && password.length > 0) {
+ this.hide();
+ return this.updatePassword(password);
+ }
+ }
+};
+
+
+var DELAY_BEFORE_HIDING_CONTROLS = 3000; // in ms
+var SELECTOR = 'presentationControls';
+var DELAY_BEFORE_RESETTING_SWITCH_IN_PROGRESS = 1000; // in ms
+
+var PresentationMode = {
+ active: false,
+ args: null,
+ contextMenuOpen: false,
+ prevCoords: { x: null, y: null },
+
+ initialize: function presentationModeInitialize(options) {
+ this.container = options.container;
+ this.secondaryToolbar = options.secondaryToolbar;
+
+ this.viewer = this.container.firstElementChild;
+
+ this.firstPage = options.firstPage;
+ this.lastPage = options.lastPage;
+ this.pageRotateCw = options.pageRotateCw;
+ this.pageRotateCcw = options.pageRotateCcw;
+
+ this.firstPage.addEventListener('click', function() {
+ this.contextMenuOpen = false;
+ this.secondaryToolbar.firstPageClick();
+ }.bind(this));
+ this.lastPage.addEventListener('click', function() {
+ this.contextMenuOpen = false;
+ this.secondaryToolbar.lastPageClick();
+ }.bind(this));
+
+ this.pageRotateCw.addEventListener('click', function() {
+ this.contextMenuOpen = false;
+ this.secondaryToolbar.pageRotateCwClick();
+ }.bind(this));
+ this.pageRotateCcw.addEventListener('click', function() {
+ this.contextMenuOpen = false;
+ this.secondaryToolbar.pageRotateCcwClick();
+ }.bind(this));
+ },
+
+ get isFullscreen() {
+ return (document.fullscreenElement ||
+ document.mozFullScreen ||
+ document.webkitIsFullScreen ||
+ document.msFullscreenElement);
+ },
+
+ /**
+ * Initialize a timeout that is used to reset PDFView.currentPosition when the
+ * browser transitions to fullscreen mode. Since resize events are triggered
+ * multiple times during the switch to fullscreen mode, this is necessary in
+ * order to prevent the page from being scrolled partially, or completely,
+ * out of view when Presentation Mode is enabled.
+ * Note: This is only an issue at certain zoom levels, e.g. 'page-width'.
+ */
+ _setSwitchInProgress: function presentationMode_setSwitchInProgress() {
+ if (this.switchInProgress) {
+ clearTimeout(this.switchInProgress);
+ }
+ this.switchInProgress = setTimeout(function switchInProgressTimeout() {
+ delete this.switchInProgress;
+ }.bind(this), DELAY_BEFORE_RESETTING_SWITCH_IN_PROGRESS);
+
+ PDFView.currentPosition = null;
+ },
+
+ _resetSwitchInProgress: function presentationMode_resetSwitchInProgress() {
+ if (this.switchInProgress) {
+ clearTimeout(this.switchInProgress);
+ delete this.switchInProgress;
+ }
+ },
+
+ request: function presentationModeRequest() {
+ if (!PDFView.supportsFullscreen || this.isFullscreen ||
+ !this.viewer.hasChildNodes()) {
+ return false;
+ }
+ this._setSwitchInProgress();
+
+ if (this.container.requestFullscreen) {
+ this.container.requestFullscreen();
+ } else if (this.container.mozRequestFullScreen) {
+ this.container.mozRequestFullScreen();
+ } else if (this.container.webkitRequestFullScreen) {
+ this.container.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);
+ } else if (this.container.msRequestFullscreen) {
+ this.container.msRequestFullscreen();
+ } else {
+ return false;
+ }
+
+ this.args = {
+ page: PDFView.page,
+ previousScale: PDFView.currentScaleValue
+ };
+
+ return true;
+ },
+
+ enter: function presentationModeEnter() {
+ this.active = true;
+ this._resetSwitchInProgress();
+
+ // Ensure that the correct page is scrolled into view when entering
+ // Presentation Mode, by waiting until fullscreen mode in enabled.
+ // Note: This is only necessary in non-Mozilla browsers.
+ setTimeout(function enterPresentationModeTimeout() {
+ PDFView.page = this.args.page;
+ PDFView.setScale('page-fit', true);
+ }.bind(this), 0);
+
+ window.addEventListener('mousemove', this.mouseMove, false);
+ window.addEventListener('mousedown', this.mouseDown, false);
+ window.addEventListener('contextmenu', this.contextMenu, false);
+
+ this.showControls();
+ HandTool.enterPresentationMode();
+ this.contextMenuOpen = false;
+ this.container.setAttribute('contextmenu', 'viewerContextMenu');
+ },
+
+ exit: function presentationModeExit() {
+ var page = PDFView.page;
+
+ // Ensure that the correct page is scrolled into view when exiting
+ // Presentation Mode, by waiting until fullscreen mode is disabled.
+ // Note: This is only necessary in non-Mozilla browsers.
+ setTimeout(function exitPresentationModeTimeout() {
+ PDFView.setScale(this.args.previousScale);
+ PDFView.page = page;
+ // Keep Presentation Mode active until the page is scrolled into view,
+ // to prevent issues in non-Mozilla browsers.
+ this.active = false;
+ this.args = null;
+ }.bind(this), 0);
+
+ window.removeEventListener('mousemove', this.mouseMove, false);
+ window.removeEventListener('mousedown', this.mouseDown, false);
+ window.removeEventListener('contextmenu', this.contextMenu, false);
+
+ this.hideControls();
+ PDFView.clearMouseScrollState();
+ HandTool.exitPresentationMode();
+ this.container.removeAttribute('contextmenu');
+ this.contextMenuOpen = false;
+
+ // Ensure that the thumbnail of the current page is visible
+ // when exiting presentation mode.
+ scrollIntoView(document.getElementById('thumbnailContainer' + page));
+ },
+
+ showControls: function presentationModeShowControls() {
+ if (this.controlsTimeout) {
+ clearTimeout(this.controlsTimeout);
+ } else {
+ this.container.classList.add(SELECTOR);
+ }
+ this.controlsTimeout = setTimeout(function hideControlsTimeout() {
+ this.container.classList.remove(SELECTOR);
+ delete this.controlsTimeout;
+ }.bind(this), DELAY_BEFORE_HIDING_CONTROLS);
+ },
+
+ hideControls: function presentationModeHideControls() {
+ if (!this.controlsTimeout) {
+ return;
+ }
+ this.container.classList.remove(SELECTOR);
+ clearTimeout(this.controlsTimeout);
+ delete this.controlsTimeout;
+ },
+
+ mouseMove: function presentationModeMouseMove(evt) {
+ // Workaround for a bug in WebKit browsers that causes the 'mousemove' event
+ // to be fired when the cursor is changed. For details, see:
+ // http://code.google.com/p/chromium/issues/detail?id=103041.
+
+ var currCoords = { x: evt.clientX, y: evt.clientY };
+ var prevCoords = PresentationMode.prevCoords;
+ PresentationMode.prevCoords = currCoords;
+
+ if (currCoords.x === prevCoords.x && currCoords.y === prevCoords.y) {
+ return;
+ }
+ PresentationMode.showControls();
+ },
+
+ mouseDown: function presentationModeMouseDown(evt) {
+ var self = PresentationMode;
+ if (self.contextMenuOpen) {
+ self.contextMenuOpen = false;
+ evt.preventDefault();
+ return;
+ }
+
+ if (evt.button === 0) {
+ // Enable clicking of links in presentation mode. Please note:
+ // Only links pointing to destinations in the current PDF document work.
+ var isInternalLink = (evt.target.href &&
+ evt.target.classList.contains('internalLink'));
+ if (!isInternalLink) {
+ // Unless an internal link was clicked, advance one page.
+ evt.preventDefault();
+ PDFView.page += (evt.shiftKey ? -1 : 1);
+ }
+ }
+ },
+
+ contextMenu: function presentationModeContextMenu(evt) {
+ PresentationMode.contextMenuOpen = true;
+ }
+};
+
+(function presentationModeClosure() {
+ function presentationModeChange(e) {
+ if (PresentationMode.isFullscreen) {
+ PresentationMode.enter();
+ } else {
+ PresentationMode.exit();
+ }
+ }
+
+ window.addEventListener('fullscreenchange', presentationModeChange, false);
+ window.addEventListener('mozfullscreenchange', presentationModeChange, false);
+ window.addEventListener('webkitfullscreenchange', presentationModeChange,
+ false);
+ window.addEventListener('MSFullscreenChange', presentationModeChange, false);
+})();
+
+
+/* Copyright 2013 Rob Wu <gwnRob at gmail.com>
+ * https://github.com/Rob--W/grab-to-pan.js
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+'use strict';
+
+var GrabToPan = (function GrabToPanClosure() {
+ /**
+ * Construct a GrabToPan instance for a given HTML element.
+ * @param options.element {Element}
+ * @param options.ignoreTarget {function} optional. See `ignoreTarget(node)`
+ * @param options.onActiveChanged {function(boolean)} optional. Called
+ * when grab-to-pan is (de)activated. The first argument is a boolean that
+ * shows whether grab-to-pan is activated.
+ */
+ function GrabToPan(options) {
+ this.element = options.element;
+ this.document = options.element.ownerDocument;
+ if (typeof options.ignoreTarget === 'function') {
+ this.ignoreTarget = options.ignoreTarget;
+ }
+ this.onActiveChanged = options.onActiveChanged;
+
+ // Bind the contexts to ensure that `this` always points to
+ // the GrabToPan instance.
+ this.activate = this.activate.bind(this);
+ this.deactivate = this.deactivate.bind(this);
+ this.toggle = this.toggle.bind(this);
+ this._onmousedown = this._onmousedown.bind(this);
+ this._onmousemove = this._onmousemove.bind(this);
+ this._endPan = this._endPan.bind(this);
+ }
+ GrabToPan.prototype = {
+ /**
+ * Class name of element which can be grabbed
+ */
+ CSS_CLASS_GRAB: 'grab-to-pan-grab',
+ /**
+ * Class name of element which is being dragged & panned
+ */
+ CSS_CLASS_GRABBING: 'grab-to-pan-grabbing',
+
+ /**
+ * Bind a mousedown event to the element to enable grab-detection.
+ */
+ activate: function GrabToPan_activate() {
+ if (!this.active) {
+ this.active = true;
+ this.element.addEventListener('mousedown', this._onmousedown, true);
+ this.element.classList.add(this.CSS_CLASS_GRAB);
+ if (this.onActiveChanged) {
+ this.onActiveChanged(true);
+ }
+ }
+ },
+
+ /**
+ * Removes all events. Any pending pan session is immediately stopped.
+ */
+ deactivate: function GrabToPan_deactivate() {
+ if (this.active) {
+ this.active = false;
+ this.element.removeEventListener('mousedown', this._onmousedown, true);
+ this._endPan();
+ this.element.classList.remove(this.CSS_CLASS_GRAB);
+ if (this.onActiveChanged) {
+ this.onActiveChanged(false);
+ }
+ }
+ },
+
+ toggle: function GrabToPan_toggle() {
+ if (this.active) {
+ this.deactivate();
+ } else {
+ this.activate();
+ }
+ },
+
+ /**
+ * Whether to not pan if the target element is clicked.
+ * Override this method to change the default behaviour.
+ *
+ * @param node {Element} The target of the event
+ * @return {boolean} Whether to not react to the click event.
+ */
+ ignoreTarget: function GrabToPan_ignoreTarget(node) {
+ // Use matchesSelector to check whether the clicked element
+ // is (a child of) an input element / link
+ return node[matchesSelector](
+ 'a[href], a[href] *, input, textarea, button, button *, select, option'
+ );
+ },
+
+ /**
+ * @private
+ */
+ _onmousedown: function GrabToPan__onmousedown(event) {
+ if (event.button !== 0 || this.ignoreTarget(event.target)) {
+ return;
+ }
+ if (event.originalTarget) {
+ try {
+ /* jshint expr:true */
+ event.originalTarget.tagName;
+ } catch (e) {
+ // Mozilla-specific: element is a scrollbar (XUL element)
+ return;
+ }
+ }
+
+ this.scrollLeftStart = this.element.scrollLeft;
+ this.scrollTopStart = this.element.scrollTop;
+ this.clientXStart = event.clientX;
+ this.clientYStart = event.clientY;
+ this.document.addEventListener('mousemove', this._onmousemove, true);
+ this.document.addEventListener('mouseup', this._endPan, true);
+ // When a scroll event occurs before a mousemove, assume that the user
+ // dragged a scrollbar (necessary for Opera Presto, Safari and IE)
+ // (not needed for Chrome/Firefox)
+ this.element.addEventListener('scroll', this._endPan, true);
+ event.preventDefault();
+ event.stopPropagation();
+ this.element.classList.remove(this.CSS_CLASS_GRAB);
+ this.document.documentElement.classList.add(this.CSS_CLASS_GRABBING);
+ },
+
+ /**
+ * @private
+ */
+ _onmousemove: function GrabToPan__onmousemove(event) {
+ this.element.removeEventListener('scroll', this._endPan, true);
+ if (isLeftMouseReleased(event)) {
+ this.document.removeEventListener('mousemove', this._onmousemove, true);
+ return;
+ }
+ var xDiff = event.clientX - this.clientXStart;
+ var yDiff = event.clientY - this.clientYStart;
+ this.element.scrollTop = this.scrollTopStart - yDiff;
+ this.element.scrollLeft = this.scrollLeftStart - xDiff;
+ },
+
+ /**
+ * @private
+ */
+ _endPan: function GrabToPan__endPan() {
+ this.element.removeEventListener('scroll', this._endPan, true);
+ this.document.removeEventListener('mousemove', this._onmousemove, true);
+ this.document.removeEventListener('mouseup', this._endPan, true);
+ this.document.documentElement.classList.remove(this.CSS_CLASS_GRABBING);
+ this.element.classList.add(this.CSS_CLASS_GRAB);
+ }
+ };
+
+ // Get the correct (vendor-prefixed) name of the matches method.
+ var matchesSelector;
+ ['webkitM', 'mozM', 'msM', 'oM', 'm'].some(function(prefix) {
+ var name = prefix + 'atches';
+ if (name in document.documentElement) {
+ matchesSelector = name;
+ }
+ name += 'Selector';
+ if (name in document.documentElement) {
+ matchesSelector = name;
+ }
+ return matchesSelector; // If found, then truthy, and [].some() ends.
+ });
+
+ // Browser sniffing because it's impossible to feature-detect
+ // whether event.which for onmousemove is reliable
+ var isNotIEorIsIE10plus = !document.documentMode || document.documentMode > 9;
+ var chrome = window.chrome;
+ var isChrome15OrOpera15plus = chrome && (chrome.webstore || chrome.app);
+ // ^ Chrome 15+ ^ Opera 15+
+ var isSafari6plus = /Apple/.test(navigator.vendor) &&
+ /Version\/([6-9]\d*|[1-5]\d+)/.test(navigator.userAgent);
+
+ /**
+ * Whether the left mouse is not pressed.
+ * @param event {MouseEvent}
+ * @return {boolean} True if the left mouse button is not pressed.
+ * False if unsure or if the left mouse button is pressed.
+ */
+ function isLeftMouseReleased(event) {
+ if ('buttons' in event && isNotIEorIsIE10plus) {
+ // http://www.w3.org/TR/DOM-Level-3-Events/#events-MouseEvent-buttons
+ // Firefox 15+
+ // Internet Explorer 10+
+ return !(event.buttons | 1);
+ }
+ if (isChrome15OrOpera15plus || isSafari6plus) {
+ // Chrome 14+
+ // Opera 15+
+ // Safari 6.0+
+ return event.which === 0;
+ }
+ }
+
+ return GrabToPan;
+})();
+
+var HandTool = {
+ initialize: function handToolInitialize(options) {
+ var toggleHandTool = options.toggleHandTool;
+ this.handTool = new GrabToPan({
+ element: options.container,
+ onActiveChanged: function(isActive) {
+ if (!toggleHandTool) {
+ return;
+ }
+ if (isActive) {
+ toggleHandTool.title =
+ mozL10n.get('hand_tool_disable.title', null, 'Disable hand tool');
+ toggleHandTool.firstElementChild.textContent =
+ mozL10n.get('hand_tool_disable_label', null, 'Disable hand tool');
+ } else {
+ toggleHandTool.title =
+ mozL10n.get('hand_tool_enable.title', null, 'Enable hand tool');
+ toggleHandTool.firstElementChild.textContent =
+ mozL10n.get('hand_tool_enable_label', null, 'Enable hand tool');
+ }
+ }
+ });
+ if (toggleHandTool) {
+ toggleHandTool.addEventListener('click', this.handTool.toggle, false);
+ }
+ // TODO: Read global prefs and call this.handTool.activate() if needed.
+ },
+
+ toggle: function handToolToggle() {
+ this.handTool.toggle();
+ },
+
+ enterPresentationMode: function handToolEnterPresentationMode() {
+ if (this.handTool.active) {
+ this.wasActive = true;
+ this.handTool.deactivate();
+ }
+ },
+
+ exitPresentationMode: function handToolExitPresentationMode() {
+ if (this.wasActive) {
+ this.wasActive = null;
+ this.handTool.activate();
+ }
+ }
+};
+
+
+var PDFView = {
+ pages: [],
+ thumbnails: [],
+ currentScale: UNKNOWN_SCALE,
+ currentScaleValue: null,
+ initialBookmark: document.location.hash.substring(1),
+ container: null,
+ thumbnailContainer: null,
+ initialized: false,
+ fellback: false,
+ pdfDocument: null,
+ sidebarOpen: false,
+ pageViewScroll: null,
+ thumbnailViewScroll: null,
+ pageRotation: 0,
+ mouseScrollTimeStamp: 0,
+ mouseScrollDelta: 0,
+ lastScroll: 0,
+ previousPageNumber: 1,
+ isViewerEmbedded: (window.parent !== window),
+ idleTimeout: null,
+ currentPosition: null,
+
+ // called once when the document is loaded
+ initialize: function pdfViewInitialize() {
+ var self = this;
+ var container = this.container = document.getElementById('viewerContainer');
+ this.pageViewScroll = {};
+ this.watchScroll(container, this.pageViewScroll, updateViewarea);
+
+ var thumbnailContainer = this.thumbnailContainer =
+ document.getElementById('thumbnailView');
+ this.thumbnailViewScroll = {};
+ this.watchScroll(thumbnailContainer, this.thumbnailViewScroll,
+ this.renderHighestPriority.bind(this));
+
+ PDFFindBar.initialize({
+ bar: document.getElementById('findbar'),
+ toggleButton: document.getElementById('viewFind'),
+ findField: document.getElementById('findInput'),
+ highlightAllCheckbox: document.getElementById('findHighlightAll'),
+ caseSensitiveCheckbox: document.getElementById('findMatchCase'),
+ findMsg: document.getElementById('findMsg'),
+ findStatusIcon: document.getElementById('findStatusIcon'),
+ findPreviousButton: document.getElementById('findPrevious'),
+ findNextButton: document.getElementById('findNext')
+ });
+
+ PDFFindController.initialize({
+ pdfPageSource: this,
+ integratedFind: this.supportsIntegratedFind
+ });
+
+ HandTool.initialize({
+ container: container,
+ toggleHandTool: document.getElementById('toggleHandTool')
+ });
+
+ SecondaryToolbar.initialize({
+ toolbar: document.getElementById('secondaryToolbar'),
+ presentationMode: PresentationMode,
+ toggleButton: document.getElementById('secondaryToolbarToggle'),
+ presentationModeButton:
+ document.getElementById('secondaryPresentationMode'),
+ openFile: document.getElementById('secondaryOpenFile'),
+ print: document.getElementById('secondaryPrint'),
+ download: document.getElementById('secondaryDownload'),
+ firstPage: document.getElementById('firstPage'),
+ lastPage: document.getElementById('lastPage'),
+ pageRotateCw: document.getElementById('pageRotateCw'),
+ pageRotateCcw: document.getElementById('pageRotateCcw')
+ });
+
+ PasswordPrompt.initialize({
+ overlayContainer: document.getElementById('overlayContainer'),
+ passwordField: document.getElementById('password'),
+ passwordText: document.getElementById('passwordText'),
+ passwordSubmit: document.getElementById('passwordSubmit'),
+ passwordCancel: document.getElementById('passwordCancel')
+ });
+
+ PresentationMode.initialize({
+ container: container,
+ secondaryToolbar: SecondaryToolbar,
+ firstPage: document.getElementById('contextFirstPage'),
+ lastPage: document.getElementById('contextLastPage'),
+ pageRotateCw: document.getElementById('contextPageRotateCw'),
+ pageRotateCcw: document.getElementById('contextPageRotateCcw')
+ });
+
+ this.initialized = true;
+ container.addEventListener('scroll', function() {
+ self.lastScroll = Date.now();
+ }, false);
+ },
+
+ getPage: function pdfViewGetPage(n) {
+ return this.pdfDocument.getPage(n);
+ },
+
+ // Helper function to keep track whether a div was scrolled up or down and
+ // then call a callback.
+ watchScroll: function pdfViewWatchScroll(viewAreaElement, state, callback) {
+ state.down = true;
+ state.lastY = viewAreaElement.scrollTop;
+ viewAreaElement.addEventListener('scroll', function webViewerScroll(evt) {
+ var currentY = viewAreaElement.scrollTop;
+ var lastY = state.lastY;
+ if (currentY > lastY)
+ state.down = true;
+ else if (currentY < lastY)
+ state.down = false;
+ // else do nothing and use previous value
+ state.lastY = currentY;
+ callback();
+ }, true);
+ },
+
+ _setScaleUpdatePages: function pdfView_setScaleUpdatePages(
+ newScale, newValue, resetAutoSettings, noScroll) {
+ this.currentScaleValue = newValue;
+ if (newScale === this.currentScale) {
+ return;
+ }
+ for (var i = 0, ii = this.pages.length; i < ii; i++) {
+ this.pages[i].update(newScale);
+ }
+ this.currentScale = newScale;
+
+ if (!noScroll) {
+ var page = this.page, dest;
+ if (this.currentPosition && !IGNORE_CURRENT_POSITION_ON_ZOOM) {
+ page = this.currentPosition.page;
+ dest = [null, { name: 'XYZ' }, this.currentPosition.left,
+ this.currentPosition.top, null];
+ }
+ this.pages[page - 1].scrollIntoView(dest);
+ }
+ var event = document.createEvent('UIEvents');
+ event.initUIEvent('scalechange', false, false, window, 0);
+ event.scale = newScale;
+ event.resetAutoSettings = resetAutoSettings;
+ window.dispatchEvent(event);
+ },
+
+ setScale: function pdfViewSetScale(value, resetAutoSettings, noScroll) {
+ if (value === 'custom') {
+ return;
+ }
+ var scale = parseFloat(value);
+
+ if (scale > 0) {
+ this._setScaleUpdatePages(scale, value, true, noScroll);
+ } else {
+ var currentPage = this.pages[this.page - 1];
+ if (!currentPage) {
+ return;
+ }
+ var pageWidthScale = (this.container.clientWidth - SCROLLBAR_PADDING) /
+ currentPage.width * currentPage.scale;
+ var pageHeightScale = (this.container.clientHeight - VERTICAL_PADDING) /
+ currentPage.height * currentPage.scale;
+ switch (value) {
+ case 'page-actual':
+ scale = 1;
+ break;
+ case 'page-width':
+ scale = pageWidthScale;
+ break;
+ case 'page-height':
+ scale = pageHeightScale;
+ break;
+ case 'page-fit':
+ scale = Math.min(pageWidthScale, pageHeightScale);
+ break;
+ case 'auto':
+ scale = Math.min(MAX_AUTO_SCALE, pageWidthScale);
+ break;
+ default:
+ console.error('pdfViewSetScale: \'' + value +
+ '\' is an unknown zoom value.');
+ return;
+ }
+ this._setScaleUpdatePages(scale, value, resetAutoSettings, noScroll);
+
+ selectScaleOption(value);
+ }
+ },
+
+ zoomIn: function pdfViewZoomIn(ticks) {
+ var newScale = this.currentScale;
+ do {
+ newScale = (newScale * DEFAULT_SCALE_DELTA).toFixed(2);
+ newScale = Math.ceil(newScale * 10) / 10;
+ newScale = Math.min(MAX_SCALE, newScale);
+ } while (--ticks && newScale < MAX_SCALE);
+ this.setScale(newScale, true);
+ },
+
+ zoomOut: function pdfViewZoomOut(ticks) {
+ var newScale = this.currentScale;
+ do {
+ newScale = (newScale / DEFAULT_SCALE_DELTA).toFixed(2);
+ newScale = Math.floor(newScale * 10) / 10;
+ newScale = Math.max(MIN_SCALE, newScale);
+ } while (--ticks && newScale > MIN_SCALE);
+ this.setScale(newScale, true);
+ },
+
+ set page(val) {
+ var pages = this.pages;
+ var event = document.createEvent('UIEvents');
+ event.initUIEvent('pagechange', false, false, window, 0);
+
+ if (!(0 < val && val <= pages.length)) {
+ this.previousPageNumber = val;
+ event.pageNumber = this.page;
+ window.dispatchEvent(event);
+ return;
+ }
+
+ pages[val - 1].updateStats();
+ this.previousPageNumber = currentPageNumber;
+ currentPageNumber = val;
+ event.pageNumber = val;
+ window.dispatchEvent(event);
+
+ // checking if the this.page was called from the updateViewarea function:
+ // avoiding the creation of two "set page" method (internal and public)
+ if (updateViewarea.inProgress) {
+ return;
+ }
+ // Avoid scrolling the first page during loading
+ if (this.loading && val === 1) {
+ return;
+ }
+ pages[val - 1].scrollIntoView();
+ },
+
+ get page() {
+ return currentPageNumber;
+ },
+
+ get supportsPrinting() {
+ var canvas = document.createElement('canvas');
+ var value = 'mozPrintCallback' in canvas;
+ // shadow
+ Object.defineProperty(this, 'supportsPrinting', { value: value,
+ enumerable: true,
+ configurable: true,
+ writable: false });
+ return value;
+ },
+
+ get supportsFullscreen() {
+ var doc = document.documentElement;
+ var support = doc.requestFullscreen || doc.mozRequestFullScreen ||
+ doc.webkitRequestFullScreen || doc.msRequestFullscreen;
+
+ if (document.fullscreenEnabled === false ||
+ document.mozFullScreenEnabled === false ||
+ document.webkitFullscreenEnabled === false ||
+ document.msFullscreenEnabled === false) {
+ support = false;
+ } else if (this.isViewerEmbedded) {
+ // Need to check if the viewer is embedded as well, to prevent issues with
+ // presentation mode when the viewer is embedded in '<object>' tags.
+ support = false;
+ }
+
+ Object.defineProperty(this, 'supportsFullscreen', { value: support,
+ enumerable: true,
+ configurable: true,
+ writable: false });
+ return support;
+ },
+
+ get supportsIntegratedFind() {
+ var support = false;
+ Object.defineProperty(this, 'supportsIntegratedFind', { value: support,
+ enumerable: true,
+ configurable: true,
+ writable: false });
+ return support;
+ },
+
+ get supportsDocumentFonts() {
+ var support = true;
+ Object.defineProperty(this, 'supportsDocumentFonts', { value: support,
+ enumerable: true,
+ configurable: true,
+ writable: false });
+ return support;
+ },
+
+ get supportsDocumentColors() {
+ var support = true;
+ Object.defineProperty(this, 'supportsDocumentColors', { value: support,
+ enumerable: true,
+ configurable: true,
+ writable: false });
+ return support;
+ },
+
+ get loadingBar() {
+ var bar = new ProgressBar('#loadingBar', {});
+ Object.defineProperty(this, 'loadingBar', { value: bar,
+ enumerable: true,
+ configurable: true,
+ writable: false });
+ return bar;
+ },
+
+ get isHorizontalScrollbarEnabled() {
+ return (PresentationMode.active ? false :
+ (this.container.scrollWidth > this.container.clientWidth));
+ },
+
+ initPassiveLoading: function pdfViewInitPassiveLoading() {
+ var pdfDataRangeTransport = {
+ rangeListeners: [],
+ progressListeners: [],
+
+ addRangeListener: function PdfDataRangeTransport_addRangeListener(
+ listener) {
+ this.rangeListeners.push(listener);
+ },
+
+ addProgressListener: function PdfDataRangeTransport_addProgressListener(
+ listener) {
+ this.progressListeners.push(listener);
+ },
+
+ onDataRange: function PdfDataRangeTransport_onDataRange(begin, chunk) {
+ var listeners = this.rangeListeners;
+ for (var i = 0, n = listeners.length; i < n; ++i) {
+ listeners[i](begin, chunk);
+ }
+ },
+
+ onDataProgress: function PdfDataRangeTransport_onDataProgress(loaded) {
+ var listeners = this.progressListeners;
+ for (var i = 0, n = listeners.length; i < n; ++i) {
+ listeners[i](loaded);
+ }
+ },
+
+ requestDataRange: function PdfDataRangeTransport_requestDataRange(
+ begin, end) {
+ FirefoxCom.request('requestDataRange', { begin: begin, end: end });
+ }
+ };
+
+ window.addEventListener('message', function windowMessage(e) {
+ var args = e.data;
+
+ if (typeof args !== 'object' || !('pdfjsLoadAction' in args))
+ return;
+ switch (args.pdfjsLoadAction) {
+ case 'supportsRangedLoading':
+ PDFView.open(args.pdfUrl, 0, undefined, pdfDataRangeTransport, {
+ length: args.length,
+ initialData: args.data
+ });
+ break;
+ case 'range':
+ pdfDataRangeTransport.onDataRange(args.begin, args.chunk);
+ break;
+ case 'rangeProgress':
+ pdfDataRangeTransport.onDataProgress(args.loaded);
+ break;
+ case 'progress':
+ PDFView.progress(args.loaded / args.total);
+ break;
+ case 'complete':
+ if (!args.data) {
+ PDFView.error(mozL10n.get('loading_error', null,
+ 'An error occurred while loading the PDF.'), e);
+ break;
+ }
+ PDFView.open(args.data, 0);
+ break;
+ }
+ });
+ FirefoxCom.requestSync('initPassiveLoading', null);
+ },
+
+ setTitleUsingUrl: function pdfViewSetTitleUsingUrl(url) {
+ this.url = url;
+ try {
+ this.setTitle(decodeURIComponent(getFileName(url)) || url);
+ } catch (e) {
+ // decodeURIComponent may throw URIError,
+ // fall back to using the unprocessed url in that case
+ this.setTitle(url);
+ }
+ },
+
+ setTitle: function pdfViewSetTitle(title) {
+ document.title = title;
+ },
+
+ // TODO(mack): This function signature should really be pdfViewOpen(url, args)
+ open: function pdfViewOpen(url, scale, password,
+ pdfDataRangeTransport, args) {
+ var parameters = {password: password};
+ if (typeof url === 'string') { // URL
+ this.setTitleUsingUrl(url);
+ parameters.url = url;
+ } else if (url && 'byteLength' in url) { // ArrayBuffer
+ parameters.data = url;
+ }
+ if (args) {
+ for (var prop in args) {
+ parameters[prop] = args[prop];
+ }
+ }
+
+ this.pdfDocument = null;
+ var self = this;
+ self.loading = true;
+ var passwordNeeded = function passwordNeeded(updatePassword, reason) {
+ PasswordPrompt.updatePassword = updatePassword;
+ PasswordPrompt.reason = reason;
+ PasswordPrompt.show();
+ };
+
+ function getDocumentProgress(progressData) {
+ self.progress(progressData.loaded / progressData.total);
+ }
+
+ PDFJS.getDocument(parameters, pdfDataRangeTransport, passwordNeeded,
+ getDocumentProgress).then(
+ function getDocumentCallback(pdfDocument) {
+ self.load(pdfDocument, scale);
+ self.loading = false;
+ },
+ function getDocumentError(message, exception) {
+ var loadingErrorMessage = mozL10n.get('loading_error', null,
+ 'An error occurred while loading the PDF.');
+
+ if (exception && exception.name === 'InvalidPDFException') {
+ // change error message also for other builds
+ var loadingErrorMessage = mozL10n.get('invalid_file_error', null,
+ 'Invalid or corrupted PDF file.');
+ }
+
+ if (exception && exception.name === 'MissingPDFException') {
+ // special message for missing PDF's
+ var loadingErrorMessage = mozL10n.get('missing_file_error', null,
+ 'Missing PDF file.');
+
+ }
+
+ var moreInfo = {
+ message: message
+ };
+ self.error(loadingErrorMessage, moreInfo);
+ self.loading = false;
+ }
+ );
+ },
+
+ download: function pdfViewDownload() {
+ function noData() {
+ downloadManager.downloadUrl(url, filename);
+ }
+
+ var url = this.url.split('#')[0];
+ var filename = getPDFFileNameFromURL(url);
+ var downloadManager = new DownloadManager();
+ downloadManager.onerror = function (err) {
+ // This error won't really be helpful because it's likely the
+ // fallback won't work either (or is already open).
+ PDFView.error('PDF failed to download.');
+ };
+
+ if (!this.pdfDocument) { // the PDF is not ready yet
+ noData();
+ return;
+ }
+
+ this.pdfDocument.getData().then(
+ function getDataSuccess(data) {
+ var blob = PDFJS.createBlob(data, 'application/pdf');
+ downloadManager.download(blob, url, filename);
+ },
+ noData // Error occurred try downloading with just the url.
+ ).then(null, noData);
+ },
+
+ fallback: function pdfViewFallback(featureId) {
+ return;
+ },
+
+ navigateTo: function pdfViewNavigateTo(dest) {
+ var destString = '';
+ var self = this;
+
+ var goToDestination = function(destRef) {
+ self.pendingRefStr = null;
+ // dest array looks like that: <page-ref> </XYZ|FitXXX> <args..>
+ var pageNumber = destRef instanceof Object ?
+ self.pagesRefMap[destRef.num + ' ' + destRef.gen + ' R'] :
+ (destRef + 1);
+ if (pageNumber) {
+ if (pageNumber > self.pages.length) {
+ pageNumber = self.pages.length;
+ }
+ var currentPage = self.pages[pageNumber - 1];
+ currentPage.scrollIntoView(dest);
+
+ // Update the browsing history.
+ PDFHistory.push({ dest: dest, hash: destString, page: pageNumber });
+ } else {
+ self.pdfDocument.getPageIndex(destRef).then(function (pageIndex) {
+ var pageNum = pageIndex + 1;
+ self.pagesRefMap[destRef.num + ' ' + destRef.gen + ' R'] = pageNum;
+ goToDestination(destRef);
+ });
+ }
+ };
+
+ this.destinationsPromise.then(function() {
+ if (typeof dest === 'string') {
+ destString = dest;
+ dest = self.destinations[dest];
+ }
+ if (!(dest instanceof Array)) {
+ return; // invalid destination
+ }
+ goToDestination(dest[0]);
+ });
+ },
+
+ getDestinationHash: function pdfViewGetDestinationHash(dest) {
+ if (typeof dest === 'string')
+ return PDFView.getAnchorUrl('#' + escape(dest));
+ if (dest instanceof Array) {
+ var destRef = dest[0]; // see navigateTo method for dest format
+ var pageNumber = destRef instanceof Object ?
+ this.pagesRefMap[destRef.num + ' ' + destRef.gen + ' R'] :
+ (destRef + 1);
+ if (pageNumber) {
+ var pdfOpenParams = PDFView.getAnchorUrl('#page=' + pageNumber);
+ var destKind = dest[1];
+ if (typeof destKind === 'object' && 'name' in destKind &&
+ destKind.name == 'XYZ') {
+ var scale = (dest[4] || this.currentScaleValue);
+ var scaleNumber = parseFloat(scale);
+ if (scaleNumber) {
+ scale = scaleNumber * 100;
+ }
+ pdfOpenParams += '&zoom=' + scale;
+ if (dest[2] || dest[3]) {
+ pdfOpenParams += ',' + (dest[2] || 0) + ',' + (dest[3] || 0);
+ }
+ }
+ return pdfOpenParams;
+ }
+ }
+ return '';
+ },
+
+ /**
+ * Prefix the full url on anchor links to make sure that links are resolved
+ * relative to the current URL instead of the one defined in <base href>.
+ * @param {String} anchor The anchor hash, including the #.
+ */
+ getAnchorUrl: function getAnchorUrl(anchor) {
+ return anchor;
+ },
+
+ /**
+ * Show the error box.
+ * @param {String} message A message that is human readable.
+ * @param {Object} moreInfo (optional) Further information about the error
+ * that is more technical. Should have a 'message'
+ * and optionally a 'stack' property.
+ */
+ error: function pdfViewError(message, moreInfo) {
+ var moreInfoText = mozL10n.get('error_version_info',
+ {version: PDFJS.version || '?', build: PDFJS.build || '?'},
+ 'PDF.js v{{version}} (build: {{build}})') + '\n';
+ if (moreInfo) {
+ moreInfoText +=
+ mozL10n.get('error_message', {message: moreInfo.message},
+ 'Message: {{message}}');
+ if (moreInfo.stack) {
+ moreInfoText += '\n' +
+ mozL10n.get('error_stack', {stack: moreInfo.stack},
+ 'Stack: {{stack}}');
+ } else {
+ if (moreInfo.filename) {
+ moreInfoText += '\n' +
+ mozL10n.get('error_file', {file: moreInfo.filename},
+ 'File: {{file}}');
+ }
+ if (moreInfo.lineNumber) {
+ moreInfoText += '\n' +
+ mozL10n.get('error_line', {line: moreInfo.lineNumber},
+ 'Line: {{line}}');
+ }
+ }
+ }
+
+ var errorWrapper = document.getElementById('errorWrapper');
+ errorWrapper.removeAttribute('hidden');
+
+ var errorMessage = document.getElementById('errorMessage');
+ errorMessage.textContent = message;
+
+ var closeButton = document.getElementById('errorClose');
+ closeButton.onclick = function() {
+ errorWrapper.setAttribute('hidden', 'true');
+ };
+
+ var errorMoreInfo = document.getElementById('errorMoreInfo');
+ var moreInfoButton = document.getElementById('errorShowMore');
+ var lessInfoButton = document.getElementById('errorShowLess');
+ moreInfoButton.onclick = function() {
+ errorMoreInfo.removeAttribute('hidden');
+ moreInfoButton.setAttribute('hidden', 'true');
+ lessInfoButton.removeAttribute('hidden');
+ errorMoreInfo.style.height = errorMoreInfo.scrollHeight + 'px';
+ };
+ lessInfoButton.onclick = function() {
+ errorMoreInfo.setAttribute('hidden', 'true');
+ moreInfoButton.removeAttribute('hidden');
+ lessInfoButton.setAttribute('hidden', 'true');
+ };
+ moreInfoButton.oncontextmenu = noContextMenuHandler;
+ lessInfoButton.oncontextmenu = noContextMenuHandler;
+ closeButton.oncontextmenu = noContextMenuHandler;
+ moreInfoButton.removeAttribute('hidden');
+ lessInfoButton.setAttribute('hidden', 'true');
+ errorMoreInfo.value = moreInfoText;
+ },
+
+ progress: function pdfViewProgress(level) {
+ var percent = Math.round(level * 100);
+ // When we transition from full request to range requests, it's possible
+ // that we discard some of the loaded data. This can cause the loading
+ // bar to move backwards. So prevent this by only updating the bar if it
+ // increases.
+ if (percent > PDFView.loadingBar.percent) {
+ PDFView.loadingBar.percent = percent;
+ }
+ },
+
+ load: function pdfViewLoad(pdfDocument, scale) {
+ var self = this;
+ var isOnePageRenderedResolved = false;
+ var resolveOnePageRendered = null;
+ var onePageRendered = new Promise(function (resolve) {
+ resolveOnePageRendered = resolve;
+ });
+ function bindOnAfterDraw(pageView, thumbnailView) {
+ // when page is painted, using the image as thumbnail base
+ pageView.onAfterDraw = function pdfViewLoadOnAfterDraw() {
+ if (!isOnePageRenderedResolved) {
+ isOnePageRenderedResolved = true;
+ resolveOnePageRendered();
+ }
+ thumbnailView.setImage(pageView.canvas);
+ };
+ }
+
+ PDFFindController.reset();
+
+ this.pdfDocument = pdfDocument;
+
+ var errorWrapper = document.getElementById('errorWrapper');
+ errorWrapper.setAttribute('hidden', 'true');
+
+ pdfDocument.dataLoaded().then(function() {
+ PDFView.loadingBar.hide();
+ var outerContainer = document.getElementById('outerContainer');
+ outerContainer.classList.remove('loadingInProgress');
+ });
+
+ var thumbsView = document.getElementById('thumbnailView');
+ thumbsView.parentNode.scrollTop = 0;
+
+ while (thumbsView.hasChildNodes())
+ thumbsView.removeChild(thumbsView.lastChild);
+
+ if ('_loadingInterval' in thumbsView)
+ clearInterval(thumbsView._loadingInterval);
+
+ var container = document.getElementById('viewer');
+ while (container.hasChildNodes())
+ container.removeChild(container.lastChild);
+
+ var pagesCount = pdfDocument.numPages;
+
+ var id = pdfDocument.fingerprint;
+ document.getElementById('numPages').textContent =
+ mozL10n.get('page_of', {pageCount: pagesCount}, 'of {{pageCount}}');
+ document.getElementById('pageNumber').max = pagesCount;
+
+ var prefs = PDFView.prefs = new Preferences();
+ PDFView.documentFingerprint = id;
+ var store = PDFView.store = new ViewHistory(id);
+
+ this.pageRotation = 0;
+
+ var pages = this.pages = [];
+ var pagesRefMap = this.pagesRefMap = {};
+ var thumbnails = this.thumbnails = [];
+
+ var resolvePagesPromise;
+ var pagesPromise = new Promise(function (resolve) {
+ resolvePagesPromise = resolve;
+ });
+ this.pagesPromise = pagesPromise;
+
+ var firstPagePromise = pdfDocument.getPage(1);
+
+ // Fetch a single page so we can get a viewport that will be the default
+ // viewport for all pages
+ firstPagePromise.then(function(pdfPage) {
+ var viewport = pdfPage.getViewport((scale || 1.0) * CSS_UNITS);
+ for (var pageNum = 1; pageNum <= pagesCount; ++pageNum) {
+ var viewportClone = viewport.clone();
+ var pageView = new PageView(container, pageNum, scale,
+ self.navigateTo.bind(self),
+ viewportClone);
+ var thumbnailView = new ThumbnailView(thumbsView, pageNum,
+ viewportClone);
+ bindOnAfterDraw(pageView, thumbnailView);
+ pages.push(pageView);
+ thumbnails.push(thumbnailView);
+ }
+
+ // Fetch all the pages since the viewport is needed before printing
+ // starts to create the correct size canvas. Wait until one page is
+ // rendered so we don't tie up too many resources early on.
+ onePageRendered.then(function () {
+ if (!PDFJS.disableAutoFetch) {
+ var getPagesLeft = pagesCount;
+ for (var pageNum = 1; pageNum <= pagesCount; ++pageNum) {
+ pdfDocument.getPage(pageNum).then(function (pageNum, pdfPage) {
+ var pageView = pages[pageNum - 1];
+ if (!pageView.pdfPage) {
+ pageView.setPdfPage(pdfPage);
+ }
+ var refStr = pdfPage.ref.num + ' ' + pdfPage.ref.gen + ' R';
+ pagesRefMap[refStr] = pageNum;
+ getPagesLeft--;
+ if (!getPagesLeft) {
+ resolvePagesPromise();
+ }
+ }.bind(null, pageNum));
+ }
+ } else {
+ // XXX: Printing is semi-broken with auto fetch disabled.
+ resolvePagesPromise();
+ }
+ });
+
+ var event = document.createEvent('CustomEvent');
+ event.initCustomEvent('documentload', true, true, {});
+ window.dispatchEvent(event);
+
+ PDFView.loadingBar.setWidth(container);
+
+ PDFFindController.resolveFirstPage();
+ });
+
+ var prefsPromise = prefs.initializedPromise;
+ var storePromise = store.initializedPromise;
+ Promise.all([firstPagePromise, prefsPromise, storePromise]).
+ then(function() {
+ var showPreviousViewOnLoad = prefs.get('showPreviousViewOnLoad');
+ var defaultZoomValue = prefs.get('defaultZoomValue');
+
+ var storedHash = null;
+ if (showPreviousViewOnLoad && store.get('exists', false)) {
+ var pageNum = store.get('page', '1');
+ var zoom = defaultZoomValue || store.get('zoom', PDFView.currentScale);
+ var left = store.get('scrollLeft', '0');
+ var top = store.get('scrollTop', '0');
+
+ storedHash = 'page=' + pageNum + '&zoom=' + zoom + ',' +
+ left + ',' + top;
+ } else if (defaultZoomValue) {
+ storedHash = 'page=1&zoom=' + defaultZoomValue;
+ }
+ // Initialize the browsing history.
+ PDFHistory.initialize(self.documentFingerprint);
+
+ self.setInitialView(storedHash, scale);
+
+ // Make all navigation keys work on document load,
+ // unless the viewer is embedded in a web page.
+ if (!self.isViewerEmbedded) {
+ self.container.focus();
+ }
+ });
+
+ pagesPromise.then(function() {
+ if (PDFView.supportsPrinting) {
+ pdfDocument.getJavaScript().then(function(javaScript) {
+ if (javaScript.length) {
+ console.warn('Warning: JavaScript is not supported');
+ PDFView.fallback(PDFJS.UNSUPPORTED_FEATURES.javaScript);
+ }
+ // Hack to support auto printing.
+ var regex = /\bprint\s*\(/g;
+ for (var i = 0, ii = javaScript.length; i < ii; i++) {
+ var js = javaScript[i];
+ if (js && regex.test(js)) {
+ setTimeout(function() {
+ window.print();
+ });
+ return;
+ }
+ }
+ });
+ }
+ });
+
+ var destinationsPromise =
+ this.destinationsPromise = pdfDocument.getDestinations();
+ destinationsPromise.then(function(destinations) {
+ self.destinations = destinations;
+ });
+
+ // outline depends on destinations and pagesRefMap
+ var promises = [pagesPromise, destinationsPromise,
+ PDFView.animationStartedPromise];
+ Promise.all(promises).then(function() {
+ pdfDocument.getOutline().then(function(outline) {
+ self.outline = new DocumentOutlineView(outline);
+ document.getElementById('viewOutline').disabled = !outline;
+
+ if (outline && prefs.get('ifAvailableShowOutlineOnLoad')) {
+ if (!self.sidebarOpen) {
+ document.getElementById('sidebarToggle').click();
+ }
+ self.switchSidebarView('outline');
+ }
+ });
+ });
+
+ pdfDocument.getMetadata().then(function(data) {
+ var info = data.info, metadata = data.metadata;
+ self.documentInfo = info;
+ self.metadata = metadata;
+
+ // Provides some basic debug information
+ console.log('PDF ' + pdfDocument.fingerprint + ' [' +
+ info.PDFFormatVersion + ' ' + (info.Producer || '-') +
+ ' / ' + (info.Creator || '-') + ']' +
+ (PDFJS.version ? ' (PDF.js: ' + PDFJS.version + ')' : ''));
+
+ var pdfTitle;
+ if (metadata) {
+ if (metadata.has('dc:title'))
+ pdfTitle = metadata.get('dc:title');
+ }
+
+ if (!pdfTitle && info && info['Title'])
+ pdfTitle = info['Title'];
+
+ if (pdfTitle)
+ self.setTitle(pdfTitle + ' - ' + document.title);
+
+ if (info.IsAcroFormPresent) {
+ console.warn('Warning: AcroForm/XFA is not supported');
+ PDFView.fallback(PDFJS.UNSUPPORTED_FEATURES.forms);
+ }
+
+ });
+ },
+
+ setInitialView: function pdfViewSetInitialView(storedHash, scale) {
+ // Reset the current scale, as otherwise the page's scale might not get
+ // updated if the zoom level stayed the same.
+ this.currentScale = 0;
+ this.currentScaleValue = null;
+ // When opening a new file (when one is already loaded in the viewer):
+ // Reset 'currentPageNumber', since otherwise the page's scale will be wrong
+ // if 'currentPageNumber' is larger than the number of pages in the file.
+ document.getElementById('pageNumber').value = currentPageNumber = 1;
+ // Reset the current position when loading a new file,
+ // to prevent displaying the wrong position in the document.
+ this.currentPosition = null;
+
+ if (PDFHistory.initialDestination) {
+ this.navigateTo(PDFHistory.initialDestination);
+ PDFHistory.initialDestination = null;
+ } else if (this.initialBookmark) {
+ this.setHash(this.initialBookmark);
+ PDFHistory.push({ hash: this.initialBookmark }, !!this.initialBookmark);
+ this.initialBookmark = null;
+ } else if (storedHash) {
+ this.setHash(storedHash);
+ } else if (scale) {
+ this.setScale(scale, true);
+ this.page = 1;
+ }
+
+ if (PDFView.currentScale === UNKNOWN_SCALE) {
+ // Scale was not initialized: invalid bookmark or scale was not specified.
+ // Setting the default one.
+ this.setScale(DEFAULT_SCALE, true);
+ }
+ },
+
+ renderHighestPriority: function pdfViewRenderHighestPriority() {
+ if (PDFView.idleTimeout) {
+ clearTimeout(PDFView.idleTimeout);
+ PDFView.idleTimeout = null;
+ }
+
+ // Pages have a higher priority than thumbnails, so check them first.
+ var visiblePages = this.getVisiblePages();
+ var pageView = this.getHighestPriority(visiblePages, this.pages,
+ this.pageViewScroll.down);
+ if (pageView) {
+ this.renderView(pageView, 'page');
+ return;
+ }
+ // No pages needed rendering so check thumbnails.
+ if (this.sidebarOpen) {
+ var visibleThumbs = this.getVisibleThumbs();
+ var thumbView = this.getHighestPriority(visibleThumbs,
+ this.thumbnails,
+ this.thumbnailViewScroll.down);
+ if (thumbView) {
+ this.renderView(thumbView, 'thumbnail');
+ return;
+ }
+ }
+
+ PDFView.idleTimeout = setTimeout(function () {
+ PDFView.cleanup();
+ }, CLEANUP_TIMEOUT);
+ },
+
+ cleanup: function pdfViewCleanup() {
+ for (var i = 0, ii = this.pages.length; i < ii; i++) {
+ if (this.pages[i] &&
+ this.pages[i].renderingState !== RenderingStates.FINISHED) {
+ this.pages[i].reset();
+ }
+ }
+ this.pdfDocument.cleanup();
+ },
+
+ getHighestPriority: function pdfViewGetHighestPriority(visible, views,
+ scrolledDown) {
+ // The state has changed figure out which page has the highest priority to
+ // render next (if any).
+ // Priority:
+ // 1 visible pages
+ // 2 if last scrolled down page after the visible pages
+ // 2 if last scrolled up page before the visible pages
+ var visibleViews = visible.views;
+
+ var numVisible = visibleViews.length;
+ if (numVisible === 0) {
+ return false;
+ }
+ for (var i = 0; i < numVisible; ++i) {
+ var view = visibleViews[i].view;
+ if (!this.isViewFinished(view))
+ return view;
+ }
+
+ // All the visible views have rendered, try to render next/previous pages.
+ if (scrolledDown) {
+ var nextPageIndex = visible.last.id;
+ // ID's start at 1 so no need to add 1.
+ if (views[nextPageIndex] && !this.isViewFinished(views[nextPageIndex]))
+ return views[nextPageIndex];
+ } else {
+ var previousPageIndex = visible.first.id - 2;
+ if (views[previousPageIndex] &&
+ !this.isViewFinished(views[previousPageIndex]))
+ return views[previousPageIndex];
+ }
+ // Everything that needs to be rendered has been.
+ return false;
+ },
+
+ isViewFinished: function pdfViewIsViewFinished(view) {
+ return view.renderingState === RenderingStates.FINISHED;
+ },
+
+ // Render a page or thumbnail view. This calls the appropriate function based
+ // on the views state. If the view is already rendered it will return false.
+ renderView: function pdfViewRender(view, type) {
+ var state = view.renderingState;
+ switch (state) {
+ case RenderingStates.FINISHED:
+ return false;
+ case RenderingStates.PAUSED:
+ PDFView.highestPriorityPage = type + view.id;
+ view.resume();
+ break;
+ case RenderingStates.RUNNING:
+ PDFView.highestPriorityPage = type + view.id;
+ break;
+ case RenderingStates.INITIAL:
+ PDFView.highestPriorityPage = type + view.id;
+ view.draw(this.renderHighestPriority.bind(this));
+ break;
+ }
+ return true;
+ },
+
+ setHash: function pdfViewSetHash(hash) {
+ if (!hash)
+ return;
+
+ if (hash.indexOf('=') >= 0) {
+ var params = PDFView.parseQueryString(hash);
+ // borrowing syntax from "Parameters for Opening PDF Files"
+ if ('nameddest' in params) {
+ PDFHistory.updateNextHashParam(params.nameddest);
+ PDFView.navigateTo(params.nameddest);
+ return;
+ }
+ var pageNumber, dest;
+ if ('page' in params) {
+ pageNumber = (params.page | 0) || 1;
+ }
+ if ('zoom' in params) {
+ var zoomArgs = params.zoom.split(','); // scale,left,top
+ // building destination array
+
+ // If the zoom value, it has to get divided by 100. If it is a string,
+ // it should stay as it is.
+ var zoomArg = zoomArgs[0];
+ var zoomArgNumber = parseFloat(zoomArg);
+ if (zoomArgNumber) {
+ zoomArg = zoomArgNumber / 100;
+ }
+ dest = [null, {name: 'XYZ'},
+ zoomArgs.length > 1 ? (zoomArgs[1] | 0) : null,
+ zoomArgs.length > 2 ? (zoomArgs[2] | 0) : null,
+ zoomArg];
+ }
+ if (dest) {
+ var currentPage = this.pages[(pageNumber || this.page) - 1];
+ currentPage.scrollIntoView(dest);
+ } else if (pageNumber) {
+ this.page = pageNumber; // simple page
+ }
+ if ('pagemode' in params) {
+ var toggle = document.getElementById('sidebarToggle');
+ if (params.pagemode === 'thumbs' || params.pagemode === 'bookmarks') {
+ if (!this.sidebarOpen) {
+ toggle.click();
+ }
+ this.switchSidebarView(params.pagemode === 'thumbs' ?
+ 'thumbs' : 'outline');
+ } else if (params.pagemode === 'none' && this.sidebarOpen) {
+ toggle.click();
+ }
+ }
+ } else if (/^\d+$/.test(hash)) { // page number
+ this.page = hash;
+ } else { // named destination
+ PDFHistory.updateNextHashParam(unescape(hash));
+ PDFView.navigateTo(unescape(hash));
+ }
+ },
+
+ switchSidebarView: function pdfViewSwitchSidebarView(view) {
+ var thumbsView = document.getElementById('thumbnailView');
+ var outlineView = document.getElementById('outlineView');
+
+ var thumbsButton = document.getElementById('viewThumbnail');
+ var outlineButton = document.getElementById('viewOutline');
+
+ switch (view) {
+ case 'thumbs':
+ var wasOutlineViewVisible = thumbsView.classList.contains('hidden');
+
+ thumbsButton.classList.add('toggled');
+ outlineButton.classList.remove('toggled');
+ thumbsView.classList.remove('hidden');
+ outlineView.classList.add('hidden');
+
+ PDFView.renderHighestPriority();
+
+ if (wasOutlineViewVisible) {
+ // Ensure that the thumbnail of the current page is visible
+ // when switching from the outline view.
+ scrollIntoView(document.getElementById('thumbnailContainer' +
+ this.page));
+ }
+ break;
+
+ case 'outline':
+ thumbsButton.classList.remove('toggled');
+ outlineButton.classList.add('toggled');
+ thumbsView.classList.add('hidden');
+ outlineView.classList.remove('hidden');
+
+ if (outlineButton.getAttribute('disabled'))
+ return;
+ break;
+ }
+ },
+
+ getVisiblePages: function pdfViewGetVisiblePages() {
+ return this.getVisibleElements(this.container, this.pages,
+ !PresentationMode.active);
+ },
+
+ getVisibleThumbs: function pdfViewGetVisibleThumbs() {
+ return this.getVisibleElements(this.thumbnailContainer, this.thumbnails);
+ },
+
+ // Generic helper to find out what elements are visible within a scroll pane.
+ getVisibleElements: function pdfViewGetVisibleElements(
+ scrollEl, views, sortByVisibility) {
+ var top = scrollEl.scrollTop, bottom = top + scrollEl.clientHeight;
+ var left = scrollEl.scrollLeft, right = left + scrollEl.clientWidth;
+
+ var visible = [], view;
+ var currentHeight, viewHeight, hiddenHeight, percentHeight;
+ var currentWidth, viewWidth;
+ for (var i = 0, ii = views.length; i < ii; ++i) {
+ view = views[i];
+ currentHeight = view.el.offsetTop + view.el.clientTop;
+ viewHeight = view.el.clientHeight;
+ if ((currentHeight + viewHeight) < top) {
+ continue;
+ }
+ if (currentHeight > bottom) {
+ break;
+ }
+ currentWidth = view.el.offsetLeft + view.el.clientLeft;
+ viewWidth = view.el.clientWidth;
+ if ((currentWidth + viewWidth) < left || currentWidth > right) {
+ continue;
+ }
+ hiddenHeight = Math.max(0, top - currentHeight) +
+ Math.max(0, currentHeight + viewHeight - bottom);
+ percentHeight = ((viewHeight - hiddenHeight) * 100 / viewHeight) | 0;
+
+ visible.push({ id: view.id, x: currentWidth, y: currentHeight,
+ view: view, percent: percentHeight });
+ }
+
+ var first = visible[0];
+ var last = visible[visible.length - 1];
+
+ if (sortByVisibility) {
+ visible.sort(function(a, b) {
+ var pc = a.percent - b.percent;
+ if (Math.abs(pc) > 0.001) {
+ return -pc;
+ }
+ return a.id - b.id; // ensure stability
+ });
+ }
+ return {first: first, last: last, views: visible};
+ },
+
+ // Helper function to parse query string (e.g. ?param1=value&parm2=...).
+ parseQueryString: function pdfViewParseQueryString(query) {
+ var parts = query.split('&');
+ var params = {};
+ for (var i = 0, ii = parts.length; i < parts.length; ++i) {
+ var param = parts[i].split('=');
+ var key = param[0];
+ var value = param.length > 1 ? param[1] : null;
+ params[decodeURIComponent(key)] = decodeURIComponent(value);
+ }
+ return params;
+ },
+
+ beforePrint: function pdfViewSetupBeforePrint() {
+ if (!this.supportsPrinting) {
+ var printMessage = mozL10n.get('printing_not_supported', null,
+ 'Warning: Printing is not fully supported by this browser.');
+ this.error(printMessage);
+ return;
+ }
+
+ var alertNotReady = false;
+ if (!this.pages.length) {
+ alertNotReady = true;
+ } else {
+ for (var i = 0, ii = this.pages.length; i < ii; ++i) {
+ if (!this.pages[i].pdfPage) {
+ alertNotReady = true;
+ break;
+ }
+ }
+ }
+ if (alertNotReady) {
+ var notReadyMessage = mozL10n.get('printing_not_ready', null,
+ 'Warning: The PDF is not fully loaded for printing.');
+ window.alert(notReadyMessage);
+ return;
+ }
+
+ var body = document.querySelector('body');
+ body.setAttribute('data-mozPrintCallback', true);
+ for (var i = 0, ii = this.pages.length; i < ii; ++i) {
+ this.pages[i].beforePrint();
+ }
+ },
+
+ afterPrint: function pdfViewSetupAfterPrint() {
+ var div = document.getElementById('printContainer');
+ while (div.hasChildNodes())
+ div.removeChild(div.lastChild);
+ },
+
+ rotatePages: function pdfViewRotatePages(delta) {
+ var currentPage = this.pages[this.page - 1];
+ this.pageRotation = (this.pageRotation + 360 + delta) % 360;
+
+ for (var i = 0, l = this.pages.length; i < l; i++) {
+ var page = this.pages[i];
+ page.update(page.scale, this.pageRotation);
+ }
+
+ for (var i = 0, l = this.thumbnails.length; i < l; i++) {
+ var thumb = this.thumbnails[i];
+ thumb.update(this.pageRotation);
+ }
+
+ this.setScale(this.currentScaleValue, true, true);
+
+ this.renderHighestPriority();
+
+ if (currentPage) {
+ currentPage.scrollIntoView();
+ }
+ },
+
+ /**
+ * This function flips the page in presentation mode if the user scrolls up
+ * or down with large enough motion and prevents page flipping too often.
+ *
+ * @this {PDFView}
+ * @param {number} mouseScrollDelta The delta value from the mouse event.
+ */
+ mouseScroll: function pdfViewMouseScroll(mouseScrollDelta) {
+ var MOUSE_SCROLL_COOLDOWN_TIME = 50;
+
+ var currentTime = (new Date()).getTime();
+ var storedTime = this.mouseScrollTimeStamp;
+
+ // In case one page has already been flipped there is a cooldown time
+ // which has to expire before next page can be scrolled on to.
+ if (currentTime > storedTime &&
+ currentTime - storedTime < MOUSE_SCROLL_COOLDOWN_TIME)
+ return;
+
+ // In case the user decides to scroll to the opposite direction than before
+ // clear the accumulated delta.
+ if ((this.mouseScrollDelta > 0 && mouseScrollDelta < 0) ||
+ (this.mouseScrollDelta < 0 && mouseScrollDelta > 0))
+ this.clearMouseScrollState();
+
+ this.mouseScrollDelta += mouseScrollDelta;
+
+ var PAGE_FLIP_THRESHOLD = 120;
+ if (Math.abs(this.mouseScrollDelta) >= PAGE_FLIP_THRESHOLD) {
+
+ var PageFlipDirection = {
+ UP: -1,
+ DOWN: 1
+ };
+
+ // In presentation mode scroll one page at a time.
+ var pageFlipDirection = (this.mouseScrollDelta > 0) ?
+ PageFlipDirection.UP :
+ PageFlipDirection.DOWN;
+ this.clearMouseScrollState();
+ var currentPage = this.page;
+
+ // In case we are already on the first or the last page there is no need
+ // to do anything.
+ if ((currentPage == 1 && pageFlipDirection == PageFlipDirection.UP) ||
+ (currentPage == this.pages.length &&
+ pageFlipDirection == PageFlipDirection.DOWN))
+ return;
+
+ this.page += pageFlipDirection;
+ this.mouseScrollTimeStamp = currentTime;
+ }
+ },
+
+ /**
+ * This function clears the member attributes used with mouse scrolling in
+ * presentation mode.
+ *
+ * @this {PDFView}
+ */
+ clearMouseScrollState: function pdfViewClearMouseScrollState() {
+ this.mouseScrollTimeStamp = 0;
+ this.mouseScrollDelta = 0;
+ }
+};
+
+
+var PageView = function pageView(container, id, scale,
+ navigateTo, defaultViewport) {
+ this.id = id;
+
+ this.rotation = 0;
+ this.scale = scale || 1.0;
+ this.viewport = defaultViewport;
+ this.pdfPageRotate = defaultViewport.rotation;
+
+ this.renderingState = RenderingStates.INITIAL;
+ this.resume = null;
+
+ this.textLayer = null;
+
+ this.zoomLayer = null;
+
+ this.annotationLayer = null;
+
+ var anchor = document.createElement('a');
+ anchor.name = '' + this.id;
+
+ var div = this.el = document.createElement('div');
+ div.id = 'pageContainer' + this.id;
+ div.className = 'page';
+ div.style.width = Math.floor(this.viewport.width) + 'px';
+ div.style.height = Math.floor(this.viewport.height) + 'px';
+
+ container.appendChild(anchor);
+ container.appendChild(div);
+
+ this.setPdfPage = function pageViewSetPdfPage(pdfPage) {
+ this.pdfPage = pdfPage;
+ this.pdfPageRotate = pdfPage.rotate;
+ var totalRotation = (this.rotation + this.pdfPageRotate) % 360;
+ this.viewport = pdfPage.getViewport(this.scale * CSS_UNITS, totalRotation);
+ this.stats = pdfPage.stats;
+ this.reset();
+ };
+
+ this.destroy = function pageViewDestroy() {
+ this.zoomLayer = null;
+ this.reset();
+ if (this.pdfPage) {
+ this.pdfPage.destroy();
+ }
+ };
+
+ this.reset = function pageViewReset() {
+ if (this.renderTask) {
+ this.renderTask.cancel();
+ }
+ this.resume = null;
+ this.renderingState = RenderingStates.INITIAL;
+
+ div.style.width = Math.floor(this.viewport.width) + 'px';
+ div.style.height = Math.floor(this.viewport.height) + 'px';
+
+ var childNodes = div.childNodes;
+ for (var i = div.childNodes.length - 1; i >= 0; i--) {
+ var node = childNodes[i];
+ if (this.zoomLayer && this.zoomLayer === node) {
+ continue;
+ }
+ div.removeChild(node);
+ }
+ div.removeAttribute('data-loaded');
+
+ this.annotationLayer = null;
+
+ delete this.canvas;
+
+ this.loadingIconDiv = document.createElement('div');
+ this.loadingIconDiv.className = 'loadingIcon';
+ div.appendChild(this.loadingIconDiv);
+ };
+
+ this.update = function pageViewUpdate(scale, rotation) {
+ this.scale = scale || this.scale;
+
+ if (typeof rotation !== 'undefined') {
+ this.rotation = rotation;
+ }
+
+ var totalRotation = (this.rotation + this.pdfPageRotate) % 360;
+ this.viewport = this.viewport.clone({
+ scale: this.scale * CSS_UNITS,
+ rotation: totalRotation
+ });
+
+ if (USE_ONLY_CSS_ZOOM && this.canvas) {
+ this.cssTransform(this.canvas);
+ return;
+ } else if (this.canvas && !this.zoomLayer) {
+ this.zoomLayer = this.canvas.parentNode;
+ this.zoomLayer.style.position = 'absolute';
+ }
+ if (this.zoomLayer) {
+ this.cssTransform(this.zoomLayer.firstChild);
+ }
+ this.reset();
+ };
+
+ this.cssTransform = function pageCssTransform(canvas) {
+ // Scale canvas, canvas wrapper, and page container.
+ var width = this.viewport.width;
+ var height = this.viewport.height;
+ canvas.style.width = canvas.parentNode.style.width = div.style.width =
+ Math.floor(width) + 'px';
+ canvas.style.height = canvas.parentNode.style.height = div.style.height =
+ Math.floor(height) + 'px';
+ // The canvas may have been originally rotated, so rotate relative to that.
+ var relativeRotation = this.viewport.rotation - canvas._viewport.rotation;
+ var absRotation = Math.abs(relativeRotation);
+ var scaleX = 1, scaleY = 1;
+ if (absRotation === 90 || absRotation === 270) {
+ // Scale x and y because of the rotation.
+ scaleX = height / width;
+ scaleY = width / height;
+ }
+ var cssTransform = 'rotate(' + relativeRotation + 'deg) ' +
+ 'scale(' + scaleX + ',' + scaleY + ')';
+ CustomStyle.setProp('transform', canvas, cssTransform);
+
+ if (this.textLayer) {
+ // Rotating the text layer is more complicated since the divs inside the
+ // the text layer are rotated.
+ // TODO: This could probably be simplified by drawing the text layer in
+ // one orientation then rotating overall.
+ var textRelativeRotation = this.viewport.rotation -
+ this.textLayer.viewport.rotation;
+ var textAbsRotation = Math.abs(textRelativeRotation);
+ var scale = (width / canvas.width);
+ if (textAbsRotation === 90 || textAbsRotation === 270) {
+ scale = width / canvas.height;
+ }
+ var textLayerDiv = this.textLayer.textLayerDiv;
+ var transX, transY;
+ switch (textAbsRotation) {
+ case 0:
+ transX = transY = 0;
+ break;
+ case 90:
+ transX = 0;
+ transY = '-' + textLayerDiv.style.height;
+ break;
+ case 180:
+ transX = '-' + textLayerDiv.style.width;
+ transY = '-' + textLayerDiv.style.height;
+ break;
+ case 270:
+ transX = '-' + textLayerDiv.style.width;
+ transY = 0;
+ break;
+ default:
+ console.error('Bad rotation value.');
+ break;
+ }
+ CustomStyle.setProp('transform', textLayerDiv,
+ 'rotate(' + textAbsRotation + 'deg) ' +
+ 'scale(' + scale + ', ' + scale + ') ' +
+ 'translate(' + transX + ', ' + transY + ')');
+ CustomStyle.setProp('transformOrigin', textLayerDiv, '0% 0%');
+ }
+
+ if (USE_ONLY_CSS_ZOOM && this.annotationLayer) {
+ setupAnnotations(div, this.pdfPage, this.viewport);
+ }
+ };
+
+ Object.defineProperty(this, 'width', {
+ get: function PageView_getWidth() {
+ return this.viewport.width;
+ },
+ enumerable: true
+ });
+
+ Object.defineProperty(this, 'height', {
+ get: function PageView_getHeight() {
+ return this.viewport.height;
+ },
+ enumerable: true
+ });
+
+ var self = this;
+
+ function setupAnnotations(pageDiv, pdfPage, viewport) {
+
+ function bindLink(link, dest) {
+ link.href = PDFView.getDestinationHash(dest);
+ link.onclick = function pageViewSetupLinksOnclick() {
+ if (dest) {
+ PDFView.navigateTo(dest);
+ }
+ return false;
+ };
+ if (dest) {
+ link.className = 'internalLink';
+ }
+ }
+
+ function bindNamedAction(link, action) {
+ link.href = PDFView.getAnchorUrl('');
+ link.onclick = function pageViewSetupNamedActionOnClick() {
+ // See PDF reference, table 8.45 - Named action
+ switch (action) {
+ case 'GoToPage':
+ document.getElementById('pageNumber').focus();
+ break;
+
+ case 'GoBack':
+ PDFHistory.back();
+ break;
+
+ case 'GoForward':
+ PDFHistory.forward();
+ break;
+
+ case 'Find':
+ if (!PDFView.supportsIntegratedFind) {
+ PDFFindBar.toggle();
+ }
+ break;
+
+ case 'NextPage':
+ PDFView.page++;
+ break;
+
+ case 'PrevPage':
+ PDFView.page--;
+ break;
+
+ case 'LastPage':
+ PDFView.page = PDFView.pages.length;
+ break;
+
+ case 'FirstPage':
+ PDFView.page = 1;
+ break;
+
+ default:
+ break; // No action according to spec
+ }
+ return false;
+ };
+ link.className = 'internalLink';
+ }
+
+ pdfPage.getAnnotations().then(function(annotationsData) {
+ if (self.annotationLayer) {
+ // If an annotationLayer already exists, delete it to avoid creating
+ // duplicate annotations when rapidly re-zooming the document.
+ pageDiv.removeChild(self.annotationLayer);
+ self.annotationLayer = null;
+ }
+ viewport = viewport.clone({ dontFlip: true });
+ for (var i = 0; i < annotationsData.length; i++) {
+ var data = annotationsData[i];
+ var annotation = PDFJS.Annotation.fromData(data);
+ if (!annotation || !annotation.hasHtml()) {
+ continue;
+ }
+
+ var element = annotation.getHtmlElement(pdfPage.commonObjs);
+ mozL10n.translate(element);
+
+ data = annotation.getData();
+ var rect = data.rect;
+ var view = pdfPage.view;
+ rect = PDFJS.Util.normalizeRect([
+ rect[0],
+ view[3] - rect[1] + view[1],
+ rect[2],
+ view[3] - rect[3] + view[1]
+ ]);
+ element.style.left = rect[0] + 'px';
+ element.style.top = rect[1] + 'px';
+ element.style.position = 'absolute';
+
+ var transform = viewport.transform;
+ var transformStr = 'matrix(' + transform.join(',') + ')';
+ CustomStyle.setProp('transform', element, transformStr);
+ var transformOriginStr = -rect[0] + 'px ' + -rect[1] + 'px';
+ CustomStyle.setProp('transformOrigin', element, transformOriginStr);
+
+ if (data.subtype === 'Link' && !data.url) {
+ if (data.action) {
+ bindNamedAction(element, data.action);
+ } else {
+ bindLink(element, ('dest' in data) ? data.dest : null);
+ }
+ }
+
+ if (!self.annotationLayer) {
+ var annotationLayerDiv = document.createElement('div');
+ annotationLayerDiv.className = 'annotationLayer';
+ pageDiv.appendChild(annotationLayerDiv);
+ self.annotationLayer = annotationLayerDiv;
+ }
+ self.annotationLayer.appendChild(element);
+ }
+ });
+ }
+
+ this.getPagePoint = function pageViewGetPagePoint(x, y) {
+ return this.viewport.convertToPdfPoint(x, y);
+ };
+
+ this.scrollIntoView = function pageViewScrollIntoView(dest) {
+ if (PresentationMode.active) { // Avoid breaking presentation mode.
+ dest = null;
+ PDFView.setScale(PDFView.currentScaleValue, true, true);
+ }
+ if (!dest) {
+ scrollIntoView(div);
+ return;
+ }
+
+ var x = 0, y = 0;
+ var width = 0, height = 0, widthScale, heightScale;
+ var changeOrientation = !!(this.rotation % 180);
+ var pageWidth = (changeOrientation ? this.height : this.width) /
+ this.scale / CSS_UNITS;
+ var pageHeight = (changeOrientation ? this.width : this.height) /
+ this.scale / CSS_UNITS;
+ var scale = 0;
+ switch (dest[1].name) {
+ case 'XYZ':
+ x = dest[2];
+ y = dest[3];
+ scale = dest[4];
+ // If x and/or y coordinates are not supplied, default to
+ // _top_ left of the page (not the obvious bottom left,
+ // since aligning the bottom of the intended page with the
+ // top of the window is rarely helpful).
+ x = x !== null ? x : 0;
+ y = y !== null ? y : pageHeight;
+ break;
+ case 'Fit':
+ case 'FitB':
+ scale = 'page-fit';
+ break;
+ case 'FitH':
+ case 'FitBH':
+ y = dest[2];
+ scale = 'page-width';
+ break;
+ case 'FitV':
+ case 'FitBV':
+ x = dest[2];
+ width = pageWidth;
+ height = pageHeight;
+ scale = 'page-height';
+ break;
+ case 'FitR':
+ x = dest[2];
+ y = dest[3];
+ width = dest[4] - x;
+ height = dest[5] - y;
+ widthScale = (PDFView.container.clientWidth - SCROLLBAR_PADDING) /
+ width / CSS_UNITS;
+ heightScale = (PDFView.container.clientHeight - SCROLLBAR_PADDING) /
+ height / CSS_UNITS;
+ scale = Math.min(Math.abs(widthScale), Math.abs(heightScale));
+ break;
+ default:
+ return;
+ }
+
+ if (scale && scale !== PDFView.currentScale) {
+ PDFView.setScale(scale, true, true);
+ } else if (PDFView.currentScale === UNKNOWN_SCALE) {
+ PDFView.setScale(DEFAULT_SCALE, true, true);
+ }
+
+ if (scale === 'page-fit' && !dest[4]) {
+ scrollIntoView(div);
+ return;
+ }
+
+ var boundingRect = [
+ this.viewport.convertToViewportPoint(x, y),
+ this.viewport.convertToViewportPoint(x + width, y + height)
+ ];
+ var left = Math.min(boundingRect[0][0], boundingRect[1][0]);
+ var top = Math.min(boundingRect[0][1], boundingRect[1][1]);
+
+ scrollIntoView(div, { left: left, top: top });
+ };
+
+ this.getTextContent = function pageviewGetTextContent() {
+ return PDFView.getPage(this.id).then(function(pdfPage) {
+ return pdfPage.getTextContent();
+ });
+ };
+
+ this.draw = function pageviewDraw(callback) {
+ var pdfPage = this.pdfPage;
+
+ if (this.pagePdfPromise) {
+ return;
+ }
+ if (!pdfPage) {
+ var promise = PDFView.getPage(this.id);
+ promise.then(function(pdfPage) {
+ delete this.pagePdfPromise;
+ this.setPdfPage(pdfPage);
+ this.draw(callback);
+ }.bind(this));
+ this.pagePdfPromise = promise;
+ return;
+ }
+
+ if (this.renderingState !== RenderingStates.INITIAL) {
+ console.error('Must be in new state before drawing');
+ }
+
+ this.renderingState = RenderingStates.RUNNING;
+
+ var viewport = this.viewport;
+ // Wrap the canvas so if it has a css transform for highdpi the overflow
+ // will be hidden in FF.
+ var canvasWrapper = document.createElement('div');
+ canvasWrapper.style.width = div.style.width;
+ canvasWrapper.style.height = div.style.height;
+ canvasWrapper.classList.add('canvasWrapper');
+
+ var canvas = document.createElement('canvas');
+ canvas.id = 'page' + this.id;
+ canvasWrapper.appendChild(canvas);
+ div.appendChild(canvasWrapper);
+ this.canvas = canvas;
+
+ var scale = this.scale;
+ var ctx = canvas.getContext('2d');
+ var outputScale = getOutputScale(ctx);
+
+ if (USE_ONLY_CSS_ZOOM) {
+ var actualSizeViewport = viewport.clone({ scale: CSS_UNITS });
+ // Use a scale that will make the canvas be the original intended size
+ // of the page.
+ outputScale.sx *= actualSizeViewport.width / viewport.width;
+ outputScale.sy *= actualSizeViewport.height / viewport.height;
+ outputScale.scaled = true;
+ }
+
+ canvas.width = (Math.floor(viewport.width) * outputScale.sx) | 0;
+ canvas.height = (Math.floor(viewport.height) * outputScale.sy) | 0;
+ canvas.style.width = Math.floor(viewport.width) + 'px';
+ canvas.style.height = Math.floor(viewport.height) + 'px';
+ // Add the viewport so it's known what it was originally drawn with.
+ canvas._viewport = viewport;
+
+ var textLayerDiv = null;
+ if (!PDFJS.disableTextLayer) {
+ textLayerDiv = document.createElement('div');
+ textLayerDiv.className = 'textLayer';
+ textLayerDiv.style.width = canvas.width + 'px';
+ textLayerDiv.style.height = canvas.height + 'px';
+ div.appendChild(textLayerDiv);
+ }
+ var textLayer = this.textLayer =
+ textLayerDiv ? new TextLayerBuilder({
+ textLayerDiv: textLayerDiv,
+ pageIndex: this.id - 1,
+ lastScrollSource: PDFView,
+ viewport: this.viewport,
+ isViewerInPresentationMode: PresentationMode.active
+ }) : null;
+ // TODO(mack): use data attributes to store these
+ ctx._scaleX = outputScale.sx;
+ ctx._scaleY = outputScale.sy;
+ if (outputScale.scaled) {
+ ctx.scale(outputScale.sx, outputScale.sy);
+ }
+ if (outputScale.scaled && textLayerDiv) {
+ var cssScale = 'scale(' + (1 / outputScale.sx) + ', ' +
+ (1 / outputScale.sy) + ')';
+ CustomStyle.setProp('transform' , textLayerDiv, cssScale);
+ CustomStyle.setProp('transformOrigin' , textLayerDiv, '0% 0%');
+ textLayerDiv.dataset._scaleX = outputScale.sx;
+ textLayerDiv.dataset._scaleY = outputScale.sy;
+ }
+
+
+ // Rendering area
+
+ var self = this;
+ function pageViewDrawCallback(error) {
+ // The renderTask may have been replaced by a new one, so only remove the
+ // reference to the renderTask if it matches the one that is triggering
+ // this callback.
+ if (renderTask === self.renderTask) {
+ self.renderTask = null;
+ }
+
+ if (error === 'cancelled') {
+ return;
+ }
+
+ self.renderingState = RenderingStates.FINISHED;
+
+ if (self.loadingIconDiv) {
+ div.removeChild(self.loadingIconDiv);
+ delete self.loadingIconDiv;
+ }
+
+ if (self.zoomLayer) {
+ div.removeChild(self.zoomLayer);
+ self.zoomLayer = null;
+ }
+
+ if (error) {
+ PDFView.error(mozL10n.get('rendering_error', null,
+ 'An error occurred while rendering the page.'), error);
+ }
+
+ self.stats = pdfPage.stats;
+ self.updateStats();
+ if (self.onAfterDraw) {
+ self.onAfterDraw();
+ }
+
+ cache.push(self);
+
+ var event = document.createEvent('CustomEvent');
+ event.initCustomEvent('pagerender', true, true, {
+ pageNumber: pdfPage.pageNumber
+ });
+ div.dispatchEvent(event);
+
+ callback();
+ }
+
+ var renderContext = {
+ canvasContext: ctx,
+ viewport: this.viewport,
+ textLayer: textLayer,
+ continueCallback: function pdfViewcContinueCallback(cont) {
+ if (PDFView.highestPriorityPage !== 'page' + self.id) {
+ self.renderingState = RenderingStates.PAUSED;
+ self.resume = function resumeCallback() {
+ self.renderingState = RenderingStates.RUNNING;
+ cont();
+ };
+ return;
+ }
+ cont();
+ }
+ };
+ var renderTask = this.renderTask = this.pdfPage.render(renderContext);
+
+ this.renderTask.promise.then(
+ function pdfPageRenderCallback() {
+ pageViewDrawCallback(null);
+ },
+ function pdfPageRenderError(error) {
+ pageViewDrawCallback(error);
+ }
+ );
+
+ if (textLayer) {
+ this.getTextContent().then(
+ function textContentResolved(textContent) {
+ textLayer.setTextContent(textContent);
+ }
+ );
+ }
+
+ setupAnnotations(div, pdfPage, this.viewport);
+ div.setAttribute('data-loaded', true);
+ };
+
+ this.beforePrint = function pageViewBeforePrint() {
+ var pdfPage = this.pdfPage;
+
+ var viewport = pdfPage.getViewport(1);
+ // Use the same hack we use for high dpi displays for printing to get better
+ // output until bug 811002 is fixed in FF.
+ var PRINT_OUTPUT_SCALE = 2;
+ var canvas = document.createElement('canvas');
+ canvas.width = Math.floor(viewport.width) * PRINT_OUTPUT_SCALE;
+ canvas.height = Math.floor(viewport.height) * PRINT_OUTPUT_SCALE;
+ canvas.style.width = (PRINT_OUTPUT_SCALE * viewport.width) + 'pt';
+ canvas.style.height = (PRINT_OUTPUT_SCALE * viewport.height) + 'pt';
+ var cssScale = 'scale(' + (1 / PRINT_OUTPUT_SCALE) + ', ' +
+ (1 / PRINT_OUTPUT_SCALE) + ')';
+ CustomStyle.setProp('transform' , canvas, cssScale);
+ CustomStyle.setProp('transformOrigin' , canvas, '0% 0%');
+
+ var printContainer = document.getElementById('printContainer');
+ var canvasWrapper = document.createElement('div');
+ canvasWrapper.style.width = viewport.width + 'pt';
+ canvasWrapper.style.height = viewport.height + 'pt';
+ canvasWrapper.appendChild(canvas);
+ printContainer.appendChild(canvasWrapper);
+
+ var self = this;
+ canvas.mozPrintCallback = function(obj) {
+ var ctx = obj.context;
+
+ ctx.save();
+ ctx.fillStyle = 'rgb(255, 255, 255)';
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
+ ctx.restore();
+ ctx.scale(PRINT_OUTPUT_SCALE, PRINT_OUTPUT_SCALE);
+
+ var renderContext = {
+ canvasContext: ctx,
+ viewport: viewport
+ };
+
+ pdfPage.render(renderContext).promise.then(function() {
+ // Tell the printEngine that rendering this canvas/page has finished.
+ obj.done();
+ self.pdfPage.destroy();
+ }, function(error) {
+ console.error(error);
+ // Tell the printEngine that rendering this canvas/page has failed.
+ // This will make the print proces stop.
+ if ('abort' in obj) {
+ obj.abort();
+ } else {
+ obj.done();
+ }
+ self.pdfPage.destroy();
+ });
+ };
+ };
+
+ this.updateStats = function pageViewUpdateStats() {
+ if (!this.stats) {
+ return;
+ }
+
+ if (PDFJS.pdfBug && Stats.enabled) {
+ var stats = this.stats;
+ Stats.add(this.id, stats);
+ }
+ };
+};
+
+
+var ThumbnailView = function thumbnailView(container, id, defaultViewport) {
+ var anchor = document.createElement('a');
+ anchor.href = PDFView.getAnchorUrl('#page=' + id);
+ anchor.title = mozL10n.get('thumb_page_title', {page: id}, 'Page {{page}}');
+ anchor.onclick = function stopNavigation() {
+ PDFView.page = id;
+ return false;
+ };
+
+ this.pdfPage = undefined;
+ this.viewport = defaultViewport;
+ this.pdfPageRotate = defaultViewport.rotation;
+
+ this.rotation = 0;
+ this.pageWidth = this.viewport.width;
+ this.pageHeight = this.viewport.height;
+ this.pageRatio = this.pageWidth / this.pageHeight;
+ this.id = id;
+
+ this.canvasWidth = 98;
+ this.canvasHeight = this.canvasWidth / this.pageWidth * this.pageHeight;
+ this.scale = (this.canvasWidth / this.pageWidth);
+
+ var div = this.el = document.createElement('div');
+ div.id = 'thumbnailContainer' + id;
+ div.className = 'thumbnail';
+
+ if (id === 1) {
+ // Highlight the thumbnail of the first page when no page number is
+ // specified (or exists in cache) when the document is loaded.
+ div.classList.add('selected');
+ }
+
+ var ring = document.createElement('div');
+ ring.className = 'thumbnailSelectionRing';
+ ring.style.width = this.canvasWidth + 'px';
+ ring.style.height = this.canvasHeight + 'px';
+
+ div.appendChild(ring);
+ anchor.appendChild(div);
+ container.appendChild(anchor);
+
+ this.hasImage = false;
+ this.renderingState = RenderingStates.INITIAL;
+
+ this.setPdfPage = function thumbnailViewSetPdfPage(pdfPage) {
+ this.pdfPage = pdfPage;
+ this.pdfPageRotate = pdfPage.rotate;
+ var totalRotation = (this.rotation + this.pdfPageRotate) % 360;
+ this.viewport = pdfPage.getViewport(1, totalRotation);
+ this.update();
+ };
+
+ this.update = function thumbnailViewUpdate(rotation) {
+ if (rotation !== undefined) {
+ this.rotation = rotation;
+ }
+ var totalRotation = (this.rotation + this.pdfPageRotate) % 360;
+ this.viewport = this.viewport.clone({
+ scale: 1,
+ rotation: totalRotation
+ });
+ this.pageWidth = this.viewport.width;
+ this.pageHeight = this.viewport.height;
+ this.pageRatio = this.pageWidth / this.pageHeight;
+
+ this.canvasHeight = this.canvasWidth / this.pageWidth * this.pageHeight;
+ this.scale = (this.canvasWidth / this.pageWidth);
+
+ div.removeAttribute('data-loaded');
+ ring.textContent = '';
+ ring.style.width = this.canvasWidth + 'px';
+ ring.style.height = this.canvasHeight + 'px';
+
+ this.hasImage = false;
+ this.renderingState = RenderingStates.INITIAL;
+ this.resume = null;
+ };
+
+ this.getPageDrawContext = function thumbnailViewGetPageDrawContext() {
+ var canvas = document.createElement('canvas');
+ canvas.id = 'thumbnail' + id;
+
+ canvas.width = this.canvasWidth;
+ canvas.height = this.canvasHeight;
+ canvas.className = 'thumbnailImage';
+ canvas.setAttribute('aria-label', mozL10n.get('thumb_page_canvas',
+ {page: id}, 'Thumbnail of Page {{page}}'));
+
+ div.setAttribute('data-loaded', true);
+
+ ring.appendChild(canvas);
+
+ var ctx = canvas.getContext('2d');
+ ctx.save();
+ ctx.fillStyle = 'rgb(255, 255, 255)';
+ ctx.fillRect(0, 0, this.canvasWidth, this.canvasHeight);
+ ctx.restore();
+ return ctx;
+ };
+
+ this.drawingRequired = function thumbnailViewDrawingRequired() {
+ return !this.hasImage;
+ };
+
+ this.draw = function thumbnailViewDraw(callback) {
+ if (!this.pdfPage) {
+ var promise = PDFView.getPage(this.id);
+ promise.then(function(pdfPage) {
+ this.setPdfPage(pdfPage);
+ this.draw(callback);
+ }.bind(this));
+ return;
+ }
+
+ if (this.renderingState !== RenderingStates.INITIAL) {
+ console.error('Must be in new state before drawing');
+ }
+
+ this.renderingState = RenderingStates.RUNNING;
+ if (this.hasImage) {
+ callback();
+ return;
+ }
+
+ var self = this;
+ var ctx = this.getPageDrawContext();
+ var drawViewport = this.viewport.clone({ scale: this.scale });
+ var renderContext = {
+ canvasContext: ctx,
+ viewport: drawViewport,
+ continueCallback: function(cont) {
+ if (PDFView.highestPriorityPage !== 'thumbnail' + self.id) {
+ self.renderingState = RenderingStates.PAUSED;
+ self.resume = function() {
+ self.renderingState = RenderingStates.RUNNING;
+ cont();
+ };
+ return;
+ }
+ cont();
+ }
+ };
+ this.pdfPage.render(renderContext).promise.then(
+ function pdfPageRenderCallback() {
+ self.renderingState = RenderingStates.FINISHED;
+ callback();
+ },
+ function pdfPageRenderError(error) {
+ self.renderingState = RenderingStates.FINISHED;
+ callback();
+ }
+ );
+ this.hasImage = true;
+ };
+
+ this.setImage = function thumbnailViewSetImage(img) {
+ if (!this.pdfPage) {
+ var promise = PDFView.getPage(this.id);
+ promise.then(function(pdfPage) {
+ this.setPdfPage(pdfPage);
+ this.setImage(img);
+ }.bind(this));
+ return;
+ }
+ if (this.hasImage || !img) {
+ return;
+ }
+ this.renderingState = RenderingStates.FINISHED;
+ var ctx = this.getPageDrawContext();
+ ctx.drawImage(img, 0, 0, img.width, img.height,
+ 0, 0, ctx.canvas.width, ctx.canvas.height);
+
+ this.hasImage = true;
+ };
+};
+
+
+var FIND_SCROLL_OFFSET_TOP = -50;
+var FIND_SCROLL_OFFSET_LEFT = -400;
+
+/**
+ * TextLayerBuilder provides text-selection
+ * functionality for the PDF. It does this
+ * by creating overlay divs over the PDF
+ * text. This divs contain text that matches
+ * the PDF text they are overlaying. This
+ * object also provides for a way to highlight
+ * text that is being searched for.
+ */
+var TextLayerBuilder = function textLayerBuilder(options) {
+ var textLayerFrag = document.createDocumentFragment();
+
+ this.textLayerDiv = options.textLayerDiv;
+ this.layoutDone = false;
+ this.divContentDone = false;
+ this.pageIdx = options.pageIndex;
+ this.matches = [];
+ this.lastScrollSource = options.lastScrollSource;
+ this.viewport = options.viewport;
+ this.isViewerInPresentationMode = options.isViewerInPresentationMode;
+
+ if(typeof PDFFindController === 'undefined') {
+ window.PDFFindController = null;
+ }
+
+ if(typeof this.lastScrollSource === 'undefined') {
+ this.lastScrollSource = null;
+ }
+
+ this.beginLayout = function textLayerBuilderBeginLayout() {
+ this.textDivs = [];
+ this.renderingDone = false;
+ };
+
+ this.endLayout = function textLayerBuilderEndLayout() {
+ this.layoutDone = true;
+ this.insertDivContent();
+ };
+
+ this.renderLayer = function textLayerBuilderRenderLayer() {
+ var self = this;
+ var textDivs = this.textDivs;
+ var bidiTexts = this.textContent.bidiTexts;
+ var textLayerDiv = this.textLayerDiv;
+ var canvas = document.createElement('canvas');
+ var ctx = canvas.getContext('2d');
+
+ // No point in rendering so many divs as it'd make the browser unusable
+ // even after the divs are rendered
+ var MAX_TEXT_DIVS_TO_RENDER = 100000;
+ if (textDivs.length > MAX_TEXT_DIVS_TO_RENDER)
+ return;
+
+ for (var i = 0, ii = textDivs.length; i < ii; i++) {
+ var textDiv = textDivs[i];
+ if ('isWhitespace' in textDiv.dataset) {
+ continue;
+ }
+
+ ctx.font = textDiv.style.fontSize + ' ' + textDiv.style.fontFamily;
+ var width = ctx.measureText(textDiv.textContent).width;
+
+ if (width > 0) {
+ textLayerFrag.appendChild(textDiv);
+ var textScale = textDiv.dataset.canvasWidth / width;
+ var rotation = textDiv.dataset.angle;
+ var transform = 'scale(' + textScale + ', 1)';
+ transform = 'rotate(' + rotation + 'deg) ' + transform;
+ CustomStyle.setProp('transform' , textDiv, transform);
+ CustomStyle.setProp('transformOrigin' , textDiv, '0% 0%');
+ }
+ }
+
+ textLayerDiv.appendChild(textLayerFrag);
+ this.renderingDone = true;
+ this.updateMatches();
+ };
+
+ this.setupRenderLayoutTimer = function textLayerSetupRenderLayoutTimer() {
+ // Schedule renderLayout() if user has been scrolling, otherwise
+ // run it right away
+ var RENDER_DELAY = 200; // in ms
+ var self = this;
+ var lastScroll = this.lastScrollSource === null ?
+ 0 : this.lastScrollSource.lastScroll;
+
+ if (Date.now() - lastScroll > RENDER_DELAY) {
+ // Render right away
+ this.renderLayer();
+ } else {
+ // Schedule
+ if (this.renderTimer)
+ clearTimeout(this.renderTimer);
+ this.renderTimer = setTimeout(function() {
+ self.setupRenderLayoutTimer();
+ }, RENDER_DELAY);
+ }
+ };
+
+ this.appendText = function textLayerBuilderAppendText(geom) {
+ var textDiv = document.createElement('div');
+
+ // vScale and hScale already contain the scaling to pixel units
+ var fontHeight = geom.fontSize * Math.abs(geom.vScale);
+ textDiv.dataset.canvasWidth = geom.canvasWidth * Math.abs(geom.hScale);
+ textDiv.dataset.fontName = geom.fontName;
+ textDiv.dataset.angle = geom.angle * (180 / Math.PI);
+
+ textDiv.style.fontSize = fontHeight + 'px';
+ textDiv.style.fontFamily = geom.fontFamily;
+ var fontAscent = geom.ascent ? geom.ascent * fontHeight :
+ geom.descent ? (1 + geom.descent) * fontHeight : fontHeight;
+ textDiv.style.left = (geom.x + (fontAscent * Math.sin(geom.angle))) + 'px';
+ textDiv.style.top = (geom.y - (fontAscent * Math.cos(geom.angle))) + 'px';
+
+ // The content of the div is set in the `setTextContent` function.
+
+ this.textDivs.push(textDiv);
+ };
+
+ this.insertDivContent = function textLayerUpdateTextContent() {
+ // Only set the content of the divs once layout has finished, the content
+ // for the divs is available and content is not yet set on the divs.
+ if (!this.layoutDone || this.divContentDone || !this.textContent)
+ return;
+
+ this.divContentDone = true;
+
+ var textDivs = this.textDivs;
+ var bidiTexts = this.textContent.bidiTexts;
+
+ for (var i = 0; i < bidiTexts.length; i++) {
+ var bidiText = bidiTexts[i];
+ var textDiv = textDivs[i];
+ if (!/\S/.test(bidiText.str)) {
+ textDiv.dataset.isWhitespace = true;
+ continue;
+ }
+
+ textDiv.textContent = bidiText.str;
+ // TODO refactor text layer to use text content position
+ /**
+ * var arr = this.viewport.convertToViewportPoint(bidiText.x, bidiText.y);
+ * textDiv.style.left = arr[0] + 'px';
+ * textDiv.style.top = arr[1] + 'px';
+ */
+ // bidiText.dir may be 'ttb' for vertical texts.
+ textDiv.dir = bidiText.dir;
+ }
+
+ this.setupRenderLayoutTimer();
+ };
+
+ this.setTextContent = function textLayerBuilderSetTextContent(textContent) {
+ this.textContent = textContent;
+ this.insertDivContent();
+ };
+
+ this.convertMatches = function textLayerBuilderConvertMatches(matches) {
+ var i = 0;
+ var iIndex = 0;
+ var bidiTexts = this.textContent.bidiTexts;
+ var end = bidiTexts.length - 1;
+ var queryLen = PDFFindController === null ?
+ 0 : PDFFindController.state.query.length;
+
+ var lastDivIdx = -1;
+ var pos;
+
+ var ret = [];
+
+ // Loop over all the matches.
+ for (var m = 0; m < matches.length; m++) {
+ var matchIdx = matches[m];
+ // # Calculate the begin position.
+
+ // Loop over the divIdxs.
+ while (i !== end && matchIdx >= (iIndex + bidiTexts[i].str.length)) {
+ iIndex += bidiTexts[i].str.length;
+ i++;
+ }
+
+ // TODO: Do proper handling here if something goes wrong.
+ if (i == bidiTexts.length) {
+ console.error('Could not find matching mapping');
+ }
+
+ var match = {
+ begin: {
+ divIdx: i,
+ offset: matchIdx - iIndex
+ }
+ };
+
+ // # Calculate the end position.
+ matchIdx += queryLen;
+
+ // Somewhat same array as above, but use a > instead of >= to get the end
+ // position right.
+ while (i !== end && matchIdx > (iIndex + bidiTexts[i].str.length)) {
+ iIndex += bidiTexts[i].str.length;
+ i++;
+ }
+
+ match.end = {
+ divIdx: i,
+ offset: matchIdx - iIndex
+ };
+ ret.push(match);
+ }
+
+ return ret;
+ };
+
+ this.renderMatches = function textLayerBuilder_renderMatches(matches) {
+ // Early exit if there is nothing to render.
+ if (matches.length === 0) {
+ return;
+ }
+
+ var bidiTexts = this.textContent.bidiTexts;
+ var textDivs = this.textDivs;
+ var prevEnd = null;
+ var isSelectedPage = PDFFindController === null ?
+ false : (this.pageIdx === PDFFindController.selected.pageIdx);
+
+ var selectedMatchIdx = PDFFindController === null ?
+ -1 : PDFFindController.selected.matchIdx;
+
+ var highlightAll = PDFFindController === null ?
+ false : PDFFindController.state.highlightAll;
+
+ var infty = {
+ divIdx: -1,
+ offset: undefined
+ };
+
+ function beginText(begin, className) {
+ var divIdx = begin.divIdx;
+ var div = textDivs[divIdx];
+ div.textContent = '';
+
+ var content = bidiTexts[divIdx].str.substring(0, begin.offset);
+ var node = document.createTextNode(content);
+ if (className) {
+ var isSelected = isSelectedPage &&
+ divIdx === selectedMatchIdx;
+ var span = document.createElement('span');
+ span.className = className + (isSelected ? ' selected' : '');
+ span.appendChild(node);
+ div.appendChild(span);
+ return;
+ }
+ div.appendChild(node);
+ }
+
+ function appendText(from, to, className) {
+ var divIdx = from.divIdx;
+ var div = textDivs[divIdx];
+
+ var content = bidiTexts[divIdx].str.substring(from.offset, to.offset);
+ var node = document.createTextNode(content);
+ if (className) {
+ var span = document.createElement('span');
+ span.className = className;
+ span.appendChild(node);
+ div.appendChild(span);
+ return;
+ }
+ div.appendChild(node);
+ }
+
+ function highlightDiv(divIdx, className) {
+ textDivs[divIdx].className = className;
+ }
+
+ var i0 = selectedMatchIdx, i1 = i0 + 1, i;
+
+ if (highlightAll) {
+ i0 = 0;
+ i1 = matches.length;
+ } else if (!isSelectedPage) {
+ // Not highlighting all and this isn't the selected page, so do nothing.
+ return;
+ }
+
+ for (i = i0; i < i1; i++) {
+ var match = matches[i];
+ var begin = match.begin;
+ var end = match.end;
+
+ var isSelected = isSelectedPage && i === selectedMatchIdx;
+ var highlightSuffix = (isSelected ? ' selected' : '');
+ if (isSelected && !this.isViewerInPresentationMode) {
+ scrollIntoView(textDivs[begin.divIdx], { top: FIND_SCROLL_OFFSET_TOP,
+ left: FIND_SCROLL_OFFSET_LEFT });
+ }
+
+ // Match inside new div.
+ if (!prevEnd || begin.divIdx !== prevEnd.divIdx) {
+ // If there was a previous div, then add the text at the end
+ if (prevEnd !== null) {
+ appendText(prevEnd, infty);
+ }
+ // clears the divs and set the content until the begin point.
+ beginText(begin);
+ } else {
+ appendText(prevEnd, begin);
+ }
+
+ if (begin.divIdx === end.divIdx) {
+ appendText(begin, end, 'highlight' + highlightSuffix);
+ } else {
+ appendText(begin, infty, 'highlight begin' + highlightSuffix);
+ for (var n = begin.divIdx + 1; n < end.divIdx; n++) {
+ highlightDiv(n, 'highlight middle' + highlightSuffix);
+ }
+ beginText(end, 'highlight end' + highlightSuffix);
+ }
+ prevEnd = end;
+ }
+
+ if (prevEnd) {
+ appendText(prevEnd, infty);
+ }
+ };
+
+ this.updateMatches = function textLayerUpdateMatches() {
+ // Only show matches, once all rendering is done.
+ if (!this.renderingDone)
+ return;
+
+ // Clear out all matches.
+ var matches = this.matches;
+ var textDivs = this.textDivs;
+ var bidiTexts = this.textContent.bidiTexts;
+ var clearedUntilDivIdx = -1;
+
+ // Clear out all current matches.
+ for (var i = 0; i < matches.length; i++) {
+ var match = matches[i];
+ var begin = Math.max(clearedUntilDivIdx, match.begin.divIdx);
+ for (var n = begin; n <= match.end.divIdx; n++) {
+ var div = textDivs[n];
+ div.textContent = bidiTexts[n].str;
+ div.className = '';
+ }
+ clearedUntilDivIdx = match.end.divIdx + 1;
+ }
+
+ if (PDFFindController === null || !PDFFindController.active)
+ return;
+
+ // Convert the matches on the page controller into the match format used
+ // for the textLayer.
+ this.matches = matches =
+ this.convertMatches(PDFFindController === null ?
+ [] : (PDFFindController.pageMatches[this.pageIdx] || []));
+
+ this.renderMatches(this.matches);
+ };
+};
+
+
+
+var DocumentOutlineView = function documentOutlineView(outline) {
+ var outlineView = document.getElementById('outlineView');
+ var outlineButton = document.getElementById('viewOutline');
+ while (outlineView.firstChild)
+ outlineView.removeChild(outlineView.firstChild);
+
+ if (!outline) {
+ if (!outlineView.classList.contains('hidden'))
+ PDFView.switchSidebarView('thumbs');
+
+ return;
+ }
+
+ function bindItemLink(domObj, item) {
+ domObj.href = PDFView.getDestinationHash(item.dest);
+ domObj.onclick = function documentOutlineViewOnclick(e) {
+ PDFView.navigateTo(item.dest);
+ return false;
+ };
+ }
+
+
+ var queue = [{parent: outlineView, items: outline}];
+ while (queue.length > 0) {
+ var levelData = queue.shift();
+ var i, n = levelData.items.length;
+ for (i = 0; i < n; i++) {
+ var item = levelData.items[i];
+ var div = document.createElement('div');
+ div.className = 'outlineItem';
+ var a = document.createElement('a');
+ bindItemLink(a, item);
+ a.textContent = item.title;
+ div.appendChild(a);
+
+ if (item.items.length > 0) {
+ var itemsDiv = document.createElement('div');
+ itemsDiv.className = 'outlineItems';
+ div.appendChild(itemsDiv);
+ queue.push({parent: itemsDiv, items: item.items});
+ }
+
+ levelData.parent.appendChild(div);
+ }
+ }
+};
+
+
+document.addEventListener('DOMContentLoaded', function webViewerLoad(evt) {
+ PDFView.initialize();
+
+ var params = PDFView.parseQueryString(document.location.search.substring(1));
+ var file = params.file || DEFAULT_URL;
+
+
+ var fileInput = document.createElement('input');
+ fileInput.id = 'fileInput';
+ fileInput.className = 'fileInput';
+ fileInput.setAttribute('type', 'file');
+ fileInput.oncontextmenu = noContextMenuHandler;
+ document.body.appendChild(fileInput);
+
+ if (!window.File || !window.FileReader || !window.FileList || !window.Blob) {
+ //document.getElementById('openFile').setAttribute('hidden', 'true');
+ //document.getElementById('secondaryOpenFile').setAttribute('hidden', 'true');
+ } else {
+ document.getElementById('fileInput').value = null;
+ }
+
+ // Special debugging flags in the hash section of the URL.
+ var hash = document.location.hash.substring(1);
+ var hashParams = PDFView.parseQueryString(hash);
+
+ if ('disableWorker' in hashParams) {
+ PDFJS.disableWorker = (hashParams['disableWorker'] === 'true');
+ }
+
+ if ('disableRange' in hashParams) {
+ PDFJS.disableRange = (hashParams['disableRange'] === 'true');
+ }
+
+ if ('disableAutoFetch' in hashParams) {
+ PDFJS.disableAutoFetch = (hashParams['disableAutoFetch'] === 'true');
+ }
+
+ if ('disableFontFace' in hashParams) {
+ PDFJS.disableFontFace = (hashParams['disableFontFace'] === 'true');
+ }
+
+ if ('disableHistory' in hashParams) {
+ PDFJS.disableHistory = (hashParams['disableHistory'] === 'true');
+ }
+
+ if ('useOnlyCssZoom' in hashParams) {
+ USE_ONLY_CSS_ZOOM = (hashParams['useOnlyCssZoom'] === 'true');
+ }
+
+ if ('verbosity' in hashParams) {
+ PDFJS.verbosity = hashParams['verbosity'] | 0;
+ }
+
+ if ('ignoreCurrentPositionOnZoom' in hashParams) {
+ IGNORE_CURRENT_POSITION_ON_ZOOM =
+ (hashParams['ignoreCurrentPositionOnZoom'] === 'true');
+ }
+
+ var locale = navigator.language;
+ if ('locale' in hashParams)
+ locale = hashParams['locale'];
+ mozL10n.setLanguage(locale);
+
+ if ('textLayer' in hashParams) {
+ switch (hashParams['textLayer']) {
+ case 'off':
+ PDFJS.disableTextLayer = true;
+ break;
+ case 'visible':
+ case 'shadow':
+ case 'hover':
+ var viewer = document.getElementById('viewer');
+ viewer.classList.add('textLayer-' + hashParams['textLayer']);
+ break;
+ }
+ }
+
+ if ('pdfBug' in hashParams) {
+ PDFJS.pdfBug = true;
+ var pdfBug = hashParams['pdfBug'];
+ var enabled = pdfBug.split(',');
+ PDFBug.enable(enabled);
+ PDFBug.init();
+ }
+
+ if (!PDFView.supportsPrinting) {
+ document.getElementById('print').classList.add('hidden');
+ document.getElementById('secondaryPrint').classList.add('hidden');
+ }
+
+ if (!PDFView.supportsFullscreen) {
+ document.getElementById('presentationMode').classList.add('hidden');
+ document.getElementById('secondaryPresentationMode').
+ classList.add('hidden');
+ }
+
+ if (PDFView.supportsIntegratedFind) {
+ document.getElementById('viewFind').classList.add('hidden');
+ }
+
+ // Listen for unsuporrted features to trigger the fallback UI.
+ PDFJS.UnsupportedManager.listen(PDFView.fallback.bind(PDFView));
+
+ // Suppress context menus for some controls
+ document.getElementById('scaleSelect').oncontextmenu = noContextMenuHandler;
+
+ var mainContainer = document.getElementById('mainContainer');
+ var outerContainer = document.getElementById('outerContainer');
+ mainContainer.addEventListener('transitionend', function(e) {
+ if (e.target == mainContainer) {
+ var event = document.createEvent('UIEvents');
+ event.initUIEvent('resize', false, false, window, 0);
+ window.dispatchEvent(event);
+ outerContainer.classList.remove('sidebarMoving');
+ }
+ }, true);
+
+ document.getElementById('sidebarToggle').addEventListener('click',
+ function() {
+ this.classList.toggle('toggled');
+ outerContainer.classList.add('sidebarMoving');
+ outerContainer.classList.toggle('sidebarOpen');
+ PDFView.sidebarOpen = outerContainer.classList.contains('sidebarOpen');
+ PDFView.renderHighestPriority();
+ });
+
+ document.getElementById('viewThumbnail').addEventListener('click',
+ function() {
+ PDFView.switchSidebarView('thumbs');
+ });
+
+ document.getElementById('viewOutline').addEventListener('click',
+ function() {
+ PDFView.switchSidebarView('outline');
+ });
+
+ document.getElementById('previous').addEventListener('click',
+ function() {
+ PDFView.page--;
+ });
+
+ document.getElementById('next').addEventListener('click',
+ function() {
+ PDFView.page++;
+ });
+
+ document.getElementById('zoomIn').addEventListener('click',
+ function() {
+ PDFView.zoomIn();
+ });
+
+ document.getElementById('zoomOut').addEventListener('click',
+ function() {
+ PDFView.zoomOut();
+ });
+
+ document.getElementById('pageNumber').addEventListener('click',
+ function() {
+ this.select();
+ });
+
+ document.getElementById('pageNumber').addEventListener('change',
+ function() {
+ // Handle the user inputting a floating point number.
+ PDFView.page = (this.value | 0);
+
+ if (this.value !== (this.value | 0).toString()) {
+ this.value = PDFView.page;
+ }
+ });
+
+ document.getElementById('scaleSelect').addEventListener('change',
+ function() {
+ PDFView.setScale(this.value);
+ });
+
+ document.getElementById('presentationMode').addEventListener('click',
+ SecondaryToolbar.presentationModeClick.bind(SecondaryToolbar));
+
+// document.getElementById('openFile').addEventListener('click',
+// SecondaryToolbar.openFileClick.bind(SecondaryToolbar));
+
+ document.getElementById('print').addEventListener('click',
+ SecondaryToolbar.printClick.bind(SecondaryToolbar));
+
+// document.getElementById('download').addEventListener('click',
+// SecondaryToolbar.downloadClick.bind(SecondaryToolbar));
+
+
+ PDFView.open(file, 0);
+}, true);
+
+function updateViewarea() {
+
+ if (!PDFView.initialized)
+ return;
+ var visible = PDFView.getVisiblePages();
+ var visiblePages = visible.views;
+ if (visiblePages.length === 0) {
+ return;
+ }
+
+ PDFView.renderHighestPriority();
+
+ var currentId = PDFView.page;
+ var firstPage = visible.first;
+
+ for (var i = 0, ii = visiblePages.length, stillFullyVisible = false;
+ i < ii; ++i) {
+ var page = visiblePages[i];
+
+ if (page.percent < 100)
+ break;
+
+ if (page.id === PDFView.page) {
+ stillFullyVisible = true;
+ break;
+ }
+ }
+
+ if (!stillFullyVisible) {
+ currentId = visiblePages[0].id;
+ }
+
+ updateViewarea.inProgress = true; // used in "set page"
+ PDFView.page = currentId;
+ updateViewarea.inProgress = false;
+
+ var currentScale = PDFView.currentScale;
+ var currentScaleValue = PDFView.currentScaleValue;
+ var normalizedScaleValue = parseFloat(currentScaleValue) === currentScale ?
+ Math.round(currentScale * 10000) / 100 : currentScaleValue;
+
+ var pageNumber = firstPage.id;
+ var pdfOpenParams = '#page=' + pageNumber;
+ pdfOpenParams += '&zoom=' + normalizedScaleValue;
+ var currentPage = PDFView.pages[pageNumber - 1];
+ var container = PDFView.container;
+ var topLeft = currentPage.getPagePoint((container.scrollLeft - firstPage.x),
+ (container.scrollTop - firstPage.y));
+ var intLeft = Math.round(topLeft[0]);
+ var intTop = Math.round(topLeft[1]);
+ pdfOpenParams += ',' + intLeft + ',' + intTop;
+
+ if (PresentationMode.active || PresentationMode.switchInProgress) {
+ PDFView.currentPosition = null;
+ } else {
+ PDFView.currentPosition = { page: pageNumber, left: intLeft, top: intTop };
+ }
+
+ var store = PDFView.store;
+ store.initializedPromise.then(function() {
+ store.set('exists', true);
+ store.set('page', pageNumber);
+ store.set('zoom', normalizedScaleValue);
+ store.set('scrollLeft', intLeft);
+ store.set('scrollTop', intTop);
+ });
+ var href = PDFView.getAnchorUrl(pdfOpenParams);
+ document.getElementById('viewBookmark').href = href;
+ document.getElementById('secondaryViewBookmark').href = href;
+
+ // Update the current bookmark in the browsing history.
+ PDFHistory.updateCurrentBookmark(pdfOpenParams, pageNumber);
+}
+
+window.addEventListener('resize', function webViewerResize(evt) {
+ if (PDFView.initialized &&
+ (document.getElementById('pageWidthOption').selected ||
+ document.getElementById('pageFitOption').selected ||
+ document.getElementById('pageAutoOption').selected)) {
+ PDFView.setScale(document.getElementById('scaleSelect').value);
+ }
+ updateViewarea();
+
+ // Set the 'max-height' CSS property of the secondary toolbar.
+ SecondaryToolbar.setMaxHeight(PDFView.container);
+});
+
+window.addEventListener('hashchange', function webViewerHashchange(evt) {
+ if (PDFHistory.isHashChangeUnlocked) {
+ PDFView.setHash(document.location.hash.substring(1));
+ }
+});
+
+window.addEventListener('change', function webViewerChange(evt) {
+ var files = evt.target.files;
+ if (!files || files.length === 0)
+ return;
+
+ // Read the local file into a Uint8Array.
+ var fileReader = new FileReader();
+ fileReader.onload = function webViewerChangeFileReaderOnload(evt) {
+ var buffer = evt.target.result;
+ var uint8Array = new Uint8Array(buffer);
+ PDFView.open(uint8Array, 0);
+ };
+
+ var file = files[0];
+ fileReader.readAsArrayBuffer(file);
+ PDFView.setTitleUsingUrl(file.name);
+
+ // URL does not reflect proper document location - hiding some icons.
+ document.getElementById('viewBookmark').setAttribute('hidden', 'true');
+ document.getElementById('secondaryViewBookmark').
+ setAttribute('hidden', 'true');
+ document.getElementById('download').setAttribute('hidden', 'true');
+ document.getElementById('secondaryDownload').setAttribute('hidden', 'true');
+}, true);
+
+function selectScaleOption(value) {
+ var options = document.getElementById('scaleSelect').options;
+ var predefinedValueFound = false;
+ for (var i = 0; i < options.length; i++) {
+ var option = options[i];
+ if (option.value != value) {
+ option.selected = false;
+ continue;
+ }
+ option.selected = true;
+ predefinedValueFound = true;
+ }
+ return predefinedValueFound;
+}
+
+window.addEventListener('localized', function localized(evt) {
+ document.getElementsByTagName('html')[0].dir = mozL10n.getDirection();
+
+ PDFView.animationStartedPromise.then(function() {
+ // Adjust the width of the zoom box to fit the content.
+ // Note: This is only done if the zoom box is actually visible,
+ // since otherwise element.clientWidth will return 0.
+ var container = document.getElementById('scaleSelectContainer');
+ if (container.clientWidth > 0) {
+ var select = document.getElementById('scaleSelect');
+ select.setAttribute('style', 'min-width: inherit;');
+ var width = select.clientWidth + SCALE_SELECT_CONTAINER_PADDING;
+ select.setAttribute('style', 'min-width: ' +
+ (width + SCALE_SELECT_PADDING) + 'px;');
+ container.setAttribute('style', 'min-width: ' + width + 'px; ' +
+ 'max-width: ' + width + 'px;');
+ }
+
+ // Set the 'max-height' CSS property of the secondary toolbar.
+ SecondaryToolbar.setMaxHeight(PDFView.container);
+ });
+}, true);
+
+window.addEventListener('scalechange', function scalechange(evt) {
+ document.getElementById('zoomOut').disabled = (evt.scale === MIN_SCALE);
+ document.getElementById('zoomIn').disabled = (evt.scale === MAX_SCALE);
+
+ var customScaleOption = document.getElementById('customScaleOption');
+ customScaleOption.selected = false;
+
+ if (!evt.resetAutoSettings &&
+ (document.getElementById('pageWidthOption').selected ||
+ document.getElementById('pageFitOption').selected ||
+ document.getElementById('pageAutoOption').selected)) {
+ updateViewarea();
+ return;
+ }
+
+ var predefinedValueFound = selectScaleOption('' + evt.scale);
+ if (!predefinedValueFound) {
+ customScaleOption.textContent = Math.round(evt.scale * 10000) / 100 + '%';
+ customScaleOption.selected = true;
+ }
+ updateViewarea();
+}, true);
+
+window.addEventListener('pagechange', function pagechange(evt) {
+ var page = evt.pageNumber;
+ if (PDFView.previousPageNumber !== page) {
+ document.getElementById('pageNumber').value = page;
+ var selected = document.querySelector('.thumbnail.selected');
+ if (selected) {
+ selected.classList.remove('selected');
+ }
+ var thumbnail = document.getElementById('thumbnailContainer' + page);
+ thumbnail.classList.add('selected');
+ var visibleThumbs = PDFView.getVisibleThumbs();
+ var numVisibleThumbs = visibleThumbs.views.length;
+
+ // If the thumbnail isn't currently visible, scroll it into view.
+ if (numVisibleThumbs > 0) {
+ var first = visibleThumbs.first.id;
+ // Account for only one thumbnail being visible.
+ var last = (numVisibleThumbs > 1 ? visibleThumbs.last.id : first);
+ if (page <= first || page >= last) {
+ scrollIntoView(thumbnail, { top: THUMBNAIL_SCROLL_MARGIN });
+ }
+ }
+ }
+ document.getElementById('previous').disabled = (page <= 1);
+ document.getElementById('next').disabled = (page >= PDFView.pages.length);
+}, true);
+
+// Firefox specific event, so that we can prevent browser from zooming
+window.addEventListener('DOMMouseScroll', function(evt) {
+ if (evt.ctrlKey) {
+ evt.preventDefault();
+
+ var ticks = evt.detail;
+ var direction = (ticks > 0) ? 'zoomOut' : 'zoomIn';
+ PDFView[direction](Math.abs(ticks));
+ } else if (PresentationMode.active) {
+ var FIREFOX_DELTA_FACTOR = -40;
+ PDFView.mouseScroll(evt.detail * FIREFOX_DELTA_FACTOR);
+ }
+}, false);
+
+window.addEventListener('click', function click(evt) {
+ if (!PresentationMode.active) {
+ if (SecondaryToolbar.opened && PDFView.container.contains(evt.target)) {
+ SecondaryToolbar.close();
+ }
+ } else if (evt.button === 0) {
+ // Necessary since preventDefault() in 'mousedown' won't stop
+ // the event propagation in all circumstances in presentation mode.
+ evt.preventDefault();
+ }
+}, false);
+
+window.addEventListener('keydown', function keydown(evt) {
+ if (PasswordPrompt.visible) {
+ return;
+ }
+
+ var handled = false;
+ var cmd = (evt.ctrlKey ? 1 : 0) |
+ (evt.altKey ? 2 : 0) |
+ (evt.shiftKey ? 4 : 0) |
+ (evt.metaKey ? 8 : 0);
+
+ // First, handle the key bindings that are independent whether an input
+ // control is selected or not.
+ if (cmd === 1 || cmd === 8 || cmd === 5 || cmd === 12) {
+ // either CTRL or META key with optional SHIFT.
+ switch (evt.keyCode) {
+ case 70: // f
+ if (!PDFView.supportsIntegratedFind) {
+ PDFFindBar.open();
+ handled = true;
+ }
+ break;
+ case 71: // g
+ if (!PDFView.supportsIntegratedFind) {
+ PDFFindBar.dispatchEvent('again', cmd === 5 || cmd === 12);
+ handled = true;
+ }
+ break;
+ case 61: // FF/Mac '='
+ case 107: // FF '+' and '='
+ case 187: // Chrome '+'
+ case 171: // FF with German keyboard
+ PDFView.zoomIn();
+ handled = true;
+ break;
+ case 173: // FF/Mac '-'
+ case 109: // FF '-'
+ case 189: // Chrome '-'
+ PDFView.zoomOut();
+ handled = true;
+ break;
+ case 48: // '0'
+ case 96: // '0' on Numpad of Swedish keyboard
+ // keeping it unhandled (to restore page zoom to 100%)
+ setTimeout(function () {
+ // ... and resetting the scale after browser adjusts its scale
+ PDFView.setScale(DEFAULT_SCALE, true);
+ });
+ handled = false;
+ break;
+ }
+ }
+
+ // CTRL+ALT or Option+Command
+ if (cmd === 3 || cmd === 10) {
+ switch (evt.keyCode) {
+ case 80: // p
+ SecondaryToolbar.presentationModeClick();
+ handled = true;
+ break;
+ case 71: // g
+ // focuses input#pageNumber field
+ document.getElementById('pageNumber').select();
+ handled = true;
+ break;
+ }
+ }
+
+ if (handled) {
+ evt.preventDefault();
+ return;
+ }
+
+ // Some shortcuts should not get handled if a control/input element
+ // is selected.
+ var curElement = document.activeElement || document.querySelector(':focus');
+ if (curElement && (curElement.tagName.toUpperCase() === 'INPUT' ||
+ curElement.tagName.toUpperCase() === 'TEXTAREA' ||
+ curElement.tagName.toUpperCase() === 'SELECT')) {
+ // Make sure that the secondary toolbar is closed when Escape is pressed.
+ if (evt.keyCode !== 27) { // 'Esc'
+ return;
+ }
+ }
+ var controlsElement = document.getElementById('toolbar');
+ while (curElement) {
+ if (curElement === controlsElement && !PresentationMode.active)
+ return; // ignoring if the 'toolbar' element is focused
+ curElement = curElement.parentNode;
+ }
+
+ if (cmd === 0) { // no control key pressed at all.
+ switch (evt.keyCode) {
+ case 38: // up arrow
+ case 33: // pg up
+ case 8: // backspace
+ if (!PresentationMode.active &&
+ PDFView.currentScaleValue !== 'page-fit') {
+ break;
+ }
+ /* in presentation mode */
+ /* falls through */
+ case 37: // left arrow
+ // horizontal scrolling using arrow keys
+ if (PDFView.isHorizontalScrollbarEnabled) {
+ break;
+ }
+ /* falls through */
+ case 75: // 'k'
+ case 80: // 'p'
+ PDFView.page--;
+ handled = true;
+ break;
+ case 27: // esc key
+ if (SecondaryToolbar.opened) {
+ SecondaryToolbar.close();
+ handled = true;
+ }
+ if (!PDFView.supportsIntegratedFind && PDFFindBar.opened) {
+ PDFFindBar.close();
+ handled = true;
+ }
+ break;
+ case 40: // down arrow
+ case 34: // pg down
+ case 32: // spacebar
+ if (!PresentationMode.active &&
+ PDFView.currentScaleValue !== 'page-fit') {
+ break;
+ }
+ /* falls through */
+ case 39: // right arrow
+ // horizontal scrolling using arrow keys
+ if (PDFView.isHorizontalScrollbarEnabled) {
+ break;
+ }
+ /* falls through */
+ case 74: // 'j'
+ case 78: // 'n'
+ PDFView.page++;
+ handled = true;
+ break;
+
+ case 36: // home
+ if (PresentationMode.active) {
+ PDFView.page = 1;
+ handled = true;
+ }
+ break;
+ case 35: // end
+ if (PresentationMode.active) {
+ PDFView.page = PDFView.pdfDocument.numPages;
+ handled = true;
+ }
+ break;
+
+ case 72: // 'h'
+ if (!PresentationMode.active) {
+ HandTool.toggle();
+ }
+ break;
+ case 82: // 'r'
+ PDFView.rotatePages(90);
+ break;
+ }
+ }
+
+ if (cmd === 4) { // shift-key
+ switch (evt.keyCode) {
+ case 32: // spacebar
+ if (!PresentationMode.active &&
+ PDFView.currentScaleValue !== 'page-fit') {
+ break;
+ }
+ PDFView.page--;
+ handled = true;
+ break;
+
+ case 82: // 'r'
+ PDFView.rotatePages(-90);
+ break;
+ }
+ }
+
+ if (cmd === 2) { // alt-key
+ switch (evt.keyCode) {
+ case 37: // left arrow
+ if (PresentationMode.active) {
+ PDFHistory.back();
+ handled = true;
+ }
+ break;
+ case 39: // right arrow
+ if (PresentationMode.active) {
+ PDFHistory.forward();
+ handled = true;
+ }
+ break;
+ }
+ }
+
+ if (handled) {
+ evt.preventDefault();
+ PDFView.clearMouseScrollState();
+ }
+});
+
+window.addEventListener('beforeprint', function beforePrint(evt) {
+ PDFView.beforePrint();
+});
+
+window.addEventListener('afterprint', function afterPrint(evt) {
+ PDFView.afterPrint();
+});
+
+(function animationStartedClosure() {
+ // The offsetParent is not set until the pdf.js iframe or object is visible.
+ // Waiting for first animation.
+ var requestAnimationFrame = window.requestAnimationFrame ||
+ window.mozRequestAnimationFrame ||
+ window.webkitRequestAnimationFrame ||
+ window.oRequestAnimationFrame ||
+ window.msRequestAnimationFrame ||
+ function startAtOnce(callback) { callback(); };
+ PDFView.animationStartedPromise = new Promise(function (resolve) {
+ requestAnimationFrame(function onAnimationFrame() {
+ resolve();
+ });
+ });
+})();
+
+
diff --git a/plugins/pdfviewer/viewer/viewer.min.js b/plugins/pdfviewer/viewer/viewer.min.js
new file mode 100644
index 0000000..e11ec84
--- /dev/null
+++ b/plugins/pdfviewer/viewer/viewer.min.js
@@ -0,0 +1,164 @@
+var DEFAULT_URL=null,DEFAULT_SCALE="auto",DEFAULT_SCALE_DELTA=1.1,UNKNOWN_SCALE=0,CACHE_SIZE=20,CSS_UNITS=96/72,SCROLLBAR_PADDING=40,VERTICAL_PADDING=5,MAX_AUTO_SCALE=1.25,MIN_SCALE=0.25,MAX_SCALE=4,VIEW_HISTORY_MEMORY=20,SCALE_SELECT_CONTAINER_PADDING=8,SCALE_SELECT_PADDING=22,THUMBNAIL_SCROLL_MARGIN=-19,USE_ONLY_CSS_ZOOM=!1,CLEANUP_TIMEOUT=3E4,IGNORE_CURRENT_POSITION_ON_ZOOM=!1,RenderingStates={INITIAL:0,RUNNING:1,PAUSED:2,FINISHED:3},FindStates={FIND_FOUND:0,FIND_NOTFOUND:1,FIND_WRAPPED:2,FIND_PENDING:3};
+PDFJS.imageResourcesPath="./images/";PDFJS.workerSrc="pdf.worker.js";
+var mozL10n=document.mozL10n||document.webL10n,CustomStyle=function(){function a(){}var b=["ms","Moz","Webkit","O"],c={};a.getProp=function(a,e){if(1==arguments.length&&"string"==typeof c[a])return c[a];e=e||document.documentElement;var g=e.style,h,f;if("string"==typeof g[a])return c[a]=a;f=a.charAt(0).toUpperCase()+a.slice(1);for(var k=0,s=b.length;k<s;k++)if(h=b[k]+f,"string"==typeof g[h])return c[a]=h;return c[a]="undefined"};a.setProp=function(a,b,c){a=this.getProp(a);"undefined"!=a&&(b.style[a]=
+c)};return a}();function getFileName(a){var b=a.indexOf("#"),c=a.indexOf("?"),b=Math.min(0<b?b:a.length,0<c?c:a.length);return a.substring(a.lastIndexOf("/",b)+1,b)}function getOutputScale(a){a=(window.devicePixelRatio||1)/(a.webkitBackingStorePixelRatio||a.mozBackingStorePixelRatio||a.msBackingStorePixelRatio||a.oBackingStorePixelRatio||a.backingStorePixelRatio||1);return{sx:a,sy:a,scaled:1!=a}}
+function scrollIntoView(a,b){var c=a.offsetParent,d=a.offsetTop+a.clientTop,e=a.offsetLeft+a.clientLeft;if(c){for(;c.clientHeight===c.scrollHeight;)if(c.dataset._scaleY&&(d/=c.dataset._scaleY,e/=c.dataset._scaleX),d+=c.offsetTop,e+=c.offsetLeft,c=c.offsetParent,!c)return;b&&(void 0!==b.top&&(d+=b.top),void 0!==b.left&&(e+=b.left,c.scrollLeft=e));c.scrollTop=d}else console.error("offsetParent is not set -- cannot scroll")}function noContextMenuHandler(a){a.preventDefault()}
+function getPDFFileNameFromURL(a){var b=/[^\/?#=]+\.pdf\b(?!.*\.pdf\b)/i;a=/^(?:([^:]+:)?\/\/[^\/]+)?([^?#]*)(\?[^#]*)?(#.*)?$/.exec(a);if(a=b.exec(a[1])||b.exec(a[2])||b.exec(a[3]))if(a=a[0],-1!=a.indexOf("%"))try{a=b.exec(decodeURIComponent(a))[0]}catch(c){}return a||"document.pdf"}
+var ProgressBar=function(){function a(a,c){this.div=document.querySelector(a+" .progress");this.bar=this.div.parentNode;this.height=c.height||100;this.width=c.width||100;this.units=c.units||"%";this.div.style.height=this.height+this.units;this.percent=0}a.prototype={updateBar:function(){this._indeterminate?(this.div.classList.add("indeterminate"),this.div.style.width=this.width+this.units):(this.div.classList.remove("indeterminate"),this.div.style.width=this.width*this._percent/100+this.units)},get percent(){return this._percent},
+set percent(a){this._indeterminate=isNaN(a);this._percent=Math.min(Math.max(a,0),100);this.updateBar()},setWidth:function(a){a&&(a=a.parentNode.offsetWidth-a.offsetWidth,0<a&&this.bar.setAttribute("style","width: calc(100% - "+a+"px);"))},hide:function(){this.bar.classList.add("hidden");this.bar.removeAttribute("style")}};return a}(),Cache=function(a){var b=[];this.push=function(c){var d=b.indexOf(c);0<=d&&b.splice(d);b.push(c);b.length>a&&b.shift().destroy()}},isLocalStorageEnabled=function(){try{return"localStorage"in
+window&&null!==window.localStorage&&localStorage}catch(a){return!1}}(),EXPORTED_SYMBOLS=["DEFAULT_PREFERENCES"],DEFAULT_PREFERENCES={showPreviousViewOnLoad:!0,defaultZoomValue:"",ifAvailableShowOutlineOnLoad:!1},Preferences=function(){function a(){this.prefs={};this.isInitializedPromiseResolved=!1;this.initializedPromise=this.readFromStorage().then(function(a){this.isInitializedPromiseResolved=!0;a&&(this.prefs=a)}.bind(this))}a.prototype={writeToStorage:function(a){},readFromStorage:function(){return Promise.resolve()},
+reset:function(){this.isInitializedPromiseResolved&&(this.prefs={},this.writeToStorage(this.prefs))},set:function(a,c){if(this.isInitializedPromiseResolved)if(void 0===DEFAULT_PREFERENCES[a])console.error("Preferences_set: '"+a+"' is undefined.");else if(void 0===c)console.error("Preferences_set: no value is specified.");else{var d=typeof c,e=typeof DEFAULT_PREFERENCES[a];if(d!==e)if("number"===d&&"string"===e)c=c.toString();else{console.error("Preferences_set: '"+c+"' is a \""+d+'", expected a "'+
+e+'".');return}this.prefs[a]=c;this.writeToStorage(this.prefs)}},get:function(a){var c=DEFAULT_PREFERENCES[a];if(void 0===c)console.error("Preferences_get: '"+a+"' is undefined.");else return this.isInitializedPromiseResolved&&(a=this.prefs[a],void 0!==a)?a:c}};return a}();Preferences.prototype.writeToStorage=function(a){isLocalStorageEnabled&&localStorage.setItem("preferences",JSON.stringify(a))};
+Preferences.prototype.readFromStorage=function(){return new Promise(function(a){if(isLocalStorageEnabled){var b=JSON.parse(localStorage.getItem("preferences"));a(b)}})};
+(function(){function a(a){var b=document.createEvent("CustomEvent");b.initCustomEvent(a,!1,!1,"custom");window.dispatchEvent(b)}function b(){if(e)if(d(),++g<e.length){var a=e[g];"function"===typeof a.mozPrintCallback?a.mozPrintCallback({context:a.getContext("2d"),abort:c,done:b}):b()}else d(),h.call(window),setTimeout(c,20)}function c(){e&&(e=null,d(),a("afterprint"))}function d(){var a=document.getElementById("mozPrintCallback-shim");if(e){var b=Math.round(100*g/e.length),d=a.querySelector("progress"),
+h=a.querySelector(".relative-progress");d.value=b;h.textContent=b+"%";a.removeAttribute("hidden");a.onclick=c}else a.setAttribute("hidden","")}if(!("mozPrintCallback"in document.createElement("canvas"))){HTMLCanvasElement.prototype.mozPrintCallback=void 0;var e,g,h=window.print;window.print=function(){if(e)console.warn("Ignored window.print() because of a pending print job.");else try{a("beforeprint")}finally{e=document.querySelectorAll("canvas"),g=-1,b()}};var f=!!document.attachEvent;window.addEventListener("keydown",
+function(a){80===a.keyCode&&(a.ctrlKey||a.metaKey)?(window.print(),f||(a.preventDefault(),a.stopImmediatePropagation?a.stopImmediatePropagation():a.stopPropagation())):27===a.keyCode&&e&&c()},!0);f&&document.attachEvent("onkeydown",function(a){a=a||window.event;if(80===a.keyCode&&a.ctrlKey)return a.keyCode=0,!1});if("onbeforeprint"in window){var k=function(a){"custom"!==a.detail&&a.stopImmediatePropagation&&a.stopImmediatePropagation()};window.addEventListener("beforeprint",k,!1);window.addEventListener("afterprint",
+k,!1)}}})();
+var DownloadManager=function(){function a(a,b){var e=document.createElement("a");e.click?(e.href=a,e.target="_parent","download"in e&&(e.download=b),(document.body||document.documentElement).appendChild(e),e.click(),e.parentNode.removeChild(e)):(window.top===window&&a.split("#")[0]===window.location.href.split("#")[0]&&(e=-1===a.indexOf("?")?"?":"&",a=a.replace(/#|$/,e+"$&")),window.open(a,"_parent"))}function b(){}b.prototype={downloadUrl:function(b,d){PDFJS.isValidUrl(b,!0)&&a(b+"#pdfjs.action=download",d)},
+download:function(b,d,e){URL?navigator.msSaveBlob?navigator.msSaveBlob(b,e)||this.downloadUrl(d,e):(b=URL.createObjectURL(b),a(b,e)):this.downloadUrl(d,e)}};return b}(),cache=new Cache(CACHE_SIZE),currentPageNumber=1,ViewHistory=function(){function a(a){this.fingerprint=a;var c;this.isInitializedPromiseResolved=!1;this.initializedPromise=new Promise(function(a){c=a});a=function(a){this.isInitializedPromiseResolved=!0;this.initialize(a||"{}");c()}.bind(this);isLocalStorageEnabled&&a(localStorage.getItem("database"))}
+a.prototype={initialize:function(a){a=JSON.parse(a);"files"in a||(a.files=[]);a.files.length>=VIEW_HISTORY_MEMORY&&a.files.shift();for(var c,d=0,e=a.files.length;d<e;d++)if(a.files[d].fingerprint===this.fingerprint){c=d;break}"number"!==typeof c&&(c=a.files.push({fingerprint:this.fingerprint})-1);this.file=a.files[c];this.database=a},set:function(a,c){if(this.isInitializedPromiseResolved){this.file[a]=c;var d=JSON.stringify(this.database);isLocalStorageEnabled&&localStorage.setItem("database",d)}},
+get:function(a,c){return this.isInitializedPromiseResolved?this.file[a]||c:c}};return a}(),PDFFindBar={opened:!1,bar:null,toggleButton:null,findField:null,highlightAll:null,caseSensitive:null,findMsg:null,findStatusIcon:null,findPreviousButton:null,findNextButton:null,initialize:function(a){if("undefined"===typeof PDFFindController||null===PDFFindController)throw"PDFFindBar cannot be initialized without a PDFFindController instance.";this.bar=a.bar;this.toggleButton=a.toggleButton;this.findField=
+a.findField;this.highlightAll=a.highlightAllCheckbox;this.caseSensitive=a.caseSensitiveCheckbox;this.findMsg=a.findMsg;this.findStatusIcon=a.findStatusIcon;this.findPreviousButton=a.findPreviousButton;this.findNextButton=a.findNextButton;var b=this;this.toggleButton.addEventListener("click",function(){b.toggle()});this.findField.addEventListener("input",function(){b.dispatchEvent("")});this.bar.addEventListener("keydown",function(a){switch(a.keyCode){case 13:a.target===b.findField&&b.dispatchEvent("again",
+a.shiftKey);break;case 27:b.close()}});this.findPreviousButton.addEventListener("click",function(){b.dispatchEvent("again",!0)});this.findNextButton.addEventListener("click",function(){b.dispatchEvent("again",!1)});this.highlightAll.addEventListener("click",function(){b.dispatchEvent("highlightallchange")});this.caseSensitive.addEventListener("click",function(){b.dispatchEvent("casesensitivitychange")})},dispatchEvent:function(a,b){var c=document.createEvent("CustomEvent");c.initCustomEvent("find"+
+a,!0,!0,{query:this.findField.value,caseSensitive:this.caseSensitive.checked,highlightAll:this.highlightAll.checked,findPrevious:b});return window.dispatchEvent(c)},updateUIState:function(a,b){var c=!1,d="",e="";switch(a){case FindStates.FIND_PENDING:e="pending";break;case FindStates.FIND_NOTFOUND:d=mozL10n.get("find_not_found",null,"Phrase not found");c=!0;break;case FindStates.FIND_WRAPPED:d=b?mozL10n.get("find_reached_top",null,"Reached top of document, continued from bottom"):mozL10n.get("find_reached_bottom",
+null,"Reached end of document, continued from top")}c?this.findField.classList.add("notFound"):this.findField.classList.remove("notFound");this.findField.setAttribute("data-status",e);this.findMsg.textContent=d},open:function(){this.opened||(this.opened=!0,this.toggleButton.classList.add("toggled"),this.bar.classList.remove("hidden"));this.findField.select();this.findField.focus()},close:function(){this.opened&&(this.opened=!1,this.toggleButton.classList.remove("toggled"),this.bar.classList.add("hidden"),
+PDFFindController.active=!1)},toggle:function(){this.opened?this.close():this.open()}},PDFFindController={startedTextExtraction:!1,extractTextPromises:[],pendingFindMatches:{},active:!1,pageContents:[],pageMatches:[],selected:{pageIdx:-1,matchIdx:-1},offset:{pageIdx:null,matchIdx:null},resumePageIdx:null,resumeCallback:null,state:null,dirtyMatch:!1,findTimeout:null,pdfPageSource:null,integratedFind:!1,initialize:function(a){if("undefined"===typeof PDFFindBar||null===PDFFindBar)throw"PDFFindController cannot be initialized without a PDFFindController instance";
+this.pdfPageSource=a.pdfPageSource;this.integratedFind=a.integratedFind;a=["find","findagain","findhighlightallchange","findcasesensitivitychange"];this.firstPagePromise=new Promise(function(a){this.resolveFirstPage=a}.bind(this));this.handleEvent=this.handleEvent.bind(this);for(var b=0;b<a.length;b++)window.addEventListener(a[b],this.handleEvent)},reset:function(){this.startedTextExtraction=!1;this.extractTextPromises=[];this.active=!1},calcFindMatch:function(a){var b=this.pageContents[a],c=this.state.query,
+d=this.state.caseSensitive,e=c.length;if(0!==e){d||(b=b.toLowerCase(),c=c.toLowerCase());for(var d=[],g=-e;;){g=b.indexOf(c,g+e);if(-1===g)break;d.push(g)}this.pageMatches[a]=d;this.updatePage(a);this.resumePageIdx===a&&(a=this.resumeCallback,this.resumeCallback=this.resumePageIdx=null,a())}},extractText:function(){function a(c){e.pdfPageSource.pages[c].getTextContent().then(function(d){d=d.bidiTexts;for(var f="",k=0;k<d.length;k++)f+=d[k].str;e.pageContents.push(f);b[c](c);c+1<e.pdfPageSource.pages.length&&
+a(c+1)})}if(!this.startedTextExtraction){this.startedTextExtraction=!0;this.pageContents=[];for(var b=[],c=0,d=this.pdfPageSource.pdfDocument.numPages;c<d;c++)this.extractTextPromises.push(new Promise(function(a){b.push(a)}));var e=this;a(0)}},handleEvent:function(a){if(null===this.state||"findagain"!==a.type)this.dirtyMatch=!0;this.state=a.detail;this.updateUIState(FindStates.FIND_PENDING);this.firstPagePromise.then(function(){this.extractText();clearTimeout(this.findTimeout);"find"===a.type?this.findTimeout=
+setTimeout(this.nextMatch.bind(this),250):this.nextMatch()}.bind(this))},updatePage:function(a){var b=this.pdfPageSource.pages[a];this.selected.pageIdx===a&&b.scrollIntoView();b.textLayer&&b.textLayer.updateMatches()},nextMatch:function(){var a=this.state.findPrevious,b=this.pdfPageSource.page-1,c=this.pdfPageSource.pages.length;this.active=!0;if(this.dirtyMatch){this.dirtyMatch=!1;this.selected.pageIdx=this.selected.matchIdx=-1;this.offset.pageIdx=b;this.offset.matchIdx=null;this.hadMatch=!1;this.resumePageIdx=
+this.resumeCallback=null;this.pageMatches=[];for(var d=this,b=0;b<c;b++)this.updatePage(b),b in this.pendingFindMatches||(this.pendingFindMatches[b]=!0,this.extractTextPromises[b].then(function(a){delete d.pendingFindMatches[a];d.calcFindMatch(a)}))}if(""===this.state.query)this.updateUIState(FindStates.FIND_FOUND);else if(!this.resumeCallback){c=this.offset;if(null!==c.matchIdx){b=this.pageMatches[c.pageIdx].length;if(!a&&c.matchIdx+1<b||a&&0<c.matchIdx){this.hadMatch=!0;c.matchIdx=a?c.matchIdx-
+1:c.matchIdx+1;this.updateMatch(!0);return}this.advanceOffsetPage(a)}this.nextPageMatch()}},nextPageMatch:function(){null!==this.resumePageIdx&&console.error("There can only be one pending page.");var a=function(a){var b=this.offset;a=a.length;var c=this.state.findPrevious;if(a)this.hadMatch=!0,b.matchIdx=c?a-1:0,this.updateMatch(!0);else{this.advanceOffsetPage(c);if(b.wrapped&&(b.matchIdx=null,!this.hadMatch)){this.updateMatch(!1);return}this.nextPageMatch()}}.bind(this),b=this.offset.pageIdx,c=
+this.pageMatches;c[b]?a(c[b]):(this.resumeCallback=function(){a(c[b])},this.resumePageIdx=b)},advanceOffsetPage:function(a){var b=this.offset,c=this.extractTextPromises.length;b.pageIdx=a?b.pageIdx-1:b.pageIdx+1;b.matchIdx=null;if(b.pageIdx>=c||0>b.pageIdx)b.pageIdx=a?c-1:0,b.wrapped=!0},updateMatch:function(a){var b=FindStates.FIND_NOTFOUND,c=this.offset.wrapped;this.offset.wrapped=!1;a&&(a=this.selected.pageIdx,this.selected.pageIdx=this.offset.pageIdx,this.selected.matchIdx=this.offset.matchIdx,
+b=c?FindStates.FIND_WRAPPED:FindStates.FIND_FOUND,-1!==a&&a!==this.selected.pageIdx&&this.updatePage(a));this.updateUIState(b,this.state.findPrevious);-1!==this.selected.pageIdx&&this.updatePage(this.selected.pageIdx,!0)},updateUIState:function(a,b){this.integratedFind?FirefoxCom.request("updateFindControlState",{result:a,findPrevious:b}):PDFFindBar.updateUIState(a,b)}},PDFHistory={initialized:!1,initialDestination:null,initialize:function(a){function b(){var a=c._getPreviousParams(null,!0);a&&(c._pushToHistory(a,
+!1,!c.current.dest&&c.current.hash!==c.previousHash),c._updatePreviousBookmark());window.removeEventListener("beforeunload",b,!1)}if(!PDFJS.disableHistory&&!PDFView.isViewerEmbedded){this.initialized=!0;this.reInitialized=!1;this.historyUnlocked=this.allowHashChange=!0;this.previousHash=window.location.hash.substring(1);this.currentBookmark="";this.currentPage=0;this.updatePreviousBookmark=!1;this.previousBookmark="";this.previousPage=0;this.nextHashParam="";this.fingerprint=a;this.currentUid=this.uid=
+0;this.current={};a=window.history.state;this._isStateObjectDefined(a)?(a.target.dest?this.initialDestination=a.target.dest:PDFView.initialBookmark=a.target.hash,this.currentUid=a.uid,this.uid=a.uid+1,this.current=a.target):(a&&a.fingerprint&&this.fingerprint!==a.fingerprint&&(this.reInitialized=!0),this._pushOrReplaceState({fingerprint:this.fingerprint},!0));var c=this;window.addEventListener("popstate",function(a){a.preventDefault();a.stopPropagation();c.historyUnlocked&&(a.state?c._goTo(a.state):
+(c.previousHash=window.location.hash.substring(1),0===c.uid&&(a=c.previousHash&&c.currentBookmark&&c.previousHash!==c.currentBookmark?{hash:c.currentBookmark,page:c.currentPage}:{page:1},c.historyUnlocked=!1,c.allowHashChange=!1,window.history.back(),c._pushToHistory(a,!1,!0),window.history.forward(),c.historyUnlocked=!0),c._pushToHistory({hash:c.previousHash},!1,!0),c._updatePreviousBookmark()))},!1);window.addEventListener("beforeunload",b,!1);window.addEventListener("pageshow",function(a){window.addEventListener("beforeunload",
+b,!1)},!1)}},_isStateObjectDefined:function(a){return a&&0<=a.uid&&a.fingerprint&&this.fingerprint===a.fingerprint&&a.target&&a.target.hash?!0:!1},_pushOrReplaceState:function(a,b){b?window.history.replaceState(a,"",document.URL):window.history.pushState(a,"",document.URL)},get isHashChangeUnlocked(){if(!this.initialized)return!0;var a=this.allowHashChange;this.allowHashChange=!0;return a},_updatePreviousBookmark:function(){this.updatePreviousBookmark&&this.currentBookmark&&this.currentPage&&(this.previousBookmark=
+this.currentBookmark,this.previousPage=this.currentPage,this.updatePreviousBookmark=!1)},updateCurrentBookmark:function(a,b){this.initialized&&(this.currentBookmark=a.substring(1),this.currentPage=b|0,this._updatePreviousBookmark())},updateNextHashParam:function(a){this.initialized&&(this.nextHashParam=a)},push:function(a,b){if(this.initialized&&this.historyUnlocked)if(a.dest&&!a.hash&&(a.hash=this.current.hash&&this.current.dest&&this.current.dest===a.dest?this.current.hash:PDFView.getDestinationHash(a.dest).split("#")[1]),
+a.page&&(a.page|=0),b){var c=window.history.state.target;c||(this._pushToHistory(a,!1),this.previousHash=window.location.hash.substring(1));this.updatePreviousBookmark=this.nextHashParam?!1:!0;c&&this._updatePreviousBookmark()}else{if(this.nextHashParam){if(this.nextHashParam===a.hash){this.nextHashParam=null;this.updatePreviousBookmark=!0;return}this.nextHashParam=null}a.hash?this.current.hash?this.current.hash!==a.hash?this._pushToHistory(a,!0):(!this.current.page&&a.page&&this._pushToHistory(a,
+!1,!0),this.updatePreviousBookmark=!0):this._pushToHistory(a,!0):this.current.page&&a.page&&this.current.page!==a.page&&this._pushToHistory(a,!0)}},_getPreviousParams:function(a,b){if(!this.currentBookmark||!this.currentPage)return null;this.updatePreviousBookmark&&(this.updatePreviousBookmark=!1);if(0<this.uid&&(!this.previousBookmark||!this.previousPage))return null;if(!this.current.dest&&!a||b){if(this.previousBookmark===this.currentBookmark)return null}else if(this.current.page||a){if(this.previousPage===
+this.currentPage)return null}else return null;var c={hash:this.currentBookmark,page:this.currentPage};PresentationMode.active&&(c.hash=null);return c},_stateObj:function(a){return{fingerprint:this.fingerprint,uid:this.uid,target:a}},_pushToHistory:function(a,b,c){this.initialized&&(!a.hash&&a.page&&(a.hash="page="+a.page),b&&!c&&(b=this._getPreviousParams())&&this._pushToHistory(b,!1,!this.current.dest&&this.current.hash!==this.previousHash),this._pushOrReplaceState(this._stateObj(a),c||0===this.uid),
+this.currentUid=this.uid++,this.current=a,this.updatePreviousBookmark=!0)},_goTo:function(a){if(this.initialized&&this.historyUnlocked&&this._isStateObjectDefined(a)){if(!this.reInitialized&&a.uid<this.currentUid){var b=this._getPreviousParams(!0);if(b){this._pushToHistory(this.current,!1);this._pushToHistory(b,!1);this.currentUid=a.uid;window.history.back();return}}this.historyUnlocked=!1;a.target.dest?PDFView.navigateTo(a.target.dest):PDFView.setHash(a.target.hash);this.currentUid=a.uid;a.uid>this.uid&&
+(this.uid=a.uid);this.current=a.target;this.updatePreviousBookmark=!0;a=window.location.hash.substring(1);this.previousHash!==a&&(this.allowHashChange=!1);this.previousHash=a;this.historyUnlocked=!0}},back:function(){this.go(-1)},forward:function(){this.go(1)},go:function(a){if(this.initialized&&this.historyUnlocked){var b=window.history.state;-1===a&&b&&0<b.uid?window.history.back():1===a&&b&&b.uid<this.uid-1&&window.history.forward()}}},SecondaryToolbar={opened:!1,previousContainerHeight:null,newContainerHeight:null,
+initialize:function(a){this.toolbar=a.toolbar;this.presentationMode=a.presentationMode;this.buttonContainer=this.toolbar.firstElementChild;this.toggleButton=a.toggleButton;this.presentationModeButton=a.presentationModeButton;this.openFile=a.openFile;this.print=a.print;this.download=a.download;this.firstPage=a.firstPage;this.lastPage=a.lastPage;this.pageRotateCw=a.pageRotateCw;this.pageRotateCcw=a.pageRotateCcw;a=[{element:this.toggleButton,handler:this.toggle},{element:this.presentationModeButton,
+handler:this.presentationModeClick},{element:this.print,handler:this.printClick},{element:this.firstPage,handler:this.firstPageClick},{element:this.lastPage,handler:this.lastPageClick},{element:this.pageRotateCw,handler:this.pageRotateCwClick},{element:this.pageRotateCcw,handler:this.pageRotateCcwClick}];for(var b in a){var c=a[b].element;c&&c.addEventListener("click",a[b].handler.bind(this))}},presentationModeClick:function(a){this.presentationMode.request();this.close()},openFileClick:function(a){document.getElementById("fileInput").click();
+this.close(a.target)},printClick:function(a){window.print();this.close(a.target)},downloadClick:function(a){PDFView.download();this.close(a.target)},firstPageClick:function(a){PDFView.page=1},lastPageClick:function(a){PDFView.page=PDFView.pdfDocument.numPages},pageRotateCwClick:function(a){PDFView.rotatePages(90)},pageRotateCcwClick:function(a){PDFView.rotatePages(-90)},setMaxHeight:function(a){a&&this.buttonContainer&&(this.newContainerHeight=a.clientHeight,this.previousContainerHeight!==this.newContainerHeight&&
+(this.buttonContainer.setAttribute("style","max-height: "+(this.newContainerHeight-SCROLLBAR_PADDING)+"px;"),this.previousContainerHeight=this.newContainerHeight))},open:function(){this.opened||(this.opened=!0,this.toggleButton.classList.add("toggled"),this.toolbar.classList.remove("hidden"))},close:function(a){!this.opened||a&&!this.toolbar.contains(a)||(this.opened=!1,this.toolbar.classList.add("hidden"),this.toggleButton.classList.remove("toggled"))},toggle:function(){this.opened?this.close():
+this.open()}},PasswordPrompt={visible:!1,updatePassword:null,reason:null,overlayContainer:null,passwordField:null,passwordText:null,passwordSubmit:null,passwordCancel:null,initialize:function(a){this.overlayContainer=a.overlayContainer;this.passwordField=a.passwordField;this.passwordText=a.passwordText;this.passwordSubmit=a.passwordSubmit;this.passwordCancel=a.passwordCancel;this.passwordSubmit.addEventListener("click",this.verifyPassword.bind(this));this.passwordCancel.addEventListener("click",this.hide.bind(this));
+this.passwordField.addEventListener("keydown",function(a){13===a.keyCode&&this.verifyPassword()}.bind(this));this.overlayContainer.addEventListener("keydown",function(a){27===a.keyCode&&this.hide()}.bind(this))},show:function(){if(!this.visible){this.visible=!0;this.overlayContainer.classList.remove("hidden");this.passwordField.focus();var a=mozL10n.get("password_label",null,"Enter the password to open this PDF file.");this.reason===PDFJS.PasswordResponses.INCORRECT_PASSWORD&&(a=mozL10n.get("password_invalid",
+null,"Invalid password. Please try again."));this.passwordText.textContent=a}},hide:function(){this.visible&&(this.visible=!1,this.passwordField.value="",this.overlayContainer.classList.add("hidden"))},verifyPassword:function(){var a=this.passwordField.value;if(a&&0<a.length)return this.hide(),this.updatePassword(a)}},DELAY_BEFORE_HIDING_CONTROLS=3E3,SELECTOR="presentationControls",DELAY_BEFORE_RESETTING_SWITCH_IN_PROGRESS=1E3,PresentationMode={active:!1,args:null,contextMenuOpen:!1,prevCoords:{x:null,
+y:null},initialize:function(a){this.container=a.container;this.secondaryToolbar=a.secondaryToolbar;this.viewer=this.container.firstElementChild;this.firstPage=a.firstPage;this.lastPage=a.lastPage;this.pageRotateCw=a.pageRotateCw;this.pageRotateCcw=a.pageRotateCcw;this.firstPage.addEventListener("click",function(){this.contextMenuOpen=!1;this.secondaryToolbar.firstPageClick()}.bind(this));this.lastPage.addEventListener("click",function(){this.contextMenuOpen=!1;this.secondaryToolbar.lastPageClick()}.bind(this));
+this.pageRotateCw.addEventListener("click",function(){this.contextMenuOpen=!1;this.secondaryToolbar.pageRotateCwClick()}.bind(this));this.pageRotateCcw.addEventListener("click",function(){this.contextMenuOpen=!1;this.secondaryToolbar.pageRotateCcwClick()}.bind(this))},get isFullscreen(){return document.fullscreenElement||document.mozFullScreen||document.webkitIsFullScreen||document.msFullscreenElement},_setSwitchInProgress:function(){this.switchInProgress&&clearTimeout(this.switchInProgress);this.switchInProgress=
+setTimeout(function(){delete this.switchInProgress}.bind(this),DELAY_BEFORE_RESETTING_SWITCH_IN_PROGRESS);PDFView.currentPosition=null},_resetSwitchInProgress:function(){this.switchInProgress&&(clearTimeout(this.switchInProgress),delete this.switchInProgress)},request:function(){if(!PDFView.supportsFullscreen||this.isFullscreen||!this.viewer.hasChildNodes())return!1;this._setSwitchInProgress();if(this.container.requestFullscreen)this.container.requestFullscreen();else if(this.container.mozRequestFullScreen)this.container.mozRequestFullScreen();
+else if(this.container.webkitRequestFullScreen)this.container.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);else if(this.container.msRequestFullscreen)this.container.msRequestFullscreen();else return!1;this.args={page:PDFView.page,previousScale:PDFView.currentScaleValue};return!0},enter:function(){this.active=!0;this._resetSwitchInProgress();setTimeout(function(){PDFView.page=this.args.page;PDFView.setScale("page-fit",!0)}.bind(this),0);window.addEventListener("mousemove",this.mouseMove,!1);
+window.addEventListener("mousedown",this.mouseDown,!1);window.addEventListener("contextmenu",this.contextMenu,!1);this.showControls();HandTool.enterPresentationMode();this.contextMenuOpen=!1;this.container.setAttribute("contextmenu","viewerContextMenu")},exit:function(){var a=PDFView.page;setTimeout(function(){PDFView.setScale(this.args.previousScale);PDFView.page=a;this.active=!1;this.args=null}.bind(this),0);window.removeEventListener("mousemove",this.mouseMove,!1);window.removeEventListener("mousedown",
+this.mouseDown,!1);window.removeEventListener("contextmenu",this.contextMenu,!1);this.hideControls();PDFView.clearMouseScrollState();HandTool.exitPresentationMode();this.container.removeAttribute("contextmenu");this.contextMenuOpen=!1;scrollIntoView(document.getElementById("thumbnailContainer"+a))},showControls:function(){this.controlsTimeout?clearTimeout(this.controlsTimeout):this.container.classList.add(SELECTOR);this.controlsTimeout=setTimeout(function(){this.container.classList.remove(SELECTOR);
+delete this.controlsTimeout}.bind(this),DELAY_BEFORE_HIDING_CONTROLS)},hideControls:function(){this.controlsTimeout&&(this.container.classList.remove(SELECTOR),clearTimeout(this.controlsTimeout),delete this.controlsTimeout)},mouseMove:function(a){a={x:a.clientX,y:a.clientY};var b=PresentationMode.prevCoords;PresentationMode.prevCoords=a;a.x===b.x&&a.y===b.y||PresentationMode.showControls()},mouseDown:function(a){var b=PresentationMode;b.contextMenuOpen?(b.contextMenuOpen=!1,a.preventDefault()):0!==
+a.button||a.target.href&&a.target.classList.contains("internalLink")||(a.preventDefault(),PDFView.page+=a.shiftKey?-1:1)},contextMenu:function(a){PresentationMode.contextMenuOpen=!0}};(function(){function a(a){PresentationMode.isFullscreen?PresentationMode.enter():PresentationMode.exit()}window.addEventListener("fullscreenchange",a,!1);window.addEventListener("mozfullscreenchange",a,!1);window.addEventListener("webkitfullscreenchange",a,!1);window.addEventListener("MSFullscreenChange",a,!1)})();"use strict";
+var GrabToPan=function(){function a(a){this.element=a.element;this.document=a.element.ownerDocument;"function"===typeof a.ignoreTarget&&(this.ignoreTarget=a.ignoreTarget);this.onActiveChanged=a.onActiveChanged;this.activate=this.activate.bind(this);this.deactivate=this.deactivate.bind(this);this.toggle=this.toggle.bind(this);this._onmousedown=this._onmousedown.bind(this);this._onmousemove=this._onmousemove.bind(this);this._endPan=this._endPan.bind(this)}a.prototype={CSS_CLASS_GRAB:"grab-to-pan-grab",
+CSS_CLASS_GRABBING:"grab-to-pan-grabbing",activate:function(){if(!this.active&&(this.active=!0,this.element.addEventListener("mousedown",this._onmousedown,!0),this.element.classList.add(this.CSS_CLASS_GRAB),this.onActiveChanged))this.onActiveChanged(!0)},deactivate:function(){if(this.active&&(this.active=!1,this.element.removeEventListener("mousedown",this._onmousedown,!0),this._endPan(),this.element.classList.remove(this.CSS_CLASS_GRAB),this.onActiveChanged))this.onActiveChanged(!1)},toggle:function(){this.active?
+this.deactivate():this.activate()},ignoreTarget:function(a){return a[b]("a[href], a[href] *, input, textarea, button, button *, select, option")},_onmousedown:function(a){if(0===a.button&&!this.ignoreTarget(a.target)){if(a.originalTarget)try{a.originalTarget.tagName}catch(b){return}this.scrollLeftStart=this.element.scrollLeft;this.scrollTopStart=this.element.scrollTop;this.clientXStart=a.clientX;this.clientYStart=a.clientY;this.document.addEventListener("mousemove",this._onmousemove,!0);this.document.addEventListener("mouseup",
+this._endPan,!0);this.element.addEventListener("scroll",this._endPan,!0);a.preventDefault();a.stopPropagation();this.element.classList.remove(this.CSS_CLASS_GRAB);this.document.documentElement.classList.add(this.CSS_CLASS_GRABBING)}},_onmousemove:function(a){this.element.removeEventListener("scroll",this._endPan,!0);var b;b="buttons"in a&&c?!(a.buttons|1):e||g?0===a.which:void 0;b?this.document.removeEventListener("mousemove",this._onmousemove,!0):(b=a.clientX-this.clientXStart,this.element.scrollTop=
+this.scrollTopStart-(a.clientY-this.clientYStart),this.element.scrollLeft=this.scrollLeftStart-b)},_endPan:function(){this.element.removeEventListener("scroll",this._endPan,!0);this.document.removeEventListener("mousemove",this._onmousemove,!0);this.document.removeEventListener("mouseup",this._endPan,!0);this.document.documentElement.classList.remove(this.CSS_CLASS_GRABBING);this.element.classList.add(this.CSS_CLASS_GRAB)}};var b;["webkitM","mozM","msM","oM","m"].some(function(a){a+="atches";a in
+document.documentElement&&(b=a);a+="Selector";a in document.documentElement&&(b=a);return b});var c=!document.documentMode||9<document.documentMode,d=window.chrome,e=d&&(d.webstore||d.app),g=/Apple/.test(navigator.vendor)&&/Version\/([6-9]\d*|[1-5]\d+)/.test(navigator.userAgent);return a}(),HandTool={initialize:function(a){var b=a.toggleHandTool;this.handTool=new GrabToPan({element:a.container,onActiveChanged:function(a){b&&(a?(b.title=mozL10n.get("hand_tool_disable.title",null,"Disable hand tool"),
+b.firstElementChild.textContent=mozL10n.get("hand_tool_disable_label",null,"Disable hand tool")):(b.title=mozL10n.get("hand_tool_enable.title",null,"Enable hand tool"),b.firstElementChild.textContent=mozL10n.get("hand_tool_enable_label",null,"Enable hand tool")))}});b&&b.addEventListener("click",this.handTool.toggle,!1)},toggle:function(){this.handTool.toggle()},enterPresentationMode:function(){this.handTool.active&&(this.wasActive=!0,this.handTool.deactivate())},exitPresentationMode:function(){this.wasActive&&
+(this.wasActive=null,this.handTool.activate())}},PDFView={pages:[],thumbnails:[],currentScale:UNKNOWN_SCALE,currentScaleValue:null,initialBookmark:document.location.hash.substring(1),container:null,thumbnailContainer:null,initialized:!1,fellback:!1,pdfDocument:null,sidebarOpen:!1,pageViewScroll:null,thumbnailViewScroll:null,pageRotation:0,mouseScrollTimeStamp:0,mouseScrollDelta:0,lastScroll:0,previousPageNumber:1,isViewerEmbedded:window.parent!==window,idleTimeout:null,currentPosition:null,initialize:function(){var a=
+this,b=this.container=document.getElementById("viewerContainer");this.pageViewScroll={};this.watchScroll(b,this.pageViewScroll,updateViewarea);var c=this.thumbnailContainer=document.getElementById("thumbnailView");this.thumbnailViewScroll={};this.watchScroll(c,this.thumbnailViewScroll,this.renderHighestPriority.bind(this));PDFFindBar.initialize({bar:document.getElementById("findbar"),toggleButton:document.getElementById("viewFind"),findField:document.getElementById("findInput"),highlightAllCheckbox:document.getElementById("findHighlightAll"),
+caseSensitiveCheckbox:document.getElementById("findMatchCase"),findMsg:document.getElementById("findMsg"),findStatusIcon:document.getElementById("findStatusIcon"),findPreviousButton:document.getElementById("findPrevious"),findNextButton:document.getElementById("findNext")});PDFFindController.initialize({pdfPageSource:this,integratedFind:this.supportsIntegratedFind});HandTool.initialize({container:b,toggleHandTool:document.getElementById("toggleHandTool")});SecondaryToolbar.initialize({toolbar:document.getElementById("secondaryToolbar"),
+presentationMode:PresentationMode,toggleButton:document.getElementById("secondaryToolbarToggle"),presentationModeButton:document.getElementById("secondaryPresentationMode"),openFile:document.getElementById("secondaryOpenFile"),print:document.getElementById("secondaryPrint"),download:document.getElementById("secondaryDownload"),firstPage:document.getElementById("firstPage"),lastPage:document.getElementById("lastPage"),pageRotateCw:document.getElementById("pageRotateCw"),pageRotateCcw:document.getElementById("pageRotateCcw")});
+PasswordPrompt.initialize({overlayContainer:document.getElementById("overlayContainer"),passwordField:document.getElementById("password"),passwordText:document.getElementById("passwordText"),passwordSubmit:document.getElementById("passwordSubmit"),passwordCancel:document.getElementById("passwordCancel")});PresentationMode.initialize({container:b,secondaryToolbar:SecondaryToolbar,firstPage:document.getElementById("contextFirstPage"),lastPage:document.getElementById("contextLastPage"),pageRotateCw:document.getElementById("contextPageRotateCw"),
+pageRotateCcw:document.getElementById("contextPageRotateCcw")});this.initialized=!0;b.addEventListener("scroll",function(){a.lastScroll=Date.now()},!1)},getPage:function(a){return this.pdfDocument.getPage(a)},watchScroll:function(a,b,c){b.down=!0;b.lastY=a.scrollTop;a.addEventListener("scroll",function(d){d=a.scrollTop;var e=b.lastY;d>e?b.down=!0:d<e&&(b.down=!1);b.lastY=d;c()},!0)},_setScaleUpdatePages:function(a,b,c,d){this.currentScaleValue=b;if(a!==this.currentScale){b=0;for(var e=this.pages.length;b<
+e;b++)this.pages[b].update(a);this.currentScale=a;if(!d){d=this.page;var g;this.currentPosition&&!IGNORE_CURRENT_POSITION_ON_ZOOM&&(d=this.currentPosition.page,g=[null,{name:"XYZ"},this.currentPosition.left,this.currentPosition.top,null]);this.pages[d-1].scrollIntoView(g)}g=document.createEvent("UIEvents");g.initUIEvent("scalechange",!1,!1,window,0);g.scale=a;g.resetAutoSettings=c;window.dispatchEvent(g)}},setScale:function(a,b,c){if("custom"!==a){var d=parseFloat(a);if(0<d)this._setScaleUpdatePages(d,
+a,!0,c);else{var e=this.pages[this.page-1];if(e){d=(this.container.clientWidth-SCROLLBAR_PADDING)/e.width*e.scale;e=(this.container.clientHeight-VERTICAL_PADDING)/e.height*e.scale;switch(a){case "page-actual":d=1;break;case "page-width":break;case "page-height":d=e;break;case "page-fit":d=Math.min(d,e);break;case "auto":d=Math.min(MAX_AUTO_SCALE,d);break;default:console.error("pdfViewSetScale: '"+a+"' is an unknown zoom value.");return}this._setScaleUpdatePages(d,a,b,c);selectScaleOption(a)}}}},zoomIn:function(a){var b=
+this.currentScale;do b=(b*DEFAULT_SCALE_DELTA).toFixed(2),b=Math.ceil(10*b)/10,b=Math.min(MAX_SCALE,b);while(--a&&b<MAX_SCALE);this.setScale(b,!0)},zoomOut:function(a){var b=this.currentScale;do b=(b/DEFAULT_SCALE_DELTA).toFixed(2),b=Math.floor(10*b)/10,b=Math.max(MIN_SCALE,b);while(--a&&b>MIN_SCALE);this.setScale(b,!0)},set page(a){var b=this.pages,c=document.createEvent("UIEvents");c.initUIEvent("pagechange",!1,!1,window,0);0<a&&a<=b.length?(b[a-1].updateStats(),this.previousPageNumber=currentPageNumber,
+currentPageNumber=a,c.pageNumber=a,window.dispatchEvent(c),updateViewarea.inProgress||this.loading&&1===a||b[a-1].scrollIntoView()):(this.previousPageNumber=a,c.pageNumber=this.page,window.dispatchEvent(c))},get page(){return currentPageNumber},get supportsPrinting(){var a="mozPrintCallback"in document.createElement("canvas");Object.defineProperty(this,"supportsPrinting",{value:a,enumerable:!0,configurable:!0,writable:!1});return a},get supportsFullscreen(){var a=document.documentElement,a=a.requestFullscreen||
+a.mozRequestFullScreen||a.webkitRequestFullScreen||a.msRequestFullscreen;!1===document.fullscreenEnabled||!1===document.mozFullScreenEnabled||!1===document.webkitFullscreenEnabled||!1===document.msFullscreenEnabled?a=!1:this.isViewerEmbedded&&(a=!1);Object.defineProperty(this,"supportsFullscreen",{value:a,enumerable:!0,configurable:!0,writable:!1});return a},get supportsIntegratedFind(){Object.defineProperty(this,"supportsIntegratedFind",{value:!1,enumerable:!0,configurable:!0,writable:!1});return!1},
+get supportsDocumentFonts(){Object.defineProperty(this,"supportsDocumentFonts",{value:!0,enumerable:!0,configurable:!0,writable:!1});return!0},get supportsDocumentColors(){Object.defineProperty(this,"supportsDocumentColors",{value:!0,enumerable:!0,configurable:!0,writable:!1});return!0},get loadingBar(){var a=new ProgressBar("#loadingBar",{});Object.defineProperty(this,"loadingBar",{value:a,enumerable:!0,configurable:!0,writable:!1});return a},get isHorizontalScrollbarEnabled(){return PresentationMode.active?
+!1:this.container.scrollWidth>this.container.clientWidth},initPassiveLoading:function(){var a={rangeListeners:[],progressListeners:[],addRangeListener:function(a){this.rangeListeners.push(a)},addProgressListener:function(a){this.progressListeners.push(a)},onDataRange:function(a,c){for(var d=this.rangeListeners,e=0,g=d.length;e<g;++e)d[e](a,c)},onDataProgress:function(a){for(var c=this.progressListeners,d=0,e=c.length;d<e;++d)c[d](a)},requestDataRange:function(a,c){FirefoxCom.request("requestDataRange",
+{begin:a,end:c})}};window.addEventListener("message",function(b){var c=b.data;if("object"===typeof c&&"pdfjsLoadAction"in c)switch(c.pdfjsLoadAction){case "supportsRangedLoading":PDFView.open(c.pdfUrl,0,void 0,a,{length:c.length,initialData:c.data});break;case "range":a.onDataRange(c.begin,c.chunk);break;case "rangeProgress":a.onDataProgress(c.loaded);break;case "progress":PDFView.progress(c.loaded/c.total);break;case "complete":if(!c.data){PDFView.error(mozL10n.get("loading_error",null,"An error occurred while loading the PDF."),
+b);break}PDFView.open(c.data,0)}});FirefoxCom.requestSync("initPassiveLoading",null)},setTitleUsingUrl:function(a){this.url=a;try{this.setTitle(decodeURIComponent(getFileName(a))||a)}catch(b){this.setTitle(a)}},setTitle:function(a){document.title=a},open:function(a,b,c,d,e){c={password:c};"string"===typeof a?(this.setTitleUsingUrl(a),c.url=a):a&&"byteLength"in a&&(c.data=a);if(e)for(var g in e)c[g]=e[g];this.pdfDocument=null;var h=this;h.loading=!0;PDFJS.getDocument(c,d,function(a,b){PasswordPrompt.updatePassword=
+a;PasswordPrompt.reason=b;PasswordPrompt.show()},function(a){h.progress(a.loaded/a.total)}).then(function(a){h.load(a,b);h.loading=!1},function(a,b){var c=mozL10n.get("loading_error",null,"An error occurred while loading the PDF.");b&&"InvalidPDFException"===b.name&&(c=mozL10n.get("invalid_file_error",null,"Invalid or corrupted PDF file."));b&&"MissingPDFException"===b.name&&(c=mozL10n.get("missing_file_error",null,"Missing PDF file."));h.error(c,{message:a});h.loading=!1})},download:function(){function a(){d.downloadUrl(b,
+c)}var b=this.url.split("#")[0],c=getPDFFileNameFromURL(b),d=new DownloadManager;d.onerror=function(a){PDFView.error("PDF failed to download.")};this.pdfDocument?this.pdfDocument.getData().then(function(a){a=PDFJS.createBlob(a,"application/pdf");d.download(a,b,c)},a).then(null,a):a()},fallback:function(a){},navigateTo:function(a){var b="",c=this,d=function(e){c.pendingRefStr=null;var g=e instanceof Object?c.pagesRefMap[e.num+" "+e.gen+" R"]:e+1;g?(g>c.pages.length&&(g=c.pages.length),c.pages[g-1].scrollIntoView(a),
+PDFHistory.push({dest:a,hash:b,page:g})):c.pdfDocument.getPageIndex(e).then(function(a){c.pagesRefMap[e.num+" "+e.gen+" R"]=a+1;d(e)})};this.destinationsPromise.then(function(){"string"===typeof a&&(b=a,a=c.destinations[a]);a instanceof Array&&d(a[0])})},getDestinationHash:function(a){if("string"===typeof a)return PDFView.getAnchorUrl("#"+escape(a));if(a instanceof Array){var b=a[0];if(b=b instanceof Object?this.pagesRefMap[b.num+" "+b.gen+" R"]:b+1){var b=PDFView.getAnchorUrl("#page="+b),c=a[1];
+if("object"===typeof c&&"name"in c&&"XYZ"==c.name){var c=a[4]||this.currentScaleValue,d=parseFloat(c);d&&(c=100*d);b+="&zoom="+c;if(a[2]||a[3])b+=","+(a[2]||0)+","+(a[3]||0)}return b}}return""},getAnchorUrl:function(a){return a},error:function(a,b){var c=mozL10n.get("error_version_info",{version:PDFJS.version||"?",build:PDFJS.build||"?"},"PDF.js v{{version}} (build: {{build}})")+"\n";b&&(c+=mozL10n.get("error_message",{message:b.message},"Message: {{message}}"),b.stack?c+="\n"+mozL10n.get("error_stack",
+{stack:b.stack},"Stack: {{stack}}"):(b.filename&&(c+="\n"+mozL10n.get("error_file",{file:b.filename},"File: {{file}}")),b.lineNumber&&(c+="\n"+mozL10n.get("error_line",{line:b.lineNumber},"Line: {{line}}"))));var d=document.getElementById("errorWrapper");d.removeAttribute("hidden");document.getElementById("errorMessage").textContent=a;var e=document.getElementById("errorClose");e.onclick=function(){d.setAttribute("hidden","true")};var g=document.getElementById("errorMoreInfo"),h=document.getElementById("errorShowMore"),
+f=document.getElementById("errorShowLess");h.onclick=function(){g.removeAttribute("hidden");h.setAttribute("hidden","true");f.removeAttribute("hidden");g.style.height=g.scrollHeight+"px"};f.onclick=function(){g.setAttribute("hidden","true");h.removeAttribute("hidden");f.setAttribute("hidden","true")};h.oncontextmenu=noContextMenuHandler;f.oncontextmenu=noContextMenuHandler;e.oncontextmenu=noContextMenuHandler;h.removeAttribute("hidden");f.setAttribute("hidden","true");g.value=c},progress:function(a){a=
+Math.round(100*a);a>PDFView.loadingBar.percent&&(PDFView.loadingBar.percent=a)},load:function(a,b){function c(a,b){a.onAfterDraw=function(){e||(e=!0,g());b.setImage(a.canvas)}}var d=this,e=!1,g=null,h=new Promise(function(a){g=a});PDFFindController.reset();this.pdfDocument=a;document.getElementById("errorWrapper").setAttribute("hidden","true");a.dataLoaded().then(function(){PDFView.loadingBar.hide();document.getElementById("outerContainer").classList.remove("loadingInProgress")});var f=document.getElementById("thumbnailView");
+for(f.parentNode.scrollTop=0;f.hasChildNodes();)f.removeChild(f.lastChild);"_loadingInterval"in f&&clearInterval(f._loadingInterval);for(var k=document.getElementById("viewer");k.hasChildNodes();)k.removeChild(k.lastChild);var s=a.numPages,n=a.fingerprint;document.getElementById("numPages").textContent=mozL10n.get("page_of",{pageCount:s},"of {{pageCount}}");document.getElementById("pageNumber").max=s;var q=PDFView.prefs=new Preferences;PDFView.documentFingerprint=n;var t=PDFView.store=new ViewHistory(n);
+this.pageRotation=0;var u=this.pages=[],p=this.pagesRefMap={},l=this.thumbnails=[],r;this.pagesPromise=n=new Promise(function(a){r=a});var m=a.getPage(1);m.then(function(e){e=e.getViewport((b||1)*CSS_UNITS);for(var g=1;g<=s;++g){var n=e.clone(),q=new PageView(k,g,b,d.navigateTo.bind(d),n),n=new ThumbnailView(f,g,n);c(q,n);u.push(q);l.push(n)}h.then(function(){if(PDFJS.disableAutoFetch)r();else for(var b=s,c=1;c<=s;++c)a.getPage(c).then(function(a,c){var d=u[a-1];d.pdfPage||d.setPdfPage(c);p[c.ref.num+
+" "+c.ref.gen+" R"]=a;b--;b||r()}.bind(null,c))});e=document.createEvent("CustomEvent");e.initCustomEvent("documentload",!0,!0,{});window.dispatchEvent(e);PDFView.loadingBar.setWidth(k);PDFFindController.resolveFirstPage()});Promise.all([m,q.initializedPromise,t.initializedPromise]).then(function(){var a=q.get("showPreviousViewOnLoad"),c=q.get("defaultZoomValue"),e=null;if(a&&t.get("exists",!1))var a=t.get("page","1"),c=c||t.get("zoom",PDFView.currentScale),e=t.get("scrollLeft","0"),h=t.get("scrollTop",
+"0"),e="page="+a+"&zoom="+c+","+e+","+h;else c&&(e="page=1&zoom="+c);PDFHistory.initialize(d.documentFingerprint);d.setInitialView(e,b);d.isViewerEmbedded||d.container.focus()});n.then(function(){PDFView.supportsPrinting&&a.getJavaScript().then(function(a){a.length&&(console.warn("Warning: JavaScript is not supported"),PDFView.fallback(PDFJS.UNSUPPORTED_FEATURES.javaScript));for(var b=/\bprint\s*\(/g,c=0,d=a.length;c<d;c++){var e=a[c];if(e&&b.test(e)){setTimeout(function(){window.print()});break}}})});
+m=this.destinationsPromise=a.getDestinations();m.then(function(a){d.destinations=a});Promise.all([n,m,PDFView.animationStartedPromise]).then(function(){a.getOutline().then(function(a){d.outline=new DocumentOutlineView(a);document.getElementById("viewOutline").disabled=!a;a&&q.get("ifAvailableShowOutlineOnLoad")&&(d.sidebarOpen||document.getElementById("sidebarToggle").click(),d.switchSidebarView("outline"))})});a.getMetadata().then(function(b){var c=b.info;b=b.metadata;d.documentInfo=c;d.metadata=
+b;console.log("PDF "+a.fingerprint+" ["+c.PDFFormatVersion+" "+(c.Producer||"-")+" / "+(c.Creator||"-")+"]"+(PDFJS.version?" (PDF.js: "+PDFJS.version+")":""));var e;b&&b.has("dc:title")&&(e=b.get("dc:title"));!e&&c&&c.Title&&(e=c.Title);e&&d.setTitle(e+" - "+document.title);c.IsAcroFormPresent&&(console.warn("Warning: AcroForm/XFA is not supported"),PDFView.fallback(PDFJS.UNSUPPORTED_FEATURES.forms))})},setInitialView:function(a,b){this.currentScale=0;this.currentScaleValue=null;document.getElementById("pageNumber").value=
+currentPageNumber=1;this.currentPosition=null;PDFHistory.initialDestination?(this.navigateTo(PDFHistory.initialDestination),PDFHistory.initialDestination=null):this.initialBookmark?(this.setHash(this.initialBookmark),PDFHistory.push({hash:this.initialBookmark},!!this.initialBookmark),this.initialBookmark=null):a?this.setHash(a):b&&(this.setScale(b,!0),this.page=1);PDFView.currentScale===UNKNOWN_SCALE&&this.setScale(DEFAULT_SCALE,!0)},renderHighestPriority:function(){PDFView.idleTimeout&&(clearTimeout(PDFView.idleTimeout),
+PDFView.idleTimeout=null);var a=this.getVisiblePages();if(a=this.getHighestPriority(a,this.pages,this.pageViewScroll.down))this.renderView(a,"page");else{if(this.sidebarOpen&&(a=this.getVisibleThumbs(),a=this.getHighestPriority(a,this.thumbnails,this.thumbnailViewScroll.down))){this.renderView(a,"thumbnail");return}PDFView.idleTimeout=setTimeout(function(){PDFView.cleanup()},CLEANUP_TIMEOUT)}},cleanup:function(){for(var a=0,b=this.pages.length;a<b;a++)this.pages[a]&&this.pages[a].renderingState!==
+RenderingStates.FINISHED&&this.pages[a].reset();this.pdfDocument.cleanup()},getHighestPriority:function(a,b,c){var d=a.views,e=d.length;if(0===e)return!1;for(var g=0;g<e;++g){var h=d[g].view;if(!this.isViewFinished(h))return h}a=c?a.last.id:a.first.id-2;return b[a]&&!this.isViewFinished(b[a])?b[a]:!1},isViewFinished:function(a){return a.renderingState===RenderingStates.FINISHED},renderView:function(a,b){switch(a.renderingState){case RenderingStates.FINISHED:return!1;case RenderingStates.PAUSED:PDFView.highestPriorityPage=
+b+a.id;a.resume();break;case RenderingStates.RUNNING:PDFView.highestPriorityPage=b+a.id;break;case RenderingStates.INITIAL:PDFView.highestPriorityPage=b+a.id,a.draw(this.renderHighestPriority.bind(this))}return!0},setHash:function(a){if(a)if(0<=a.indexOf("="))if(a=PDFView.parseQueryString(a),"nameddest"in a)PDFHistory.updateNextHashParam(a.nameddest),PDFView.navigateTo(a.nameddest);else{var b,c;"page"in a&&(b=a.page|0||1);if("zoom"in a){c=a.zoom.split(",");var d=c[0],e=parseFloat(d);e&&(d=e/100);
+c=[null,{name:"XYZ"},1<c.length?c[1]|0:null,2<c.length?c[2]|0:null,d]}c?this.pages[(b||this.page)-1].scrollIntoView(c):b&&(this.page=b);"pagemode"in a&&(b=document.getElementById("sidebarToggle"),"thumbs"===a.pagemode||"bookmarks"===a.pagemode?(this.sidebarOpen||b.click(),this.switchSidebarView("thumbs"===a.pagemode?"thumbs":"outline")):"none"===a.pagemode&&this.sidebarOpen&&b.click())}else/^\d+$/.test(a)?this.page=a:(PDFHistory.updateNextHashParam(unescape(a)),PDFView.navigateTo(unescape(a)))},switchSidebarView:function(a){var b=
+document.getElementById("thumbnailView"),c=document.getElementById("outlineView"),d=document.getElementById("viewThumbnail"),e=document.getElementById("viewOutline");switch(a){case "thumbs":a=b.classList.contains("hidden");d.classList.add("toggled");e.classList.remove("toggled");b.classList.remove("hidden");c.classList.add("hidden");PDFView.renderHighestPriority();a&&scrollIntoView(document.getElementById("thumbnailContainer"+this.page));break;case "outline":d.classList.remove("toggled"),e.classList.add("toggled"),
+b.classList.add("hidden"),c.classList.remove("hidden"),e.getAttribute("disabled")}},getVisiblePages:function(){return this.getVisibleElements(this.container,this.pages,!PresentationMode.active)},getVisibleThumbs:function(){return this.getVisibleElements(this.thumbnailContainer,this.thumbnails)},getVisibleElements:function(a,b,c){var d=a.scrollTop,e=d+a.clientHeight,g=a.scrollLeft,h=g+a.clientWidth;a=[];for(var f,k,s,n,q,t=0,u=b.length;t<u;++t)if(f=b[t],k=f.el.offsetTop+f.el.clientTop,s=f.el.clientHeight,
+!(k+s<d)){if(k>e)break;q=f.el.offsetLeft+f.el.clientLeft;n=f.el.clientWidth;q+n<g||q>h||(n=Math.max(0,d-k)+Math.max(0,k+s-e),s=100*(s-n)/s|0,a.push({id:f.id,x:q,y:k,view:f,percent:s}))}b=a[0];d=a[a.length-1];c&&a.sort(function(a,b){var c=a.percent-b.percent;return 0.0010<Math.abs(c)?-c:a.id-b.id});return{first:b,last:d,views:a}},parseQueryString:function(a){a=a.split("&");for(var b={},c=0;c<a.length;++c){var d=a[c].split("="),e=1<d.length?d[1]:null;b[decodeURIComponent(d[0])]=decodeURIComponent(e)}return b},
+beforePrint:function(){if(this.supportsPrinting){var a=!1;if(this.pages.length)for(var b=0,c=this.pages.length;b<c;++b){if(!this.pages[b].pdfPage){a=!0;break}}else a=!0;if(a)a=mozL10n.get("printing_not_ready",null,"Warning: The PDF is not fully loaded for printing."),window.alert(a);else for(document.querySelector("body").setAttribute("data-mozPrintCallback",!0),b=0,c=this.pages.length;b<c;++b)this.pages[b].beforePrint()}else a=mozL10n.get("printing_not_supported",null,"Warning: Printing is not fully supported by this browser."),
+this.error(a)},afterPrint:function(){for(var a=document.getElementById("printContainer");a.hasChildNodes();)a.removeChild(a.lastChild)},rotatePages:function(a){var b=this.pages[this.page-1];this.pageRotation=(this.pageRotation+360+a)%360;a=0;for(var c=this.pages.length;a<c;a++){var d=this.pages[a];d.update(d.scale,this.pageRotation)}a=0;for(c=this.thumbnails.length;a<c;a++)this.thumbnails[a].update(this.pageRotation);this.setScale(this.currentScaleValue,!0,!0);this.renderHighestPriority();b&&b.scrollIntoView()},
+mouseScroll:function(a){var b=(new Date).getTime(),c=this.mouseScrollTimeStamp;b>c&&50>b-c||((0<this.mouseScrollDelta&&0>a||0>this.mouseScrollDelta&&0<a)&&this.clearMouseScrollState(),this.mouseScrollDelta+=a,120<=Math.abs(this.mouseScrollDelta)&&(a=0<this.mouseScrollDelta?-1:1,this.clearMouseScrollState(),c=this.page,1==c&&-1==a||c==this.pages.length&&1==a||(this.page+=a,this.mouseScrollTimeStamp=b)))},clearMouseScrollState:function(){this.mouseScrollDelta=this.mouseScrollTimeStamp=0}},PageView=
+function(a,b,c,d,e){function g(a,b,c){function d(a,b){a.href=PDFView.getDestinationHash(b);a.onclick=function(){b&&PDFView.navigateTo(b);return!1};b&&(a.className="internalLink")}function e(a,b){a.href=PDFView.getAnchorUrl("");a.onclick=function(){switch(b){case "GoToPage":document.getElementById("pageNumber").focus();break;case "GoBack":PDFHistory.back();break;case "GoForward":PDFHistory.forward();break;case "Find":PDFView.supportsIntegratedFind||PDFFindBar.toggle();break;case "NextPage":PDFView.page++;
+break;case "PrevPage":PDFView.page--;break;case "LastPage":PDFView.page=PDFView.pages.length;break;case "FirstPage":PDFView.page=1}return!1};a.className="internalLink"}b.getAnnotations().then(function(h){f.annotationLayer&&(a.removeChild(f.annotationLayer),f.annotationLayer=null);c=c.clone({dontFlip:!0});for(var g=0;g<h.length;g++){var l=h[g];if((l=PDFJS.Annotation.fromData(l))&&l.hasHtml()){var r=l.getHtmlElement(b.commonObjs);mozL10n.translate(r);var l=l.getData(),m=l.rect,v=b.view,m=PDFJS.Util.normalizeRect([m[0],
+v[3]-m[1]+v[1],m[2],v[3]-m[3]+v[1]]);r.style.left=m[0]+"px";r.style.top=m[1]+"px";r.style.position="absolute";v="matrix("+c.transform.join(",")+")";CustomStyle.setProp("transform",r,v);CustomStyle.setProp("transformOrigin",r,-m[0]+"px "+-m[1]+"px");"Link"!==l.subtype||l.url||(l.action?e(r,l.action):d(r,"dest"in l?l.dest:null));f.annotationLayer||(l=document.createElement("div"),l.className="annotationLayer",a.appendChild(l),f.annotationLayer=l);f.annotationLayer.appendChild(r)}}})}this.id=b;this.rotation=
+0;this.scale=c||1;this.viewport=e;this.pdfPageRotate=e.rotation;this.renderingState=RenderingStates.INITIAL;this.annotationLayer=this.zoomLayer=this.textLayer=this.resume=null;b=document.createElement("a");b.name=""+this.id;var h=this.el=document.createElement("div");h.id="pageContainer"+this.id;h.className="page";h.style.width=Math.floor(this.viewport.width)+"px";h.style.height=Math.floor(this.viewport.height)+"px";a.appendChild(b);a.appendChild(h);this.setPdfPage=function(a){this.pdfPage=a;this.pdfPageRotate=
+a.rotate;this.viewport=a.getViewport(this.scale*CSS_UNITS,(this.rotation+this.pdfPageRotate)%360);this.stats=a.stats;this.reset()};this.destroy=function(){this.zoomLayer=null;this.reset();this.pdfPage&&this.pdfPage.destroy()};this.reset=function(){this.renderTask&&this.renderTask.cancel();this.resume=null;this.renderingState=RenderingStates.INITIAL;h.style.width=Math.floor(this.viewport.width)+"px";h.style.height=Math.floor(this.viewport.height)+"px";for(var a=h.childNodes,b=h.childNodes.length-1;0<=
+b;b--){var c=a[b];this.zoomLayer&&this.zoomLayer===c||h.removeChild(c)}h.removeAttribute("data-loaded");this.annotationLayer=null;delete this.canvas;this.loadingIconDiv=document.createElement("div");this.loadingIconDiv.className="loadingIcon";h.appendChild(this.loadingIconDiv)};this.update=function(a,b){this.scale=a||this.scale;"undefined"!==typeof b&&(this.rotation=b);this.viewport=this.viewport.clone({scale:this.scale*CSS_UNITS,rotation:(this.rotation+this.pdfPageRotate)%360});USE_ONLY_CSS_ZOOM&&
+this.canvas?this.cssTransform(this.canvas):(this.canvas&&!this.zoomLayer&&(this.zoomLayer=this.canvas.parentNode,this.zoomLayer.style.position="absolute"),this.zoomLayer&&this.cssTransform(this.zoomLayer.firstChild),this.reset())};this.cssTransform=function(a){var b=this.viewport.width,c=this.viewport.height;a.style.width=a.parentNode.style.width=h.style.width=Math.floor(b)+"px";a.style.height=a.parentNode.style.height=h.style.height=Math.floor(c)+"px";var d=this.viewport.rotation-a._viewport.rotation,
+e=Math.abs(d),f=1,p=1;if(90===e||270===e)f=c/b,p=b/c;CustomStyle.setProp("transform",a,"rotate("+d+"deg) scale("+f+","+p+")");if(this.textLayer){c=Math.abs(this.viewport.rotation-this.textLayer.viewport.rotation);d=b/a.width;if(90===c||270===c)d=b/a.height;a=this.textLayer.textLayerDiv;var l,r;switch(c){case 0:l=r=0;break;case 90:l=0;r="-"+a.style.height;break;case 180:l="-"+a.style.width;r="-"+a.style.height;break;case 270:l="-"+a.style.width;r=0;break;default:console.error("Bad rotation value.")}CustomStyle.setProp("transform",
+a,"rotate("+c+"deg) scale("+d+", "+d+") translate("+l+", "+r+")");CustomStyle.setProp("transformOrigin",a,"0% 0%")}USE_ONLY_CSS_ZOOM&&this.annotationLayer&&g(h,this.pdfPage,this.viewport)};Object.defineProperty(this,"width",{get:function(){return this.viewport.width},enumerable:!0});Object.defineProperty(this,"height",{get:function(){return this.viewport.height},enumerable:!0});var f=this;this.getPagePoint=function(a,b){return this.viewport.convertToPdfPoint(a,b)};this.scrollIntoView=function(a){PresentationMode.active&&
+(a=null,PDFView.setScale(PDFView.currentScaleValue,!0,!0));if(a){var b=0,c=0,d=0,e=0,g,f;f=!!(this.rotation%180);g=(f?this.height:this.width)/this.scale/CSS_UNITS;f=(f?this.width:this.height)/this.scale/CSS_UNITS;var l=0;switch(a[1].name){case "XYZ":b=a[2];c=a[3];l=a[4];b=null!==b?b:0;c=null!==c?c:f;break;case "Fit":case "FitB":l="page-fit";break;case "FitH":case "FitBH":c=a[2];l="page-width";break;case "FitV":case "FitBV":b=a[2];d=g;e=f;l="page-height";break;case "FitR":b=a[2];c=a[3];d=a[4]-b;e=
+a[5]-c;g=(PDFView.container.clientWidth-SCROLLBAR_PADDING)/d/CSS_UNITS;f=(PDFView.container.clientHeight-SCROLLBAR_PADDING)/e/CSS_UNITS;l=Math.min(Math.abs(g),Math.abs(f));break;default:return}l&&l!==PDFView.currentScale?PDFView.setScale(l,!0,!0):PDFView.currentScale===UNKNOWN_SCALE&&PDFView.setScale(DEFAULT_SCALE,!0,!0);"page-fit"!==l||a[4]?(b=[this.viewport.convertToViewportPoint(b,c),this.viewport.convertToViewportPoint(b+d,c+e)],a=Math.min(b[0][0],b[1][0]),b=Math.min(b[0][1],b[1][1]),scrollIntoView(h,
+{left:a,top:b})):scrollIntoView(h)}else scrollIntoView(h)};this.getTextContent=function(){return PDFView.getPage(this.id).then(function(a){return a.getTextContent()})};this.draw=function(a){function b(d){v===m.renderTask&&(m.renderTask=null);if("cancelled"!==d){m.renderingState=RenderingStates.FINISHED;m.loadingIconDiv&&(h.removeChild(m.loadingIconDiv),delete m.loadingIconDiv);m.zoomLayer&&(h.removeChild(m.zoomLayer),m.zoomLayer=null);d&&PDFView.error(mozL10n.get("rendering_error",null,"An error occurred while rendering the page."),
+d);m.stats=c.stats;m.updateStats();if(m.onAfterDraw)m.onAfterDraw();cache.push(m);d=document.createEvent("CustomEvent");d.initCustomEvent("pagerender",!0,!0,{pageNumber:c.pageNumber});h.dispatchEvent(d);a()}}var c=this.pdfPage;if(!this.pagePdfPromise)if(c){this.renderingState!==RenderingStates.INITIAL&&console.error("Must be in new state before drawing");this.renderingState=RenderingStates.RUNNING;var d=this.viewport,e=document.createElement("div");e.style.width=h.style.width;e.style.height=h.style.height;
+e.classList.add("canvasWrapper");var f=document.createElement("canvas");f.id="page"+this.id;e.appendChild(f);h.appendChild(e);this.canvas=f;var e=f.getContext("2d"),p=getOutputScale(e);if(USE_ONLY_CSS_ZOOM){var l=d.clone({scale:CSS_UNITS});p.sx*=l.width/d.width;p.sy*=l.height/d.height;p.scaled=!0}f.width=Math.floor(d.width)*p.sx|0;f.height=Math.floor(d.height)*p.sy|0;f.style.width=Math.floor(d.width)+"px";f.style.height=Math.floor(d.height)+"px";f._viewport=d;d=null;PDFJS.disableTextLayer||(d=document.createElement("div"),
+d.className="textLayer",d.style.width=f.width+"px",d.style.height=f.height+"px",h.appendChild(d));var r=this.textLayer=d?new TextLayerBuilder({textLayerDiv:d,pageIndex:this.id-1,lastScrollSource:PDFView,viewport:this.viewport,isViewerInPresentationMode:PresentationMode.active}):null;e._scaleX=p.sx;e._scaleY=p.sy;p.scaled&&e.scale(p.sx,p.sy);p.scaled&&d&&(CustomStyle.setProp("transform",d,"scale("+1/p.sx+", "+1/p.sy+")"),CustomStyle.setProp("transformOrigin",d,"0% 0%"),d.dataset._scaleX=p.sx,d.dataset._scaleY=
+p.sy);var m=this,v=this.renderTask=this.pdfPage.render({canvasContext:e,viewport:this.viewport,textLayer:r,continueCallback:function(a){PDFView.highestPriorityPage!=="page"+m.id?(m.renderingState=RenderingStates.PAUSED,m.resume=function(){m.renderingState=RenderingStates.RUNNING;a()}):a()}});this.renderTask.promise.then(function(){b(null)},function(a){b(a)});r&&this.getTextContent().then(function(a){r.setTextContent(a)});g(h,c,this.viewport);h.setAttribute("data-loaded",!0)}else f=PDFView.getPage(this.id),
+f.then(function(b){delete this.pagePdfPromise;this.setPdfPage(b);this.draw(a)}.bind(this)),this.pagePdfPromise=f};this.beforePrint=function(){var a=this.pdfPage,b=a.getViewport(1),c=document.createElement("canvas");c.width=2*Math.floor(b.width);c.height=2*Math.floor(b.height);c.style.width=2*b.width+"pt";c.style.height=2*b.height+"pt";CustomStyle.setProp("transform",c,"scale(0.5, 0.5)");CustomStyle.setProp("transformOrigin",c,"0% 0%");var d=document.getElementById("printContainer"),e=document.createElement("div");
+e.style.width=b.width+"pt";e.style.height=b.height+"pt";e.appendChild(c);d.appendChild(e);var h=this;c.mozPrintCallback=function(d){var e=d.context;e.save();e.fillStyle="rgb(255, 255, 255)";e.fillRect(0,0,c.width,c.height);e.restore();e.scale(2,2);a.render({canvasContext:e,viewport:b}).promise.then(function(){d.done();h.pdfPage.destroy()},function(a){console.error(a);"abort"in d?d.abort():d.done();h.pdfPage.destroy()})}};this.updateStats=function(){this.stats&&PDFJS.pdfBug&&Stats.enabled&&Stats.add(this.id,
+this.stats)}},ThumbnailView=function(a,b,c){var d=document.createElement("a");d.href=PDFView.getAnchorUrl("#page="+b);d.title=mozL10n.get("thumb_page_title",{page:b},"Page {{page}}");d.onclick=function(){PDFView.page=b;return!1};this.pdfPage=void 0;this.viewport=c;this.pdfPageRotate=c.rotation;this.rotation=0;this.pageWidth=this.viewport.width;this.pageHeight=this.viewport.height;this.pageRatio=this.pageWidth/this.pageHeight;this.id=b;this.canvasWidth=98;this.canvasHeight=this.canvasWidth/this.pageWidth*
+this.pageHeight;this.scale=this.canvasWidth/this.pageWidth;var e=this.el=document.createElement("div");e.id="thumbnailContainer"+b;e.className="thumbnail";1===b&&e.classList.add("selected");var g=document.createElement("div");g.className="thumbnailSelectionRing";g.style.width=this.canvasWidth+"px";g.style.height=this.canvasHeight+"px";e.appendChild(g);d.appendChild(e);a.appendChild(d);this.hasImage=!1;this.renderingState=RenderingStates.INITIAL;this.setPdfPage=function(a){this.pdfPage=a;this.pdfPageRotate=
+a.rotate;this.viewport=a.getViewport(1,(this.rotation+this.pdfPageRotate)%360);this.update()};this.update=function(a){void 0!==a&&(this.rotation=a);this.viewport=this.viewport.clone({scale:1,rotation:(this.rotation+this.pdfPageRotate)%360});this.pageWidth=this.viewport.width;this.pageHeight=this.viewport.height;this.pageRatio=this.pageWidth/this.pageHeight;this.canvasHeight=this.canvasWidth/this.pageWidth*this.pageHeight;this.scale=this.canvasWidth/this.pageWidth;e.removeAttribute("data-loaded");
+g.textContent="";g.style.width=this.canvasWidth+"px";g.style.height=this.canvasHeight+"px";this.hasImage=!1;this.renderingState=RenderingStates.INITIAL;this.resume=null};this.getPageDrawContext=function(){var a=document.createElement("canvas");a.id="thumbnail"+b;a.width=this.canvasWidth;a.height=this.canvasHeight;a.className="thumbnailImage";a.setAttribute("aria-label",mozL10n.get("thumb_page_canvas",{page:b},"Thumbnail of Page {{page}}"));e.setAttribute("data-loaded",!0);g.appendChild(a);a=a.getContext("2d");
+a.save();a.fillStyle="rgb(255, 255, 255)";a.fillRect(0,0,this.canvasWidth,this.canvasHeight);a.restore();return a};this.drawingRequired=function(){return!this.hasImage};this.draw=function(a){if(this.pdfPage)if(this.renderingState!==RenderingStates.INITIAL&&console.error("Must be in new state before drawing"),this.renderingState=RenderingStates.RUNNING,this.hasImage)a();else{var b=this,c=this.getPageDrawContext(),d=this.viewport.clone({scale:this.scale});this.pdfPage.render({canvasContext:c,viewport:d,
+continueCallback:function(a){PDFView.highestPriorityPage!=="thumbnail"+b.id?(b.renderingState=RenderingStates.PAUSED,b.resume=function(){b.renderingState=RenderingStates.RUNNING;a()}):a()}}).promise.then(function(){b.renderingState=RenderingStates.FINISHED;a()},function(c){b.renderingState=RenderingStates.FINISHED;a()});this.hasImage=!0}else PDFView.getPage(this.id).then(function(b){this.setPdfPage(b);this.draw(a)}.bind(this))};this.setImage=function(a){if(!this.pdfPage)PDFView.getPage(this.id).then(function(b){this.setPdfPage(b);
+this.setImage(a)}.bind(this));else if(!this.hasImage&&a){this.renderingState=RenderingStates.FINISHED;var b=this.getPageDrawContext();b.drawImage(a,0,0,a.width,a.height,0,0,b.canvas.width,b.canvas.height);this.hasImage=!0}}},FIND_SCROLL_OFFSET_TOP=-50,FIND_SCROLL_OFFSET_LEFT=-400,TextLayerBuilder=function(a){var b=document.createDocumentFragment();this.textLayerDiv=a.textLayerDiv;this.divContentDone=this.layoutDone=!1;this.pageIdx=a.pageIndex;this.matches=[];this.lastScrollSource=a.lastScrollSource;
+this.viewport=a.viewport;this.isViewerInPresentationMode=a.isViewerInPresentationMode;"undefined"===typeof PDFFindController&&(window.PDFFindController=null);"undefined"===typeof this.lastScrollSource&&(this.lastScrollSource=null);this.beginLayout=function(){this.textDivs=[];this.renderingDone=!1};this.endLayout=function(){this.layoutDone=!0;this.insertDivContent()};this.renderLayer=function(){var a=this.textDivs,d=this.textLayerDiv,e=document.createElement("canvas").getContext("2d");if(!(1E5<a.length)){for(var g=
+0,h=a.length;g<h;g++){var f=a[g];if(!("isWhitespace"in f.dataset)){e.font=f.style.fontSize+" "+f.style.fontFamily;var k=e.measureText(f.textContent).width;0<k&&(b.appendChild(f),k="scale("+f.dataset.canvasWidth/k+", 1)",k="rotate("+f.dataset.angle+"deg) "+k,CustomStyle.setProp("transform",f,k),CustomStyle.setProp("transformOrigin",f,"0% 0%"))}}d.appendChild(b);this.renderingDone=!0;this.updateMatches()}};this.setupRenderLayoutTimer=function(){var a=this,b=null===this.lastScrollSource?0:this.lastScrollSource.lastScroll;
+200<Date.now()-b?this.renderLayer():(this.renderTimer&&clearTimeout(this.renderTimer),this.renderTimer=setTimeout(function(){a.setupRenderLayoutTimer()},200))};this.appendText=function(a){var b=document.createElement("div"),e=a.fontSize*Math.abs(a.vScale);b.dataset.canvasWidth=a.canvasWidth*Math.abs(a.hScale);b.dataset.fontName=a.fontName;b.dataset.angle=180/Math.PI*a.angle;b.style.fontSize=e+"px";b.style.fontFamily=a.fontFamily;e=a.ascent?a.ascent*e:a.descent?(1+a.descent)*e:e;b.style.left=a.x+e*
+Math.sin(a.angle)+"px";b.style.top=a.y-e*Math.cos(a.angle)+"px";this.textDivs.push(b)};this.insertDivContent=function(){if(this.layoutDone&&!this.divContentDone&&this.textContent){this.divContentDone=!0;for(var a=this.textDivs,b=this.textContent.bidiTexts,e=0;e<b.length;e++){var g=b[e],h=a[e];/\S/.test(g.str)?(h.textContent=g.str,h.dir=g.dir):h.dataset.isWhitespace=!0}this.setupRenderLayoutTimer()}};this.setTextContent=function(a){this.textContent=a;this.insertDivContent()};this.convertMatches=function(a){for(var b=
+0,e=0,g=this.textContent.bidiTexts,h=g.length-1,f=null===PDFFindController?0:PDFFindController.state.query.length,k=[],s=0;s<a.length;s++){for(var n=a[s];b!==h&&n>=e+g[b].str.length;)e+=g[b].str.length,b++;b==g.length&&console.error("Could not find matching mapping");for(var q={begin:{divIdx:b,offset:n-e}},n=n+f;b!==h&&n>e+g[b].str.length;)e+=g[b].str.length,b++;q.end={divIdx:b,offset:n-e};k.push(q)}return k};this.renderMatches=function(a){function b(a,c){var d=a.divIdx,e=h[d];e.textContent="";var f=
+g[d].str.substring(0,a.offset),f=document.createTextNode(f);if(c){var d=k&&d===s,l=document.createElement("span");l.className=c+(d?" selected":"");l.appendChild(f);e.appendChild(l)}else e.appendChild(f)}function e(a,b,c){var d=a.divIdx,e=h[d];a=g[d].str.substring(a.offset,b.offset);a=document.createTextNode(a);c?(b=document.createElement("span"),b.className=c,b.appendChild(a),e.appendChild(b)):e.appendChild(a)}if(0!==a.length){var g=this.textContent.bidiTexts,h=this.textDivs,f=null,k=null===PDFFindController?
+!1:this.pageIdx===PDFFindController.selected.pageIdx,s=null===PDFFindController?-1:PDFFindController.selected.matchIdx,n={divIdx:-1,offset:void 0},q=s,t=q+1;if(null===PDFFindController?0:PDFFindController.state.highlightAll)q=0,t=a.length;else if(!k)return;for(;q<t;q++){var u=a[q],p=u.begin,u=u.end,l=k&&q===s,r=l?" selected":"";l&&!this.isViewerInPresentationMode&&scrollIntoView(h[p.divIdx],{top:FIND_SCROLL_OFFSET_TOP,left:FIND_SCROLL_OFFSET_LEFT});f&&p.divIdx===f.divIdx?e(f,p):(null!==f&&e(f,n),
+b(p));if(p.divIdx===u.divIdx)e(p,u,"highlight"+r);else{e(p,n,"highlight begin"+r);for(f=p.divIdx+1;f<u.divIdx;f++)h[f].className="highlight middle"+r;b(u,"highlight end"+r)}f=u}f&&e(f,n)}};this.updateMatches=function(){if(this.renderingDone){for(var a=this.matches,b=this.textDivs,e=this.textContent.bidiTexts,g=-1,h=0;h<a.length;h++){for(var f=a[h],g=Math.max(g,f.begin.divIdx);g<=f.end.divIdx;g++){var k=b[g];k.textContent=e[g].str;k.className=""}g=f.end.divIdx+1}null!==PDFFindController&&PDFFindController.active&&
+(this.matches=this.convertMatches(null===PDFFindController?[]:PDFFindController.pageMatches[this.pageIdx]||[]),this.renderMatches(this.matches))}}},DocumentOutlineView=function(a){function b(a,b){a.href=PDFView.getDestinationHash(b.dest);a.onclick=function(a){PDFView.navigateTo(b.dest);return!1}}var c=document.getElementById("outlineView");for(document.getElementById("viewOutline");c.firstChild;)c.removeChild(c.firstChild);if(a)for(a=[{parent:c,items:a}];0<a.length;){var c=a.shift(),d,e=c.items.length;
+for(d=0;d<e;d++){var g=c.items[d],h=document.createElement("div");h.className="outlineItem";var f=document.createElement("a");b(f,g);f.textContent=g.title;h.appendChild(f);0<g.items.length&&(f=document.createElement("div"),f.className="outlineItems",h.appendChild(f),a.push({parent:f,items:g.items}));c.parent.appendChild(h)}}else c.classList.contains("hidden")||PDFView.switchSidebarView("thumbs")};
+document.addEventListener("DOMContentLoaded",function(a){PDFView.initialize();a=PDFView.parseQueryString(document.location.search.substring(1)).file||DEFAULT_URL;var b=document.createElement("input");b.id="fileInput";b.className="fileInput";b.setAttribute("type","file");b.oncontextmenu=noContextMenuHandler;document.body.appendChild(b);window.File&&window.FileReader&&window.FileList&&window.Blob&&(document.getElementById("fileInput").value=null);b=document.location.hash.substring(1);b=PDFView.parseQueryString(b);
+"disableWorker"in b&&(PDFJS.disableWorker="true"===b.disableWorker);"disableRange"in b&&(PDFJS.disableRange="true"===b.disableRange);"disableAutoFetch"in b&&(PDFJS.disableAutoFetch="true"===b.disableAutoFetch);"disableFontFace"in b&&(PDFJS.disableFontFace="true"===b.disableFontFace);"disableHistory"in b&&(PDFJS.disableHistory="true"===b.disableHistory);"useOnlyCssZoom"in b&&(USE_ONLY_CSS_ZOOM="true"===b.useOnlyCssZoom);"verbosity"in b&&(PDFJS.verbosity=b.verbosity|0);"ignoreCurrentPositionOnZoom"in
+b&&(IGNORE_CURRENT_POSITION_ON_ZOOM="true"===b.ignoreCurrentPositionOnZoom);var c=navigator.language;"locale"in b&&(c=b.locale);mozL10n.setLanguage(c);if("textLayer"in b)switch(b.textLayer){case "off":PDFJS.disableTextLayer=!0;break;case "visible":case "shadow":case "hover":document.getElementById("viewer").classList.add("textLayer-"+b.textLayer)}"pdfBug"in b&&(PDFJS.pdfBug=!0,b=b.pdfBug.split(","),PDFBug.enable(b),PDFBug.init());PDFView.supportsPrinting||(document.getElementById("print").classList.add("hidden"),
+document.getElementById("secondaryPrint").classList.add("hidden"));PDFView.supportsFullscreen||(document.getElementById("presentationMode").classList.add("hidden"),document.getElementById("secondaryPresentationMode").classList.add("hidden"));PDFView.supportsIntegratedFind&&document.getElementById("viewFind").classList.add("hidden");PDFJS.UnsupportedManager.listen(PDFView.fallback.bind(PDFView));document.getElementById("scaleSelect").oncontextmenu=noContextMenuHandler;var d=document.getElementById("mainContainer"),
+e=document.getElementById("outerContainer");d.addEventListener("transitionend",function(a){a.target==d&&(a=document.createEvent("UIEvents"),a.initUIEvent("resize",!1,!1,window,0),window.dispatchEvent(a),e.classList.remove("sidebarMoving"))},!0);document.getElementById("sidebarToggle").addEventListener("click",function(){this.classList.toggle("toggled");e.classList.add("sidebarMoving");e.classList.toggle("sidebarOpen");PDFView.sidebarOpen=e.classList.contains("sidebarOpen");PDFView.renderHighestPriority()});
+document.getElementById("viewThumbnail").addEventListener("click",function(){PDFView.switchSidebarView("thumbs")});document.getElementById("viewOutline").addEventListener("click",function(){PDFView.switchSidebarView("outline")});document.getElementById("previous").addEventListener("click",function(){PDFView.page--});document.getElementById("next").addEventListener("click",function(){PDFView.page++});document.getElementById("zoomIn").addEventListener("click",function(){PDFView.zoomIn()});document.getElementById("zoomOut").addEventListener("click",
+function(){PDFView.zoomOut()});document.getElementById("pageNumber").addEventListener("click",function(){this.select()});document.getElementById("pageNumber").addEventListener("change",function(){PDFView.page=this.value|0;this.value!==(this.value|0).toString()&&(this.value=PDFView.page)});document.getElementById("scaleSelect").addEventListener("change",function(){PDFView.setScale(this.value)});document.getElementById("presentationMode").addEventListener("click",SecondaryToolbar.presentationModeClick.bind(SecondaryToolbar));
+document.getElementById("print").addEventListener("click",SecondaryToolbar.printClick.bind(SecondaryToolbar));PDFView.open(a,0)},!0);
+function updateViewarea(){if(PDFView.initialized){var a=PDFView.getVisiblePages(),b=a.views;if(0!==b.length){PDFView.renderHighestPriority();for(var c=PDFView.page,a=a.first,d=0,e=b.length,g=!1;d<e;++d){var h=b[d];if(100>h.percent)break;if(h.id===PDFView.page){g=!0;break}}g||(c=b[0].id);updateViewarea.inProgress=!0;PDFView.page=c;updateViewarea.inProgress=!1;var b=PDFView.currentScale,c=PDFView.currentScaleValue,f=parseFloat(c)===b?Math.round(1E4*b)/100:c,k=a.id,b="#page="+k+("&zoom="+f),c=PDFView.container,
+a=PDFView.pages[k-1].getPagePoint(c.scrollLeft-a.x,c.scrollTop-a.y),s=Math.round(a[0]),n=Math.round(a[1]),b=b+(","+s+","+n);PDFView.currentPosition=PresentationMode.active||PresentationMode.switchInProgress?null:{page:k,left:s,top:n};var q=PDFView.store;q.initializedPromise.then(function(){q.set("exists",!0);q.set("page",k);q.set("zoom",f);q.set("scrollLeft",s);q.set("scrollTop",n)});a=PDFView.getAnchorUrl(b);document.getElementById("viewBookmark").href=a;document.getElementById("secondaryViewBookmark").href=
+a;PDFHistory.updateCurrentBookmark(b,k)}}}window.addEventListener("resize",function(a){PDFView.initialized&&(document.getElementById("pageWidthOption").selected||document.getElementById("pageFitOption").selected||document.getElementById("pageAutoOption").selected)&&PDFView.setScale(document.getElementById("scaleSelect").value);updateViewarea();SecondaryToolbar.setMaxHeight(PDFView.container)});window.addEventListener("hashchange",function(a){PDFHistory.isHashChangeUnlocked&&PDFView.setHash(document.location.hash.substring(1))});
+window.addEventListener("change",function(a){var b=a.target.files;b&&0!==b.length&&(a=new FileReader,a.onload=function(a){a=new Uint8Array(a.target.result);PDFView.open(a,0)},b=b[0],a.readAsArrayBuffer(b),PDFView.setTitleUsingUrl(b.name),document.getElementById("viewBookmark").setAttribute("hidden","true"),document.getElementById("secondaryViewBookmark").setAttribute("hidden","true"),document.getElementById("download").setAttribute("hidden","true"),document.getElementById("secondaryDownload").setAttribute("hidden",
+"true"))},!0);function selectScaleOption(a){for(var b=document.getElementById("scaleSelect").options,c=!1,d=0;d<b.length;d++){var e=b[d];e.value!=a?e.selected=!1:c=e.selected=!0}return c}
+window.addEventListener("localized",function(a){document.getElementsByTagName("html")[0].dir=mozL10n.getDirection();PDFView.animationStartedPromise.then(function(){var a=document.getElementById("scaleSelectContainer");if(0<a.clientWidth){var c=document.getElementById("scaleSelect");c.setAttribute("style","min-width: inherit;");var d=c.clientWidth+SCALE_SELECT_CONTAINER_PADDING;c.setAttribute("style","min-width: "+(d+SCALE_SELECT_PADDING)+"px;");a.setAttribute("style","min-width: "+d+"px; max-width: "+
+d+"px;")}SecondaryToolbar.setMaxHeight(PDFView.container)})},!0);
+window.addEventListener("scalechange",function(a){document.getElementById("zoomOut").disabled=a.scale===MIN_SCALE;document.getElementById("zoomIn").disabled=a.scale===MAX_SCALE;var b=document.getElementById("customScaleOption");b.selected=!1;!a.resetAutoSettings&&(document.getElementById("pageWidthOption").selected||document.getElementById("pageFitOption").selected||document.getElementById("pageAutoOption").selected)||selectScaleOption(""+a.scale)||(b.textContent=Math.round(1E4*a.scale)/100+"%",b.selected=
+!0);updateViewarea()},!0);
+window.addEventListener("pagechange",function(a){a=a.pageNumber;if(PDFView.previousPageNumber!==a){document.getElementById("pageNumber").value=a;var b=document.querySelector(".thumbnail.selected");b&&b.classList.remove("selected");b=document.getElementById("thumbnailContainer"+a);b.classList.add("selected");var c=PDFView.getVisibleThumbs(),d=c.views.length;if(0<d){var e=c.first.id,c=1<d?c.last.id:e;(a<=e||a>=c)&&scrollIntoView(b,{top:THUMBNAIL_SCROLL_MARGIN})}}document.getElementById("previous").disabled=1>=
+a;document.getElementById("next").disabled=a>=PDFView.pages.length},!0);window.addEventListener("DOMMouseScroll",function(a){a.ctrlKey?(a.preventDefault(),a=a.detail,PDFView[0<a?"zoomOut":"zoomIn"](Math.abs(a))):PresentationMode.active&&PDFView.mouseScroll(-40*a.detail)},!1);window.addEventListener("click",function(a){PresentationMode.active?0===a.button&&a.preventDefault():SecondaryToolbar.opened&&PDFView.container.contains(a.target)&&SecondaryToolbar.close()},!1);
+window.addEventListener("keydown",function(a){if(!PasswordPrompt.visible){var b=!1,c=(a.ctrlKey?1:0)|(a.altKey?2:0)|(a.shiftKey?4:0)|(a.metaKey?8:0);if(1===c||8===c||5===c||12===c)switch(a.keyCode){case 70:PDFView.supportsIntegratedFind||(PDFFindBar.open(),b=!0);break;case 71:PDFView.supportsIntegratedFind||(PDFFindBar.dispatchEvent("again",5===c||12===c),b=!0);break;case 61:case 107:case 187:case 171:PDFView.zoomIn();b=!0;break;case 173:case 109:case 189:PDFView.zoomOut();b=!0;break;case 48:case 96:setTimeout(function(){PDFView.setScale(DEFAULT_SCALE,
+!0)}),b=!1}if(3===c||10===c)switch(a.keyCode){case 80:SecondaryToolbar.presentationModeClick();b=!0;break;case 71:document.getElementById("pageNumber").select(),b=!0}if(b)a.preventDefault();else{var d=document.activeElement||document.querySelector(":focus");if(!d||"INPUT"!==d.tagName.toUpperCase()&&"TEXTAREA"!==d.tagName.toUpperCase()&&"SELECT"!==d.tagName.toUpperCase()||27===a.keyCode){for(var e=document.getElementById("toolbar");d;){if(d===e&&!PresentationMode.active)return;d=d.parentNode}if(0===
+c)switch(a.keyCode){case 38:case 33:case 8:if(!PresentationMode.active&&"page-fit"!==PDFView.currentScaleValue)break;case 37:if(PDFView.isHorizontalScrollbarEnabled)break;case 75:case 80:PDFView.page--;b=!0;break;case 27:SecondaryToolbar.opened&&(SecondaryToolbar.close(),b=!0);!PDFView.supportsIntegratedFind&&PDFFindBar.opened&&(PDFFindBar.close(),b=!0);break;case 40:case 34:case 32:if(!PresentationMode.active&&"page-fit"!==PDFView.currentScaleValue)break;case 39:if(PDFView.isHorizontalScrollbarEnabled)break;
+case 74:case 78:PDFView.page++;b=!0;break;case 36:PresentationMode.active&&(PDFView.page=1,b=!0);break;case 35:PresentationMode.active&&(PDFView.page=PDFView.pdfDocument.numPages,b=!0);break;case 72:PresentationMode.active||HandTool.toggle();break;case 82:PDFView.rotatePages(90)}if(4===c)switch(a.keyCode){case 32:if(!PresentationMode.active&&"page-fit"!==PDFView.currentScaleValue)break;PDFView.page--;b=!0;break;case 82:PDFView.rotatePages(-90)}if(2===c)switch(a.keyCode){case 37:PresentationMode.active&&
+(PDFHistory.back(),b=!0);break;case 39:PresentationMode.active&&(PDFHistory.forward(),b=!0)}b&&(a.preventDefault(),PDFView.clearMouseScrollState())}}}});window.addEventListener("beforeprint",function(a){PDFView.beforePrint()});window.addEventListener("afterprint",function(a){PDFView.afterPrint()});
+(function(){var a=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(a){a()};PDFView.animationStartedPromise=new Promise(function(b){a(function(){b()})})})();
More information about the commits
mailing list