diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..7d0949a --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,129 @@ +## 1.4.0 - 2022-08-24 +### Fixed + - substantial bit rot accrued in 4 years of non-maintenance which made Reader unusable + - Reader now works reliably on public pages - or at least it _Works For Me™_ + +### Changed + - Refactored a substantial part of the code to comply to the "current" (ha ha) Nextcloud API + - Dropped Owncloud compatibility for lack of a testing installation + - Dropped IE (<11) support + - Dropped compatibility with older (<20) Nextcloud versions + - Dropped app-specific ajax code, now handled by SettingsController + - Updated dependencies where applicable + +## 1.2.3 - 2018-02-24 +### Fixed + - (#76) typo plus some missing code kept Reader from being used to preview shared files + - (#79) typo kept Reader from being used by default for CBx + - (#82) missing setDefault kept actual style settings from being saved + +## 1.2.2 - 2018-02-02 +### Fixed + - (#75) NC and OC are diverging, NC encodes everything on $settings as JSON, OC does not yet. + +## 1.2.1 - 2018-01-31 +### Changed + - change default settings to enabled for all supported mime types + +## 1.2.0 - 2018-01-31 +### Added + - PDF: (#73) new preference 'scroll to top of page on page turn' + - PDF: defaults and per-document settings are now saved and restored + - PDF: nightmode (using CSS3 filters, only works in recent browsers), toggle with 'd', by clicking nightmode button or clicking in empty area on button bar, adjust in settings + +### Changed + - remove from templates to avoid warning in console, statement was ineffective anyway de to (overly restrictive) hardcoded policy in NC/OC. + - removed (or rather disabled) merging of PDF annotations into user bookmarks as it only served to mess up the bookmark list and slowed things down. This feature can be re-enabled once Reader gains a functional PDF annotation editor. + +### Fixed + - PDF: (#72) $title not ['title'] in pdfreader template, hopefully the last remaining bug related to template refactoring + - PDF: browsing the thumbnail list in single-page mode did not work as intended due to datatype mismatch in page calculation routine, fixed with explicit toString() + - PDF: page 0 does not exist so don't try to go there + +## 1.1.1 - 2018-01-19 +### Added + - signed package for publication in Owncloud marketplace + +### Changed + - updated bitjs unrar.js and rarvm.js + +## 1.1.0 - 2018-01-18 +### Added + - Reader now supports PDF + - PDF double page spreads are supported + - optional double-buffering for faster rendering, can be disabled for low-memory devices + - optional selectable text layer, can be disabled for low-memory devices + +### Changed + - #38: moved declarations in js/ready.js one level lower to work around a bug in the Palemoon browser + - new version bitjs archive tools, fixes compatibility problems with some CBR files + - increased maximum supported version for OC and NC + +## 1.0.4 - 2017-04-09 +### Fixed + - #43, remove table aliases in hooks to avoid being bit by querybuilder/doctrine/MySQL incompatibility/idiosyncracy + - #39, #41 and #42, NOTE: if you're on MySQL or MariaDB you might need to enable 4-byte support if this has not been done yet, otherwise you'll get a '1071 Specified key was too long' error on install. More information on this issue - which also occurs when trying to use Emoji characters in a NC/OC installation on a MySQL or MariaDB database - can be found here: https://docs.nextcloud.com/server/11/admin_manual/maintenance/mysql_4byte_support.html + +## 1.0.3 - 2017-03-29 +### Fixed + - #40, detect shared file OR folder and (try to) get fileId for such when applicable + +## 1.0.2 - 2017-03-25 +### Fixed + - #37, use getAppManager()->isInstalled('files_opds') instead of class_exists to avoid log spam + +### Changed + - new version bitjs unarchiver, increases compatibility with CBR files (at the cost of some speed) + - move function declarations in js/ready.js down one block level so browsers which do not support + ES6 (e.g. Palemoon) can find them. Unfortunately the above new version of bitjs uses another ES6 + feature (classes) which Palemoon does not support so this change may be moot... + +## 1.0.1 - 2017-03-19 +### Fixed + - #35: Internal Server Error: fixed path resolution so app works when NC/OC hosted in subdirectory + +## 1.0.0 - 2017-03-15 +### Added + - Reader now supports CBR/CBZ ('comics') files + - Book position ('cursor') is saved on server and restored on next invocation + - Default settings (independent of fileid) and file-specific settings are saved and restored + - Bookmarks and annotations (notes) are saved and restored (bookmarks are a type of annotation). + - Full-text search implemented. + - Framework to support more file format renderers + - hooks added to remove defaults, settings and annotations/bookmarks for deleted files or users + - epubreader + * night mode now works more reliably + * new 'day mode', ie. user-defined colours + * new font settings: font weight + * column width user-configurable + * new mode: maximize reader area, for small-screen devices + * page turn arrows optional, hidden by default + - cbreader + * supports CBR (rar) and CBZ (zip) archives + * single and double page (spread) mode, auto-adjusts to screen geometry + * optional image enhancement filters + * seamless full screen mode (where browser allows user full control of experience, ie. not on apple) + +## 0.8.3 - 2017-02-02 +### Fixed + . #31: ReferenceError: cleanStartTextContent is not defined, caused by failure to declare local var in epub.js + +## 0.8.3 - 2017-02-01 +### Fixed + - missing $title parameter in template/reader.php caused warnings in log, fixed + +## 0.8.2 - 2017-01-10 +### Fixed + - Nextcloud-port broke compatibility with Owncloud due to OC not supporting CSPv3, workaround implemented + +## 0.8.1 - 2017-01-09 +### Added + - Modified info.xml, added screenshots + +## 0.8.0 - 2017-01-09 +### Added + - new version 0.2.15 of Futurepress epub.js renderer + +### Changed + - New logo + - First release to be compatible with Nextcloud diff --git a/README.md b/README.md index b9f0d17..6c634ba 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,136 @@ -# files_reader +files_reader +------------ + +Reader is an ebook reader based on pure javascript renderers. It works for publications formatted according to the following standards: + + - [Epub] + - [PDF] + - [CBR and CBZ] ('comics') + +For Epub Reader uses the futurepress [epub.js] renderer to provide near-native looks, especially when used full-screen. Turn pages by pressing the left/right hand side of the screen/window or using the cursor keys (if you have those), use the sidebar to browse through chapters or bookmarks and add annotations. + +PDF is handled by Mozilla's [pdf.js] renderer in combination with a custom reader app to enable side-by-side display, batch search and more. Controls are like those used in the Epub renderer with a few exceptions, e.g. night mode has not been implemented yet. + +CBR and CBZ are supported using a custom renderer inspired by [balaclark]'s work. As with Epub, books can be navigated using the keyboard as well as mouse or touch navigation. Reader generates a visual index of all pages, show in the sidebar (thumbnail generation can be disabled for low-memory and/or -speed devices). As CBx files are often of varying quality, a set of image enhancement filters are provided. + +# Features +Reader remembers the last-visited page in a book and returns to that page when the book is re-opened. As all settings are stored on the server these features are device-independent, ie. you can start reading on a mobile device, continue on a PC to finish the book on a tablet. + +### Text-based formats incl. PDF + + - seamless full-screen mode supported on browsers which allow full user-control, ie. not on Apple) + - single- and double-page viewing mode + - user-configurable font and colour settings + - night mode, toggled by clicking the book title/author on top of the viewer or the night mode button (PDF) + - full-text search with keyword highlighting + - bookmarks (with automatic snippet generation) + - annotations (not yet implemented for PDF) + - keyboard and pointer/touch-based navigation + +### CBR/CBZ ('Comics') + + - seamless full-screen mode supported on browsers which allow full user-control, ie. not on Apple) + - single- and double-page viewing mode + - optional image enhancement filters + - Left-to-right and right-to-left (_manga_) modes + - visual index (thumbnail size user-configurable, can be disabled for low-memory or -cpu devices) + - keyboard and pointer/touch-based navigation + +PDF support is still somewhat rough around the edges, not all features have been implemented yet. There is a known cosmetical issue in that in spread mode the (invisible but selectable) text layer for the left page is offset from the left when opening a document. As soon as a page is turned this problem disappears. + +### Keyboard navigation +Reader supports both pointer/touch-based as well as keyboard-based navigation. Pointer/touch based is mostly self-explanatory, + +| key | function | +| ---:| --- | +|_left_, _page-up_ | move to previous page; move to next page in RTL(_manga_) mode | +|_right_, _page-down_, _space_ | move to next page; move to previous page in RTL (_mange_) mode | +|_home_| move to first page | +|_end_| move to last page | +|s| toggle side bar | +|_esc_| close sidebar | +|f| toggle full screen| +|t| toggle toolbar | +|l| _CBR_: toggle layout | +|a| _EPUB_: annotate | +|b| _EPUB_: bookmark | +|r| _EPUB_: reflow text when sidebar is open | +|d| _EPUB_: toggle day (custom colour) mode | +|n| _EPUB_: toggle night mode | + +### Defaults and Preferences + +Reader stores __defaults__ - settings which are independent of _fileId_ (ie. independent of the book currently open) - and __preferences__ - _fileId_-dependent (ie. different for every book) - on the server. Defaults are not shared between renderers, ie. the CBR renderer does not share defaults with the EPUB or PDF renderer. Defaults and preferences are removed from the server when the associated book or user is deleted. + +### Annotations and Bookmarks + +Reader supports _annotations_ (notes linked to a given position in a book) and _bookmarks_ (position markers with automatically generated text snippets). An automatically generated bookmark (called '__ CURSOR __', not visible in the bookmarks list) is used to keep track of the current reading position. Annotations and bookmark snippets can be edited or deleted in the sidebar. + + +# Screenshots +### Epub +| | | +---|--- +Reader showing page spread in 'night mode'|![Reader showing page spread in 'night mode'][SS01] +Epub single page, full screen on a small-screen device |![Epub single page, full screen][SS02] +Day mode color selector|![Day mode color selector][SS03] +Longing for that olde-time terminal feeling...|![Longing for that olde-time terminal feeling...][SS04] +Full-text search|![Full-text search][SS05] +Small screen device, __maximize text area__ enabled|![Small screen device, maximize text area enabled][SS06] +Search on small-screen device|![Search on small-screen device][SS07] +As close to full-screen as you can get on iOS|![As close to full-screen as you can get on iOS][SS08] +Android supports true fullscreen (as do most other systems)|![Android supports true fullscreen (as do most other systems)][SS09] + +### PDF +| | | +---|--- +Reader showing PDF Reference document in spread mode (pages side by side)|![Reader showing PDF Reference document in spread mode (pages side by side)][SS20] +Search through a document, showing all results in the sidebar|![Search through a document, showing all results in the sidebar][SS19] +Dropdown showing page format options - spread, single page, page width and zoom options|![Dropdown showing page format options - spread, single page, page width and zoom options][SS21] +Reader showing PDF in spread mode, thumbnails in the sidebar|![Reader showing PDF in spread mode, thumbnails in the sidebar][SS22] + +### CBR/CBZ +| | | +---|--- + iOS approximation of full screen, CBR|![iOS approximation of full screen, CBR][SS10] +The same book, now in landscape mode, switch to 2-page spread is automatic|![The same book, now in landscape mode, switch to 2-page spread is automatic][SS11] +Sidebar open, showing index, landscape mode|![Sidebar open, showing index, landscape mode][SS12] +Sidebar open, showing index, portrait mode|![Sidebar open, showing index, portrait mode][SS13] +Image enhancement filters, desaturate (grayscale) active|![Image enhancement filters, desaturate (grayscale) active][SS14] +full screen (apart from iOS restrictions), controls hidden|![full screen (apart from iOS restrictions), controls hidden][SS15] +Same page, zoomed in|![Same page, zoomed in][SS16] +Small-screen, low memory (Android) device showing full-page book cover|![Small-screen, low memory Android device showing full-page book cover][SS17] +The same Android device showing a zoomed-in part of a page|![The same Android device showing a zoomed-in part of a page][SS18] + + + + [epub.js]: https://github.com/futurepress/epub.js + [Epub]: http://idpf.org/epub + [CBR and CBZ]: https://wiki.mobileread.com/wiki/CBR_and_CBZ + [balaclark]: https://github.com/balaclark/HTML5-Comic-Book-Reader + [PDF]: https://en.wikipedia.org/wiki/Portable_Document_Format + [pdf.js]: https://github.com/mozilla/pdf.js + [SS01]: https://raw.githubusercontent.com/Yetangitu/owncloud-apps/master/screenshots/files_reader-1.png "Reader showing day/nighyt mode" + [SS02]: https://raw.githubusercontent.com/Yetangitu/owncloud-apps/master/screenshots/files_reader-3.png "Single page full screen on a small-screen device" + [SS03]: https://raw.githubusercontent.com/Yetangitu/owncloud-apps/master/screenshots/photo_2017-03-15_17-21-39.jpg "Day mode color selector" + [SS04]: https://raw.githubusercontent.com/Yetangitu/owncloud-apps/master/screenshots/photo_2017-03-15_17-21-41.jpg?raw=true "Longing For that olde-time terminal feeling..." + [SS05]: https://raw.githubusercontent.com/Yetangitu/owncloud-apps/master/screenshots/photo_2017-03-15_17-21-53.jpg "Full-text search" + [SS06]: https://raw.githubusercontent.com/Yetangitu/owncloud-apps/master/screenshots/photo_2017-03-15_18-28-46.jpg "Small screen device, __maximize text area__ enabled" + [SS07]: https://github.com/Yetangitu/owncloud-apps/blob/master/screenshots/photo_2017-03-15_18-28-49.jpg?raw=true "Search on small-screen device" + [SS08]: https://github.com/Yetangitu/owncloud-apps/blob/master/screenshots/photo_2017-03-15_17-21-52.jpg?raw=true "As close to full-screen as you can get on iOS" + [SS09]: https://github.com/Yetangitu/owncloud-apps/blob/master/screenshots/Screenshot_2014-09-29-20-21-50.png?raw=true "Android supports true fullscreen (as do most other systems)" + [SS10]: https://github.com/Yetangitu/owncloud-apps/blob/master/screenshots/photo_2017-03-15_17-21-59.jpg?raw=true "iOS approximation of full screen, CBR" + [SS11]: https://github.com/Yetangitu/owncloud-apps/blob/master/screenshots/photo_2017-03-15_17-22-00.jpg?raw=true "The same book, now in landscape mode, switch to 2-page spread is automatic" + [SS12]: https://github.com/Yetangitu/owncloud-apps/blob/master/screenshots/photo_2017-03-15_17-22-01.jpg?raw=true "Sidebar open, showing index, landscape mode" + [SS13]: https://github.com/Yetangitu/owncloud-apps/blob/master/screenshots/photo_2017-03-15_17-22-02.jpg?raw=true "Sidebar open, showing index, portrait mode" + [SS14]: https://github.com/Yetangitu/owncloud-apps/blob/master/screenshots/photo_2017-03-15_17-22-05.jpg?raw=true "Image enhancement filters, desaturate (grayscale) active" + [SS15]: https://github.com/Yetangitu/owncloud-apps/blob/master/screenshots/photo_2017-03-15_17-22-08.jpg?raw=true "full screen (apart from iOS restrictions), controls hidden" + [SS16]: https://github.com/Yetangitu/owncloud-apps/blob/master/screenshots/photo_2017-03-15_17-22-10.jpg?raw=true "Same page, zoomed in" + [SS17]: https://github.com/Yetangitu/owncloud-apps/blob/master/screenshots/photo_2017-03-15_18-28-54.jpg?raw=true "Small-screen, low memory (Android) device showing full-page book cover" + [SS18]: https://github.com/Yetangitu/owncloud-apps/blob/master/screenshots/photo_2017-03-15_18-28-56.jpg?raw=true "The same Android device showing a zoomed-in part of a page" + [SS19]: https://github.com/Yetangitu/owncloud-apps/blob/master/screenshots/files_reader_PDF_001.png?raw=true "Search through a document, showing all results in the sidebar" + [SS20]: https://github.com/Yetangitu/owncloud-apps/blob/master/screenshots/files_reader_PDF_002.png?raw=true "Reader showing PDF Reference document in spread mode (pages side by side)" + [SS21]: https://github.com/Yetangitu/owncloud-apps/blob/master/screenshots/files_reader_PDF_005.png?raw=true "Dropdown showing page format options - spread, single page, page width and zoom options" + [SS22]: https://github.com/Yetangitu/owncloud-apps/blob/master/screenshots/files_reader_PDF_006.png?raw=true "Reader showing PDF in spread mode, thumbnails in the sidebar" + -EPUB/PDF/CBx reader application for Nextcloud \ No newline at end of file diff --git a/TODO b/TODO new file mode 100644 index 0000000..184985c --- /dev/null +++ b/TODO @@ -0,0 +1,5 @@ + - annotations + - rtl and ltr + - test canvas size restriction + - add IDs to highlights so they can be marked when hovered - or when related list item is hovered + diff --git a/appinfo/info.xml b/appinfo/info.xml new file mode 100644 index 0000000..e7a56a8 --- /dev/null +++ b/appinfo/info.xml @@ -0,0 +1,57 @@ + + + files_reader + Reader (ebook reader) + Files_Reader + A multi-format browser-based ebook reader which supports EPUB, PDF and CBR/CBZ + + + + 1.4.0 + AGPL + Frank de Lange + + https://github.com/Yetangitu/owncloud-apps/blob/master/files_reader/README.md + + https://github.com/Yetangitu/owncloud-apps/issues + https://github.com/Yetangitu/owncloud-apps/tree/master/files_reader + https://raw.githubusercontent.com/Yetangitu/owncloud-apps/master/screenshots/files_reader-1.png + https://raw.githubusercontent.com/Yetangitu/owncloud-apps/master/screenshots/files_reader-3.png + https://raw.githubusercontent.com/Yetangitu/owncloud-apps/master/screenshots/files_reader_PDF_005.png + https://raw.githubusercontent.com/Yetangitu/owncloud-apps/master/screenshots/files_reader_PDF_006.png + https://raw.githubusercontent.com/Yetangitu/owncloud-apps/master/screenshots/photo_2017-03-15_17-22-00.jpg + https://raw.githubusercontent.com/Yetangitu/owncloud-apps/master/screenshots/photo_2017-03-15_17-22-02.jpg + files + multimedia + office + + \OCA\Files_Reader\Settings\Personal + + + + + + diff --git a/appinfo/routes.php b/appinfo/routes.php new file mode 100644 index 0000000..43fa9bd --- /dev/null +++ b/appinfo/routes.php @@ -0,0 +1,43 @@ + [ + // Page + ['name' => 'page#showReader', 'url' => '/', 'verb' => 'GET'], + + // Bookmarks + ['name' => 'bookmark#get_cursor', 'url' => '/bookmark/cursor/{fileId}', 'verb' => 'GET'], + ['name' => 'bookmark#set_cursor', 'url' => '/bookmark/cursor', 'verb' => 'POST'], + ['name' => 'bookmark#delete_cursor', 'url' => '/bookmark/cursor/{fileId}', 'verb' => 'DELETE'], + ['name' => 'bookmark#get', 'url' => '/bookmark/{fileId}/{name}', 'verb' => 'GET', 'defaults' => ['name' => '']], + ['name' => 'bookmark#get', 'url' => '/bookmark/{fileId}/{type}/{name}', 'verb' => 'GET', 'defaults' => ['name' => '']], + ['name' => 'bookmark#set', 'url' => '/bookmark', 'verb' => 'POST'], + ['name' => 'bookmark#delete', 'url' => '/bookmark/{fileId}/{name}', 'verb' => 'DELETE'], + + // Metadata + ['name' => 'metadata#get', 'url' => '/metadata/{fileId}/{name}', 'verb' => 'GET', 'defaults' => ['name' => '']], + ['name' => 'metadata#set', 'url' => '/metadata/{fileId}/{name}/{value}', 'verb' => 'POST'], + + // Preferences + ['name' => 'preference#get_default', 'url' => '/preference/default/{scope}/{name}', 'verb' => 'GET', 'defaults' => ['name' => '']], + ['name' => 'preference#set_default', 'url' => '/preference/default', 'verb' => 'POST'], + ['name' => 'preference#delete_default', 'url' => '/preference/default/{scope}/{name}', 'verb' => 'DELETE'], + ['name' => 'preference#get', 'url' => '/preference/{fileId}/{scope}/{name}', 'verb' => 'GET', 'defaults' => ['name' => '']], + ['name' => 'preference#set', 'url' => '/preference', 'verb' => 'POST'], + ['name' => 'preference#delete', 'url' => '/preference/{fileId}/{scope}/{name}', 'verb' => 'DELETE'], + + // Settings + ['name' => 'Settings#personal', 'url' => '/settings', 'verb' => 'POST'], +]]; + diff --git a/appinfo/signature.json b/appinfo/signature.json new file mode 100644 index 0000000..cf1467c --- /dev/null +++ b/appinfo/signature.json @@ -0,0 +1,137 @@ +{ + "hashes": { + "CHANGELOG.md": "9f76fce63c1d183462127b3bb2795d070f9f514e0d981233f8ecdcb98712e5fb0974cd807b8cdeed49918e0e9535f70e0c6797bc595eb88184a3b758d66fa940", + "README.md": "27742b78bac23d2dd5fde269b9e3070c2042c44d6b120017a7d701c59cfa10433e79bea47cbf2af1edee0ac311d8fbfec4d27849c46ba79e2427090013e9a224", + "TODO": "2e96d92edf624625cb0fa84032e772aa674cd0b5b8270389acb64e5d8071d958a23489b90eaa3d4243cacd1f2a5934af7064dec66ffa5146f59945a9d797ab9a", + "ajax\/personal.php": "fbd21da9f8c4ea90dd549e82479aea877214b3b0ac102e4c4abc8c4e5914d77253bd1b82c36093ad7e21e7b85c78433006927a607a853b37c664f4f28236cbdf", + "appinfo\/app.php": "347e7c861afcd5c4ad54af36a0d393c6108abd1cbc50524bede213c3cddcd7701a484ed14d9fe64ed9c6cf9e7fc37618b7ba4e8fc74b775c9c43112860ca6543", + "appinfo\/database.xml": "111a18a81749237ad4e23c94f0b0986e08964c8b1ae5495b0dfe082f4801dc8951eb7c862f96edc8493eba1c4808c2227cde1ab48572d806b026c37abab07a85", + "appinfo\/info.xml": "8c2e6d2c42df2d9e17eee978cc49f1abf7a284d6fe7ec2515e917961ccee3a648f455a9d127d6df1231adf35b1118a004d27788658b6bf90c3f7a861c619d854", + "appinfo\/routes.php": "64eaeaba5915721487dddef721dd4d747b070a658653e3c74287607faa7f3553bba907761779227a0c08870cc86420bdd97a4764887e4137f960d5bcb1e8006c", + "css\/settings.css": "4c6d3bd224ad754e5396eeea719fb16ad975a2bd7f9dc363b4c7faf3a1e8c16c317b2b4092845280456e922048afb2155e43dcca108ac1ba535c83755ac27e59", + "img\/app.svg": "88bc2059bd09013de866eaf61be0207bb96f4b84cfa3df0164e5b65aaa99db5f616e340a6da8e3c01fd5a07c8e4c727019f74760ca581552074e9f1a0237d35e", + "img\/book.png": "9804b463779b32d1b8d9ced85a11f7e3201d9aef9a48b55b1381ae6addf19a78f5a3990c7201ce5702e798fd6bfad36c7a8e11e699f851351adf9b5b85cb3e68", + "img\/loading.gif": "4ce13c9402690a9beee76c8f6aa21ab48211377ef679e1b5d0ceca26f231a7ceecb2f00c0ad4facafa922e292e4afbde64cd85360e3a06d45ee1a71ca0e1a4c8", + "js\/lib\/Blob.js": "b0c7760f8b8365d39baf3a6320c2259660cadc5a4a877f35ef212ccfaee645a48ac6b754536d716539841c62a96f2b5036fe1087a0cb3c4b4c6b6fa34d406021", + "js\/lib\/blob.js": "c04ed3426cd6688e970818a6494bcb9be02ac69f72ad0ca9121af8e20092b602d9595f8061fab5f69e538e4b0606ea6eb9a142cb40ce36adb34163c917004832", + "js\/lib\/typedarray.js": "e8fee5f0cbd4e5282083182ee7ec2cc6c6f86d6d1f0c259853612983b1ef5cd1187061546baadb1eb0f8629dbaaa3bb4520a4d161f5acf932503ce7e52a3a6c0", + "js\/lib\/typedarray.min.js": "c78aa9dc295212548ac927783c62f1a5a5ff56c05164999f09d0ac5ea6a98afbe71aaa4e45eca469e379d920cc73beccbdebdd25f9797335f5b361fc4d87d09c", + "js\/lib\/wgxpath.install.js": "afbb4af1de778f5d135ef4be4d4eea98d27a323a139463d06b3f0b2c4cea00730e45d8414a0e74eace952c634f87e383a925c132bae043216312f9425a1b246d", + "js\/personal.js": "60e099c1e1136ad21216709562f3227031a46e359a8a86841dbd23770de3e1b039f36b19ccfb710b5d22bb1316113f5fd59f7861c37aade0f644839f0c6bf2b3", + "js\/plugin.js": "e7f1993c663e2bcf2bc51b42bccf6c873d6e2387fa02121e8ad5b64274198d52d54eb7d1b574dd68c762e8129abdc5a43ce210506f08b83a8e98c48166086d25", + "js\/ready.js": "a3fd42592fa94fa2d573b867238f5e35780681e218dc1aa23ce8a8afe66614ea0d8fa94abda4c7b7ab595727cd724c75d452a97bb0819b2d35fe2e145c985f00", + "js\/settings.js": "a627c42dd7ed708b0e3cf25494d402afa546b489cb0d53c7d15786ee3e333211c4a283c1eec6b6964d30a4b7c018f51f780aac6ad1b574d380b1c8514c48fabb", + "lib\/Controller\/BookmarkController.php": "1e1d680f5bcbf5edc49df09a696d011920d8695e305bebcc1c87cc9283a73a5ec8770a264312b8ec80c72f45855ea0baeb2753a7d7df05befb0c29db50ed692a", + "lib\/Controller\/MetadataController.php": "23e23b95c8c15d0ba5be797b26babb315703430251967fb536e267f3cd64af7047d1953e3299940db8acfecc2a87f5339220d37c0241b254fbf524c938a55053", + "lib\/Controller\/PageController.php": "0b6520136983eee131d0369fd6958dd19bb7cb0486f5a8ca0147eacfda120cf339f4dd2c61f3ff74eb87795063325a465d1036c002fb5d307315066160ee10f5", + "lib\/Controller\/PreferenceController.php": "3f3ced2dc68698f25dc0f4732d1d4dfdf5064a75102a0774acb5e6823b15b54651eecc7157214adb8de1ab9b18bd961085a8eb79edc6304576ed5bb8fbc18e94", + "lib\/Db\/Bookmark.php": "0eeea4cba7b182896acb9b630f0c5f076ee808468bda6a1c75dc8d2b369ace2e7942602a4151a43b40351e6f12b18bb34484eac0ed3d7f0a9d85769588da7674", + "lib\/Db\/BookmarkMapper.php": "eed3576c947e0506c7769a73ab27b3651efa4596eab297dd26fe2caa32eb9c57d95bda3915f7105c60c560196d6e14cac3c764aefda2a35111172e04b604e367", + "lib\/Db\/Preference.php": "e4edb4df45318e434a3d575473e8de64425d212b1bafbfaf90344616a17e4a7be7a69f3657e1179c1cc2e28e20573698a7449d70fbfdfe7a4097298800415975", + "lib\/Db\/PreferenceMapper.php": "4697ffe43030475d9091c3ce56936a7435533186f1ced6bebe3f07bbb47e8a59fa00758f77d2d27b8c13ed766d647450d7709e7b174c4da6e7bb0115e5c44988", + "lib\/Db\/ReaderEntity.php": "cb76626c5c4f2d177756093ef7f836c5365724c4ff8906a57056bbc85563ddc91118faf5efa0cb295a9e533680d38bf51cdf78ec2dc25bd7a4f0737457e0cfdd", + "lib\/Db\/ReaderMapper.php": "c8d44cefe4c1b3de1e55e71367c7d7e07630adbfd29027d29e06a4f04559c7ea869ccc28c862af439dd35042f8bbf7019cb5cab9bbd47c616ea99e28d222326d", + "lib\/Hooks.php": "5d894611556a0da57bb33cd889c8998ccf182241d38f770a97cf52bb8ffbd6a00f91ad317e4ab0397810d4c7a92aa36a9e971d53c5c2ebff016dd4cda6457541", + "lib\/Service\/BookmarkService.php": "7df012686e8d1e9a4668738d82edc51ca0da8e584767737091053bb48bcb896f11b03262f5e20dcd030a65af9c524d24003b3405679fbc23f60d0bb5d84eba15", + "lib\/Service\/MetadataService.php": "7bc4ab9cdd16ced31f46ba137fa1efb4d6ef4784f947886e8affe667bf7b51c532bdc079e9033e774db4ea30a8da1000df958fc6e15e518bd920995dccc729cf", + "lib\/Service\/PreferenceService.php": "2b52a28a074eba355154cbdad80358aaac394635ca91698ec3d7876eee0dc7e154064d8fbbe5465e7bbc783e618fbbf9ea1f07acd3cc4ce5b84116f7d8aed81c", + "lib\/Service\/Service.php": "cdf97b612fde0bec7846c0005280f1492d63e705b753c4aeb1df2c2ad2612a122d49eb15b6e7dfbe7fd7320762171a6ac6324181511dc28ec0e1e27092872eae", + "lib\/Utility\/Time.php": "58f760099eaf647718b491a7c21012398906bbe3ac7363aeceffff1a98d952f9a76697ddff2c00abe25e6c8db1cdf4d5994c1ab7d9474a05afb76b444ab9fed6", + "lib\/config.php": "f9f15e0cddfea124ce2f094034dba422b4a6c45395ea23512dfa0949d4fac94c2adff6e7fbeacab15fa978522f2f2c903b0c80fd3fa5d0301f130908290c1574", + "personal.php": "9150fcce3c8215a76e1ef83e4092fb068e7ab663abc1aab0038c54e6cb480fffb458c82122292050f6bffdf2f0a7ac6706ed35449979b86d5425db22372f9ad9", + "templates\/cbreader.php": "7ab62f3620c7e389aba6912b0729bbd0cb630aba1e5cbff4887497be3d51f9d8f35eeb748bb69684b65a8658a608a3f72353aa2212a92ad09664e9a87e2369ea", + "templates\/epubreader.php": "dea28a9329414876f2660bff99d8f694c78967498991600e88054c1f11b285e8c1235cc472b5fbe1ea95c80a142cbc2373a10102776124d19361beff1ed4431b", + "templates\/pdfreader.php": "16726d4eba75d85839e1c09a8842fba07869d1666a33d95511ed718727aed38de11004b017b878b0bbc5a9481e01454121bb24ddf4b1497022939fc575aa1af4", + "templates\/settings-personal.php": "f51394ed8fb4fda3bc75d10381f7ed7d04aa05a0555a82a80fd10a7d3b8264290e5a678a4d689fafc09e5aeacc29ebd19aec46544d3912bfa0680fa8c1b02152", + "vendor\/bartaz\/jquery.highlight.js": "2071d929cf62d8ef6cb85df2bef1d556d21c06fd23233e4938e8ba43df794ebb167b7ef75a50c10f01c9c59af76ae4278f5d254d1b0dcfca1a7201c35cfe2e33", + "vendor\/bgrins\/spectrum.css": "0d51df46221e84245609bf96f64fcf3aafdb9d2588a14e94382e78e605763bca1fd652adbfdacfce2324ea2d264baa3f1922a628e8c6ff55d4cc221ddbe05c15", + "vendor\/bgrins\/spectrum.js": "a7e0d8302e03348effecea4cad9cb59ed861d5268552d4829af68b4d77f2022ddb46817b5a419e57f17c19e8eae48d43ae6ba858258c71f9bd658930b4484b21", + "vendor\/bitjs\/archive\/archive.js": "e1d47d6129c54faea42c572e37502bd44f4af70710e9897c0dd6f1e064edcaac9e6bb77d9eb6b93e659769d87c52381875ee4e00b9f1e4e66c8ddd976951a1d6", + "vendor\/bitjs\/archive\/rarvm.js": "7257ecafd56b2cae8e2ed4abdad429ad133c3ddd9271505750248a9008915a619d996c583e832b722c5757f6f3ca8b8dd20043af076a9ddc93e043917d685f69", + "vendor\/bitjs\/archive\/unrar.js": "35fa0539f64141c6812a440f829e0a2c99ec9470a462cd561addb3eb8ab61df1681881a2c6d87ab2046e6b656fedba28bd21975bf38d1769aa5bf85da90232a3", + "vendor\/bitjs\/archive\/untar.js": "c76b6d7bf6e9ebb0c0837a083adb059c88f4054521e6d0e00e6e6b83119f194127b76473e7f61c507ad7c0802cf94089f07971c0ad61450ae2b5f1745758a691", + "vendor\/bitjs\/archive\/unzip.js": "6e96afc92d455895f4172a932cec5829e67b9366d01cb57992a844ed494c98b550b4ca61b2ffaca0b7b9094cf2da9ba6054e939b55732e040be87685e7760cdd", + "vendor\/bitjs\/io\/bitstream.js": "526d7463d45bbe9d05461becfbbd6d8d397b46262400196714fe7a93110b36766ad224ee55de8a8c1952e337336ba735a36530877c06de85aa3e691a3370ff67", + "vendor\/bitjs\/io\/bytebuffer.js": "1415e0730090cbf4472cb9933eabf15bdd4788029a18315b9f4f04b0cbcc59623b109f0d8561700c8341735e5a102c915a27b2fdf961aea8ca5958dd4ac2b0c6", + "vendor\/bitjs\/io\/bytestream.js": "7f2114a7baae81bba59ac90982a54e715aab736624f313148449b8f0aa3cafce1a83d154f395327a0fbbc74b756f820068c08fcb782789195477d87664678e97", + "vendor\/cbrjs\/cbr.js": "170fa1f23c9bf4fda864f70e90b7c54ff093672901ef8fc0f26b126fd955ddddb172f25dfdac4129e7fbd9f05489143c0fe9f418474546668b8c41d38e2df7d9", + "vendor\/cbrjs\/css\/cbr.css": "4fc0b73984b16568b8207b8c5fe35a15f5eae7d7fe336034870f4fa384be5f0489c02ee639857d18452fdc4a14ce2a8f6151fd2ebda9bd97e5152afc0bc81587", + "vendor\/cbrjs\/css\/idevice.css": "475870d07554bf15bfae371f7c91e5ac555aaba20eb29079471e4856f1f43d0d2dffde756420bde094e3fdda43b6f12379bf694b64ea1cb862bcff4042a94af6", + "vendor\/cbrjs\/img\/loading.gif": "83773895f43e75bd31209664494da8c89f1d3869cba24930d71a3e7090b4b38dcc0a31c9e1b764d763f586534c64996e72eda2fe035a7b485a28c33b206c96f1", + "vendor\/epubjs\/css\/annotations.css": "9600da17ca67c7372bae1bd951cc933de1d8ccf8c4c43f2a7b6bea71117141dc355935f693f8e3be9d3f87c027b3221d54085c6125a24d0edc65ffe985855780", + "vendor\/epubjs\/css\/font\/fontello.eot": "06dd0ad0f1367f0811db348865be15f6dc153cd1bed819bf0abcd1ba1d19f9910047bee178f12c7d2334620734f6a1f9e8001eb28bb53959f536a765729901a3", + "vendor\/epubjs\/css\/font\/fontello.svg": "183e8846244045b8891458572bf3b8a51b6a019aa6a374ca30481fc403df7d0225aaf648e8dc7ecfdb0c7abfe3d5d8a5d5d91d5dcd7d8b456e776d38c05e652e", + "vendor\/epubjs\/css\/font\/fontello.ttf": "122beb1963a58e2a6d30945f37e5c7e7f12d382965d4352f94230adef47a446393d5b10148d445f42c201a72901f955806dafc0b4e3a569cbcf9504008118a8e", + "vendor\/epubjs\/css\/font\/fontello.woff": "45723570e0dd5b60bf2b9508f46e28b015a2b7f27bce3528410affa77a6704817e4f4885fdce968987b5bf27092237903d8da2ae20c2d6bb13482e210dd64a72", + "vendor\/epubjs\/css\/idevice.css": "57f16116dac978222fc6ecc989b1bd97e5b21b783824d8b5108761a8e2ed3e7cd31fdb587f947bb86037af0a7b258b74458eae04f13508cf61b59bddc40e4c83", + "vendor\/epubjs\/css\/main.css": "5b646c47a8729740334e8212810d6a7329550164e8b26d55b654f7ec136d2bc98bac7aee3fa83de0cc81bbd0a1060a3e4032c216b6d50fd4cdc19610ec3bd310", + "vendor\/epubjs\/css\/normalize.css": "2640cf3ac3153b95939d2c6d1b6903d24a906d7737d48f79cda4e0e6bb41098c18b0d345deb1ce41d5d27f734d92b558c8f857e9909eec23bf8147abbd4a0fd7", + "vendor\/epubjs\/css\/popup.css": "d44a1a4647f2216ca0698300d9e462b6e5a57b19a68c93642a46bdc7681caad89888c1adbbf4e5322a6789d81dc00ab102001fcd761187f87ff330d5fde428fa", + "vendor\/epubjs\/css\/sidebar.css": "1d7835670fdee603aba9af5c715be34c327ccf963f6c8de4b9c6892c876301dc643d1d2203e1f5f263e83978cf5702e80bbb945cee138951db22e53457355781", + "vendor\/epubjs\/epub.main.css": "8f11961b3353679ea1ffe3ce2744421ed005c4d50b160e3378163f2cbea739fa5ab4eb5f8b727f5aebfdd0cdd996bf6a9de9fc762aa36327d47e92bf1a1ce8c6", + "vendor\/epubjs\/epub.min.js": "fe300613fe1f868c5c5c79e4f35b40c1155113ff540d8d68a1b04b642354a691eea6a9e2826fb9636e34505939fc69a60dba985674fd75b6b2a66b634f80651e", + "vendor\/epubjs\/epub.min.map": "8876e8186958c5425d0aa61f3b421119b52df007d4e1c460213d14e5f10c9950e11fff0579800e02ee8b44ce7bc71fbe72e45c1f216bff4b228a149d5283ad73", + "vendor\/epubjs\/hooks.min.js": "85852cb5097c502e4f681f8e0e0d9e77ef085ce607379541475c8a11d22d9e6593095a104c29a94565e41dbce853a9388c3a65454832bd768d1187dc6756fe85", + "vendor\/epubjs\/hooks.min.map": "2cc2bdd48db5909337225209b489345e7c545594ac1037c09981dcfd3215dc2c87c91084442c83f2b1daf881e5013c41d861c38bc18199771072dc853be3313c", + "vendor\/epubjs\/hooks\/default\/smartimages.js": "d3fbe0efe4cc9b6c8efc23a9d2ac729d92a1ef5fdba12be988be5979381c2d8de7385e1ddf5575fe1ed9863f15be82489a36436dd68ee70c2eace92d22ff8fe5", + "vendor\/epubjs\/hooks\/extensions\/highlight.js": "2acf2004de04837dd2bf678af8d6c960023c0228cae734d90df98996a7d02be788db20e9ad7c1fd757aa09366e6ee491e2eaafb9917cd4a95a129d583521516b", + "vendor\/epubjs\/libs\/jquery.min.js": "0d40bccaa59fedecf7243d63b33c42592541d0330fefc78ec81a4c6b9689922d5b211011ca4be23ae22621cce4c658f52a1552c92d7ac3615241eb640f8514db", + "vendor\/epubjs\/libs\/screenfull.min.js": "a09c4e0b145c226881398ec523cbd560ebbfdfeada44d41e2c1df27d0ac9de9839875cbbdcabd61febab37145e58e76fdd49f98062f05c48416244326ca7a117", + "vendor\/epubjs\/libs\/zip.min.js": "6ff9a48ad45127627e59e63a11d533663c608c73147d3a372774132cfc7f3b743268d3fb65cf177cbd56cd7fd105e9dfd948c463d1407fb4b0623df1d3397474", + "vendor\/epubjs\/reader.min.js": "0b6a37155d319141ddf06245bf1166640bad54d51f62abadbbb2a2ef03abfb1b2055810e29629060193ca5a80ef23c593cbc661d1806529c9debfe22cd505a12", + "vendor\/epubjs\/reader.min.map": "0374d1db0db30c48a25f4f40c206aeeaf5e323b528a1794cace3aa6de85499ba58577b8d85d1c2004f554154ffe2f1abd4adf42c7b28c6c0f64cc3eceb07a06c", + "vendor\/icomoon\/fonts\/icomoon.eot": "1296c03ecf92f70094c6e0cd4568e71604c956aa3f748fc45fd08b509e2b3680e9c83356116cea2f7ae2d60252eee106dff80d1a07550befa61b87f3ca6e2b71", + "vendor\/icomoon\/fonts\/icomoon.svg": "2cea5dc6e31ce32598f7543274443689a6940ae2d6ecd2fd7dbf25d3d967a804725afddc5446540a98ae11d92df85e4e8703aa4116d6d9c71b8bef4dd387207b", + "vendor\/icomoon\/fonts\/icomoon.ttf": "3355c12d54207f9a4e5f23728c43383d1191481a77cf102383bd5e036b59ca029a7265c36ae96ca6d1991df8446bc6891f01d81675473628e5bc26dc2e177d6d", + "vendor\/icomoon\/fonts\/icomoon.woff": "44a9098f464bf9e80000b2cf89096f2b07ee046127ce5c11005a31ebbfafd7475e56de7eebe96ad9cee7cba4da96df0a7fa6c816b17310bbde38f07fd40034d6", + "vendor\/icomoon\/style.css": "e949b8af266b96651ff40bed393a8f61f4d037b56ab9751a40845dc05f59103d58cffbe444038e8dcdf726e7da007e55c28b196fcab36148388e756174b71bad", + "vendor\/jquery\/put-delete.js": "2447c4937da33d0d8d567405db3e3bb43faca00576622edb65ddb592c4545a4bbc3259ea2e0f5f71ff425db4a33e0359250ee13718a6e80f3da97bdae7960afb", + "vendor\/pdfjs\/controllers\/annotationlayer_controller.js": "8cecf74b113e7738e1168000bc27dc30ad707b7768bb668b4dd3a0ff754e823681472894ba79a6438135e2ff49e31aca35e86a848065023313622df6ac7f1fbb", + "vendor\/pdfjs\/controllers\/bookmarks_controller.js": "cfb16b41285c6346eb5d76995060e505b035f5b8d50412f0dc7feb6f2f1c598144e98a5c14e451ed1515a45880ac8a75c5faf5437d8f4bd6699234e56b392d8a", + "vendor\/pdfjs\/controllers\/controls_controller.js": "b4925b842f4ab451cba7e43fb823aa1caa294913dfa6edd4a480753929d61d7165102978ef47fd6f05b4d8a011858b354f0c0a993b982a396824904145124905", + "vendor\/pdfjs\/controllers\/meta_controller.js": "fdf4620f401e0ad27da9e3d91aa18e91d7666623cbe598bc1c92127e2fff0c25f9c089767e0ad5ca1ece5a621b8916a61a60b10e0a2bef76a4bf013343bc0dc6", + "vendor\/pdfjs\/controllers\/notes_controller.js": "ba7793f50953857ecc4fb10a7848134c0e23922cc3783360c9af87834dc34729ba04c6c6af4a69417261d31c345ab1add2c99afb6d4fbd61e6e8c91427404d46", + "vendor\/pdfjs\/controllers\/outline_controller.js": "c69fe71b155920cbf4825834cc7c7f6c91fbcbcabae4c892cf0b2d4a636db8faf9c25e54d58029544a12bfb631d1f4c74d9d7e1ed35cf10cd862a495efc1d891", + "vendor\/pdfjs\/controllers\/progress_controller.js": "9894b73c39a3b500fc057472a7ec01e876bdd6e6d8d87dce12a46698a9847aaad576294e05fb9a33d649659a00549b67921d66c04216101c61d1c75db0f8e828", + "vendor\/pdfjs\/controllers\/reader_controller.js": "d485fa07171bf2d84771008d5cd8c6284d3d870e7e3d72bb7a01e817db31bd6a96b5223bc314416cfd78d62b92039f92d22e03073c12ee7a8f0ba442df6f03c3", + "vendor\/pdfjs\/controllers\/search_controller.js": "d44a327561e9fb67e535be4fcc307d309f4aea0ee16be23057ed0f41692de01a1cf69d3f7bc2b30b26a7bdf776df5d56ff9ee26cce94f37b5cd27d4e14d5a93d", + "vendor\/pdfjs\/controllers\/settings_controller.js": "07f8288df9071afbb2f8ff6f4f505a254bd9383d6f9a57f1e06d00da98aadd321cf4563f421c0b7e214a4dda26865f0376ace14b3ad88d34aa8aaef93eceb735", + "vendor\/pdfjs\/controllers\/sidebar_controller.js": "3071f59c01d6088c21f92ef36f7c6b15024ba3dea7bc005dc1921b14c9c1c6320f7eecd158e974f9b8592dacc488ef79fc38d4925978557b09fc12815a5b86b0", + "vendor\/pdfjs\/controllers\/styles_controller.js": "9abaec5302ca07fe45eb99f8cf23a4b6e820f9153a66763e49a1d83a092ddb719e2899c888c38d9152ecc50eeade045041ec16d9d9ee991a37eba8a2f23c4303", + "vendor\/pdfjs\/controllers\/textlayer_controller.js": "ca23b356a61328cc1400fdad6b8fd52c04347187c385737f650680b326326d60816d921dd191a04e09abdf00669bd6ac2ca2140ab803986079c4e8d74df51c0f", + "vendor\/pdfjs\/controllers\/textlayer_controller.js.simple": "05f346ebf5ba57f8de6f47a5e13da6defdd0774b4e546101f4b5be1ee7b2e7848bd5b8d6c08e4ed1c7e5d3f4dfa36ec4682b7e9062adfba3ca4cfe9ded51643c", + "vendor\/pdfjs\/controllers\/toc_controller.js": "acabaf107bd8058089225b9b3f53907d96666f726cde73bd912790ef6997b13dc35f7fa2695f67923ce2279fa9e931f23eb5f684573131a3d4da4a2ca137db5f", + "vendor\/pdfjs\/css\/annotation_layer_builder.css": "b01d778e71769bfbd9f494e3e992f9b4d1762851e10b0977b5f50285dfda011ac27ace43b10c32431997432859f8458dc04aeda1cb08429fd16141157681708c", + "vendor\/pdfjs\/css\/annotations.css": "9600da17ca67c7372bae1bd951cc933de1d8ccf8c4c43f2a7b6bea71117141dc355935f693f8e3be9d3f87c027b3221d54085c6125a24d0edc65ffe985855780", + "vendor\/pdfjs\/css\/idevice.css": "57f16116dac978222fc6ecc989b1bd97e5b21b783824d8b5108761a8e2ed3e7cd31fdb587f947bb86037af0a7b258b74458eae04f13508cf61b59bddc40e4c83", + "vendor\/pdfjs\/css\/images\/annotation-check.svg": "7442036525e2d5c0ca86c3e6e343bf79f39c9d39ea4815bcbea3056f157465821fa19ef559c7079ea60c7cf99ab4a01ad47af7f46e02f8ff2822893b947b14a9", + "vendor\/pdfjs\/css\/images\/annotation-comment.svg": "3b0e0c6fa42084f28edabbaabca1052afd76c3c41576f23ebee598960da96556ab088e8730206d816c6d1434bcb03b0ba36d50abce074dad00cbce99fdff841e", + "vendor\/pdfjs\/css\/images\/annotation-help.svg": "735e99c561fe8a509bb5375f77cff79c601f9fe82c3af9254a657bc2b6274a77ccde0014855ba1e925ea2beb207e0b0c6b138f3f78f41a7e9df71f5e58f2c8c4", + "vendor\/pdfjs\/css\/images\/annotation-insert.svg": "f8caef572ed87fb5dd3c421665cdd1f5e4f414a65148d3d9990bbec21d9adad86810c58610c800b7649f719d88a53fc924f0dda88b1cb7883e74b709774061c6", + "vendor\/pdfjs\/css\/images\/annotation-key.svg": "e9e8b365bd41ae612560f438c6aeb0d1aa2e55f223812b26bf6cabf44b39bf2e1a42b41980fe60187199cea0f2adf1f31c7a0860be10edbc595832542bb1d7e5", + "vendor\/pdfjs\/css\/images\/annotation-newparagraph.svg": "ae5816a3ba95cbff2bdf876f4f2f4a0bd7e347bdbaacc09a2e65d46d0edc256c7f0b896536ee5470a2d17cd903d3bae52bd506c12d77504ac0aefb25265eebb9", + "vendor\/pdfjs\/css\/images\/annotation-noicon.svg": "b74f7a79dc719acab1f351ac70f00455654dda140d2bc24eac6d48c804bf24ef5938c7d85073004e20b0b3c52f1c38f598f811e068e5b9092e11085d468af0ed", + "vendor\/pdfjs\/css\/images\/annotation-note.svg": "566be95c1dda2d5a52ffe0a6899f5058c547f91fcdc60dbe26a79b39fe427a79802d6d52eacb711acfee368318f7b0d54dc9067d88962306d4b0d4ed65d651e4", + "vendor\/pdfjs\/css\/images\/annotation-paragraph.svg": "f016ff103e8de8e6cf19aee5e7b627ccce075844e41395cfa20342a0b42a13dce82106e4b06bbb1d7e7c135b0dfb8fba0ab3b0703f40afb9625048076ea3558e", + "vendor\/pdfjs\/css\/main.css": "1da78c281eddc61935ca89f905f5ba6f2943722e11ce9dd09a7a3005a0f733a8cd643f30669507cf5d830cda217b14de3a9201e4e246c70973fc916a2a2a3c35", + "vendor\/pdfjs\/css\/normalize.css": "2640cf3ac3153b95939d2c6d1b6903d24a906d7737d48f79cda4e0e6bb41098c18b0d345deb1ce41d5d27f734d92b558c8f857e9909eec23bf8147abbd4a0fd7", + "vendor\/pdfjs\/css\/popup.css": "d44a1a4647f2216ca0698300d9e462b6e5a57b19a68c93642a46bdc7681caad89888c1adbbf4e5322a6789d81dc00ab102001fcd761187f87ff330d5fde428fa", + "vendor\/pdfjs\/css\/sidebar.css": "aa4aa85bcc4e4ec3c40fccf59c671802ce1fa3eb49bb0c048d9a20361d56f0d0b24602ce17fb6cce4433b982147a565ef7b2922a7a88e8edbc636a47ed8d492f", + "vendor\/pdfjs\/css\/text_layer_builder.css": "1a723bcffea2832acc35cda3e90b0f7b241da62e2904309cdb61ec4fef9203ca198ad187abe24c007dca4a932a052f9f7f4e718fd86d915f1bb58f6c50227dc1", + "vendor\/pdfjs\/lib\/pdf.js": "2d7241061e30e69963a78c64345ecbb889b831ec72cdccdb07d0e684c9cf907bcf45e3781b91e51c1ca4258e796eed0a69d83e8945ccd98ace75cd57ca57d5a0", + "vendor\/pdfjs\/lib\/pdf.worker.js": "03cd966b7b23dabebbc1652e19f2511c41237d8cafcc8fef655b6424c1b5884e48fa3ea052d1ebafe3c6be096c0c6aec1c9cbad45115912a4a75eb886c591534", + "vendor\/pdfjs\/lib\/text_layer_builder.js": "f56f1d3b1a61a2b5ba4945a60057604d95a3595f2dec4e5c99b79db10f3b00a0e6be30169383fccda3a64aadda3f607f650ac261c47bbea7f0f6a3196b645f28", + "vendor\/pdfjs\/pdf.reader.js": "4c3cc3bc3f5b796ff3f9691a505fd051f768e359e4d2a9dea7725e7cede15e529c8a99760c9d1b9bdd199bc215d3db6861253ca50df75fcebf5437dce064df65", + "vendor\/pdfjs\/services\/eventbus_service.js": "851b741ec0eb06a7298664d626e648613f86d3958f4c7045cadaafb5c146088952ce584d5a4079ea51b54f07fc0cb2e9a9ddfefe52a70b2162c083b10b6293bc", + "vendor\/pdfjs\/services\/link_service.js": "b227d4163e2fcb3db4ed0ee2dd9f0af59dd263bc05153139d9588dd536071ca6d6430be214795f440061bcce6c6685986b5b002e4c9af7d0e2268ed83fe43424", + "vendor\/pdfjs\/services\/simple_link_service.js": "ffaa00f383100c5c689da1f8bfbe3baa06fc42147acfa781356eb67958cc6fbf2c34d8f448afa7f5bb14a5132c43fb78b3ad6a469f2af32ac0e29c93aa7f7ac3", + "vendor\/pixastic\/pixastic.effects.js": "85bd5facd47936aa75e5e18bcbec62641448c909a97a3714d3741e1880cfaca31fa60d85940ae6f27257d895bc278e00c87867cb742fa0c6eeb85bdd5ce9b36d", + "vendor\/pixastic\/pixastic.js": "f090060b5977941be122cf285b279e9d28fb54f1cfe9f373c0866157aa7e124296745638d3ac92356b727f719220da95f968d830eed688908498c6d8c892c226", + "vendor\/pixastic\/pixastic.worker.control.js": "c913b34aaea57f6ef76075ab6c0e169431947611789766cda6914ade93e98c877ac75cf092f2db1ca0876a6b8cc28d2fd13d22398d08101b787548ce4d2603c1", + "vendor\/pixastic\/pixastic.worker.js": "f59136a3bdbbf33fa3f81ba0cefd33b81269bbc230e7900232c725139674e53dc070f8445081b32350bcaba70ab713d6426902d66986554709c1a48952396283", + "vendor\/pixastic\/pixastic_combined.js": "a69bff7c76e6cdce7de3184184114e10f2ddcb369a2de03b1986c9a74d71f67f038d452d60df4a638e12420314bdc5c052a791a98d22ae5347a5f43bffd8b2f2", + "vendor\/sindresorhus\/screenfull.js": "29d23b28b76827f037265ce60ef5cf76c0d560c7aece03593021feae9f6220c3170abf5a8b5f380885fe15e9204425fb5446fef61c3b0ca83d6f332eb1bd1571" + }, + "signature": "Rhl7J96FALdH2LF1bnEe4VF64bAskJb0eWY9skIa1FnBsUnNMYJDERwIPse5EoNfrlB5puy88TjeKbq4DZNTC4yj4tHhX26B8wdPmZ9vw6+mXdoa90W6iRBSrpnwA0kWEH588no3RPOhsIBqzHpkuIXxSCvOEyVw6tE\/LMTRWSZBZSLpzoaTUZJEyu8Wg9keAoVv+KdyNZnDm23CMOy0JhEPfNVB+\/Bvv6x4oJFy4Rz015\/K+kkGL7r7N7BP1H93zSLEbMO4oc8OzRWWnjqd3N5Dmzkx335C3vn4DdW+XzQwxpw1kCkpR+DFNkWNB7EhykaGoFOhcwY1Hkddf8J8S\/iAC1qgGg7ZbpZV+rcSedhL5sYPrAyyP+WRx21eLqtBU\/kQyaqLycbXSxhJ0m8LrNbAZtbyhPlmDGXIGWj2+B6qcjHRBEnD+XIPt2ObRLMwolbg5Ema5dv2bs1w5gvBMmsQthyJCH9AVzfB9lFBIYIcRoWAo14Og4HMOf7gld0rjd0qPFuXDop+\/JBo4d74r5W688xnh0AYmIS8WgQoGADWFDE5NNQtp+QOLi7q7YD\/5g3rte0ElbgvfTRQO75uORqdZoymfnwtt7j1OewBm19cWzWttNmu7BtmKcUe3Qipdu+fF+s402oPvmCkb3k5M4rgh82Wl3ASj6JebtbLikw=", + "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIE+TCCAuECAhBPMA0GCSqGSIb3DQEBCwUAMG0xCzAJBgNVBAYTAlVTMQ8wDQYD\r\nVQQIDAZCb3N0b24xFjAUBgNVBAoMDW93bkNsb3VkIEluYy4xNTAzBgNVBAMMLG93\r\nbkNsb3VkIENvZGUgU2lnbmluZyBJbnRlcm1lZGlhdGUgQXV0aG9yaXR5MB4XDTE4\r\nMDExODIxMzMyNFoXDTI4MDExNjIxMzMyNFowFzEVMBMGA1UEAwwMZmlsZXNfcmVh\r\nZGVyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA2Dro3KQnJEnKeJVG\r\nnhKvrQSzLNyphcF5UNj4j3Km6wLcb86RkWtq6uX5eR6g0HI9NFZF3qxBLUGN8bpM\r\ngGyalTLwj5IsDYO\/naSZe\/wXNCBl82vZq+jjnDCYll7r2yNjTFVzRtH+o9AIQlmM\r\npt8+PCcw8n8QqlXUIq9A3kb8wggczEZnw6bCudDLQWXHYKD5\/tn7n06h9fA4VxfB\r\nQMyuv8hIjKEQqun3Qqvi3DfaR52sbeDvv9bGACxWqjiE3P6sZvL7MlDqJ5KeqWoM\r\n4qPGkgDusTtXuO7h3ro2H4NMydWXcrbUAPTXcAPo2jzTfhV8m9xQDc+45VlONjIp\r\nTFwV1oF53hnu81TlNniz1RTbDYMkExvPYtobNjNIR+VsOQs8Gq9iEDEIxyqCm2it\r\ncuMjeFhYr1rjyeS21i6cNtD\/kMxSFwKnluQPrb49pK6g2Nq5Go1iP8WgT12hAQhr\r\ni7wwH32bLe11xnD53ko6pAzhqmciaSHLxkZCm+eyTNwJzQa0uQ+gAD8gJ7bVQUxg\r\nPSjm1amfhMAzsHIraMFqzlz7IWjWA7vJGkR9DcweYBXsyt6ZloLekPsNxEKnuh3F\r\ngjBHEoy7iPLmDxGvTfPW76r6vBwBF9JgIrhJzRMtTHTsYX9olblQr957SLyiZaqJ\r\n\/kKCQZ3cKPhWBh1KydMjPlXbGFUCAwEAATANBgkqhkiG9w0BAQsFAAOCAgEAcYdp\r\ntoKFBZV7rswQ9yL6Y8F\/\/VUM1J1jincG3soCz5\/n5rL0TDekS0FI8eNWX0tay0ne\r\n3\/FZ93\/fb+gkQf7KutU\/9EWZwnc90XNq+Q3\/3DWz+nIm3EFttz6GioVYz7XEAx3A\r\nSMWeWY05ei9V7SVSnqglhouhLENrKKI8ilzGI\/pEtCs3RUv3xi7GPBdCDnvqqeXy\r\nRHrP7ZFe3v1go84v1MwQOt4\/OtaYk\/4HU51oxzUI8yDMNtLNmZm7gqLbT9bRsWCz\r\n5gqFa15K4X7sVL\/ECI72zEDZsF0RtmTCp9fJLoYXIPPQ1CACi0K0hB\/ssE6BC9Zl\r\naUXcbZ2BLwvQiZmEUhyyr0WYK4D\/dE4LbYqYpDDGRhXpf4cRhQahsYL8aMzZtZfl\r\nNDE4PN\/4sV6id6MnwrtDmsW3frMlkhzrsm8ftzwkbIyJD1Io5OAOJn6oxN2sjlWD\r\ngof0tuweAlTGuAI7\/CUA2yMZb45MFkLWDExzZsiVy9UtU641cDzOxAbg7UIeTBRZ\r\nYUdl5ci1f8299Yridc4n70yQg2GHwa8YJ6p42f93sTOo0E1UAX1+eBmuAmc\/eBq0\r\nFjjmMyPZy7EhElAUa2sqw5QS2\/AK34P0rccCaJerRJ0mU54neL5qSEuuPQnVcn\/\/\r\n3LGndYF8t5kHI3iXV3TJ2vyagUkWeDl6z9pyW0Y=\r\n-----END CERTIFICATE-----" +} \ No newline at end of file diff --git a/css/settings.css b/css/settings.css new file mode 100644 index 0000000..ed80d66 --- /dev/null +++ b/css/settings.css @@ -0,0 +1,3 @@ +.nav-icon-reader { + background-image: url('../img/app.svg?v=2'); +} diff --git a/img/app.svg b/img/app.svg new file mode 100644 index 0000000..8c89d34 --- /dev/null +++ b/img/app.svg @@ -0,0 +1,50 @@ + + + + + + image/svg+xml + + + + + + + + + +   + + diff --git a/img/book.png b/img/book.png new file mode 100644 index 0000000..a7b8079 Binary files /dev/null and b/img/book.png differ diff --git a/img/loading.gif b/img/loading.gif new file mode 100644 index 0000000..f8f3dff Binary files /dev/null and b/img/loading.gif differ diff --git a/js/lib/Blob.js b/js/lib/Blob.js new file mode 100644 index 0000000..3b44c65 --- /dev/null +++ b/js/lib/Blob.js @@ -0,0 +1,197 @@ +/* Blob.js + * A Blob implementation. + * 2014-07-24 + * + * By Eli Grey, http://eligrey.com + * By Devin Samarin, https://github.com/dsamarin + * License: X11/MIT + * See https://github.com/eligrey/Blob.js/blob/master/LICENSE.md + */ + +/*global self, unescape */ +/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true, + plusplus: true */ + +/*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */ + +(function (view) { + "use strict"; + + view.URL = view.URL || view.webkitURL; + + if (view.Blob && view.URL) { + try { + new Blob; + return; + } catch (e) {} + } + + // Internally we use a BlobBuilder implementation to base Blob off of + // in order to support older browsers that only have BlobBuilder + var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || (function(view) { + var + get_class = function(object) { + return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1]; + } + , FakeBlobBuilder = function BlobBuilder() { + this.data = []; + } + , FakeBlob = function Blob(data, type, encoding) { + this.data = data; + this.size = data.length; + this.type = type; + this.encoding = encoding; + } + , FBB_proto = FakeBlobBuilder.prototype + , FB_proto = FakeBlob.prototype + , FileReaderSync = view.FileReaderSync + , FileException = function(type) { + this.code = this[this.name = type]; + } + , file_ex_codes = ( + "NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR " + + "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR" + ).split(" ") + , file_ex_code = file_ex_codes.length + , real_URL = view.URL || view.webkitURL || view + , real_create_object_URL = real_URL.createObjectURL + , real_revoke_object_URL = real_URL.revokeObjectURL + , URL = real_URL + , btoa = view.btoa + , atob = view.atob + + , ArrayBuffer = view.ArrayBuffer + , Uint8Array = view.Uint8Array + + , origin = /^[\w-]+:\/*\[?[\w\.:-]+\]?(?::[0-9]+)?/ + ; + FakeBlob.fake = FB_proto.fake = true; + while (file_ex_code--) { + FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1; + } + // Polyfill URL + if (!real_URL.createObjectURL) { + URL = view.URL = function(uri) { + var + uri_info = document.createElementNS("http://www.w3.org/1999/xhtml", "a") + , uri_origin + ; + uri_info.href = uri; + if (!("origin" in uri_info)) { + if (uri_info.protocol.toLowerCase() === "data:") { + uri_info.origin = null; + } else { + uri_origin = uri.match(origin); + uri_info.origin = uri_origin && uri_origin[1]; + } + } + return uri_info; + }; + } + URL.createObjectURL = function(blob) { + var + type = blob.type + , data_URI_header + ; + if (type === null) { + type = "application/octet-stream"; + } + if (blob instanceof FakeBlob) { + data_URI_header = "data:" + type; + if (blob.encoding === "base64") { + return data_URI_header + ";base64," + blob.data; + } else if (blob.encoding === "URI") { + return data_URI_header + "," + decodeURIComponent(blob.data); + } if (btoa) { + return data_URI_header + ";base64," + btoa(blob.data); + } else { + return data_URI_header + "," + encodeURIComponent(blob.data); + } + } else if (real_create_object_URL) { + return real_create_object_URL.call(real_URL, blob); + } + }; + URL.revokeObjectURL = function(object_URL) { + if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) { + real_revoke_object_URL.call(real_URL, object_URL); + } + }; + FBB_proto.append = function(data/*, endings*/) { + var bb = this.data; + // decode data to a binary string + if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) { + var + str = "" + , buf = new Uint8Array(data) + , i = 0 + , buf_len = buf.length + ; + for (; i < buf_len; i++) { + str += String.fromCharCode(buf[i]); + } + bb.push(str); + } else if (get_class(data) === "Blob" || get_class(data) === "File") { + if (FileReaderSync) { + var fr = new FileReaderSync; + bb.push(fr.readAsBinaryString(data)); + } else { + // async FileReader won't work as BlobBuilder is sync + throw new FileException("NOT_READABLE_ERR"); + } + } else if (data instanceof FakeBlob) { + if (data.encoding === "base64" && atob) { + bb.push(atob(data.data)); + } else if (data.encoding === "URI") { + bb.push(decodeURIComponent(data.data)); + } else if (data.encoding === "raw") { + bb.push(data.data); + } + } else { + if (typeof data !== "string") { + data += ""; // convert unsupported types to strings + } + // decode UTF-16 to binary string + bb.push(unescape(encodeURIComponent(data))); + } + }; + FBB_proto.getBlob = function(type) { + if (!arguments.length) { + type = null; + } + return new FakeBlob(this.data.join(""), type, "raw"); + }; + FBB_proto.toString = function() { + return "[object BlobBuilder]"; + }; + FB_proto.slice = function(start, end, type) { + var args = arguments.length; + if (args < 3) { + type = null; + } + return new FakeBlob( + this.data.slice(start, args > 1 ? end : this.data.length) + , type + , this.encoding + ); + }; + FB_proto.toString = function() { + return "[object Blob]"; + }; + FB_proto.close = function() { + this.size = 0; + delete this.data; + }; + return FakeBlobBuilder; + }(view)); + + view.Blob = function(blobParts, options) { + var type = options ? (options.type || "") : ""; + var builder = new BlobBuilder(); + if (blobParts) { + for (var i = 0, len = blobParts.length; i < len; i++) { + builder.append(blobParts[i]); + } + } + return builder.getBlob(type); + }; +}(typeof self !== "undefined" && self || typeof window !== "undefined" && window || this.content || this)); diff --git a/js/lib/blob.js b/js/lib/blob.js new file mode 100644 index 0000000..b20ed0b --- /dev/null +++ b/js/lib/blob.js @@ -0,0 +1,31 @@ +Blob = (function() { + var nativeBlob = Blob; + + // Add unprefixed slice() method. + if (Blob.prototype.webkitSlice) { + Blob.prototype.slice = Blob.prototype.webkitSlice; + } + else if (Blob.prototype.mozSlice) { + Blob.prototype.slice = Blob.prototype.mozSlice; + } + + // Temporarily replace Blob() constructor with one that checks support. + return function(parts, properties) { + try { + // Restore native Blob() constructor, so this check is only evaluated once. + Blob = nativeBlob; + return new Blob(parts || [], properties || {}); + } + catch (e) { + // If construction fails provide one that uses BlobBuilder. + Blob = function (parts, properties) { + var bb = new (WebKitBlobBuilder || MozBlobBuilder), i; + for (i in parts) { + bb.append(parts[i]); + } + + return bb.getBlob(properties && properties.type ? properties.type : undefined); + }; + } + }; +}()); diff --git a/js/lib/typedarray.js b/js/lib/typedarray.js new file mode 100644 index 0000000..9c02368 --- /dev/null +++ b/js/lib/typedarray.js @@ -0,0 +1,629 @@ +/* +$LicenseInfo:firstyear=2010&license=mit$ + +Copyright (c) 2010, Linden Research, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +$/LicenseInfo$ +*/ +/*global document*/ + +// +// ES3/ES5 implementation of the Krhonos TypedArray Working Draft (work in progress): +// Ref: https://cvs.khronos.org/svn/repos/registry/trunk/public/webgl/doc/spec/TypedArray-spec.html +// Date: 2011-02-01 +// +// Variations: +// * Float/Double -> Float32/Float64, per WebGL-Public mailing list conversations (post 5/17) +// * Allows typed_array.get/set() as alias for subscripts (typed_array[]) + +var ArrayBuffer, ArrayBufferView, + Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array, + DataView; + +(function () { + "use strict"; + /*jslint bitwise: false, nomen: false */ + + // Approximations of internal ECMAScript conversion functions + var ECMAScript = { + ToInt32: function (v) { return v >> 0; }, + ToUint32: function (v) { return v >>> 0; } + }; + + // Raise an INDEX_SIZE_ERR event - intentionally induces a DOM error + function raise_INDEX_SIZE_ERR() { + if (document) { + // raises DOMException(INDEX_SIZE_ERR) + document.createTextNode("").splitText(1); + } + throw new RangeError("INDEX_SIZE_ERR"); + } + + // ES5: lock down object properties + function configureProperties(obj) { + if (Object.getOwnPropertyNames && Object.defineProperty) { + var props = Object.getOwnPropertyNames(obj), i; + for (i = 0; i < props.length; i += 1) { + Object.defineProperty(obj, props[i], { + value: obj[props[i]], + writable: false, + enumerable: false, + configurable: false + }); + } + } + } + + // emulate ES5 getter/setter API using legacy APIs + // http://blogs.msdn.com/b/ie/archive/2010/09/07/transitioning-existing-code-to-the-es5-getter-setter-apis.aspx + if (Object.prototype.__defineGetter__ && !Object.defineProperty) { + Object.defineProperty = function (obj, prop, desc) { + if (desc.hasOwnProperty('get')) { obj.__defineGetter__(prop, desc.get); } + if (desc.hasOwnProperty('set')) { obj.__defineSetter__(prop, desc.set); } + }; + } + + // ES5: Make obj[index] an alias for obj._getter(index)/obj._setter(index, value) + // for index in 0 ... obj.length + function makeArrayAccessors(obj) { + if (!Object.defineProperty) { return; } + + function makeArrayAccessor(index) { + Object.defineProperty(obj, index, { + 'get': function () { return obj._getter(index); }, + 'set': function (v) { obj._setter(index, v); }, + enumerable: true, + configurable: false + }); + } + + var i; + for (i = 0; i < obj.length; i += 1) { + makeArrayAccessor(i); + } + } + + // Internal conversion functions: + // pack() - take a number (interpreted as Type), output a byte array + // unpack() - take a byte array, output a Type-like number + + function as_signed(value, bits) { var s = 32 - bits; return (value << s) >> s; } + function as_unsigned(value, bits) { var s = 32 - bits; return (value << s) >>> s; } + + function packInt8(n) { return [n & 0xff]; } + function unpackInt8(bytes) { return as_signed(bytes[0], 8); } + + function packUint8(n) { return [n & 0xff]; } + function unpackUint8(bytes) { return as_unsigned(bytes[0], 8); } + + function packInt16(n) { return [(n >> 8) & 0xff, n & 0xff]; } + function unpackInt16(bytes) { return as_signed(bytes[0] << 8 | bytes[1], 16); } + + function packUint16(n) { return [(n >> 8) & 0xff, n & 0xff]; } + function unpackUint16(bytes) { return as_unsigned(bytes[0] << 8 | bytes[1], 16); } + + function packInt32(n) { return [(n >> 24) & 0xff, (n >> 16) & 0xff, (n >> 8) & 0xff, n & 0xff]; } + function unpackInt32(bytes) { return as_signed(bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3], 32); } + + function packUint32(n) { return [(n >> 24) & 0xff, (n >> 16) & 0xff, (n >> 8) & 0xff, n & 0xff]; } + function unpackUint32(bytes) { return as_unsigned(bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3], 32); } + + function packIEEE754(v, ebits, fbits) { + + var bias = (1 << (ebits - 1)) - 1, + s, e, f, ln, + i, bits, str, bytes; + + // Compute sign, exponent, fraction + if (isNaN(v)) { + // http://dev.w3.org/2006/webapi/WebIDL/#es-type-mapping + e = (1 << bias) - 1; f = Math.pow(2, fbits - 1); s = 0; + } + else if (v === Infinity || v === -Infinity) { + e = (1 << bias) - 1; f = 0; s = (v < 0) ? 1 : 0; + } + else if (v === 0) { + e = 0; f = 0; s = (1 / v === -Infinity) ? 1 : 0; + } + else { + s = v < 0; + v = Math.abs(v); + + if (v >= Math.pow(2, 1 - bias)) { + // Normalized + ln = Math.min(Math.floor(Math.log(v) / Math.LN2), bias); + e = ln + bias; + f = Math.round(v * Math.pow(2, fbits - ln) - Math.pow(2, fbits)); + } + else { + // Denormalized + e = 0; + f = Math.round(v / Math.pow(2, 1 - bias - fbits)); + } + } + + // Pack sign, exponent, fraction + bits = []; + for (i = fbits; i; i -= 1) { bits.push(f % 2 ? 1 : 0); f = Math.floor(f / 2); } + for (i = ebits; i; i -= 1) { bits.push(e % 2 ? 1 : 0); e = Math.floor(e / 2); } + bits.push(s ? 1 : 0); + bits.reverse(); + str = bits.join(''); + + // Bits to bytes + bytes = []; + while (str.length) { + bytes.push(parseInt(str.substring(0, 8), 2)); + str = str.substring(8); + } + return bytes; + } + + function unpackIEEE754(bytes, ebits, fbits) { + + // Bytes to bits + var bits = [], i, j, b, str, + bias, s, e, f; + + for (i = bytes.length; i; i -= 1) { + b = bytes[i - 1]; + for (j = 8; j; j -= 1) { + bits.push(b % 2 ? 1 : 0); b = b >> 1; + } + } + bits.reverse(); + str = bits.join(''); + + // Unpack sign, exponent, fraction + bias = (1 << (ebits - 1)) - 1; + s = parseInt(str.substring(0, 1), 2) ? -1 : 1; + e = parseInt(str.substring(1, 1 + ebits), 2); + f = parseInt(str.substring(1 + ebits), 2); + + // Produce number + if (e === (1 << ebits) - 1) { + return f !== 0 ? NaN : s * Infinity; + } + else if (e > 0) { + // Normalized + return s * Math.pow(2, e - bias) * (1 + f / Math.pow(2, fbits)); + } + else if (f !== 0) { + // Denormalized + return s * Math.pow(2, -(bias - 1)) * (f / Math.pow(2, fbits)); + } + else { + return s < 0 ? -0 : 0; + } + } + + function unpackFloat64(b) { return unpackIEEE754(b, 11, 52); } + function packFloat64(v) { return packIEEE754(v, 11, 52); } + function unpackFloat32(b) { return unpackIEEE754(b, 8, 23); } + function packFloat32(v) { return packIEEE754(v, 8, 23); } + + + if (!ArrayBuffer) { + (function () { + + // + // 3 The ArrayBuffer Type + // + + ArrayBuffer = function (length) { + length = ECMAScript.ToInt32(length); + if (length < 0) { throw new RangeError('ArrayBuffer size is not a small enough positive integer.'); } + + this.byteLength = length; + this._bytes = []; + this._bytes.length = length; + + var i; + for (i = 0; i < this.byteLength; i += 1) { + this._bytes[i] = 0; + } + + configureProperties(this); + }; + + + // + // 4 The ArrayBufferView Type + // + + // NOTE: this constructor is not exported + ArrayBufferView = function () { + //this.buffer = null; + //this.byteOffset = 0; + //this.byteLength = 0; + }; + + // + // 5 The Typed Array View Types + // + + function makeTypedArrayConstructor(bytesPerElement, pack, unpack) { + // Each TypedArray type requires a distinct constructor instance with + // identical logic, which this produces. + + var ctor; + ctor = function (buffer, byteOffset, length) { + var array, sequence, i, s; + + // Constructor(unsigned long length) + if (!arguments.length || typeof arguments[0] === 'number') { + this.length = ECMAScript.ToInt32(arguments[0]); + if (length < 0) { throw new RangeError('ArrayBufferView size is not a small enough positive integer.'); } + + this.byteLength = this.length * this.BYTES_PER_ELEMENT; + this.buffer = new ArrayBuffer(this.byteLength); + this.byteOffset = 0; + } + + // Constructor(TypedArray array) + else if (typeof arguments[0] === 'object' && arguments[0].constructor === ctor) { + array = arguments[0]; + + this.length = array.length; + this.byteLength = this.length * this.BYTES_PER_ELEMENT; + this.buffer = new ArrayBuffer(this.byteLength); + this.byteOffset = 0; + + for (i = 0; i < this.length; i += 1) { + this._setter(i, array._getter(i)); + } + } + + // Constructor(sequence array) + else if (typeof arguments[0] === 'object' && !(arguments[0] instanceof ArrayBuffer)) { + sequence = arguments[0]; + + this.length = ECMAScript.ToUint32(sequence.length); + this.byteLength = this.length * this.BYTES_PER_ELEMENT; + this.buffer = new ArrayBuffer(this.byteLength); + this.byteOffset = 0; + + for (i = 0; i < this.length; i += 1) { + s = sequence[i]; + this._setter(i, Number(s)); + } + } + + // Constructor(ArrayBuffer buffer, + // optional unsigned long byteOffset, optional unsigned long length) + else if (typeof arguments[0] === 'object' && arguments[0] instanceof ArrayBuffer) { + this.buffer = buffer; + + this.byteOffset = ECMAScript.ToUint32(byteOffset); + if (this.byteOffset > this.buffer.byteLength) { + raise_INDEX_SIZE_ERR(); // byteOffset out of range + } + + if (this.byteOffset % this.BYTES_PER_ELEMENT) { + // The given byteOffset must be a multiple of the element + // size of the specific type, otherwise an exception is raised. + //raise_INDEX_SIZE_ERR(); + throw new RangeError("ArrayBuffer length minus the byteOffset is not a multiple of the element size."); + } + + if (arguments.length < 3) { + this.byteLength = this.buffer.byteLength - this.byteOffset; + + if (this.byteLength % this.BYTES_PER_ELEMENT) { + raise_INDEX_SIZE_ERR(); // length of buffer minus byteOffset not a multiple of the element size + } + this.length = this.byteLength / this.BYTES_PER_ELEMENT; + } + else { + this.length = ECMAScript.ToUint32(length); + this.byteLength = this.length * this.BYTES_PER_ELEMENT; + } + + if ((this.byteOffset + this.byteLength) > this.buffer.byteLength) { + raise_INDEX_SIZE_ERR(); // byteOffset and length reference an area beyond the end of the buffer + } + } + else { + throw new TypeError("Unexpected argument type(s)"); + } + + this.constructor = ctor; + + // ES5-only magic + configureProperties(this); + makeArrayAccessors(this); + }; + + ctor.prototype = new ArrayBufferView(); + ctor.prototype.BYTES_PER_ELEMENT = bytesPerElement; + ctor.prototype._pack = pack; + ctor.prototype._unpack = unpack; + ctor.BYTES_PER_ELEMENT = bytesPerElement; + + // getter type (unsigned long index); + ctor.prototype._getter = function (index) { + if (arguments.length < 1) { throw new SyntaxError("Not enough arguments"); } + + index = ECMAScript.ToUint32(index); + if (index >= this.length) { + //raise_INDEX_SIZE_ERR(); // Array index out of range + return; // undefined + } + + var bytes = [], i, o; + for (i = 0, o = this.byteOffset + index * this.BYTES_PER_ELEMENT; + i < this.BYTES_PER_ELEMENT; + i += 1, o += 1) { + bytes.push(this.buffer._bytes[o]); + } + return this._unpack(bytes); + }; + + // NONSTANDARD: convenience alias for getter: type get(unsigned long index); + ctor.prototype.get = ctor.prototype._getter; + + // setter void (unsigned long index, type value); + ctor.prototype._setter = function (index, value) { + if (arguments.length < 2) { throw new SyntaxError("Not enough arguments"); } + + index = ECMAScript.ToUint32(index); + if (index >= this.length) { + //raise_INDEX_SIZE_ERR(); // Array index out of range + return; + } + + var bytes = this._pack(value), i, o; + for (i = 0, o = this.byteOffset + index * this.BYTES_PER_ELEMENT; + i < this.BYTES_PER_ELEMENT; + i += 1, o += 1) { + this.buffer._bytes[o] = bytes[i]; + } + }; + + // void set(TypedArray array, optional unsigned long offset); + // void set(sequence array, optional unsigned long offset); + ctor.prototype.set = function (index, value) { + if (arguments.length < 1) { throw new SyntaxError("Not enough arguments"); } + var array, sequence, offset, len, + i, s, d, + byteOffset, byteLength, tmp; + + // void set(TypedArray array, optional unsigned long offset); + if (typeof arguments[0] === 'object' && arguments[0].constructor === this.constructor) { + array = arguments[0]; + offset = ECMAScript.ToUint32(arguments[1]); + + if (offset + array.length > this.length) { + raise_INDEX_SIZE_ERR(); // Offset plus length of array is out of range + } + + byteOffset = this.byteOffset + offset * this.BYTES_PER_ELEMENT; + byteLength = array.length * this.BYTES_PER_ELEMENT; + + if (array.buffer === this.buffer) { + tmp = []; + for (i = 0, s = array.byteOffset; i < byteLength; i += 1, s += 1) { + tmp[i] = array.buffer._bytes[s]; + } + for (i = 0, d = byteOffset; i < byteLength; i += 1, d += 1) { + this.buffer._bytes[d] = tmp[i]; + } + } + else { + for (i = 0, s = array.byteOffset, d = byteOffset; + i < byteLength; i += 1, s += 1, d += 1) { + this.buffer._bytes[d] = array.buffer._bytes[s]; + } + } + } + + // void set(sequence array, optional unsigned long offset); + else if (typeof arguments[0] === 'object' && typeof arguments[0].length !== 'undefined') { + sequence = arguments[0]; + len = ECMAScript.ToUint32(sequence.length); + offset = ECMAScript.ToUint32(arguments[1]); + + if (offset + len > this.length) { + raise_INDEX_SIZE_ERR(); // Offset plus length of array is out of range + } + + for (i = 0; i < len; i += 1) { + s = sequence[i]; + this._setter(offset + i, Number(s)); + } + } + + else { + throw new TypeError("Unexpected argument type(s)"); + } + }; + + // TypedArray subarray(long begin, optional long end); + ctor.prototype.subarray = function (start, end) { + function clamp(v, min, max) { return v < min ? min : v > max ? max : v; } + + start = ECMAScript.ToInt32(start); + end = ECMAScript.ToInt32(end); + + if (arguments.length < 1) { start = 0; } + if (arguments.length < 2) { end = this.length; } + + if (start < 0) { start = this.length + start; } + if (end < 0) { end = this.length + end; } + + start = clamp(start, 0, this.length); + end = clamp(end, 0, this.length); + + var len = end - start; + if (len < 0) { + len = 0; + } + + return new this.constructor(this.buffer, start * this.BYTES_PER_ELEMENT, len); + }; + + return ctor; + } + + Int8Array = Int8Array || makeTypedArrayConstructor(1, packInt8, unpackInt8); + Uint8Array = Uint8Array || makeTypedArrayConstructor(1, packUint8, unpackUint8); + Int16Array = Int16Array || makeTypedArrayConstructor(2, packInt16, unpackInt16); + Uint16Array = Uint16Array || makeTypedArrayConstructor(2, packUint16, unpackUint16); + Int32Array = Int32Array || makeTypedArrayConstructor(4, packInt32, unpackInt32); + Uint32Array = Uint32Array || makeTypedArrayConstructor(4, packUint32, unpackUint32); + Float32Array = Float32Array || makeTypedArrayConstructor(4, packFloat32, unpackFloat32); + Float64Array = Float64Array || makeTypedArrayConstructor(8, packFloat64, unpackFloat64); + + } ()); + } + + + if (!DataView) { + (function () { + + // + // 6 The DataView View Type + // + + function r(array, index) { + if (typeof array.get === 'function') { + return array.get(index); + } + else { + return array[index]; + } + } + + + var IS_BIG_ENDIAN = (function () { + var u16array = new Uint16Array([0x1234]), + u8array = new Uint8Array(u16array.buffer); + return r(u8array, 0) === 0x12; + } ()); + + // Constructor(ArrayBuffer buffer, + // optional unsigned long byteOffset, + // optional unsigned long byteLength) + DataView = function (buffer, byteOffset, byteLength) { + if (!(typeof buffer === 'object' && buffer instanceof ArrayBuffer)) { + throw new TypeError("TypeError"); + } + + this.buffer = buffer; + + this.byteOffset = ECMAScript.ToUint32(byteOffset); + if (this.byteOffset > this.buffer.byteLength) { + raise_INDEX_SIZE_ERR(); // byteOffset out of range + } + + if (arguments.length < 3) { + this.byteLength = this.buffer.byteLength - this.byteOffset; + } + else { + this.byteLength = ECMAScript.ToUint32(byteLength); + } + + if ((this.byteOffset + this.byteLength) > this.buffer.byteLength) { + raise_INDEX_SIZE_ERR(); // byteOffset and length reference an area beyond the end of the buffer + } + + // ES5-only magic + configureProperties(this); + }; + + if (ArrayBufferView) { + DataView.prototype = new ArrayBufferView(); + } + + function makeDataView_getter(arrayType) { + return function (byteOffset, littleEndian) { + /*jslint newcap: false*/ + byteOffset = ECMAScript.ToUint32(byteOffset); + + if (byteOffset + arrayType.BYTES_PER_ELEMENT > this.byteLength) { + raise_INDEX_SIZE_ERR(); // Array index out of range + } + byteOffset += this.byteOffset; + + var uint8Array = new Uint8Array(this.buffer, byteOffset, arrayType.BYTES_PER_ELEMENT), + bytes = [], i; + for (i = 0; i < arrayType.BYTES_PER_ELEMENT; i += 1) { + bytes.push(r(uint8Array, i)); + } + + if (Boolean(littleEndian) === Boolean(IS_BIG_ENDIAN)) { + bytes.reverse(); + } + + return r(new arrayType(new Uint8Array(bytes).buffer), 0); + }; + } + + DataView.prototype.getUint8 = makeDataView_getter(Uint8Array); + DataView.prototype.getInt8 = makeDataView_getter(Int8Array); + DataView.prototype.getUint16 = makeDataView_getter(Uint16Array); + DataView.prototype.getInt16 = makeDataView_getter(Int16Array); + DataView.prototype.getUint32 = makeDataView_getter(Uint32Array); + DataView.prototype.getInt32 = makeDataView_getter(Int32Array); + DataView.prototype.getFloat32 = makeDataView_getter(Float32Array); + DataView.prototype.getFloat64 = makeDataView_getter(Float64Array); + + function makeDataView_setter(arrayType) { + return function (byteOffset, value, littleEndian) { + /*jslint newcap: false*/ + byteOffset = ECMAScript.ToUint32(byteOffset); + if (byteOffset + arrayType.BYTES_PER_ELEMENT > this.byteLength) { + raise_INDEX_SIZE_ERR(); // Array index out of range + } + + // Get bytes + var typeArray = new arrayType([value]), + byteArray = new Uint8Array(typeArray.buffer), + bytes = [], i, byteView; + + for (i = 0; i < arrayType.BYTES_PER_ELEMENT; i += 1) { + bytes.push(r(byteArray, i)); + } + + // Flip if necessary + if (Boolean(littleEndian) === Boolean(IS_BIG_ENDIAN)) { + bytes.reverse(); + } + + // Write them + byteView = new Uint8Array(this.buffer, byteOffset, arrayType.BYTES_PER_ELEMENT); + byteView.set(bytes); + }; + } + + DataView.prototype.setUint8 = makeDataView_setter(Uint8Array); + DataView.prototype.setInt8 = makeDataView_setter(Int8Array); + DataView.prototype.setUint16 = makeDataView_setter(Uint16Array); + DataView.prototype.setInt16 = makeDataView_setter(Int16Array); + DataView.prototype.setUint32 = makeDataView_setter(Uint32Array); + DataView.prototype.setInt32 = makeDataView_setter(Int32Array); + DataView.prototype.setFloat32 = makeDataView_setter(Float32Array); + DataView.prototype.setFloat64 = makeDataView_setter(Float64Array); + + } ()); + } + +} ()); + diff --git a/js/lib/typedarray.min.js b/js/lib/typedarray.min.js new file mode 100644 index 0000000..d47ad9e --- /dev/null +++ b/js/lib/typedarray.min.js @@ -0,0 +1 @@ +var ArrayBuffer,ArrayBufferView,Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array,DataView;(function(){"use strict";function t(){if(document){document.createTextNode("").splitText(1)}throw new RangeError("INDEX_SIZE_ERR")}function n(e){if(Object.getOwnPropertyNames&&Object.defineProperty){var t=Object.getOwnPropertyNames(e),n;for(n=0;n>n}function s(e,t){var n=32-t;return e<>>n}function o(e){return[e&255]}function u(e){return i(e[0],8)}function a(e){return[e&255]}function f(e){return s(e[0],8)}function l(e){return[e>>8&255,e&255]}function c(e){return i(e[0]<<8|e[1],16)}function h(e){return[e>>8&255,e&255]}function p(e){return s(e[0]<<8|e[1],16)}function d(e){return[e>>24&255,e>>16&255,e>>8&255,e&255]}function v(e){return i(e[0]<<24|e[1]<<16|e[2]<<8|e[3],32)}function m(e){return[e>>24&255,e>>16&255,e>>8&255,e&255]}function g(e){return s(e[0]<<24|e[1]<<16|e[2]<<8|e[3],32)}function y(e,t,n){var r=(1<=Math.pow(2,1-r)){u=Math.min(Math.floor(Math.log(e)/Math.LN2),r);s=u+r;o=Math.round(e*Math.pow(2,n-u)-Math.pow(2,n))}else{s=0;o=Math.round(e/Math.pow(2,1-r-n))}}f=[];for(a=n;a;a-=1){f.push(o%2?1:0);o=Math.floor(o/2)}for(a=t;a;a-=1){f.push(s%2?1:0);s=Math.floor(s/2)}f.push(i?1:0);f.reverse();l=f.join("");c=[];while(l.length){c.push(parseInt(l.substring(0,8),2));l=l.substring(8)}return c}function b(e,t,n){var r=[],i,s,o,u,a,f,l,c;for(i=e.length;i;i-=1){o=e[i-1];for(s=8;s;s-=1){r.push(o%2?1:0);o=o>>1}}r.reverse();u=r.join("");a=(1<0){return f*Math.pow(2,l-a)*(1+c/Math.pow(2,n))}else if(c!==0){return f*Math.pow(2,-(a-1))*(c/Math.pow(2,n))}else{return f<0?-0:0}}function w(e){return b(e,11,52)}function E(e){return y(e,11,52)}function S(e){return b(e,8,23)}function x(e){return y(e,8,23)}var e={ToInt32:function(e){return e>>0},ToUint32:function(e){return e>>>0}};if(Object.prototype.__defineGetter__&&!Object.defineProperty){Object.defineProperty=function(e,t,n){if(n.hasOwnProperty("get")){e.__defineGetter__(t,n.get)}if(n.hasOwnProperty("set")){e.__defineSetter__(t,n.set)}}}if(!ArrayBuffer){(function(){function i(i,s,o){var u;u=function(i,s,o){var a,f,l,c;if(!arguments.length||typeof arguments[0]==="number"){this.length=e.ToInt32(arguments[0]);if(o<0){throw new RangeError("ArrayBufferView size is not a small enough positive integer.")}this.byteLength=this.length*this.BYTES_PER_ELEMENT;this.buffer=new ArrayBuffer(this.byteLength);this.byteOffset=0}else if(typeof arguments[0]==="object"&&arguments[0].constructor===u){a=arguments[0];this.length=a.length;this.byteLength=this.length*this.BYTES_PER_ELEMENT;this.buffer=new ArrayBuffer(this.byteLength);this.byteOffset=0;for(l=0;lthis.buffer.byteLength){t()}if(this.byteOffset%this.BYTES_PER_ELEMENT){throw new RangeError("ArrayBuffer length minus the byteOffset is not a multiple of the element size.")}if(arguments.length<3){this.byteLength=this.buffer.byteLength-this.byteOffset;if(this.byteLength%this.BYTES_PER_ELEMENT){t()}this.length=this.byteLength/this.BYTES_PER_ELEMENT}else{this.length=e.ToUint32(o);this.byteLength=this.length*this.BYTES_PER_ELEMENT}if(this.byteOffset+this.byteLength>this.buffer.byteLength){t()}}else{throw new TypeError("Unexpected argument type(s)")}this.constructor=u;n(this);r(this)};u.prototype=new ArrayBufferView;u.prototype.BYTES_PER_ELEMENT=i;u.prototype._pack=s;u.prototype._unpack=o;u.BYTES_PER_ELEMENT=i;u.prototype._getter=function(t){if(arguments.length<1){throw new SyntaxError("Not enough arguments")}t=e.ToUint32(t);if(t>=this.length){return}var n=[],r,i;for(r=0,i=this.byteOffset+t*this.BYTES_PER_ELEMENT;r=this.length){return}var r=this._pack(n),i,s;for(i=0,s=this.byteOffset+t*this.BYTES_PER_ELEMENT;ithis.length){t()}c=this.byteOffset+o*this.BYTES_PER_ELEMENT;h=i.length*this.BYTES_PER_ELEMENT;if(i.buffer===this.buffer){p=[];for(a=0,f=i.byteOffset;athis.length){t()}for(a=0;an?n:e}t=e.ToInt32(t);n=e.ToInt32(n);if(arguments.length<1){t=0}if(arguments.length<2){n=this.length}if(t<0){t=this.length+t}if(n<0){n=this.length+n}t=r(t,0,this.length);n=r(n,0,this.length);var i=n-t;if(i<0){i=0}return new this.constructor(this.buffer,t*this.BYTES_PER_ELEMENT,i)};return u}ArrayBuffer=function(t){t=e.ToInt32(t);if(t<0){throw new RangeError("ArrayBuffer size is not a small enough positive integer.")}this.byteLength=t;this._bytes=[];this._bytes.length=t;var r;for(r=0;rthis.byteLength){t()}s+=this.byteOffset;var u=new Uint8Array(this.buffer,s,n.BYTES_PER_ELEMENT),a=[],f;for(f=0;fthis.byteLength){t()}var a=new n([o]),f=new Uint8Array(a.buffer),l=[],c,h;for(c=0;cthis.buffer.byteLength){t()}if(arguments.length<3){this.byteLength=this.buffer.byteLength-this.byteOffset}else{this.byteLength=e.ToUint32(s)}if(this.byteOffset+this.byteLength>this.buffer.byteLength){t()}n(this)};if(ArrayBufferView){DataView.prototype=new ArrayBufferView}DataView.prototype.getUint8=s(Uint8Array);DataView.prototype.getInt8=s(Int8Array);DataView.prototype.getUint16=s(Uint16Array);DataView.prototype.getInt16=s(Int16Array);DataView.prototype.getUint32=s(Uint32Array);DataView.prototype.getInt32=s(Int32Array);DataView.prototype.getFloat32=s(Float32Array);DataView.prototype.getFloat64=s(Float64Array);DataView.prototype.setUint8=o(Uint8Array);DataView.prototype.setInt8=o(Int8Array);DataView.prototype.setUint16=o(Uint16Array);DataView.prototype.setInt16=o(Int16Array);DataView.prototype.setUint32=o(Uint32Array);DataView.prototype.setInt32=o(Int32Array);DataView.prototype.setFloat32=o(Float32Array);DataView.prototype.setFloat64=o(Float64Array)})()}})() diff --git a/js/lib/wgxpath.install.js b/js/lib/wgxpath.install.js new file mode 100644 index 0000000..f070e5f --- /dev/null +++ b/js/lib/wgxpath.install.js @@ -0,0 +1,75 @@ +(function(){function h(a){return function(){return this[a]}}function l(a){return function(){return a}}var m=this; +function ba(a){var b=typeof a;if("object"==b)if(a){if(a instanceof Array)return"array";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if("[object Window]"==c)return"object";if("[object Array]"==c||"number"==typeof a.length&&"undefined"!=typeof a.splice&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("splice"))return"array";if("[object Function]"==c||"undefined"!=typeof a.call&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("call"))return"function"}else return"null"; +else if("function"==b&&"undefined"==typeof a.call)return"object";return b}function n(a){return"string"==typeof a}function ca(a,b,c){return a.call.apply(a.bind,arguments)}function da(a,b,c){if(!a)throw Error();if(2b?1:0};var v=Array.prototype,ia=v.indexOf?function(a,b,c){return v.indexOf.call(a,b,c)}:function(a,b,c){c=null==c?0:0>c?Math.max(0,a.length+c):c;if(n(a))return n(b)&&1==b.length?a.indexOf(b,c):-1;for(;cc?null:n(a)?a.charAt(c):a[c]}function ma(a){return v.concat.apply(v,arguments)}function na(a,b,c){return 2>=arguments.length?v.slice.call(a,b):v.slice.call(a,b,c)};var y;a:{var oa=m.navigator;if(oa){var pa=oa.userAgent;if(pa){y=pa;break a}}y=""};var qa=u(y,"Opera")||u(y,"OPR"),A=u(y,"Trident")||u(y,"MSIE"),ra=u(y,"Edge"),sa=u(y,"Gecko")&&!(u(y.toLowerCase(),"webkit")&&!u(y,"Edge"))&&!(u(y,"Trident")||u(y,"MSIE"))&&!u(y,"Edge"),ta=u(y.toLowerCase(),"webkit")&&!u(y,"Edge");function ua(){var a=y;if(sa)return/rv\:([^\);]+)(\)|;)/.exec(a);if(ra)return/Edge\/([\d\.]+)/.exec(a);if(A)return/\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/.exec(a);if(ta)return/WebKit\/(\S+)/.exec(a)}function va(){var a=m.document;return a?a.documentMode:void 0} +var wa=function(){if(qa&&m.opera){var a=m.opera.version;return"function"==ba(a)?a():a}var a="",b=ua();b&&(a=b?b[1]:"");return A&&(b=va(),b>parseFloat(a))?String(b):a}(),xa={}; +function ya(a){if(!xa[a]){for(var b=0,c=ga(String(wa)).split("."),d=ga(String(a)).split("."),e=Math.max(c.length,d.length),f=0;0==b&&f]=|\\s+|.","g"),Ga=/^\s/;function D(a,b){return a.b[a.a+(b||0)]}function F(a){return a.b[a.a++]}function Ha(a){return a.b.length<=a.a};!sa&&!A||A&&9<=Aa||sa&&ya("1.9.1");A&&ya("9");function Ia(a,b){if(a.contains&&1==b.nodeType)return a==b||a.contains(b);if("undefined"!=typeof a.compareDocumentPosition)return a==b||Boolean(a.compareDocumentPosition(b)&16);for(;b&&a!=b;)b=b.parentNode;return b==a} +function Ja(a,b){if(a==b)return 0;if(a.compareDocumentPosition)return a.compareDocumentPosition(b)&2?1:-1;if(A&&!(9<=Aa)){if(9==a.nodeType)return-1;if(9==b.nodeType)return 1}if("sourceIndex"in a||a.parentNode&&"sourceIndex"in a.parentNode){var c=1==a.nodeType,d=1==b.nodeType;if(c&&d)return a.sourceIndex-b.sourceIndex;var e=a.parentNode,f=b.parentNode;return e==f?Ka(a,b):!c&&Ia(e,b)?-1*La(a,b):!d&&Ia(f,a)?La(b,a):(c?a.sourceIndex:e.sourceIndex)-(d?b.sourceIndex:f.sourceIndex)}d=9==a.nodeType?a:a.ownerDocument|| +a.document;c=d.createRange();c.selectNode(a);c.collapse(!0);d=d.createRange();d.selectNode(b);d.collapse(!0);return c.compareBoundaryPoints(m.Range.START_TO_END,d)}function La(a,b){var c=a.parentNode;if(c==b)return-1;for(var d=b;d.parentNode!=c;)d=d.parentNode;return Ka(d,a)}function Ka(a,b){for(var c=b;c=c.previousSibling;)if(c==a)return-1;return 1};function G(a){var b=null,c=a.nodeType;1==c&&(b=a.textContent,b=void 0==b||null==b?a.innerText:b,b=void 0==b||null==b?"":b);if("string"!=typeof b)if(B&&"title"==a.nodeName.toLowerCase()&&1==c)b=a.text;else if(9==c||1==c){a=9==c?a.documentElement:a.firstChild;for(var c=0,d=[],b="";a;){do 1!=a.nodeType&&(b+=a.nodeValue),B&&"title"==a.nodeName.toLowerCase()&&(b+=a.text),d[c++]=a;while(a=a.firstChild);for(;c&&!(a=d[--c].nextSibling););}}else b=a.nodeValue;return""+b} +function H(a,b,c){if(null===b)return!0;try{if(!a.getAttribute)return!1}catch(d){return!1}Ba&&"class"==b&&(b="className");return null==c?!!a.getAttribute(b):a.getAttribute(b,2)==c}function Ma(a,b,c,d,e){return(B?Na:Oa).call(null,a,b,n(c)?c:null,n(d)?d:null,e||new I)} +function Na(a,b,c,d,e){if(a instanceof J||8==a.b||c&&null===a.b){var f=b.all;if(!f)return e;a=Pa(a);if("*"!=a&&(f=b.getElementsByTagName(a),!f))return e;if(c){for(var g=[],k=0;b=f[k++];)H(b,c,d)&&g.push(b);f=g}for(k=0;b=f[k++];)"*"==a&&"!"==b.tagName||K(e,b);return e}Qa(a,b,c,d,e);return e} +function Oa(a,b,c,d,e){b.getElementsByName&&d&&"name"==c&&!A?(b=b.getElementsByName(d),w(b,function(b){a.a(b)&&K(e,b)})):b.getElementsByClassName&&d&&"class"==c?(b=b.getElementsByClassName(d),w(b,function(b){b.className==d&&a.a(b)&&K(e,b)})):a instanceof L?Qa(a,b,c,d,e):b.getElementsByTagName&&(b=b.getElementsByTagName(a.f()),w(b,function(a){H(a,c,d)&&K(e,a)}));return e} +function Ra(a,b,c,d,e){var f;if((a instanceof J||8==a.b||c&&null===a.b)&&(f=b.childNodes)){var g=Pa(a);if("*"!=g&&(f=ja(f,function(a){return a.tagName&&a.tagName.toLowerCase()==g}),!f))return e;c&&(f=ja(f,function(a){return H(a,c,d)}));w(f,function(a){"*"==g&&("!"==a.tagName||"*"==g&&1!=a.nodeType)||K(e,a)});return e}return Sa(a,b,c,d,e)}function Sa(a,b,c,d,e){for(b=b.firstChild;b;b=b.nextSibling)H(b,c,d)&&a.a(b)&&K(e,b);return e} +function Qa(a,b,c,d,e){for(b=b.firstChild;b;b=b.nextSibling)H(b,c,d)&&a.a(b)&&K(e,b),Qa(a,b,c,d,e)}function Pa(a){if(a instanceof L){if(8==a.b)return"!";if(null===a.b)return"*"}return a.f()};function I(){this.b=this.a=null;this.l=0}function Ta(a){this.node=a;this.a=this.b=null}function Ua(a,b){if(!a.a)return b;if(!b.a)return a;for(var c=a.a,d=b.a,e=null,f=null,g=0;c&&d;){var f=c.node,k=d.node;f==k||f instanceof C&&k instanceof C&&f.a==k.a?(f=c,c=c.a,d=d.a):0",4,2,function(a,b,c){return S(function(a,b){return a>b},a,b,c)});T("<=",4,2,function(a,b,c){return S(function(a,b){return a<=b},a,b,c)}); +T(">=",4,2,function(a,b,c){return S(function(a,b){return a>=b},a,b,c)});var eb=T("=",3,2,function(a,b,c){return S(function(a,b){return a==b},a,b,c,!0)});T("!=",3,2,function(a,b,c){return S(function(a,b){return a!=b},a,b,c,!0)});T("and",2,2,function(a,b,c){return R(a,c)&&R(b,c)});T("or",1,2,function(a,b,c){return R(a,c)||R(b,c)});function hb(a,b){if(b.a.length&&4!=a.i)throw Error("Primary expression must evaluate to nodeset if filter has predicate(s).");r.call(this,a.i);this.c=a;this.h=b;this.g=a.g;this.b=a.b}q(hb);hb.prototype.a=function(a){a=this.c.a(a);return ib(this.h,a)};hb.prototype.toString=function(){var a;a="Filter:"+O(this.c);return a+=O(this.h)};function jb(a,b){if(b.lengtha.v)throw Error("Function "+a.j+" expects at most "+a.v+" arguments, "+b.length+" given");a.B&&w(b,function(b,d){if(4!=b.i)throw Error("Argument "+d+" to function "+a.j+" is not of type Nodeset: "+b);});r.call(this,a.i);this.h=a;this.c=b;bb(this,a.g||ka(b,function(a){return a.g}));cb(this,a.D&&!b.length||a.C&&!!b.length||ka(b,function(a){return a.b}))}q(jb); +jb.prototype.a=function(a){return this.h.m.apply(null,ma(a,this.c))};jb.prototype.toString=function(){var a="Function: "+this.h;if(this.c.length)var b=x(this.c,function(a,b){return a+O(b)},"Arguments:"),a=a+O(b);return a};function kb(a,b,c,d,e,f,g,k,p){this.j=a;this.i=b;this.g=c;this.D=d;this.C=e;this.m=f;this.A=g;this.v=void 0!==k?k:g;this.B=!!p}kb.prototype.toString=h("j");var lb={}; +function U(a,b,c,d,e,f,g,k){if(lb.hasOwnProperty(a))throw Error("Function already created: "+a+".");lb[a]=new kb(a,b,c,d,!1,e,f,g,k)}U("boolean",2,!1,!1,function(a,b){return R(b,a)},1);U("ceiling",1,!1,!1,function(a,b){return Math.ceil(P(b,a))},1);U("concat",3,!1,!1,function(a,b){var c=na(arguments,1);return x(c,function(b,c){return b+Q(c,a)},"")},2,null);U("contains",2,!1,!1,function(a,b,c){return u(Q(b,a),Q(c,a))},2);U("count",1,!1,!1,function(a,b){return b.a(a).l},1,1,!0); +U("false",2,!1,!1,l(!1),0);U("floor",1,!1,!1,function(a,b){return Math.floor(P(b,a))},1);U("id",4,!1,!1,function(a,b){function c(a){if(B){var b=e.all[a];if(b){if(b.nodeType&&a==b.id)return b;if(b.length)return la(b,function(b){return a==b.id})}return null}return e.getElementById(a)}var d=a.a,e=9==d.nodeType?d:d.ownerDocument,d=Q(b,a).split(/\s+/),f=[];w(d,function(a){a=c(a);!a||0<=ia(f,a)||f.push(a)});f.sort(Ja);var g=new I;w(f,function(a){K(g,a)});return g},1);U("lang",2,!1,!1,l(!1),1); +U("last",1,!0,!1,function(a){if(1!=arguments.length)throw Error("Function last expects ()");return a.f},0);U("local-name",3,!1,!0,function(a,b){var c=b?Wa(b.a(a)):a.a;return c?c.localName||c.nodeName.toLowerCase():""},0,1,!0);U("name",3,!1,!0,function(a,b){var c=b?Wa(b.a(a)):a.a;return c?c.nodeName.toLowerCase():""},0,1,!0);U("namespace-uri",3,!0,!1,l(""),0,1,!0);U("normalize-space",3,!1,!0,function(a,b){return(b?Q(b,a):G(a.a)).replace(/[\s\xa0]+/g," ").replace(/^\s+|\s+$/g,"")},0,1); +U("not",2,!1,!1,function(a,b){return!R(b,a)},1);U("number",1,!1,!0,function(a,b){return b?P(b,a):+G(a.a)},0,1);U("position",1,!0,!1,function(a){return a.b},0);U("round",1,!1,!1,function(a,b){return Math.round(P(b,a))},1);U("starts-with",2,!1,!1,function(a,b,c){b=Q(b,a);a=Q(c,a);return 0==b.lastIndexOf(a,0)},2);U("string",3,!1,!0,function(a,b){return b?Q(b,a):G(a.a)},0,1);U("string-length",1,!1,!0,function(a,b){return(b?Q(b,a):G(a.a)).length},0,1); +U("substring",3,!1,!1,function(a,b,c,d){c=P(c,a);if(isNaN(c)||Infinity==c||-Infinity==c)return"";d=d?P(d,a):Infinity;if(isNaN(d)||-Infinity===d)return"";c=Math.round(c)-1;var e=Math.max(c,0);a=Q(b,a);if(Infinity==d)return a.substring(e);b=Math.round(d);return a.substring(e,c+b)},2,3);U("substring-after",3,!1,!1,function(a,b,c){b=Q(b,a);a=Q(c,a);c=b.indexOf(a);return-1==c?"":b.substring(c+a.length)},2); +U("substring-before",3,!1,!1,function(a,b,c){b=Q(b,a);a=Q(c,a);a=b.indexOf(a);return-1==a?"":b.substring(0,a)},2);U("sum",1,!1,!1,function(a,b){for(var c=M(b.a(a)),d=0,e=N(c);e;e=N(c))d+=+G(e);return d},1,1,!0);U("translate",3,!1,!1,function(a,b,c,d){b=Q(b,a);c=Q(c,a);var e=Q(d,a);a=[];for(d=0;da.length)throw Error("Unclosed literal string");return new nb(a)}function Lb(a){var b=F(a.a),c=b.indexOf(":");if(-1==c)return new J(b);var d=b.substring(0,c);a=a.b(d);if(!a)throw Error("Namespace prefix not declared: "+d);b=b.substr(c+1);return new J(b,a)} +function Mb(a){var b,c=[],d;if(tb(D(a.a))){b=F(a.a);d=D(a.a);if("/"==b&&(Ha(a.a)||"."!=d&&".."!=d&&"@"!=d&&"*"!=d&&!/(?![0-9])[\w]/.test(d)))return new rb;d=new rb;X(a,"Missing next location step.");b=Nb(a,b);c.push(b)}else{a:{b=D(a.a);d=b.charAt(0);switch(d){case "$":throw Error("Variable reference not allowed in HTML XPath");case "(":F(a.a);b=Gb(a);X(a,'unclosed "("');Ib(a,")");break;case '"':case "'":b=Kb(a);break;default:if(isNaN(+b))if(!mb(b)&&/(?![0-9])[\w]/.test(d)&&"("==D(a.a,1)){b=F(a.a); +b=lb[b]||null;F(a.a);for(d=[];")"!=D(a.a);){X(a,"Missing function argument list.");d.push(Gb(a));if(","!=D(a.a))break;F(a.a)}X(a,"Unclosed function argument list.");Jb(a);b=new jb(b,d)}else{b=null;break a}else b=new ob(+F(a.a))}"["==D(a.a)&&(d=new wb(Ob(a)),b=new hb(b,d))}if(b)if(tb(D(a.a)))d=b;else return b;else b=Nb(a,"/"),d=new sb,c.push(b)}for(;tb(D(a.a));)b=F(a.a),X(a,"Missing next location step."),b=Nb(a,b),c.push(b);return new pb(d,c)} +function Nb(a,b){var c,d,e;if("/"!=b&&"//"!=b)throw Error('Step op should be "/" or "//"');if("."==D(a.a))return d=new V(Cb,new L("node")),F(a.a),d;if(".."==D(a.a))return d=new V(Bb,new L("node")),F(a.a),d;var f;if("@"==D(a.a))f=qb,F(a.a),X(a,"Missing attribute name");else if("::"==D(a.a,1)){if(!/(?![0-9])[\w]/.test(D(a.a).charAt(0)))throw Error("Bad token: "+F(a.a));c=F(a.a);f=Ab[c]||null;if(!f)throw Error("No axis with name: "+c);F(a.a);X(a,"Missing node name")}else f=xb;c=D(a.a);if(/(?![0-9])[\w]/.test(c.charAt(0)))if("("== +D(a.a,1)){if(!mb(c))throw Error("Invalid node type: "+c);c=F(a.a);if(!mb(c))throw Error("Invalid type name: "+c);Ib(a,"(");X(a,"Bad nodetype");e=D(a.a).charAt(0);var g=null;if('"'==e||"'"==e)g=Kb(a);X(a,"Bad nodetype");Jb(a);c=new L(c,g)}else c=Lb(a);else if("*"==c)c=Lb(a);else throw Error("Bad token: "+F(a.a));e=new wb(Ob(a),f.a);return d||new V(f,c,e,"//"==b)} +function Ob(a){for(var b=[];"["==D(a.a);){F(a.a);X(a,"Missing predicate expression.");var c=Gb(a);b.push(c);X(a,"Unclosed predicate expression.");Ib(a,"]")}return b}function Hb(a){if("-"==D(a.a))return F(a.a),new Db(Hb(a));var b=Mb(a);if("|"!=D(a.a))a=b;else{for(b=[b];"|"==F(a.a);)X(a,"Missing next union location path."),b.push(Mb(a));a.a.a--;a=new Eb(b)}return a};function Pb(a,b){if(!a.length)throw Error("Empty XPath expression.");var c=Ea(a);if(Ha(c))throw Error("Invalid XPath expression.");b?"function"==ba(b)||(b=ea(b.lookupNamespaceURI,b)):b=l(null);var d=Gb(new Fb(c,b));if(!Ha(c))throw Error("Bad token: "+F(c));this.evaluate=function(a,b){var c=d.a(new t(a));return new Y(c,b)}} +function Y(a,b){if(0==b)if(a instanceof I)b=4;else if("string"==typeof a)b=2;else if("number"==typeof a)b=1;else if("boolean"==typeof a)b=3;else throw Error("Unexpected evaluation result.");if(2!=b&&1!=b&&3!=b&&!(a instanceof I))throw Error("value could not be converted to the specified type");this.resultType=b;var c;switch(b){case 2:this.stringValue=a instanceof I?Xa(a):""+a;break;case 1:this.numberValue=a instanceof I?+Xa(a):+a;break;case 3:this.booleanValue=a instanceof I?0=c.length?null:c[f++]};this.snapshotItem=function(a){if(6!=b&&7!=b)throw Error("snapshotItem called with wrong result type");return a>=c.length|| +0>a?null:c[a]}}Y.ANY_TYPE=0;Y.NUMBER_TYPE=1;Y.STRING_TYPE=2;Y.BOOLEAN_TYPE=3;Y.UNORDERED_NODE_ITERATOR_TYPE=4;Y.ORDERED_NODE_ITERATOR_TYPE=5;Y.UNORDERED_NODE_SNAPSHOT_TYPE=6;Y.ORDERED_NODE_SNAPSHOT_TYPE=7;Y.ANY_UNORDERED_NODE_TYPE=8;Y.FIRST_ORDERED_NODE_TYPE=9;function Qb(a){this.lookupNamespaceURI=Za(a)} +function Rb(a){a=a||m;var b=a.document;b.evaluate||(a.XPathResult=Y,b.evaluate=function(a,b,e,f){return(new Pb(a,e)).evaluate(b,f)},b.createExpression=function(a,b){return new Pb(a,b)},b.createNSResolver=function(a){return new Qb(a)})}var Sb=["wgxpath","install"],Z=m;Sb[0]in Z||!Z.execScript||Z.execScript("var "+Sb[0]);for(var Tb;Sb.length&&(Tb=Sb.shift());)Sb.length||void 0===Rb?Z[Tb]?Z=Z[Tb]:Z=Z[Tb]={}:Z[Tb]=Rb;})() diff --git a/js/personal.js b/js/personal.js new file mode 100644 index 0000000..e8fdd93 --- /dev/null +++ b/js/personal.js @@ -0,0 +1,22 @@ +$(document).ready(function(){ + // save settings + var readerSettings = { + save : function() { + var data = { + epub_enable: document.getElementById('epub_enable').checked ? 'true' : 'false', + pdf_enable: document.getElementById('pdf_enable').checked ? 'true' : 'false', + cbx_enable: document.getElementById('cbx_enable').checked ? 'true' : 'false' + }; + + OC.msg.startSaving('#reader-personal .msg'); + $.post(OC.filePath('files_reader', 'lib', 'personal-back.php'), data, readerSettings.afterSave); + }, + afterSave : function(data){ + OC.msg.finishedSaving('#reader-personal .msg', data); + } + }; + $('#epub_enable').on("change", readerSettings.save); + $('#pdf_enable').on("change", readerSettings.save); + $('#cbx_enable').on("change", readerSettings.save); +}); + diff --git a/js/plugin-public.js b/js/plugin-public.js new file mode 100644 index 0000000..eec5bcd --- /dev/null +++ b/js/plugin-public.js @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2015-2017 Frank de Lange + * Copyright (c) 2013-2014 Lukas Reschke + * + * This file is licensed under the Affero General Public License version 3 + * or later. + * + * See the COPYING-README file. + * + */ + + +(function(OCA) { + + OCA.Files_Reader = OCA.Files_Reader || {}; + const epub_enabled = OCP.InitialState.loadState('files_reader', 'epub_enabled'); + const pdf_enabled = OCP.InitialState.loadState('files_reader', 'pdf_enabled'); + const cbx_enabled = OCP.InitialState.loadState('files_reader', 'cbx_enabled'); + + /* comicbooks come in many different forms... */ + const cbx_types= [ + 'application/comicbook+7z', + 'application/comicbook+rar', + 'application/comicbook+tar', + 'application/comicbook+zip', + 'application/x-cbr', + ]; + + + var isMobile = navigator.userAgent.match(/Mobi/i); + var hasTouch = 'ontouchstart' in document.documentElement; + + function actionHandler(fileName, mime, context) { + var sharingToken = $('#sharingToken').val(); + var downloadUrl = OC.generateUrl('/s/{token}/download?files={files}&path={path}', { + token: sharingToken, + files: fileName, + path: context.dir + }); + OCA.Files_Reader.Plugin.show(downloadUrl, mime, true); + } + + /** + * @namespace OCA.Files_Reader.Plugin + */ + OCA.Files_Reader.Plugin = { + + /** + * @param fileList + */ + attach: function(fileList) { + this._extendFileActions(fileList.fileActions); + }, + + hideControls: function() { + $('#app-content #controls').hide(); + // and, for NC12... + $('#app-navigation').css("display", "none"); + $('#view-toggle').css("display", "none"); + }, + + hide: function() { + if ($('#fileList').length) { + FileList.setViewerMode(false); + } + $("#controls").show(); + $('#app-content #controls').removeClass('hidden'); + // NC12... + $('#app-navigation').css("display", ""); + $('#view-toggle').css("display", ""); + $('#imgframe').show(); + $('footer').show(); + $('.directLink').show(); + $('.directDownload').show(); + $('iframe').remove(); + }, + + /** + * @param downloadUrl + * @param isFileList + */ + show: function(downloadUrl, mimeType, isFileList) { + var self = this; + var $iframe; + var viewer = OC.generateUrl('/apps/files_reader/?file={file}&type={type}', {file: downloadUrl, type: mimeType}); + // launch in new window on mobile and touch devices... + if (isMobile || hasTouch) { + window.open(viewer, downloadUrl); + } else { + $iframe = '