- 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™_

 - 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
This commit is contained in:
Frank de Lange 2022-09-24 00:00:03 +00:00
parent 16afbe45fe
commit b190e180ef
137 changed files with 30984 additions and 2 deletions

129
CHANGELOG.md Normal file
View file

@ -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 <base> from templates to avoid warning in console, <base> 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

137
README.md
View file

@ -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

5
TODO Normal file
View file

@ -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

57
appinfo/info.xml Normal file
View file

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<info>
<id>files_reader</id>
<name>Reader (ebook reader)</name>
<namespace>Files_Reader</namespace>
<summary>A multi-format browser-based ebook reader which supports EPUB, PDF and CBR/CBZ</summary>
<description>
<![CDATA[
# 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.
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.
See [README] for more exhaustive information on features and potential misfeatures of this app
[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
[README]: https://github.com/Yetangitu/owncloud-apps/blob/master/files_reader/README.md
]]>
</description>
<version>1.4.0</version>
<licence>AGPL</licence>
<author>Frank de Lange</author>
<documentation>
<user>https://github.com/Yetangitu/owncloud-apps/blob/master/files_reader/README.md</user>
</documentation>
<bugs>https://github.com/Yetangitu/owncloud-apps/issues</bugs>
<website>https://github.com/Yetangitu/owncloud-apps/tree/master/files_reader</website>
<screenshot>https://raw.githubusercontent.com/Yetangitu/owncloud-apps/master/screenshots/files_reader-1.png</screenshot>
<screenshot>https://raw.githubusercontent.com/Yetangitu/owncloud-apps/master/screenshots/files_reader-3.png</screenshot>
<screenshot>https://raw.githubusercontent.com/Yetangitu/owncloud-apps/master/screenshots/files_reader_PDF_005.png</screenshot>
<screenshot>https://raw.githubusercontent.com/Yetangitu/owncloud-apps/master/screenshots/files_reader_PDF_006.png</screenshot>
<screenshot>https://raw.githubusercontent.com/Yetangitu/owncloud-apps/master/screenshots/photo_2017-03-15_17-22-00.jpg</screenshot>
<screenshot>https://raw.githubusercontent.com/Yetangitu/owncloud-apps/master/screenshots/photo_2017-03-15_17-22-02.jpg</screenshot>
<category>files</category>
<category>multimedia</category>
<category>office</category>
<settings>
<personal>\OCA\Files_Reader\Settings\Personal</personal>
</settings>
<dependencies>
<owncloud max-version="0" min-version="0"/>
<nextcloud min-version="20" max-version="24"/>
</dependencies>
</info>

43
appinfo/routes.php Normal file
View file

@ -0,0 +1,43 @@
<?php
/**
* ownCloud - Files_Reader App
*
* @author Frank de Lange
* @copyright 2015 Frank de Lange
*
* This file is licensed under the Affero General Public License version 3 or
* later.
*/
namespace OCA\Files_Reader\AppInfo;
return ['routes' => [
// 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'],
]];

137
appinfo/signature.json Normal file
View file

@ -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-----"
}

3
css/settings.css Normal file
View file

@ -0,0 +1,3 @@
.nav-icon-reader {
background-image: url('../img/app.svg?v=2');
}

50
img/app.svg Normal file
View file

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
id="svg5261"
version="1.1"
viewBox="0 0 32 32"
width="32"
height="32">
<metadata
id="metadata5267">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs5265" />
<g
style="fill:#060000;fill-opacity:1"
id="layer1"
transform="translate(1.4457782,-1020.2752)">
<path
d="m 11.168042,1021.5246 c -2.2036689,-1.0138 -6.5467059,0.9451 -7.7942059,2.6697 -0.555819,0.7717 -0.516525,1.3278 -0.516525,1.6433 v 16.8796 l 16.2867569,8.8577 3.062736,-1.4617 v -16.4387 l -16.7222168,-8.3914 c 0.897356,-0.9871 2.9155749,-2.1908 4.4288007,-1.7074 l 14.8949581,6.9633 v 18.3129 l 3.070508,-1.4642 v -18.3122 z"
id="path2989"
style="fill:#060000;fill-opacity:1" />
</g>
<text
id="text3335"
y="11.710122"
x="6.2117367"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-size:40px;line-height:1.25"
y="11.710122"
x="6.2117367"
id="tspan3337"> </tspan></text>
<path
style="fill:#fcfcfc;fill-opacity:1"
id="path4015-6"
d="m 11.935898,22.551661 -3.7773648,-6.800426 4.5440888,-2.201163 1.259258,2.266597 -3.029623,1.467379 1.259148,2.266823 4.544091,-2.201162 -3.290554,-5.923647 c -0.268675,-0.483984 -0.748735,-0.749275 -1.072248,-0.592546 l -6.4023558,3.101677 c -0.323238,0.156596 -0.367469,0.675885 -0.09879,1.159868 l 5.3222018,9.580704 c 0.268927,0.484123 0.748989,0.749415 1.072249,0.592546 l 6.402425,-3.10145 c 0.32326,-0.156869 0.367492,-0.676158 0.09879,-1.159868 l -0.772645,-1.390597 z" />
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
img/book.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
img/loading.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

197
js/lib/Blob.js Normal file
View file

@ -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));

31
js/lib/blob.js Normal file
View file

@ -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);
};
}
};
}());

629
js/lib/typedarray.js Normal file
View file

@ -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<Type>() - take a number (interpreted as Type), output a byte array
// unpack<Type>() - 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<type> 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<type> 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<type> 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);
} ());
}
} ());

1
js/lib/typedarray.min.js vendored Normal file

File diff suppressed because one or more lines are too long

75
js/lib/wgxpath.install.js Normal file
View file

@ -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(2<arguments.length){var d=Array.prototype.slice.call(arguments,2);return function(){var c=Array.prototype.slice.call(arguments);Array.prototype.unshift.apply(c,d);return a.apply(b,c)}}return function(){return a.apply(b,arguments)}}
function ea(a,b,c){ea=Function.prototype.bind&&-1!=Function.prototype.bind.toString().indexOf("native code")?ca:da;return ea.apply(null,arguments)}function fa(a,b){var c=Array.prototype.slice.call(arguments,1);return function(){var b=c.slice();b.push.apply(b,arguments);return a.apply(this,b)}}
function q(a){var b=r;function c(){}c.prototype=b.prototype;a.G=b.prototype;a.prototype=new c;a.F=function(a,c,f){for(var g=Array(arguments.length-2),k=2;k<arguments.length;k++)g[k-2]=arguments[k];return b.prototype[c].apply(a,g)}};/*
The MIT License
Copyright (c) 2007 Cybozu Labs, Inc.
Copyright (c) 2012 Google 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.
*/
function t(a,b,c){this.a=a;this.b=b||1;this.f=c||1};var ga=String.prototype.trim?function(a){return a.trim()}:function(a){return a.replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")};function u(a,b){return-1!=a.indexOf(b)}function ha(a,b){return a<b?-1:a>b?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(;c<a.length;c++)if(c in a&&a[c]===b)return c;return-1},w=v.forEach?function(a,b,c){v.forEach.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=n(a)?a.split(""):a,f=0;f<d;f++)f in e&&b.call(c,e[f],f,a)},ja=v.filter?function(a,b,c){return v.filter.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=[],f=0,g=n(a)?
a.split(""):a,k=0;k<d;k++)if(k in g){var p=g[k];b.call(c,p,k,a)&&(e[f++]=p)}return e},x=v.reduce?function(a,b,c,d){d&&(b=ea(b,d));return v.reduce.call(a,b,c)}:function(a,b,c,d){var e=c;w(a,function(c,g){e=b.call(d,e,c,g,a)});return e},ka=v.some?function(a,b,c){return v.some.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=n(a)?a.split(""):a,f=0;f<d;f++)if(f in e&&b.call(c,e[f],f,a))return!0;return!1};
function la(a,b){var c;a:{c=a.length;for(var d=n(a)?a.split(""):a,e=0;e<c;e++)if(e in d&&b.call(void 0,d[e],e,a)){c=e;break a}c=-1}return 0>c?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<e;f++){var g=c[f]||"",k=d[f]||"",p=RegExp("(\\d*)(\\D*)","g"),z=RegExp("(\\d*)(\\D*)","g");do{var E=p.exec(g)||["","",""],aa=z.exec(k)||["","",""];if(0==E[0].length&&0==aa[0].length)break;b=ha(0==E[1].length?0:parseInt(E[1],10),0==aa[1].length?0:parseInt(aa[1],10))||ha(0==E[2].length,0==aa[2].length)||ha(E[2],aa[2])}while(0==b)}xa[a]=0<=b}}
var za=m.document,Aa=za&&A?va()||("CSS1Compat"==za.compatMode?parseInt(wa,10):5):void 0;var B=A&&!(9<=Aa),Ba=A&&!(8<=Aa);function C(a,b,c,d){this.a=a;this.nodeName=c;this.nodeValue=d;this.nodeType=2;this.parentNode=this.ownerElement=b}function Ca(a,b){var c=Ba&&"href"==b.nodeName?a.getAttribute(b.nodeName,2):b.nodeValue;return new C(b,a,b.nodeName,c)};function Da(a){this.b=a;this.a=0}function Ea(a){a=a.match(Fa);for(var b=0;b<a.length;b++)Ga.test(a[b])&&a.splice(b,1);return new Da(a)}var Fa=RegExp("\\$?(?:(?![0-9-])[\\w-]+:)?(?![0-9-])[\\w-]+|\\/\\/|\\.\\.|::|\\d+(?:\\.\\d*)?|\\.\\d+|\"[^\"]*\"|'[^']*'|[!<>]=|\\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<Ja(c.node,d.node)?(f=d,d=d.a):(f=c,c=c.a);(f.b=e)?e.a=f:a.a=f;e=f;g++}for(f=c||d;f;)f.b=e,e=e.a=f,g++,f=f.a;a.b=e;a.l=g;return a}function Va(a,b){var c=new Ta(b);c.a=a.a;a.b?a.a.b=c:a.a=a.b=c;a.a=c;a.l++}
function K(a,b){var c=new Ta(b);c.b=a.b;a.a?a.b.a=c:a.a=a.b=c;a.b=c;a.l++}function Wa(a){return(a=a.a)?a.node:null}function Xa(a){return(a=Wa(a))?G(a):""}function M(a,b){return new Ya(a,!!b)}function Ya(a,b){this.f=a;this.b=(this.c=b)?a.b:a.a;this.a=null}function N(a){var b=a.b;if(null==b)return null;var c=a.a=b;a.b=a.c?b.b:b.a;return c.node};function Za(a){switch(a.nodeType){case 1:return fa($a,a);case 9:return Za(a.documentElement);case 11:case 10:case 6:case 12:return ab;default:return a.parentNode?Za(a.parentNode):ab}}function ab(){return null}function $a(a,b){if(a.prefix==b)return a.namespaceURI||"http://www.w3.org/1999/xhtml";var c=a.getAttributeNode("xmlns:"+b);return c&&c.specified?c.value||null:a.parentNode&&9!=a.parentNode.nodeType?$a(a.parentNode,b):null};function r(a){this.i=a;this.b=this.g=!1;this.f=null}function O(a){return"\n "+a.toString().split("\n").join("\n ")}function bb(a,b){a.g=b}function cb(a,b){a.b=b}function P(a,b){var c=a.a(b);return c instanceof I?+Xa(c):+c}function Q(a,b){var c=a.a(b);return c instanceof I?Xa(c):""+c}function R(a,b){var c=a.a(b);return c instanceof I?!!c.l:!!c};function db(a,b,c){r.call(this,a.i);this.c=a;this.h=b;this.o=c;this.g=b.g||c.g;this.b=b.b||c.b;this.c==eb&&(c.b||c.g||4==c.i||0==c.i||!b.f?b.b||b.g||4==b.i||0==b.i||!c.f||(this.f={name:c.f.name,s:b}):this.f={name:b.f.name,s:c})}q(db);
function S(a,b,c,d,e){b=b.a(d);c=c.a(d);var f;if(b instanceof I&&c instanceof I){e=M(b);for(d=N(e);d;d=N(e))for(b=M(c),f=N(b);f;f=N(b))if(a(G(d),G(f)))return!0;return!1}if(b instanceof I||c instanceof I){b instanceof I?e=b:(e=c,c=b);e=M(e);b=typeof c;for(d=N(e);d;d=N(e)){switch(b){case "number":d=+G(d);break;case "boolean":d=!!G(d);break;case "string":d=G(d);break;default:throw Error("Illegal primitive type for comparison.");}if(a(d,c))return!0}return!1}return e?"boolean"==typeof b||"boolean"==typeof c?
a(!!b,!!c):"number"==typeof b||"number"==typeof c?a(+b,+c):a(b,c):a(+b,+c)}db.prototype.a=function(a){return this.c.m(this.h,this.o,a)};db.prototype.toString=function(){var a="Binary Expression: "+this.c,a=a+O(this.h);return a+=O(this.o)};function fb(a,b,c,d){this.a=a;this.w=b;this.i=c;this.m=d}fb.prototype.toString=h("a");var gb={};function T(a,b,c,d){if(gb.hasOwnProperty(a))throw Error("Binary operator already created: "+a);a=new fb(a,b,c,d);return gb[a.toString()]=a}
T("div",6,1,function(a,b,c){return P(a,c)/P(b,c)});T("mod",6,1,function(a,b,c){return P(a,c)%P(b,c)});T("*",6,1,function(a,b,c){return P(a,c)*P(b,c)});T("+",5,1,function(a,b,c){return P(a,c)+P(b,c)});T("-",5,1,function(a,b,c){return P(a,c)-P(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)});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.length<a.A)throw Error("Function "+a.j+" expects at least"+a.A+" arguments, "+b.length+" given");if(null!==a.v&&b.length>a.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;d<c.length;d++){var f=c.charAt(d);f in a||(a[f]=e.charAt(d))}c="";for(d=0;d<b.length;d++)f=b.charAt(d),c+=f in a?a[f]:f;return c},3);U("true",2,!1,!1,l(!0),0);function L(a,b){this.h=a;this.c=void 0!==b?b:null;this.b=null;switch(a){case "comment":this.b=8;break;case "text":this.b=3;break;case "processing-instruction":this.b=7;break;case "node":break;default:throw Error("Unexpected argument");}}function mb(a){return"comment"==a||"text"==a||"processing-instruction"==a||"node"==a}L.prototype.a=function(a){return null===this.b||this.b==a.nodeType};L.prototype.f=h("h");L.prototype.toString=function(){var a="Kind Test: "+this.h;null===this.c||(a+=O(this.c));return a};function nb(a){r.call(this,3);this.c=a.substring(1,a.length-1)}q(nb);nb.prototype.a=h("c");nb.prototype.toString=function(){return"Literal: "+this.c};function J(a,b){this.j=a.toLowerCase();this.c=b?b.toLowerCase():"http://www.w3.org/1999/xhtml"}J.prototype.a=function(a){var b=a.nodeType;return 1!=b&&2!=b?!1:"*"!=this.j&&this.j!=a.nodeName.toLowerCase()?!1:this.c==(a.namespaceURI?a.namespaceURI.toLowerCase():"http://www.w3.org/1999/xhtml")};J.prototype.f=h("j");J.prototype.toString=function(){return"Name Test: "+("http://www.w3.org/1999/xhtml"==this.c?"":this.c+":")+this.j};function ob(a){r.call(this,1);this.c=a}q(ob);ob.prototype.a=h("c");ob.prototype.toString=function(){return"Number: "+this.c};function pb(a,b){r.call(this,a.i);this.h=a;this.c=b;this.g=a.g;this.b=a.b;if(1==this.c.length){var c=this.c[0];c.u||c.c!=qb||(c=c.o,"*"!=c.f()&&(this.f={name:c.f(),s:null}))}}q(pb);function rb(){r.call(this,4)}q(rb);rb.prototype.a=function(a){var b=new I;a=a.a;9==a.nodeType?K(b,a):K(b,a.ownerDocument);return b};rb.prototype.toString=l("Root Helper Expression");function sb(){r.call(this,4)}q(sb);sb.prototype.a=function(a){var b=new I;K(b,a.a);return b};sb.prototype.toString=l("Context Helper Expression");
function tb(a){return"/"==a||"//"==a}pb.prototype.a=function(a){var b=this.h.a(a);if(!(b instanceof I))throw Error("Filter expression must evaluate to nodeset.");a=this.c;for(var c=0,d=a.length;c<d&&b.l;c++){var e=a[c],f=M(b,e.c.a),g;if(e.g||e.c!=ub)if(e.g||e.c!=vb)for(g=N(f),b=e.a(new t(g));null!=(g=N(f));)g=e.a(new t(g)),b=Ua(b,g);else g=N(f),b=e.a(new t(g));else{for(g=N(f);(b=N(f))&&(!g.contains||g.contains(b))&&b.compareDocumentPosition(g)&8;g=b);b=e.a(new t(g))}}return b};
pb.prototype.toString=function(){var a;a="Path Expression:"+O(this.h);if(this.c.length){var b=x(this.c,function(a,b){return a+O(b)},"Steps:");a+=O(b)}return a};function wb(a,b){this.a=a;this.b=!!b}
function ib(a,b,c){for(c=c||0;c<a.a.length;c++)for(var d=a.a[c],e=M(b),f=b.l,g,k=0;g=N(e);k++){var p=a.b?f-k:k+1;g=d.a(new t(g,p,f));if("number"==typeof g)p=p==g;else if("string"==typeof g||"boolean"==typeof g)p=!!g;else if(g instanceof I)p=0<g.l;else throw Error("Predicate.evaluate returned an unexpected type.");if(!p){p=e;g=p.f;var z=p.a;if(!z)throw Error("Next must be called at least once before remove.");var E=z.b,z=z.a;E?E.a=z:g.a=z;z?z.b=E:g.b=E;g.l--;p.a=null}}return b}
wb.prototype.toString=function(){return x(this.a,function(a,b){return a+O(b)},"Predicates:")};function V(a,b,c,d){r.call(this,4);this.c=a;this.o=b;this.h=c||new wb([]);this.u=!!d;b=this.h;b=0<b.a.length?b.a[0].f:null;a.b&&b&&(a=b.name,a=B?a.toLowerCase():a,this.f={name:a,s:b.s});a:{a=this.h;for(b=0;b<a.a.length;b++)if(c=a.a[b],c.g||1==c.i||0==c.i){a=!0;break a}a=!1}this.g=a}q(V);
V.prototype.a=function(a){var b=a.a,c=null,c=this.f,d=null,e=null,f=0;c&&(d=c.name,e=c.s?Q(c.s,a):null,f=1);if(this.u)if(this.g||this.c!=xb)if(a=M((new V(yb,new L("node"))).a(a)),b=N(a))for(c=this.m(b,d,e,f);null!=(b=N(a));)c=Ua(c,this.m(b,d,e,f));else c=new I;else c=Ma(this.o,b,d,e),c=ib(this.h,c,f);else c=this.m(a.a,d,e,f);return c};V.prototype.m=function(a,b,c,d){a=this.c.f(this.o,a,b,c);return a=ib(this.h,a,d)};
V.prototype.toString=function(){var a;a="Step:"+O("Operator: "+(this.u?"//":"/"));this.c.j&&(a+=O("Axis: "+this.c));a+=O(this.o);if(this.h.a.length){var b=x(this.h.a,function(a,b){return a+O(b)},"Predicates:");a+=O(b)}return a};function zb(a,b,c,d){this.j=a;this.f=b;this.a=c;this.b=d}zb.prototype.toString=h("j");var Ab={};function W(a,b,c,d){if(Ab.hasOwnProperty(a))throw Error("Axis already created: "+a);b=new zb(a,b,c,!!d);return Ab[a]=b}
W("ancestor",function(a,b){for(var c=new I,d=b;d=d.parentNode;)a.a(d)&&Va(c,d);return c},!0);W("ancestor-or-self",function(a,b){var c=new I,d=b;do a.a(d)&&Va(c,d);while(d=d.parentNode);return c},!0);
var qb=W("attribute",function(a,b){var c=new I,d=a.f();if("style"==d&&b.style&&B)return K(c,new C(b.style,b,"style",b.style.cssText)),c;var e=b.attributes;if(e)if(a instanceof L&&null===a.b||"*"==d)for(var d=0,f;f=e[d];d++)B?f.nodeValue&&K(c,Ca(b,f)):K(c,f);else(f=e.getNamedItem(d))&&(B?f.nodeValue&&K(c,Ca(b,f)):K(c,f));return c},!1),xb=W("child",function(a,b,c,d,e){return(B?Ra:Sa).call(null,a,b,n(c)?c:null,n(d)?d:null,e||new I)},!1,!0);W("descendant",Ma,!1,!0);
var yb=W("descendant-or-self",function(a,b,c,d){var e=new I;H(b,c,d)&&a.a(b)&&K(e,b);return Ma(a,b,c,d,e)},!1,!0),ub=W("following",function(a,b,c,d){var e=new I;do for(var f=b;f=f.nextSibling;)H(f,c,d)&&a.a(f)&&K(e,f),e=Ma(a,f,c,d,e);while(b=b.parentNode);return e},!1,!0);W("following-sibling",function(a,b){for(var c=new I,d=b;d=d.nextSibling;)a.a(d)&&K(c,d);return c},!1);W("namespace",function(){return new I},!1);
var Bb=W("parent",function(a,b){var c=new I;if(9==b.nodeType)return c;if(2==b.nodeType)return K(c,b.ownerElement),c;var d=b.parentNode;a.a(d)&&K(c,d);return c},!1),vb=W("preceding",function(a,b,c,d){var e=new I,f=[];do f.unshift(b);while(b=b.parentNode);for(var g=1,k=f.length;g<k;g++){var p=[];for(b=f[g];b=b.previousSibling;)p.unshift(b);for(var z=0,E=p.length;z<E;z++)b=p[z],H(b,c,d)&&a.a(b)&&K(e,b),e=Ma(a,b,c,d,e)}return e},!0,!0);
W("preceding-sibling",function(a,b){for(var c=new I,d=b;d=d.previousSibling;)a.a(d)&&Va(c,d);return c},!0);var Cb=W("self",function(a,b){var c=new I;a.a(b)&&K(c,b);return c},!1);function Db(a){r.call(this,1);this.c=a;this.g=a.g;this.b=a.b}q(Db);Db.prototype.a=function(a){return-P(this.c,a)};Db.prototype.toString=function(){return"Unary Expression: -"+O(this.c)};function Eb(a){r.call(this,4);this.c=a;bb(this,ka(this.c,function(a){return a.g}));cb(this,ka(this.c,function(a){return a.b}))}q(Eb);Eb.prototype.a=function(a){var b=new I;w(this.c,function(c){c=c.a(a);if(!(c instanceof I))throw Error("Path expression must evaluate to NodeSet.");b=Ua(b,c)});return b};Eb.prototype.toString=function(){return x(this.c,function(a,b){return a+O(b)},"Union Expression:")};function Fb(a,b){this.a=a;this.b=b}function Gb(a){for(var b,c=[];;){X(a,"Missing right hand side of binary expression.");b=Hb(a);var d=F(a.a);if(!d)break;var e=(d=gb[d]||null)&&d.w;if(!e){a.a.a--;break}for(;c.length&&e<=c[c.length-1].w;)b=new db(c.pop(),c.pop(),b);c.push(b,d)}for(;c.length;)b=new db(c.pop(),c.pop(),b);return b}function X(a,b){if(Ha(a.a))throw Error(b);}function Ib(a,b){var c=F(a.a);if(c!=b)throw Error("Bad token, expected: "+b+" got: "+c);}
function Jb(a){a=F(a.a);if(")"!=a)throw Error("Bad token: "+a);}function Kb(a){a=F(a.a);if(2>a.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<a.l:!!a;break;case 4:case 5:case 6:case 7:var d=
M(a);c=[];for(var e=N(d);e;e=N(d))c.push(e instanceof C?e.a:e);this.snapshotLength=a.l;this.invalidIteratorState=!1;break;case 8:case 9:d=Wa(a);this.singleNodeValue=d instanceof C?d.a:d;break;default:throw Error("Unknown XPathResult type.");}var f=0;this.iterateNext=function(){if(4!=b&&5!=b)throw Error("iterateNext called with wrong result type");return f>=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;})()

22
js/personal.js Normal file
View file

@ -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);
});

177
js/plugin-public.js Normal file
View file

@ -0,0 +1,177 @@
/*
* Copyright (c) 2015-2017 Frank de Lange
* Copyright (c) 2013-2014 Lukas Reschke <lukas@owncloud.com>
*
* 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 = '<iframe style="width:100%;height:100%;display:block;position:absolute;top:0;" src="' + viewer + '" allowfullscreen="true" webkitallowfullscreen="true" mozallowfullscreen="true" sandbox="allow-scripts allow-same-origin"/>';
if (isFileList === true) {
FileList.setViewerMode(true);
}
// force the preview to adjust its height
$('#preview').append($iframe).css({ height: '100%' });
$('body').css({ height: '100%' });
$('footer').addClass('hidden');
$('#imgframe').addClass('hidden');
$('.directLink').addClass('hidden');
$('.directDownload').addClass('hidden');
$('#controls').addClass('hidden');
}
},
/**
* @param fileActions
* @private
*/
_extendFileActions: function(fileActions) {
var self = this;
fileActions.registerAction({
name: 'view-epub',
displayName: 'View',
mime: 'application/epub+zip',
permissions: OC.PERMISSION_READ,
actionHandler: function(fileName, context){
return actionHandler(fileName, 'application/epub+zip', context);
}
});
for (let i = 0; i < cbx_types.length; i++) {
fileActions.registerAction({
name: 'view-cbr',
displayName: 'View',
mime: cbx_types[i],
permissions: OC.PERMISSION_READ,
actionHandler: function(fileName, context) {
return actionHandler(fileName, 'application/x-cbr', context);
}
});
}
fileActions.registerAction({
name: 'view-pdf',
displayName: 'View',
mime: 'application/pdf',
permissions: OC.PERMISSION_READ,
actionHandler: function(fileName, context) {
return actionHandler(fileName, 'application/pdf', context);
}
});
if (epub_enabled === 'true')
fileActions.setDefault('application/epub+zip', 'view-epub');
if (cbx_enabled === 'true') {
for (let i = 0; i < cbx_types.length; i++) {
fileActions.setDefault(cbx_types[i], 'view-cbr');
}
}
if (pdf_enabled === 'true')
fileActions.setDefault('application/pdf', 'view-pdf');
}
};
})(OCA);
OC.Plugins.register('OCA.Files.FileList', OCA.Files_Reader.Plugin);
// FIXME: Hack for single public file view since it is not attached to the fileslist
$(document).ready(function(){
const mimetype=$('#mimetype').val();
if ($('#isPublic').val()
&& (mimetype === 'application/epub+zip'
|| mimetype === 'application/pdf'
|| mimetype === 'application/x-cbr'
|| mimetype.startsWith('application/comicbook'))
) {
var sharingToken = $('#sharingToken').val();
var downloadUrl = OC.generateUrl('/s/{token}/download', {token: sharingToken});
var viewer = OCA.Files_Reader.Plugin;
var mime = $('#mimetype').val();
if (mimetype.startsWith('application/comicbook'))
mime = 'application/x-cbr';
viewer.show(downloadUrl, mime, false);
}
});

131
js/plugin.js Normal file
View file

@ -0,0 +1,131 @@
/*
* Copyright (c) 2015-2017 Frank de Lange
* Copyright (c) 2013-2014 Lukas Reschke <lukas@owncloud.com>
*
* 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');
const mimeHandlers = {
'epub': { default: epub_enabled, mimeTypes: ['application/epub+zip']},
'pdf': { default: pdf_enabled, mimeTypes: ['application/pdf']},
'cbx': { default: cbx_enabled, mimeTypes: [
'application/comicbook+7z',
'application/comicbook+rar',
'application/comicbook+tar',
'application/comicbook+zip',
'application/x-cbr'
]}
};
const mimeMappings = {
'application/epub+zip': 'epub',
'application/pdf': 'pdf',
'application/x-cbr': 'cbx',
'application/comicbook+7z': 'cbx',
'application/comicbook+rar': 'cbx',
'application/comicbook+tar': 'cbx',
'application/comicbook+zip': 'cbx'
};
const isMobileUAD = window.navigator.userAgentData?.mobile;
const isMobile = typeof isMobileUAD === 'boolean'
? isMobileUAD
: navigator.userAgent.match(/Mobi/i);
function actionHandler(fileName, mime, context) {
const downloadUrl = Files.getDownloadUrl(fileName, context.dir);
OCA.Files_Reader.Plugin.show(downloadUrl, mimeMappings[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", "");
$('iframe').remove();
},
/**
* @param downloadUrl
* @param isFileList
*/
show: function(downloadUrl, fileType, isFileList) {
var self = this;
var $iframe;
var viewer = OC.generateUrl('/apps/files_reader/?file={file}&type={type}', {file: downloadUrl, type: fileType});
// launch in new window on mobile devices...
if (isMobile) {
window.open(viewer, downloadUrl);
} else {
$iframe = '<iframe style="width:100%;height:100%;display:block;position:absolute;top:0;" src="' + viewer + '" allowfullscreen="true" webkitallowfullscreen="true" mozallowfullscreen="true" sandbox="allow-scripts allow-same-origin"/>';
if (isFileList === true) {
FileList.setViewerMode(true);
}
$('#app-content').append($iframe);
self.hideControls();
}
},
/**
* @param fileActions
* @private
*/
_extendFileActions: function(fileActions) {
var self = this;
for (handler in mimeHandlers) {
const actionName = 'view-' + handler;
mimeHandlers[handler].mimeTypes.forEach(function(mimeType) {
fileActions.registerAction({
name: actionName,
displayName: 'View',
mime: mimeType,
permissions: OC.PERMISSION_READ,
actionHandler: function(fileName, context){
return actionHandler(fileName, mimeType, context);
}
});
if (mimeHandlers[handler].default === 'true')
fileActions.setDefault(mimeType, actionName);
});
}
}
};
})(OCA);
OC.Plugins.register('OCA.Files.FileList', OCA.Files_Reader.Plugin);

142
js/ready.js Normal file
View file

@ -0,0 +1,142 @@
document.onreadystatechange = function () {
if (document.readyState == "complete") {
var type=decodeURIComponent(getUrlParameter('type')),
file=decodeURIComponent(getUrlParameter('file')),
options = {},
$session = $('.session');
options.session = {};
options.session.filename = decodeURI($session.data('filename'));
options.session.format = $session.data('filetype');
options.session.fileId = $session.data('fileid');
options.session.title = options.session.filename;
options.session.nonce = $session.data('nonce') || "";
options.session.version = $session.data('version') || "";
options.session.metadata = $session.data('metadata') || {};
options.session.annotations = $session.data('annotations') || {};
options.session.fileId = $session.data('fileid') || "";
options.session.scope = $session.data('scope') || "";
options.session.cursor = $session.data('cursor') || {};
options.session.defaults = $session.data('defaults') || {};
options.session.preferences = $session.data('preferences') || {};
options.session.defaults = $session.data('defaults') || {};
options.session.basePath = $session.data('basepath');
options.session.downloadLink = $session.data('downloadlink');
console.log(options.session.basePath);
/* functions return jquery promises */
options.session.getPreference = function(name) {
return $.get(options.session.basePath + "preference/" + options.session.fileId + "/" + options.session.scope + "/" + name);
};
options.session.setPreference = function(name, value) {
return $.post(options.session.basePath + "preference",
{
"fileId": options.session.fileId,
"scope": options.session.scope,
"name": name,
"value": JSON.stringify(value)
});
};
options.session.deletePreference = function(name) {
return $.delete(options.session.basePath + "preference/" + options.session.fileId + "/" + options.session.scope + "/" + name);
};
options.session.getDefault = function(name) {
return $.get(options.session.basePath + "preference/default/" + options.session.scope + "/" + name);
};
options.session.setDefault = function(name, value) {
return $.post(options.session.basePath + "preference/default",
{
"scope": options.session.scope,
"name": name,
"value": JSON.stringify(value)
});
};
options.session.deleteDefault = function(name) {
return $.delete(options.session.basePath + "preference/default/" + options.session.scope + "/" + name);
};
options.session.getBookmark = function(name, type) {
return $.get(options.session.basePath + "bookmark/" + options.session.fileId + "/" + type + "/" + name);
};
options.session.setBookmark = function(name, value, type, content) {
return $.post(options.session.basePath + "bookmark",
{
"fileId": options.session.fileId,
"name": name,
"value": JSON.stringify(value),
"type": type,
"content": JSON.stringify(content)
});
};
options.session.deleteBookmark = function(name) {
return $.delete(options.session.basePath + "bookmark/" + options.session.fileId + "/" + name);
};
options.session.getCursor = function() {
return $.get(options.session.basePath + "bookmark/cursor/" + options.session.fileId);
};
options.session.setCursor = function(value) {
return $.post(options.session.basePath + "bookmark/cursor",
{
"fileId": options.session.fileId,
"value": JSON.stringify(value)
});
};
options.session.deleteCursor = function() {
return $.delete(options.session.basePath + "bookmark/cursor/" + options.session.fileId);
};
switch (type) {
case 'epub':
options['contained'] = true;
renderEpub(file, options);
break;
case 'cbx':
renderCbr(file, options);
break;
case 'pdf':
renderPdf(file, options);
break;
default:
console.log(type + ' is not supported by Reader');
}
}
// why is there no standard library function for this?
function getUrlParameter (param) {
var pattern = new RegExp('[?&]'+param+'((=([^&]*))|(?=(&|$)))','i');
var m = window.location.search.match(pattern);
return m && ( typeof(m[3])==='undefined' ? '' : m[3] );
}
// start epub.js renderer
function renderEpub(file, options) {
// some parameters...
EPUBJS.filePath = "vendor/epubjs/";
EPUBJS.cssPath = "vendor/epubjs/css/";
EPUBJS.basePath = $('.session').data('basepath');
var reader = ePubReader(file, options);
}
// start cbr.js renderer
function renderCbr(file, options) {
CBRJS.filePath = "vendor/cbrjs/";
var reader = cbReader(file, options);
}
// start pdf.js renderer
function renderPdf(file, options) {
PDFJS.filePath = "vendor/pdfjs/";
PDFJS.imageResourcesPath = "vendor/pdfjs/css/images/";
PDFJS.workerSrc = options.session.basePath + 'vendor/pdfjs/lib/pdf.worker.js';
var reader = pdfReader(file, options);
}
};

24
js/settings.js Normal file
View file

@ -0,0 +1,24 @@
$(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.generateUrl('/apps/files_reader/settings'), data, function(response) {
OC.msg.finishedSuccess('#reader-personal .msg', response.data.message);
});
},
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);
});

View file

@ -0,0 +1,51 @@
<?php
declare(strict_types=1);
/**
* @author Frank de Lange
* @copyright 2022 Frank de Lange
*
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace OCA\Files_Reader\AppInfo;
use OCA\Files_Reader\Hooks;
use OCA\Files_Reader\Listeners\CSPListener;
use OCA\Files_Reader\Listeners\LoadPublicViewerListener;
use OCA\Files_Reader\Listeners\LoadViewerListener;
use OCA\Viewer\Event\LoadViewer;
use OCP\AppFramework\App;
use OCP\AppFramework\Bootstrap\IBootContext;
use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\Bootstrap\IRegistrationContext;
use OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent;
use OCP\Security\CSP\AddContentSecurityPolicyEvent;
class Application extends App implements IBootstrap {
public const APP_ID = 'files_reader';
public function __construct() {
parent::__construct(self::APP_ID);
}
public function register(IRegistrationContext $context): void {
$context->registerEventListener(LoadViewer::class, LoadViewerListener::class);
$context->registerEventListener(BeforeTemplateRenderedEvent::class, LoadPublicViewerListener::class);
$context->registerEventListener(AddContentSecurityPolicyEvent::class, CSPListener::class);
}
public function registerPersonalSettings() {
\OCP\App::registerPersonal(self::APP_ID, 'personal');
}
public function boot(IBootContext $context): void {
Hooks::register();
}
}

View file

@ -0,0 +1,124 @@
<?php
/**
* @author Frank de Lange
* @copyright 2017 Frank de Lange
*
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace OCA\Files_Reader\Controller;
use OCP\IRequest;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\DataResponse;
use OCA\Files_Reader\Service\BookmarkService;
class BookmarkController extends Controller {
private $bookmarkService;
/**
* @param string $AppName
* @param IRequest $request
* @param BookmarkService $bookmarkService
*/
public function __construct($AppName,
IRequest $request,
BookmarkService $bookmarkService ) {
parent::__construct($AppName, $request);
$this->bookmarkService = $bookmarkService;
}
/**
* @brief return bookmark
*
* @NoAdminRequired
* @NoCSRFRequired
*
* @param int $fileId
* @param string $name
*
* @return array|\OCP\AppFramework\Http\JSONResponse
*/
public function get($fileId, $name, $type=null) {
return $this->bookmarkService->get($fileId, $name, $type);
}
/**
* @brief write bookmark
*
* @NoAdminRequired
* @NoCSRFRequired
*
* @param int $fileId
* @param string $name
* @param string $value
*
* @return array|\OCP\AppFramework\Http\JSONResponse
*/
public function set($fileId, $name, $value, $type=null, $content=null) {
return $this->bookmarkService->set($fileId, $name, $value, $type, $content);
}
/**
* @brief return cursor for $fileId
*
* @NoAdminRequired
* @NoCSRFRequired
*
* @param int $fileId
*
* @return array|\OCP\AppFramework\Http\JSONResponse
*/
public function getCursor($fileId) {
return $this->bookmarkService->getCursor($fileId);
}
/**
* @brief write cursor for $fileId
*
* @NoAdminRequired
* @NoCSRFRequired
*
* @param int $fileId
* @param string $value
*
* @return array|\OCP\AppFramework\Http\JSONResponse
*/
public function setCursor($fileId, $value) {
return $this->bookmarkService->setCursor($fileId, $value);
}
/**
* @brief delete bookmark
*
* @NoAdminRequired
* @NoCSRFRequired
*
* @param int $fileId
* @param string name
*
*/
public function delete($fileId, $name) {
return $this->bookmarkService->delete($fileId, $name);
}
/**
* @brief delete cursor
*
* @NoAdminRequired
* @NoCSRFRequired
*
* @param int $fileId
*
*/
public function deleteCursor($fileId) {
return $this->bookmarkService->deleteCursor($fileId);
}
}

View file

@ -0,0 +1,80 @@
<?php
/**
* @author Frank de Lange
* @copyright 2017 Frank de Lange
*
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace OCA\Files_Reader\Controller;
use OCP\IRequest;
use OCP\AppFramework\Controller;
use OCA\Files_Reader\Service\MetadataService;
class MetadataController extends Controller {
private $metadataService;
/**
* @param string $AppName
* @param IRequest $request
* @param MetadataService $metadataService
*/
public function __construct($AppName,
IRequest $request,
MetadataService $metadataService ) {
parent::__construct($AppName, $request);
$this->metadataService = $metadataService;
}
/**
* @brief write metadata
*
* @NoAdminRequired
*
* @param int $fileId
* @param string $value
*
* @return array|\OCP\AppFramework\Http\JSONResponse
*/
public function setAll($fileId, $value) {
return $this->metadataService->setAll($fileId, $value);
}
/**
* @brief return metadata item
*
* @NoAdminRequired
* @NoCSRFRequired
*
* @param int $fileId
* @param string $name
*
* @return array|\OCP\AppFramework\Http\JSONResponse
*/
public function get($fileId, $name) {
return $this->metadataService->get($fileId, $name);
}
/**
* @brief write metadata item
*
* @NoAdminRequired
*
* @param int $fileId
* @param string $name
* @param string $value
*
* @return array|\OCP\AppFramework\Http\JSONResponse
*/
public function set($fileId, $name, $value) {
return $this->metadataService->set($fileId, $name, $value);
}
}

View file

@ -0,0 +1,177 @@
<?php
/**
* @author Frank de Lange
* @copyright 2015 Frank de Lange
*
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace OCA\Files_Reader\Controller;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\AppFramework\Http\ContentSecurityPolicy;
use OCP\IRequest;
use OCP\IURLGenerator;
use OCP\Files\IRootFolder;
use OCP\Share\IManager;
use OCP\Files\FileInfo;
use OCP\Files\NotFoundException;
use OCA\Files_Reader\Service\BookmarkService;
use OCA\Files_Reader\Service\MetadataService;
use OCA\Files_Reader\Service\PreferenceService;
class PageController extends Controller {
/** @var IURLGenerator */
private $urlGenerator;
/** @var IRootFolder */
private $rootFolder;
private $shareManager;
private $userId;
private $bookmarkService;
private $metadataService;
private $preferenceService;
/**
* @param string $AppName
* @param IRequest $request
* @param IURLGenerator $urlGenerator
* @param IRootFolder $rootFolder
* @param IManager $shareManager
* @param string $UserId
* @param BookmarkService $bookmarkService
* @param PreferenceService $preferenceService
* @param MetadataService $metadataService
*/
public function __construct(
$AppName,
IRequest $request,
IURLGenerator $urlGenerator,
IRootFolder $rootFolder,
IManager $shareManager,
$UserId,
BookmarkService $bookmarkService,
PreferenceService $preferenceService,
MetadataService $metadataService) {
parent::__construct($AppName, $request);
$this->urlGenerator = $urlGenerator;
$this->rootFolder = $rootFolder;
$this->shareManager = $shareManager;
$this->userId = $UserId;
$this->bookmarkService = $bookmarkService;
$this->metadataService = $metadataService;
$this->preferenceService = $preferenceService;
}
/**
* @PublicPage
* @NoCSRFRequired
*
* @return TemplateResponse
*/
public function showReader() {
$templates= [
'epub' => 'epubreader',
'pdf' => 'pdfreader',
'cbx' => 'cbreader'
];
/**
* $fileInfo = [
* fileId => null,
* fileName => null,
* fileType => null
* ];
*/
$fileInfo = $this->getFileInfo($this->request->get['file']);
$fileId = $fileInfo['fileId'];
$type = $this->request->get["type"];
$scope = $template = $templates[$type];
$params = [
'urlGenerator' => $this->urlGenerator,
'downloadLink' => $this->request->get['file'],
'scope' => $scope,
'fileId' => $fileInfo['fileId'],
'fileName' => $fileInfo['fileName'],
'fileType' => $fileInfo['fileType'],
'cursor' => $this->toJson($this->bookmarkService->getCursor($fileId)),
'defaults' => $this->toJson($this->preferenceService->getDefault($scope)),
'preferences' => $this->toJson($this->preferenceService->get($scope, $fileId)),
'defaults' => $this->toJson($this->preferenceService->getDefault($scope)),
'metadata' => $this->toJson($this->metadataService->get($fileId)),
'annotations' => $this->toJson($this->bookmarkService->get($fileId))
];
$policy = new ContentSecurityPolicy();
$policy->addAllowedStyleDomain('\'self\'');
$policy->addAllowedStyleDomain('blob:');
$policy->addAllowedScriptDomain('\'self\'');
$policy->addAllowedFrameDomain('\'self\'');
$policy->addAllowedChildSrcDomain('\'self\'');
$policy->addAllowedFontDomain('\'self\'');
$policy->addAllowedFontDomain('data:');
$policy->addAllowedFontDomain('blob:');
$policy->addAllowedImageDomain('blob:');
$response = new TemplateResponse($this->appName, $template, $params, 'blank');
$response->setContentSecurityPolicy($policy);
return $response;
}
/**
* @brief sharing-aware file info retriever
*
* Work around the differences between normal and shared file access
* (this should be abstracted away in OC/NC IMnsHO)
*
* @param string $path path-fragment from url
* @return array
* @throws NotFoundException
*/
private function getFileInfo($path) {
$count = 0;
$shareToken = preg_replace("/(?:\/index\.php)?\/s\/([A-Za-z0-9]{15,32})\/download.*/", "$1", $path, 1,$count);
if ($count === 1) {
/* shared file or directory */
$node = $this->shareManager->getShareByToken($shareToken)->getNode();
$type = $node->getType();
/* shared directory, need file path to continue, */
if ($type == \OCP\Files\FileInfo::TYPE_FOLDER) {
$query = [];
parse_str(parse_url($path, PHP_URL_QUERY), $query);
if (isset($query['path']) && isset($query['files'])) {
$node = $node->get($query['path'])->get($query['files']);
} else {
throw new NotFoundException('Shared file path or name not set');
}
}
$filePath = $node->getPath();
$fileId = $node->getId();
} else {
$filePath = $path;
$fileId = $this->rootFolder->getUserFolder($this->userId)
->get(preg_replace("/.*\/remote.php\/webdav(.*)/", "$1", rawurldecode($this->request->get['file'])))
->getFileInfo()
->getId();
}
return [
'fileName' => pathInfo($filePath, PATHINFO_FILENAME),
'fileType' => strtolower(pathInfo($filePath, PATHINFO_EXTENSION)),
'fileId' => $fileId
];
}
private function toJson($value) {
return htmlspecialchars(json_encode($value), ENT_QUOTES, 'UTF-8');
}
}

View file

@ -0,0 +1,128 @@
<?php
/**
* @author Frank de Lange
* @copyright 2017 Frank de Lange
*
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace OCA\Files_Reader\Controller;
use OCP\IRequest;
use OCP\IURLGenerator;
use OCP\AppFramework\Http;
use OCP\AppFramework\Controller;
use OCA\Files_Reader\Service\PreferenceService;
class PreferenceController extends Controller {
private $urlGenerator;
private $preferenceService;
/**
* @param string $AppName
* @param IRequest $request
* @param IURLGenerator $urlGenerator
* @param PreferenceService $preferenceService
*/
public function __construct($AppName,
IRequest $request,
IURLGenerator $urlGenerator,
PreferenceService $preferenceService ) {
parent::__construct($AppName, $request);
$this->urlGenerator = $urlGenerator;
$this->preferenceService = $preferenceService;
}
/**
* @brief return preference for $fileId
*
* @NoAdminRequired
* @NoCSRFRequired
*
* @param string $scope
* @param int $fileId
* @param string $name if null, return all preferences for $scope + $fileId
*
* @return array|\OCP\AppFramework\Http\JSONResponse
*/
public function get($scope, $fileId, $name) {
return $this->preferenceService->get($scope, $fileId, $name);
}
/**
* @brief write preference for $fileId
*
* @NoAdminRequired
* @NoCSRFRequired
*
* @param string $scope
* @param int $fileId
* @param string $name
* @param string $value
*
* @return array|\OCP\AppFramework\Http\JSONResponse
*/
public function set($scope, $fileId, $name, $value) {
return $this->preferenceService->set($scope, $fileId, $name, $value);
}
/**
* @brief return default preference
*
* @NoAdminRequired
* @NoCSRFRequired
*
* @param string $scope
* @param string $name if null, return all default preferences for scope
*
* @return array|\OCP\AppFramework\Http\JSONResponse
*/
public function getDefault($scope, $name) {
return $this->preferenceService->getDefault($scope, $name);
}
/**
* @brief write default preference
*
* @NoAdminRequired
* @NoCSRFRequired
*
* @param string $scope
* @param string $name
* @param string $value
*
* @return array|\OCP\AppFramework\Http\JSONResponse
*/
public function setDefault($scope, $name, $value) {
return $this->preferenceService->setDefault($scope, $name, $value);
}
/**
* @brief delete preference
*
* @param string $scope
* @param int $fileId
* @param string $name
*
*/
public function delete($scope, $fileId, $name) {
return $this->preferenceService->delete($scope, $fileId, $name);
}
/**
* @brief delete default preference
*
* @param $scope
* @param $name
*
*/
public function deleteDefault($scope, $name) {
return $this->preferenceService->deleteDefault($scope, $name);
}
}

View file

@ -0,0 +1,60 @@
<?php
declare(strict_types=1);
/**
* @author Frank de Lange
* @copyright 2022 Frank de Lange
*
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace OCA\Files_Reader\Controller;
use OCA\Files_Reader\AppInfo\Application;
use OCP\IL10N;
use OCP\IConfig;
use OCP\IRequest;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\DataResponse;
class SettingsController extends Controller {
protected IConfig $config;
protected Il10n $l10n;
protected string $userId;
public function __construct(
IRequest $request,
IConfig $config,
string $userId,
IL10N $l10n) {
parent::__construct(Application::APP_ID, $request);
$this->config = $config;
$this->userId = $userId;
$this->l10n = $l10n;
}
public function personal(string $epub_enable, string $pdf_enable, string $cbx_enable) {
$this->config->setUserValue(
$this->userId, Application::APP_ID, 'epub_enable', $epub_enable
);
$this->config->setUserValue(
$this->userId, Application::APP_ID, 'pdf_enable', $pdf_enable
);
$this->config->setUserValue(
$this->userId, Application::APP_ID, 'cbx_enable', $cbx_enable
);
return new DataResponse([
'data' => [
'message' => $this->l10n->t('Your settings have been updated.'),
],
]);
}
}

48
lib/Db/Bookmark.php Normal file
View file

@ -0,0 +1,48 @@
<?php
/**
* @author Frank de Lange
* @copyright 2015 Frank de Lange
*
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace OCA\Files_Reader\Db;
use OCP\AppFramework\Db\Entity;
class Bookmark extends ReaderEntity implements \JsonSerializable {
protected $userId; // user
protected $fileId; // book (identified by fileId) for which this mark is valid
protected $type; // type, defaults to "bookmark"
protected $name; // name, defaults to $location
protected $value; // bookmark value (format-specific, eg. page number for PDF, CFI for epub, etc)
protected $content; // bookmark content (annotations etc), can be empty
protected $lastModified; // modification timestamp
public function jsonSerialize() {
return [
'id' => $this->getId(),
'userId' => $this->getUserId(),
'fileId' => $this->getFileId(),
'type' => $this->getType(),
'name' => $this->getName(),
'value' => static::conditional_json_decode($this->getValue()),
'content' => static::conditional_json_decode($this->getContent()),
'lastModified' => $this->getLastModified()
];
}
public function toService() {
return [
'name' => $this->getName(),
'type' => $this->getType(),
'value' => $this->conditional_json_decode($this->getValue()),
'content' => $this->conditional_json_decode($this->getContent()),
'lastModified' => $this->getLastModified(),
];
}
}

121
lib/Db/BookmarkMapper.php Normal file
View file

@ -0,0 +1,121 @@
<?php
/**
* @author Frank de Lange
* @copyright 2017 Frank de Lange
*
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace OCA\Files_Reader\Db;
use OCP\IDBConnection;
use OCA\Files_Reader\Utility\Time;
class BookmarkMapper extends ReaderMapper {
private $userId;
/**
* @param IDbConnection $db
* @param $UserId
* @param Time $time
*/
public function __construct(IDBConnection $db, $UserId, Time $time) {
parent::__construct($db, 'reader_bookmarks', Bookmark::class, $time);
/** @var int $UserId */
$this->userId = $UserId;
}
/**
* @brief get bookmarks for $fileId+$userId(+$name)
* @param $fileId
* @param string $name
* @return array
*/
public function get($fileId, $name, $type=null) {
$sql = "SELECT * FROM `*PREFIX*reader_bookmarks` WHERE file_id=? AND `user_id`=?";
$args = [ $fileId, $this->userId ];
if (!(null === $type)) {
$sql .= " AND `type`=?";
$args[] = $type;
}
if (!(null === $name)) {
$sql .= " AND `name`=?";
$args[] = $name;
}
return $this->findEntities($sql, $args);
}
/**
* @brief write bookmark to database
*
* @param int $fileId
* @param string $name
* @param string $value
*
* @return Bookmark the newly created or updated bookmark
*/
public function set($fileId, $name, $value, $type, $content=null) {
$result = $this->get($fileId, $name);
if(empty($result)) {
// anonymous bookmarks are named after their contents
if (null === $name) {
$name = $value;
}
// default type is "bookmark"
if (null === $type) {
$type = "bookmark";
}
$bookmark = new Bookmark();
$bookmark->setFileId($fileId);
$bookmark->setUserId($this->userId);
$bookmark->setType($type);
$bookmark->setName($name);
$bookmark->setValue($value);
$bookmark->setContent($content);
$this->insert($bookmark);
} else {
$bookmark = $result[0];
$bookmark->setValue($value);
$bookmark->setContent($content);
$this->update($bookmark);
}
return $bookmark;
}
/* currently not used */
public function deleteForFileId($fileId) {
$sql = "SELECT * FROM `*PREFIX*reader_bookmarks` WHERE file_id=?";
$args = [ $fileId ];
array_map(
function($entity) {
$this->delete($entity);
}, $this->findEntities($sql, $args)
);
}
/* currently not used */
public function deleteForUserId($userId) {
$sql = "SELECT * FROM `*PREFIX*reader_bookmarks` WHERE user_id=?";
$args = [ $userId ];
array_map(
function($entity) {
$this->delete($entity);
}, $this->findEntities($sql, $args)
);
}
}

42
lib/Db/Preference.php Normal file
View file

@ -0,0 +1,42 @@
<?php
/**
* @author Frank de Lange
* @copyright 2015 Frank de Lange
*
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace OCA\Files_Reader\Db;
use OCP\AppFramework\Db\Entity;
class Preference extends ReaderEntity implements \JsonSerializable {
protected $userId; // user for whom this preference is valid
protected $scope; // scope (default or specific renderer)
protected $fileId; // file for which this preference is set
protected $name; // preference name
protected $value; // preference value
protected $lastModified; // modification timestamp
public function jsonSerialize() {
return [
'id' => $this->getId(),
'scope' => $this->getScope(),
'fileId' => $this->getFileId(),
'name' => $this->getName(),
'value' => $this->conditional_json_decode($this->getValue()),
'lastModified' => $this->getLastModified(),
];
}
public function toService() {
return [
'name' => $this->getName(),
'value' => $this->conditional_json_decode($this->getValue()),
];
}
}

105
lib/Db/PreferenceMapper.php Normal file
View file

@ -0,0 +1,105 @@
<?php
/**
* @author Frank de Lange
* @copyright 2017 Frank de Lange
*
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace OCA\Files_Reader\Db;
use OCA\Files_Reader\Utility\Time;
use OCP\IDBConnection;
class PreferenceMapper extends ReaderMapper {
public function __construct(IDBConnection $db, $UserId, Time $time) {
parent::__construct($db, 'reader_preferences', Preference::class, $time);
$this->userId = $UserId;
}
/**
* @brief get preferences for $scope+$fileId+$userId(+$name)
*
* @param string $scope
* @param int $fileId
* @param string $name
* @return array
*/
public function get($scope, $fileId, $name=null) {
if(!empty($name)) {
$sql = "SELECT * FROM `*PREFIX*reader_preferences` WHERE `scope`=? AND `file_id`=? AND `user_id`=? AND `name`=?";
$args = array(
$scope,
$fileId,
$this->userId,
$name);
} else {
$sql = "SELECT * FROM `*PREFIX*reader_preferences` WHERE `scope`=? AND `file_id`=? AND `user_id`=?";
$args = array(
$scope,
$fileId,
$this->userId);
}
return $this->findEntities($sql, $args);
}
/**
* @brief write preference to database
*
* @param string $scope
* @param int $fileId
* @param string $name
* @param string $value
*
* @return Preference the newly created or updated preference
*/
public function set($scope, $fileId, $name, $value) {
$result = $this->get($scope, $fileId, $name);
if(empty($result)) {
$preference = new Preference();
$preference->setScope($scope);
$preference->setFileId($fileId);
$preference->setUserId($this->userId);
$preference->setName($name);
$preference->setValue($value);
$this->insert($preference);
} else {
$preference = $result[0];
$preference->setValue($value);
$this->update($preference);
}
return $preference;
}
/* currently not used*/
public function deleteForFileId($fileId) {
$sql = "SELECT * FROM `*PREFIX*reader_preferences` WHERE file_id=?";
$args = [ $fileId ];
array_map(
function($entity) {
$this->delete($entity);
}, $this->findEntities($sql, $args)
);
}
/* currently not used*/
public function deleteForUserId($userId) {
$sql = "SELECT * FROM `*PREFIX*reader_preferences` WHERE user_id=?";
$args = [ $userId ];
array_map(
function($entity) {
$this->delete($entity);
}, $this->findEntities($sql, $args)
);
}
}

39
lib/Db/ReaderEntity.php Normal file
View file

@ -0,0 +1,39 @@
<?php
/**
* @author Frank de Lange
* @copyright 2015 Frank de Lange
*
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace OCA\Files_Reader\Db;
use OCP\AppFramework\Db\Entity;
class ReaderEntity extends Entity {
/* returns decoded json if input is json, otherwise returns input */
public static function conditional_json_decode($el) {
$result = json_decode($el);
if (json_last_error() === JSON_ERROR_NONE) {
return $result;
} else {
return $el;
}
}
/*
public function toService() {
return [
'name' => $this->getName(),
'type' => $this->getType(),
'value' => $this->conditional_json_decode($this->getValue()),
'content' => $this->conditional_json_decode($this->getContent()),
'lastModified' => $this->getLastModified(),
];
}
*/
}

40
lib/Db/ReaderMapper.php Normal file
View file

@ -0,0 +1,40 @@
<?php
/**
* @author Frank de Lange
* @copyright 2017 Frank de Lange
*
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace OCA\Files_Reader\Db;
use OCP\IDBConnection;
use OCP\AppFramework\Db\Mapper;
use OCP\AppFramework\Db\Entity;
use OCA\Files_Reader\Utility\Time;
abstract class ReaderMapper extends Mapper {
/**
* @var Time
*/
private $time;
public function __construct(IDBConnection $db, $table, $entity, Time $time) {
parent::__construct($db, $table, $entity);
$this->time = $time;
}
public function update(Entity $entity) {
$entity->setLastModified($this->time->getMicroTime());
return parent::update($entity);
}
public function insert(Entity $entity) {
$entity->setLastModified($this->time->getMicroTime());
return parent::insert($entity);
}
}

49
lib/Hooks.php Normal file
View file

@ -0,0 +1,49 @@
<?php
/**
* @author Frank de Lange
* @copyright 2017 Frank de Lange
*
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace OCA\Files_Reader;
use OCP\IDBConnection;
class Hooks {
public static function register() {
\OC::$server->getRootFolder()->listen('\OC\Files', 'preDelete', function (Node $node) {
$fileId = $node->getId();
$connection = \OC::$server->getDatabaseConnection();
self::deleteFile($connection, $fileId);
});
\OC::$server->getUserManager()->listen('\OC\User', 'preDelete', function (User $user) {
$userId = $user->getUID();
$connection = \OC::$server->getDatabaseConnection();
self::deleteUser($connection, $userId);
});
}
protected static function deleteFile(IDBConnection $connection, $fileId) {
$queryBuilder = $connection->getQueryBuilder();
$queryBuilder->delete('reader_bookmarks')->where('file_id = :file_id')->setParameter(':file_id', $fileId);
$queryBuilder->execute();
$queryBuilder = $connection->getQueryBuilder();
$queryBuilder->delete('reader_preferences')->where('file_id = :file_id')->setParameter(':file_id', $fileId);
$queryBuilder->execute();
}
protected static function deleteUser(IDBConnection $connection, $userId) {
$queryBuilder = $connection->getQueryBuilder();
$queryBuilder->delete('reader_bookmarks')->where('user_id = :user_id')->setParameter(':user_id', $userId);
$queryBuilder->execute();
$queryBuilder = $connection->getQueryBuilder();
$queryBuilder->delete('reader_preferences')->where('user_id = :user_id')->setParameter(':user_id', $userId);
$queryBuilder->execute();
}
}

View file

@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
/**
* @author Frank de Lange
* @copyright 2022 Frank de Lange
*
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace OCA\Files_Reader\Listeners;
use OCP\AppFramework\Http\EmptyContentSecurityPolicy;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
use OCP\Security\CSP\AddContentSecurityPolicyEvent;
class CSPListener implements IEventListener {
public function handle(Event $event): void {
if (!$event instanceof AddContentSecurityPolicyEvent) {
return;
}
$csp = new EmptyContentSecurityPolicy();
$csp->addAllowedFrameDomain('\'self\'');
$event->addPolicy($csp);
}
}

View file

@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
/**
* @author Frank de Lange
* @copyright 2022 Frank de Lange
*
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace OCA\Files_Reader\Listeners;
use OCA\Files_Reader\AppInfo\Application;
use OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\AppFramework\Services\IInitialState;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
use OCP\Util;
class LoadPublicViewerListener implements IEventListener {
private IInitialState $initialStateService;
public function __construct(
IInitialState $initialStateService,
) {
$this->initialStateService = $initialStateService;
}
public function handle(Event $event): void {
if (!$event instanceof BeforeTemplateRenderedEvent) {
return;
}
// Make sure we are on a public page rendering
if ($event->getResponse()->getRenderAs() !== TemplateResponse::RENDER_AS_PUBLIC) {
return;
}
$this->initialStateService->provideInitialState('epub_enabled', 'true');
$this->initialStateService->provideInitialState('pdf_enabled', 'true');
$this->initialStateService->provideInitialState('cbx_enabled', 'true');
Util::addScript(Application::APP_ID, 'plugin-public');
}
}

View file

@ -0,0 +1,51 @@
<?php
declare(strict_types=1);
/**
* @author Frank de Lange
* @copyright 2022 Frank de Lange
*
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace OCA\Files_Reader\Listeners;
use OCA\Files_Reader\AppInfo\Application;
use OCA\Viewer\Event\LoadViewer;
use OCP\AppFramework\Services\IInitialState;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
use OCP\Util;
use OCP\IConfig;
use OCP\IUserSession;
class LoadViewerListener implements IEventListener {
private IInitialState $initialStateService;
private IConfig $config;
private string $userId;
public function __construct(
IInitialState $initialStateService,
IConfig $config,
string $userId
) {
$this->initialStateService = $initialStateService;
$this->config = $config;
$this->userId = $userId;
}
public function handle(Event $event): void {
if (!($event instanceof LoadViewer || $event instanceof LoadAdditionalScriptsEvent)) {
return;
}
$this->initialStateService->provideInitialState('epub_enabled', $this->config->getUserValue($this->userId, Application::APP_ID, 'epub_enable'));
$this->initialStateService->provideInitialState('pdf_enabled', $this->config->getUserValue($this->userId, Application::APP_ID, 'pdf_enable'));
$this->initialStateService->provideInitialState('cbx_enabled', $this->config->getUserValue($this->userId, Application::APP_ID, 'cbx_enable'));
Util::addScript(Application::APP_ID, 'plugin');
}
}

View file

@ -0,0 +1,143 @@
<?php
declare(strict_types=1);
namespace OCA\Files_Reader\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
/**
* Auto-generated migration step
*/
class Version013000Date202209191710407 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
*/
public function preSchemaChange(IOutput $output, Closure $schemaClosure, array $options) {
}
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
if (!$schema->hasTable('reader_bookmarks')) {
$table = $schema->createTable('reader_bookmarks');
$table->addColumn('id', 'bigint', [
'autoincrement' => true,
'notnull' => true,
'length' => 8,
'unsigned' => true,
]);
// user ID, maps bookmark to NC/OC user
$table->addColumn('user_id', 'string', [
'notnull' => true,
'length' => 64,
'default' => '',
]);
// file ID, maps to NC/OC file ID
$table->addColumn('file_id', 'bigint', [
'notnull' => true,
'length' => 11,
'unsigned' => true,
]);
// type (bookmark, annotation, etc)
$table->addColumn('type', 'string', [
'notnull' => true,
'length' => 32,
'default' => '',
]);
$table->addColumn('name', 'string', [
'notnull' => true,
'length' => 512,
'default' => '',
]);
$table->addColumn('value', 'string', [
'notnull' => true,
'length' => 512,
'default' => '',
]);
$table->addColumn('content', 'string', [
'notnull' => false,
'length' => 4096,
]);
$table->addColumn('last_modified', 'bigint', [
'notnull' => false,
'length' => 8,
'default' => 0,
'unsigned' => true,
]);
$table->setPrimaryKey(['id']);
$table->addIndex(['file_id'], 'reader_bookmarks_file_id_index');
$table->addIndex(['user_id'], 'reader_bookmarks_user_id_index');
$table->addIndex(['name'], 'reader_bookmarks_name_index');
}
if (!$schema->hasTable('reader_prefs')) {
$table = $schema->createTable('reader_prefs');
$table->addColumn('id', 'bigint', [
'autoincrement' => true,
'notnull' => true,
'length' => 8,
'unsigned' => true,
]);
// user ID, maps preference to NC/OC user
$table->addColumn('user_id', 'string', [
'notnull' => true,
'length' => 64,
'default' => '',
]);
// file ID, maps to NC/OC file ID
$table->addColumn('file_id', 'bigint', [
'notnull' => true,
'length' => 11,
'unsigned' => true,
]);
$table->addColumn('scope', 'string', [
'notnull' => true,
'length' => 32,
'default' => '',
]);
$table->addColumn('name', 'string', [
'notnull' => true,
'length' => 128,
'default' => '',
]);
$table->addColumn('value', 'string', [
'notnull' => true,
'length' => 4096,
'default' => '',
]);
$table->addColumn('last_modified', 'bigint', [
'notnull' => false,
'length' => 8,
'default' => 0,
'unsigned' => true,
]);
$table->setPrimaryKey(['id']);
$table->addIndex(['file_id'], 'reader_prefs_file_id_index');
$table->addIndex(['user_id'], 'reader_prefs_user_id_index');
$table->addIndex(['scope'], 'reader_prefs_scope_index');
}
return $schema;
}
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
*/
public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options) {
}
}

View file

@ -0,0 +1,113 @@
<?php
/**
* @author Frank de Lange
* @copyright 2017 Frank de Lange
*
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace OCA\Files_Reader\Service;
use OCA\Files_Reader\Db\BookmarkMapper;
class BookmarkService extends Service {
// "bookmark" name to use for the cursor (current reading position)
const CURSOR = '__CURSOR__';
const bookmark_type = 'bookmark';
private $bookmarkMapper;
private $userId;
public function __construct(BookmarkMapper $bookmarkMapper, $UserId) {
parent::__construct($bookmarkMapper);
$this->bookmarkMapper = $bookmarkMapper;
$this->userId = $UserId;
}
/**
* @brief get bookmark
*
* bookmark type is format-dependent, eg CFI for epub, page number for CBR/CBZ, etc
*
* @param int $fileId
* @param string $name
*
* @return array
*/
public function get($fileId, $name=null, $type=null) {
$result = $this->bookmarkMapper->get($fileId, $name, $type);
return array_map(
function($entity) {
return $entity->toService();
}, $result);
}
/**
* @brief write bookmark
*
* position type is format-dependent, eg CFI for epub, page number for CBR/CBZ, etc
*
* @param int $fileId
* @param string $name
* @param string $value
*
* @return array
*/
public function set($fileId, $name, $value, $type=null, $content=null) {
return $this->bookmarkMapper->set($fileId, $name, $value, $type, $content);
}
/**
* @brief get cursor (current position in book)
*
* @param int $fileId
*
* @return array
*/
public function getCursor($fileId) {
$result = $this->get($fileId, static::CURSOR);
if (count($result) === 1) {
return $result[0];
}
}
/**
* @brief set cursor (current position in book)
*
* @param int $fileId
* @param string $value
*
* @return array
*/
public function setCursor($fileId, $value) {
return $this->bookmarkMapper->set($fileId, static::CURSOR, $value, static::bookmark_type);
}
/**
* @brief delete bookmark
*
* @param int $fileId
* @param string $name
*
*/
public function delete($fileId, $name, $type=null) {
foreach ($this->bookmarkMapper->get($fileId, $name, $type) as $bookmark) {
$this->bookmarkMapper->delete($bookmark);
}
}
/**
* @brief delete cursor
*
* @param int $fileId
*
*/
public function deleteCursor($fileId) {
$this->delete($fileId, static::CURSOR, static::bookmark_type);
}
}

View file

@ -0,0 +1,75 @@
<?php
/**
* @author Frank de Lange
* @copyright 2017 Frank de Lange
*
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace OCA\Files_Reader\Service;
use OCP\App\IAppManager;
class MetadataService {
private $appManager;
/**
* @param IAppManager $appManager
*/
public function __construct(IAppManager $appManager) {
$this->appManager = $appManager;
}
/**
* @brief get metadata item(s)
*
* @param int $fileId
* @param string $name
*
* @return array
*/
public function get($fileId, $name=null) {
if ($this->appManager->isInstalled('files_opds')) {
if ($meta = \OCA\Files_Opds\Meta::get($fileId)) {
if (!empty($name) && array_key_exists($name, $meta)) {
return [$item => $meta[$name]];
} else {
return $meta;
}
}
}
return [];
}
/**
* @brief write metadata to database
*
* @param int $fileId
* @param array $value
*
* @return array
*/
public function setAll($fileId, $value) {
// no-op for now
return [];
}
/**
* @brief write metadata item to database
*
* @param int $fileId
* @param string $name
* @param array $value
*
* @return array
*/
public function set($fileId, $name, $value) {
// no-op for now
return [];
}
}

View file

@ -0,0 +1,117 @@
<?php
/**
* @author Frank de Lange
* @copyright 2017 Frank de Lange
*
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace OCA\Files_Reader\Service;
use OCA\Files_Reader\Db\PreferenceMapper;
class PreferenceService extends Service {
// (ab)use the fact that $fileId never goes below 1 by using the
// value 0 to indicate a default preference
const DEFAULTS = 0;
private $preferenceMapper;
/**
* @param PreferenceMapper $preferenceMapper
*/
public function __construct(PreferenceMapper $preferenceMapper) {
parent::__construct($preferenceMapper);
$this->preferenceMapper = $preferenceMapper;
}
/**
* @brief get preference
*
* scope identifies preference source, i.e. which renderer the preference applies to
* preference type is format-dependent, eg CFI for epub, page number for CBR/CBZ, etc
*
* @param string $scope
* @param int $fileId
* @param string $name
*
* @return array
*/
public function get($scope, $fileId, $name=null) {
$result = $this->preferenceMapper->get($scope, $fileId, $name);
return array_map(
function($entity) {
return $entity->toService();
}, $result);
}
/**
* @brief write preference
*
* scope identifies preference source, i.e. which renderer the preference applies to
* position type is format-dependent, eg CFI for epub, page number for CBR/CBZ, etc
*
* @param string $scope
* @param int $fileId
* @param string $name
* @param string $value
*
* @return array
*/
public function set($scope, $fileId, $name, $value) {
return $this->preferenceMapper->set($scope, $fileId, $name, $value);
}
/**
* @brief get default preference
*
* @param string $scope
* @param string $name
*
* @return array
*/
public function getDefault($scope, $name=null) {
return $this->get($scope, static::DEFAULTS, $name);
}
/**
* @brief set default preference
*
* @param string $scope
* @param string $name
* @param string $value
*
* @return array
*/
public function setDefault($scope, $name, $value) {
return $this->preferenceMapper->set($scope, static::DEFAULTS, $name, $value);
}
/**
* @brief delete preference
*
* @param string $scope
* @param int $fileId
* @param string $name
*
*/
public function delete($scope, $fileId, $name) {
foreach($this->preferenceMapper->get($scope, $fileId, $name) as $preference) {
$this->preferenceMapper->delete($preference);
}
}
/**
* @brief delete default
*
* @param string $scope
* @param string $name
*
*/
public function deleteDefault($scope, $name) {
$this->delete($scope, static::DEFAULTS, $name);
}
}

25
lib/Service/Service.php Normal file
View file

@ -0,0 +1,25 @@
<?php
/**
* @author Frank de Lange
* @copyright 2017 Frank de Lange
*
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace OCA\Files_Reader\Service;
use OCA\Files_Reader\Db\ReaderMapper;
abstract class Service {
protected $mapper;
public function __construct(ReaderMapper $mapper){
$this->mapper = $mapper;
}
}

48
lib/Settings/Personal.php Normal file
View file

@ -0,0 +1,48 @@
<?php
declare(strict_types=1);
/**
* @author Frank de Lange
* @copyright 2022 Frank de Lange
*
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace OCA\Files_Reader\Settings;
use OCA\Files_Reader\AppInfo\Application;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\IUserSession;
use OCP\IConfig;
use OCP\Settings\ISettings;
class Personal implements ISettings {
private IConfig $config;
private string $userId;
public function __construct(IConfig $config, string $userId) {
$this->config = $config;
$this->userId = $userId;
}
public function getForm(): TemplateResponse {
$parameters = [
'epub_enable' => $this->config->getUserValue($this->userId, Application::APP_ID, 'epub_enable', 'false'),
'pdf_enable' => $this->config->getUserValue($this->userId, Application::APP_ID, 'pdf_enable', 'false'),
'cbx_enable' => $this->config->getUserValue($this->userId, Application::APP_ID, 'cbx_enable', 'false')
];
return new TemplateResponse(Application::APP_ID, 'personal', $parameters);
}
public function getSection(): string {
return 'additional';
}
public function getPriority(): int {
return 90;
}
}

27
lib/Utility/Time.php Normal file
View file

@ -0,0 +1,27 @@
<?php
/**
* @author Frank de Lange
* @copyright 2017 Frank de Lange
*
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace OCA\Files_Reader\Utility;
class Time {
public function getTime() {
return time();
}
/**
*
* @return int the current unix time in miliseconds
*/
public function getMicroTime() {
list($millisecs, $secs) = explode(" ", microtime());
return $secs . substr($millisecs, 2, 6);
}
}

233
templates/cbreader.php Normal file
View file

@ -0,0 +1,233 @@
<?php
$urlGenerator = $_['urlGenerator'];
$downloadLink = $_['downloadLink'];
$fileId = $_['fileId'];
$fileName = $_['fileName'];
$fileType = $_['fileType'];
$scope = $_['scope'];
$cursor = $_['cursor'];
$defaults = $_['defaults'];
$preferences = $_['preferences'];
$metadata = $_['metadata'];
$annotations = $_['annotations'];
$title = htmlentities(basename($downloadLink));
$revision = '0049';
$version = \OC::$server->getAppManager()->getAppVersion('files_reader') . '.' . $revision;
/* Mobile safari, the new IE6 */
$idevice = (strstr($_SERVER['HTTP_USER_AGENT'],'iPhone')
|| strstr($_SERVER['HTTP_USER_AGENT'],'iPad')
|| strstr($_SERVER['HTTP_USER_AGENT'],'iPod'));
$nonce = \OC::$server->getContentSecurityPolicyNonceManager()->getNonce();
?>
<html dir="ltr">
<head class="session" data-nonce='<?php p($nonce);?>' data-downloadlink='<?php print_unescaped($downloadLink);?>' data-fileid='<?php print_unescaped($fileId);?>' data-filetype='<?php print_unescaped($fileType);?>' data-filename='<?php print_unescaped($fileName);?>' data-version='<?php print_unescaped($version);?>' data-basepath='<?php p($urlGenerator->linkTo("files_reader",""));?>' data-scope='<?php print_unescaped($scope);?>' data-cursor='<?php print_unescaped($cursor);?>' data-defaults='<?php print_unescaped($defaults);?>' data-preferences='<?php print_unescaped($preferences);?>' data-metadata='<?php print_unescaped($metadata);?>' data-annotations='<?php print_unescaped($annotations);?>'>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="apple-mobile-web-app-capable" content="yes">
<!-- <base href="<?php p($urlGenerator->linkTo('files_reader',''));?>"> -->
<title>
<?php p($title);?>
</title>
<link rel="shortcut icon" href="img/book.png">
<link rel="stylesheet" href="vendor/icomoon/style.css?v=<?php p($version) ?>">
<link rel="stylesheet" href="vendor/cbrjs/css/cbr.css?v=<?php p($version) ?>">
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'js/lib/Blob.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/epubjs/libs/jquery.min.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/sindresorhus/screenfull.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/pixastic/pixastic_combined.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/bitjs/archive/archive.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/cbrjs/cbr.js')) ?>?v=<?php p($version) ?>"> </script>
<?php if ($idevice): ?>
<link rel="stylesheet" href="<?php p($urlGenerator->linkTo('files_reader', 'vendor/cbrjs/css/idevice.css')) ?>?v=<?php p($version) ?>">
<?php endif; ?>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'js/ready.js')) ?>?v=<?php p($version) ?>"> </script>
</head>
<body>
<!-- data -->
<!-- /data -->
<!-- loading progressbar -->
<div id="progressbar" style="display:none;">
<span class="progress"><span class="bar"></span></span>
<br>
<div class="message"><span class="message-icons"><span class="icon-cloud_download"></span><span class="icon-unarchive"></span></span> <span class="message-text"></span></div>
</div>
<!-- /loading progressbar -->
<!-- toolbar -->
<div class="toolbar control" name="toolbar">
<div class="pull-left">
<button data-trigger="click" data-action="openSidebar" title="open sidebar" class="icon-menu"></button>
</div>
<div class="metainfo">
<span class="book-title"></span>&nbsp;<span class="current-page"></span> / <span class="page-count"></span>
</div>
<div class="pull-right">
<div>
<button data-trigger="click" data-action="toggleLayout" title="toggle one/two pages at a time" class="icon-single_page_mode layout layout-single"></button>
<button data-trigger="click" data-action="toggleLayout" title="toggle one/two pages at a time" class="icon-double_page_mode layout layout-double"></button>
</div>
<div>
<button data-trigger="click" data-action="zoomOut" title="zoom out" class="icon-zoom_out"></button>
</div>
<div>
<button data-trigger="click" data-action="zoomIn" title="zoom in" class="icon-zoom_in"></button>
</div>
<div>
<button data-trigger="click" data-action="fitWidth" title="fit page to window width" class="icon-icon-fit-width"></button>
</div>
<div>
<button data-trigger="click" data-action="fitWindow" title="fit page to window" class="icon-icon-fit-window"></button>
</div>
<div>
<button data-trigger="click" data-action="toggleReadingMode" title="switch reading direction" class="icon-format_textdirection_l_to_r manga-false"></button>
<button data-trigger="click" data-action="toggleReadingMode" title="switch reading direction" class="icon-format_textdirection_r_to_l manga-true"></button>
</div>
<div>
<button data-trigger="click" data-action="toggleFullscreen" title="toggle fullscreen" class="icon-fullscreen fullscreen-false"></button>
<button data-trigger="click" data-action="toggleFullscreen" title="toggle fullscreen" class="icon-fullscreen_exit fullscreen-true"></button>
</div>
<div class="hide close separator"></div>
<div class="hide close">
<button data-trigger="click" data-action="close" title="close" class="icon-exit"></button>
</div>
</div>
</div>
<!-- /toolbar -->
<!-- loading overlay -->
<div id="cbr-loading-overlay" class="cbr-control control overlay" name="loadingOverlay" style="display:none"></div>
<!-- /loading overlay -->
<!-- busy overlay -->
<div id="cbr-busy-overlay" class="cbr-control control overlay" name="busyOverlay" data-trigger="click" data-action="closeSidebar" style="display:none"></div>
<!-- /busy overlay -->
<!-- navigation -->
<div data-trigger="click" data-action="navigation" data-navigate-side="left" class="cbr-control navigate navigate-left control" name="navigateLeft">
<span class="icon-navigate_before"></span>
</div>
<!-- toggle toolbar (disabled)
<div data-trigger="click" data-action="toggleToolbar" class="toggle-controls control" name="toggleToolbar"></div>
-->
<div data-trigger="click" data-action="navigation" data-navigate-side="right" class="cbr-control navigate navigate-right control" name="navigateRight">
<span class="icon-navigate_next"></span>
</div>
<!-- /navigation -->
<!-- inline progressbar -->
<div id="cbr-status" class="cbr-control control" name="progressbar" style="display:none">
<div id="cbr-progress-bar">
<div class="progressbar-value"></div>
</div>
</div>
<!-- /inline progressbar -->
<!-- sidebar -->
<div class="sidebar control" name="sidebar" id="sidebar">
<div class="panels">
<div class="pull-left">
<button data-trigger="click" data-action="showToc" title="Table of Contents" class="icon-format_list_numbered toc-view open"></button>
<button data-trigger="click" data-action="showBookSettings" title="Book settings" class="icon-rate_review book-settings-view"></button>
<button data-trigger="click" data-action="showSettings" title="Default settings" class="icon-settings settings-view"></button>
</div>
<div class="pull-right">
<button id="toc-populate" data-trigger="click" data-action="tocPopulate" title="generate thumbnails" class="icon-sync" style="display:none"></button>
<button data-trigger="click" data-action="closeSidebar" title="close sidebar" class="icon-menu"></button>
</div>
</div>
<div class="toc-view view open">
<ul id="toc">
</ul>
</div>
<div class="book-settings-view view">
<div class="metadata">
<table>
<tr>
<td>Title:</td><td class="book-title"></td>
</tr>
<tr>
<td>Format:</td><td class="book-format"></td>
</tr>
<tr>
<td>Page count:</td><td class="book-pagecount"></td>
</tr>
<tr>
<td>Size:</td><td class="book-size"></td>
</tr>
</table>
</div>
<div class="settings-container" name="enhancements" id="enhancements">
<label for="enhancements">Image enhancements</label>
<form name="image-enhancements" data-trigger="reset" data-action="resetEnhancements">
<div class="sliders">
<div class="control-group">
<label title="adjust brightness" class="icon-brightness_low"></label>
<input id="brightness" data-trigger="change" data-action="brightness" type="range" min="-100" max="100" step="1" value="0">
</div>
<div class="control-group">
<label title="adjust contrast" class="icon-contrast"></label>
<input id="contrast" data-trigger="change" data-action="brightness" type="range" min="-1" max="1" step="0.1" value="0">
</div>
<div class="control-group">
<label title="sharpen" class="icon-droplet"></label>
<input id="sharpen" data-trigger="change" data-action="sharpen" type="range" min="0" max="1" step="0.1" value="0">
</div>
</div>
<div class="control-group pull-left">
<input id="image-desaturate" type="checkbox" data-trigger="change" data-action="desaturate">
<label for="image-desaturate">desaturate</label>
<input id="image-removenoise" type="checkbox" data-trigger="change" data-action="removenoise">
<label for="image-removenoise">remove noise</label>
</div>
<div class="control-group pull-right">
<input type="reset" value="reset">
</div>
</form>
</div>
</div>
<div class="settings-view view">
<div class="settings-container" name="thumbnail-settings" id="thumbnail-settings">
<label for="thumbnail-settings">Thumbnails</label>
<div class="control-group pull-left">
<input id="thumbnail-generate" data-trigger="change" data-action="thumbnails" type="checkbox">
<label for="thumbnail-generate">Thumbnails in index </label>
</div>
<div class="control-group pull-left">
<label for="thumbnail-width">Thumbnail width:</label>
<input id="thumbnail-width" data-trigger="change" data-action="thumbnailWidth" type="number" min="50" max="500" step="10" value="200" >
<label for="thumbnail-width">px</label>
</div>
</div>
<div class="settings-container" name="sidebar-settings" id="sidebar-settings">
<label for="sidebar-settings">Sidebar</label>
<form name="sidebar-preferences" data-trigger="reset" data-action="resetSidebar">
<div class="control-group pull-left">
<input id="sidebar-wide" data-trigger="change" data-action="sidebarWide" type="checkbox">
<label for="sidebar-wide">Use extra-wide sidebar</label>
</div>
<div class="control-group pull-left">
<label for="sidebar-width">Sidebar width:</label>
<input id="sidebar-width" data-trigger="change" data-action="sidebarWidth" type="number" min="5" max="100" step="1" value="20" >
<label for="sidebar-width">%</label>
</div>
<div class="control-group pull-right">
<input type="reset" value="reset">
</div>
</form>
</div>
</div>
</div>
<!-- /sidebar -->
<canvas id="viewer" style="display:none;"></canvas>
</body>
</html>

294
templates/epubreader.php Normal file
View file

@ -0,0 +1,294 @@
<?php
$urlGenerator = $_['urlGenerator'];
$downloadLink = $_['downloadLink'];
$fileId = $_['fileId'];
$fileName = $_['fileName'];
$fileType = $_['fileType'];
$scope = $_['scope'];
$cursor = $_['cursor'];
$defaults = $_['defaults'];
$preferences = $_['preferences'];
$metadata = $_['metadata'];
$annotations = $_['annotations'];
$title = htmlentities(basename($downloadLink));
$revision = '0073';
$version = \OC::$server->getAppManager()->getAppVersion('files_reader') . '.' . $revision;
/* Mobile safari, the new IE6 */
$idevice = (strstr($_SERVER['HTTP_USER_AGENT'],'iPhone')
|| strstr($_SERVER['HTTP_USER_AGENT'],'iPad')
|| strstr($_SERVER['HTTP_USER_AGENT'],'iPod'));
$nonce = \OC::$server->getContentSecurityPolicyNonceManager()->getNonce();
?>
<html dir="ltr">
<head class="session" data-nonce='<?php p($nonce);?>' data-downloadlink='<?php print_unescaped($downloadLink);?>' data-fileid='<?php print_unescaped($fileId);?>' data-filetype='<?php print_unescaped($fileType);?>' data-filename='<?php print_unescaped($fileName);?>' data-version='<?php print_unescaped($version);?>' data-basepath='<?php p($urlGenerator->linkTo("files_reader",""));?>' data-scope='<?php print_unescaped($scope);?>' data-cursor='<?php print_unescaped($cursor);?>' data-defaults='<?php print_unescaped($defaults);?>' data-preferences='<?php print_unescaped($preferences);?>' data-metadata='<?php print_unescaped($metadata);?>' data-annotations='<?php print_unescaped($annotations);?>'>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="apple-mobile-web-app-capable" content="yes">
<!-- <base href="<?php p($urlGenerator->linkTo('files_reader',''));?>"> -->
<title>
<?php p($title);?>
</title>
<link rel="shortcut icon" href="img/book.png">
<link rel="stylesheet" href="<?php p($urlGenerator->linkTo('files_reader', 'vendor/icomoon/style.css')) ?>?v=<?php p($version) ?>">
<link rel="stylesheet" href="<?php p($urlGenerator->linkTo('files_reader', 'vendor/epubjs/css/main.css')) ?>?v=<?php p($version) ?>">
<link rel="stylesheet" href="<?php p($urlGenerator->linkTo('files_reader', 'vendor/epubjs/css/sidebar.css')) ?>?v=<?php p($version) ?>">
<link rel="stylesheet" href="<?php p($urlGenerator->linkTo('files_reader', 'vendor/epubjs/css/popup.css')) ?>?v=<?php p($version) ?>">
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'js/lib/typedarray.min.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'js/lib/Blob.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'js/lib/wgxpath.install.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/epubjs/libs/jquery.min.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/bartaz/jquery.highlight.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/jquery/put-delete.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/sindresorhus/screenfull.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/epubjs/libs/zip.min.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/epubjs/epub.min.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/epubjs/hooks.min.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/epubjs/hooks/extensions/highlight.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/epubjs/reader.min.js')) ?>?v=<?php p($version) ?>"> </script>
<?php if ($idevice): ?>
<link rel="stylesheet" href="<?php p($urlGenerator->linkTo('files_reader', 'vendor/epubjs/css/idevice.css')) ?>?v=<?php p($version) ?>">
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/bgrins/spectrum.js')) ?>?v=<?php p($version) ?>"> </script>
<link rel="stylesheet" href="<?php p($urlGenerator->linkTo('files_reader', 'vendor/bgrins/spectrum.css')) ?>?v=<?php p($version) ?>">
<?php endif; ?>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'js/ready.js')) ?>?v=<?php p($version) ?>"> </script>
</head>
<body>
<div id="outerContainer">
<!-- sidebar -->
<div id="sidebar" class="sidebar">
<div id="panels" class="panels">
<div class="pull-left">
<button id="show-Toc" class="show_view icon-format_list_numbered open" title="Table of Contents" data-view="Toc"></button>
<button id="show-Bookmarks" class="show_view icon-turned_in" title="Bookmarks" data-view="Bookmarks"></button>
<button id="show-Search" class="show_view icon-search" title="Search" data-view="Search"></button>
<button id="show-Notes" class="show_view icon-comment" title="Notes" data-view="Notes"></button>
<button id="show-Settings" class="show_view icon-settings" title="Settings" data-view="Settings"></button>
</div>
<div class="pull-right">
<button id="hide-Sidebar" class="close_sidebar icon-arrow-left2" title="Close sidebar"></button>
</div>
</div>
<div id="views">
<div id="tocView" class="toc-view view open">
</div>
<div id="bookmarksView" class="bookmarks-view view">
<ul id="bookmarks" class="bookmarks">
</ul>
</div>
<div id="searchView" class="view search-view">
<div>
<div class="search-input">
<input id="searchBox" class="searchbox" placeholder="search..." type="input">
<span title="Clear">x</span>
<button id="clear_search" class="icon-cancel pull-right" title="Clear"></button>
</div>
<ul id="searchResults" class="search-results">
</ul>
</div>
</div>
<div id="notesView" class="notes-view view">
<div>
<div class="notes-input">
<textarea id="note-text" class="note-text" placeholder="Write note, press 'marker' button and select position in text to link note."></textarea>
<button id="note-anchor" class="note-anchor icon-room pull-right"></button>
</div>
<ol id="notes" class="notes">
</ol>
</div>
</div>
<div id="settingsView" class="settings-view view">
<fieldset class="settings-container" name="font-settings">
<legend>font</legend>
<div class="control-group">
<div>
<input type="checkbox" id="custom_font_family" name="font_family">
<label for="custom_font_family">custom font</label>
<select id="font_family" disabled="">
<option value="verdana, trebuchet, droid sans serif, sans, sans-serif"> sans </option>
<option value="georgia, times new roman, droid serif, serif"> serif </option>
<option value="monospace"> monospace </option>
</select>
</div>
<div>
<input type="checkbox" id="custom_font_size" name="font_size">
<label for="custom_font_size">font size</label>
<input type="number" id="font_size" value="100" min="50" max="150" disabled=""> %
</div>
<div>
<input type="checkbox" id="custom_font_weight" name="font_weight">
<label for="custom_font_weight">font weight</label>
<select id="font_weight" disabled="">
<option value="100">thin</option>
<option value="200">extra light</option>
<option value="300">light</option>
<option value="400">normal</option>
<option value="500">medium</option>
<option value="600">semi-bold</option>
<option value="700">bold</option>
<option value="800">extra bold</option>
<option value="900">black</option>
</select>
</div>
<div id="font_example" class="user font_example">
<div>
Et nos esse veri viri scire volemus
</div>
</div>
</div>
</fieldset>
<fieldset class="settings-container" name="colour-settings">
<legend>colors</legend>
<fieldset>
<legend>normal</legend>
<div class="control-group">
<input type="checkbox" id="use_custom_colors" name="use_custom_colors">
<label for="use_custom_colors">
Use custom colors
</label>
<div class="center-box">
<input type="color" id="day_color" value="#0a0a0a">
on
<input type="color" id="day_background" value="#f0f0f0">
</div>
<div id="day_example" class="day font_example">
<div>
Et nos esse veri viri scire volemus
</div>
</div>
</div>
</fieldset>
<fieldset>
<legend>night</legend>
<div class="control-group">
<div class="center-box nightshift">
nightmode can be toggled by clicking the book title
</div>
<div class="center-box">
<input type="color" id="night_color" value="#454545">
on
<input type="color" id="night_background" value="#000000">
</div>
<div id="night_example" class="night font_example">
<div>
Et nos esse veri viri scire volemus
</div>
</div>
</div>
</fieldset>
</fieldset>
<fieldset class="settings-container" name="display-settings">
<legend>display</legend>
<fieldset>
<legend>page width</legend>
<div class="control-group center-box">
maximum <input type="number" id="page_width" value="72" min="25" max="200"> characters
</div>
<div class="control-group">
<input type="checkbox" id="maximize_page" name="maximize_page">
<label for="custom_margins">maximize page area</label>
</div>
</fieldset>
<div class="control-group">
<input type="checkbox" id="sidebarReflow" name="sidebarReflow">
<label for="sidebarReflow">
reflow text when sidebars are open
</label>
</div>
<div class="control-group">
<input type="checkbox" id="touch_nav" name="touch_nav">
<label for="touch_nav">
disable extra-wide page turn areas
</label>
</div>
<div class="control-group">
<input type="checkbox" id="page_turn_arrows" name="page_turn_arrows">
<label for="page_turn_arrows">
show page turn arrows
</label>
</div>
</fieldset>
</div>
</div> <!-- views -->
</div> <!-- sidebar -->
<!-- /sidebar -->
<!-- main -->
<div id="main">
<!-- titlebar -->
<div id="titlebar">
<div id="opener">
<a id="slider" class="icon-menu">
<?php p($l->t("menu")); ?>
</a>
</div>
<div id="metainfo" class="nightshift">
<span id="book-title">
</span>
<span id="title-separator">
    
</span>
<span id="chapter-title">
</span>
</div>
<div id="title-controls">
<a id="note" class="icon-comment">
</a>
<a id="bookmark" class="icon-turned_in_not">
</a>
<a id="fullscreen" class="icon-fullscreen">
</a>
<a id="close" class="icon-exit" style="display:none">
</a>
</div>
</div>
<!-- /titlebar -->
<!-- divider -->
<div id="divider">
</div>
<!-- /divider -->
<!-- navigation + viewer -->
<div id="prev" class="arrow">
<div class="translucent">
</div>
</div>
<div id="viewer">
</div>
<div id="next" class="arrow">
<div class="translucent">
</div>
</div>
<div id="loader">
<img src="img/loading.gif">
</div>
<!-- /navigation + viewer -->
</div>
<!-- /main -->
<div class="overlay">
</div>
</div>
</body>
</html>

321
templates/pdfreader.php Normal file
View file

@ -0,0 +1,321 @@
<?php
$urlGenerator = $_['urlGenerator'];
$downloadLink = $_['downloadLink'];
$fileId = $_['fileId'];
$fileName = $_['fileName'];
$fileType = $_['fileType'];
$scope = $_['scope'];
$cursor = $_['cursor'];
$defaults = $_['defaults'];
$preferences = $_['preferences'];
$metadata = $_['metadata'];
$annotations = $_['annotations'];
$title = htmlentities(basename($downloadLink));
$revision = '0131';
$version = \OC::$server->getAppManager()->getAppVersion('files_reader') . '.' . $revision;
/* Mobile safari, the new IE6 */
$idevice = (strstr($_SERVER['HTTP_USER_AGENT'],'iPhone')
|| strstr($_SERVER['HTTP_USER_AGENT'],'iPad')
|| strstr($_SERVER['HTTP_USER_AGENT'],'iPod'));
$nonce = \OC::$server->getContentSecurityPolicyNonceManager()->getNonce();
?>
<html dir="ltr">
<head class="session" data-nonce='<?php p($nonce);?>' data-downloadlink='<?php print_unescaped($downloadLink);?>' data-fileid='<?php print_unescaped($fileId);?>' data-filetype='<?php print_unescaped($fileType);?>' data-filename='<?php print_unescaped($fileName);?>' data-version='<?php print_unescaped($version);?>' data-basepath='<?php p($urlGenerator->linkTo("files_reader",""));?>' data-scope='<?php print_unescaped($scope);?>' data-cursor='<?php print_unescaped($cursor);?>' data-defaults='<?php print_unescaped($defaults);?>' data-preferences='<?php print_unescaped($preferences);?>' data-metadata='<?php print_unescaped($metadata);?>' data-annotations='<?php print_unescaped($annotations);?>'>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="apple-mobile-web-app-capable" content="yes">
<!-- <base href="<?php p($urlGenerator->linkTo('files_reader',''));?>"> -->
<title>
<?php p($title);?>
</title>
<link rel="shortcut icon" href="img/book.png">
<link rel="stylesheet" href="<?php p($urlGenerator->linkTo('files_reader', 'vendor/icomoon/style.css')) ?>?v=<?php p($version) ?>">
<link rel="stylesheet" href="<?php p($urlGenerator->linkTo('files_reader', 'vendor/pdfjs/css/main.css')) ?>?v=<?php p($version) ?>">
<link rel="stylesheet" href="<?php p($urlGenerator->linkTo('files_reader', 'vendor/pdfjs/css/sidebar.css')) ?>?v=<?php p($version) ?>">
<link rel="stylesheet" href="<?php p($urlGenerator->linkTo('files_reader', 'vendor/pdfjs/css/text_layer_builder.css')) ?>?v=<?php p($version) ?>">
<link rel="stylesheet" href="<?php p($urlGenerator->linkTo('files_reader', 'vendor/pdfjs/css/annotation_layer_builder.css')) ?>?v=<?php p($version) ?>">
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/epubjs/libs/jquery.min.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/bartaz/jquery.highlight.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/jquery/put-delete.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/sindresorhus/screenfull.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/pdfjs/lib/pdf.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/pdfjs/pdf.reader.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/pdfjs/services/eventbus_service.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/pdfjs/services/link_service.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/pdfjs/services/simple_link_service.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/pdfjs/controllers/progress_controller.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/pdfjs/controllers/textlayer_controller.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/pdfjs/controllers/search_controller.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/pdfjs/controllers/reader_controller.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/pdfjs/controllers/sidebar_controller.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/pdfjs/controllers/settings_controller.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/pdfjs/controllers/controls_controller.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/pdfjs/controllers/toc_controller.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/pdfjs/controllers/outline_controller.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/pdfjs/controllers/annotationlayer_controller.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/pdfjs/controllers/notes_controller.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/pdfjs/controllers/bookmarks_controller.js')) ?>?v=<?php p($version) ?>"> </script>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/pdfjs/controllers/styles_controller.js')) ?>?v=<?php p($version) ?>"> </script>
<?php if ($idevice): ?>
<link rel="stylesheet" href="<?php p($urlGenerator->linkTo('files_reader', 'vendor/pdfjs/css/idevice.css')) ?>?v=<?php p($version) ?>">
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'vendor/bgrins/spectrum.js')) ?>?v=<?php p($version) ?>"> </script>
<link rel="stylesheet" href="<?php p($urlGenerator->linkTo('files_reader', 'vendor/bgrins/spectrum.css')) ?>?v=<?php p($version) ?>">
<?php endif; ?>
<script type="text/javascript" nonce="<?php p($nonce) ?>" src="<?php p($urlGenerator->linkTo('files_reader', 'js/ready.js')) ?>?v=<?php p($version) ?>"> </script>
</head>
<body>
<div id="outerContainer">
<!-- progress -->
<div id="progress" class="hide">
<span class="progress"><span class="bar"></span></span>
<br>
<div class="message"><span class="message-icons"><span id="download_icon" class="icon-cloud_download"></span></span> <span class="message-text"></span></div>
</div>
<!-- /progress -->
<!-- sidebar -->
<div id="sidebar" class="sidebar">
<div id="panels" class="panels">
<div class="pull-left">
<button id="show-Toc" class="show_view icon-dns open" title="Table of Contents" data-view="Toc"></button>
<button id="show-Outline" class="show_view icon-format_list_numbered" title="Outline" data-view="Outline"></button>
<!-- currently not used
<button id="show-Notes" class="show_view icon-comment" title="Annotations" data-view="Notes"></button>
-->
<button id="show-Bookmarks" class="show_view icon-turned_in" title="Bookmarks" data-view="Bookmarks"></button>
<button id="show-Search" class="show_view icon-search" title="Search" data-view="Search"></button>
<button id="show-Settings" class="show_view icon-settings" title="Settings" data-view="Settings"></button>
</div>
<div class="pull-right">
<button id="toc_populate" title="generate thumbnails" class="icon-sync" style="display:none"></button>
<button id="hide-Sidebar" class="close_sidebar icon-arrow-left2" title="Close sidebar"></button>
</div>
</div>
<div id="views">
<div id="tocView" class="toc-view view open">
<ul id="toc">
</ul>
</div>
<div id="outlineView" class="outline-view view">
<ul id="outline" class="outline">
</ul>
</div>
<!-- currently not used
<div id="notesView" class="notes-view view">
<div>
<div class="notes-input">
<textarea id="note-text" class="note-text" placeholder="Write note, press 'marker' button and select position in text to link note."></textarea>
<button id="note-anchor" class="note-anchor icon-room pull-right"></button>
</div>
<ol id="notes" class="notes">
</ol>
</div>
</div>
-->
<div id="bookmarksView" class="bookmarks-view view">
<ul id="bookmarks" class="bookmarks">
</ul>
</div>
<div id="searchView" class="view search-view">
<div>
<div class="search-input">
<input id="searchBox" class="searchbox" placeholder="search..." type="input">
<span title="Clear">x</span>
<button id="clear_search" class="icon-cancel pull-right" title="Clear"></button>
</div>
<ul id="searchResults" class="search-results">
</ul>
</div>
</div>
<div id="settingsView" class="settings-view view">
<fieldset class="settings-container" name="colour-settings">
<legend>colors</legend>
<fieldset>
<legend>night</legend>
<div class="control-group">
<form id="nightmode_form">
<div class="center-box nightshift">
nightmode can be toggled by clicking the nightmode button
</div>
<div class="control-group">
<label title="adjust brightness">brightness</label>
<input id="night_brightness" type="range" min="0" max="1" step="0.01" value="1">
</div>
<div class="control-group">
<label title="adjust contrast">constrast</label>
<input id="night_contrast" type="range" min="0" max="2" step="0.01" value="1">
</div>
<div class="control-group">
<label title="adjust sepia">sepia</label>
<input id="night_sepia" type="range" min="0" max="1" step="0.01" value="0">
</div>
<div class="control-group">
<label title="adjust hue">hue</label>
<input id="night_huerotate" type="range" min="0" max="359" step="1" value="0">
</div>
<div class="control-group">
<label title="adjust saturation">saturation</label>
<input id="night_saturate" type="range" min="0" max="5" step="0.01" value="1">
</div>
<div class="control-group">
<input type="reset" id="nightmode_reset" name="nightmode_reset">
</div>
</form>
</div>
</fieldset>
</fieldset>
<fieldset class="settings-container" name="display-settings">
<legend>display</legend>
<div class="control-group">
<input type="checkbox" id="touch_nav" name="touch_nav">
<label for="touch_nav">
disable extra-wide page turn areas
</label>
</div>
<div class="control-group">
<input type="checkbox" id="page_turn_arrows" name="page_turn_arrows">
<label for="page_turn_arrows">
show page turn arrows
</label>
</div>
<div class="control-group">
<input type="checkbox" id="scrollToTop" name="scrollToTop">
<label for="scrollToTop">
scroll to top of page on page turn
</label>
</div>
</fieldset>
</div>
</div> <!-- views -->
</div> <!-- sidebar -->
<!-- /sidebar -->
<!-- main -->
<div id="main">
<!-- titlebar -->
<div id="titlebar">
<div id="opener">
<a id="slider" class="icon-menu">
<?php p($l->t("menu")); ?>
</a>
<div id="status_message_left">
</div>
</div>
<div id="metainfo">
<span id="book-title">
</span>
<span id="title-separator">
    
</span>
<span id="page_num"></span>
<span id="page_num_separator">
/
</span>
<span id="total_pages">
</span>
</div>
<div id="title-controls">
<div id="status_message_right">
</div>
<div id="match_count">
</div>
<div id="nightmode" class="icon-brightness_low2 nightshift">
</div>
<span class="controls-separator"> </span>
<!-- select works fine, except for the fact that - as usual - apple mobile acts up... -->
<div id="zoom_options" class="hide">
<div class="zoom_option icon-double_page_mode" data-value="spread" data-class="icon-double_page_mode" data-text=""></div>
<div class="zoom_option icon-single_page_mode" data-value="fit_page" data-class="icon-single_page_mode" data-text=""></div>
<div class="zoom_option icon-icon-fit-width" data-value="fit_width" data-class="icon-icon-fit-width" data-text=""></div>
<div class="zoom_option" data-value="0.25" data-text="25%">25%</div>
<div class="zoom_option" data-value="0.5" data-text="50%">50%</div>
<div class="zoom_option" data-value="0.75" data-text="75%">75%</div>
<div class="zoom_option" data-value="1" data-text="100%">100%</div>
<div class="zoom_option" data-value="1.25" data-text="125%">125%</div>
<div class="zoom_option" data-value="1.5" data-text="150%">150%</div>
<div class="zoom_option" data-value="2" data-text="200%">200%</div>
<div class="zoom_option" data-value="3" data-text="300%">300%</div>
<div class="zoom_option" data-value="4" data-text="400%">400%</div>
</div>
<span id="zoom_icon"></span>
<span class="controls-separator"> </span>
<div id="rotate_options" class="hide">
<div class="rotate_option icon-rotate_0" data-value="0" data-class="icon-rotate_0" data-text=""></div>
<div class="rotate_option icon-rotate_90" data-value="90" data-class="icon-rotate_90" data-text=""></div>
<div class="rotate_option icon-rotate_180" data-value="180" data-class="icon-rotate_180" data-text=""></div>
<div class="rotate_option icon-rotate_270" data-value="270" data-class="icon-rotate_270" data-text=""></div>
</div>
<span id="rotate_left" class="icon-rotate_left"></span>
<span id="rotate_icon" class=icon-rotate_0"></span>
<span id="rotate_right" class="icon-rotate_right"></span>
<span class="controls-separator"> </span>
<a></a>
<a id="note" class="icon-comment">
</a>
<a id="bookmark" class="icon-turned_in_not">
</a>
<a id="fullscreen" class="icon-fullscreen">
</a>
<a id="close" class="icon-exit" style="display:none">
</a>
</div>
</div>
<!-- /titlebar -->
<!-- divider -->
<div id="divider">
</div>
<!-- /divider -->
<!-- navigation + viewer -->
<div id="prev" class="arrow">
<div class="translucent">
</div>
</div>
<div id="viewer" class="flex">
<canvas id="left" class="viewer"></canvas>
<div id="text_left" class="textLayer"></div>
<div id="annotations_left" class="annotationLayer"></div>
<canvas id="right" class="viewer"></canvas>
<div id="text_right" class="textLayer"></div>
<div id="annotations_right" class="annotationLayer"></div>
</div>
<div id="next" class="arrow">
<div class="translucent">
</div>
</div>
<div id="loader">
<img src="img/loading.gif">
</div>
<!-- /navigation + viewer -->
</div>
<!-- /main -->
<div class="overlay">
</div>
</div>
</body>
</html>

45
templates/personal.php Normal file
View file

@ -0,0 +1,45 @@
<?php
declare(strict_types=1);
/**
* @author Frank de Lange
* @copyright 2018 Frank de Lange
*
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
script('files_reader', 'settings');
style('files_reader', 'settings');
?>
<div id="files_reader" class="section">
<table><tr><td><h2><?php p($l->t('Reader'));?></h2></td><td>&nbsp;<span class="msg"></span></td></tr></table>
<p class="settings-hint"><?php p($l->t('Select file types for which Reader should be the default viewer.')); ?></p>
<p>
<input type="checkbox" name="epub_enable" id="epub_enable" class="checkbox"
value="1" <?php if ($_['epub_enable'] === "true") print_unescaped('checked="checked"'); ?> />
<label for="epub_enable">
<?php p($l->t('Epub'));?>
</label>
</p>
<p>
<input type="checkbox" name="pdf_enable" id="pdf_enable" class="checkbox"
value="1" <?php if ($_['pdf_enable'] === "true") print_unescaped('checked="checked"'); ?> />
<label for="pdf_enable">
<?php p($l->t('PDF'));?>
</label><br/>
</p>
<p>
<input type="checkbox" name="cbx_enable" id="cbx_enable" class="checkbox"
value="1" <?php if ($_['cbx_enable'] === "true") print_unescaped('checked="checked"'); ?> />
<label for="cbx_enable">
<?php p($l->t('CBR/CBZ'));?>
</label><br/>
</p>
</div>

108
vendor/bartaz/jquery.highlight.js vendored Normal file
View file

@ -0,0 +1,108 @@
/*
* jQuery Highlight plugin
*
* Based on highlight v3 by Johann Burkard
* http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html
*
* Code a little bit refactored and cleaned (in my humble opinion).
* Most important changes:
* - has an option to highlight only entire words (wordsOnly - false by default),
* - has an option to be case sensitive (caseSensitive - false by default)
* - highlight element tag and class names can be specified in options
*
* Usage:
* // wrap every occurrance of text 'lorem' in content
* // with <span class='highlight'> (default options)
* $('#content').highlight('lorem');
*
* // search for and highlight more terms at once
* // so you can save some time on traversing DOM
* $('#content').highlight(['lorem', 'ipsum']);
* $('#content').highlight('lorem ipsum');
*
* // search only for entire word 'lorem'
* $('#content').highlight('lorem', { wordsOnly: true });
*
* // don't ignore case during search of term 'lorem'
* $('#content').highlight('lorem', { caseSensitive: true });
*
* // wrap every occurrance of term 'ipsum' in content
* // with <em class='important'>
* $('#content').highlight('ipsum', { element: 'em', className: 'important' });
*
* // remove default highlight
* $('#content').unhighlight();
*
* // remove custom highlight
* $('#content').unhighlight({ element: 'em', className: 'important' });
*
*
* Copyright (c) 2009 Bartek Szopka
*
* Licensed under MIT license.
*
*/
jQuery.extend({
highlight: function (node, re, nodeName, className) {
if (node.nodeType === 3) {
var match = node.data.match(re);
if (match) {
var highlight = document.createElement(nodeName || 'span');
highlight.className = className || 'highlight';
var wordNode = node.splitText(match.index);
wordNode.splitText(match[0].length);
var wordClone = wordNode.cloneNode(true);
highlight.appendChild(wordClone);
wordNode.parentNode.replaceChild(highlight, wordNode);
return 1; //skip added node in parent
}
} else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children
!/(script|style)/i.test(node.tagName) && // ignore script and style nodes
!(node.tagName === nodeName.toUpperCase() && node.className === className)) { // skip if already highlighted
for (var i = 0; i < node.childNodes.length; i++) {
i += jQuery.highlight(node.childNodes[i], re, nodeName, className);
}
}
return 0;
}
});
jQuery.fn.unhighlight = function (options) {
var settings = { className: 'highlight', element: 'span' };
jQuery.extend(settings, options);
return this.find(settings.element + "." + settings.className).each(function () {
var parent = this.parentNode;
parent.replaceChild(this.firstChild, this);
parent.normalize();
}).end();
};
jQuery.fn.highlight = function (words, options) {
var settings = { className: 'highlight', element: 'span', caseSensitive: false, wordsOnly: false };
jQuery.extend(settings, options);
if (words.constructor === String) {
words = [words];
}
words = jQuery.grep(words, function(word, i){
return word != '';
});
words = jQuery.map(words, function(word, i) {
return word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
});
if (words.length == 0) { return this; };
var flag = settings.caseSensitive ? "" : "i";
var pattern = "(" + words.join("|") + ")";
if (settings.wordsOnly) {
pattern = "\\b" + pattern + "\\b";
}
var re = new RegExp(pattern, flag);
return this.each(function () {
jQuery.highlight(this, re, settings.element, settings.className);
});
};

507
vendor/bgrins/spectrum.css vendored Normal file
View file

@ -0,0 +1,507 @@
/***
Spectrum Colorpicker v1.8.0
https://github.com/bgrins/spectrum
Author: Brian Grinstead
License: MIT
***/
.sp-container {
position:absolute;
top:0;
left:0;
display:inline-block;
*display: inline;
*zoom: 1;
/* https://github.com/bgrins/spectrum/issues/40 */
z-index: 9999994;
overflow: hidden;
}
.sp-container.sp-flat {
position: relative;
}
/* Fix for * { box-sizing: border-box; } */
.sp-container,
.sp-container * {
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
}
/* http://ansciath.tumblr.com/post/7347495869/css-aspect-ratio */
.sp-top {
position:relative;
width: 100%;
display:inline-block;
}
.sp-top-inner {
position:absolute;
top:0;
left:0;
bottom:0;
right:0;
}
.sp-color {
position: absolute;
top:0;
left:0;
bottom:0;
right:20%;
}
.sp-hue {
position: absolute;
top:0;
right:0;
bottom:0;
left:84%;
height: 100%;
}
.sp-clear-enabled .sp-hue {
top:33px;
height: 77.5%;
}
.sp-fill {
padding-top: 80%;
}
.sp-sat, .sp-val {
position: absolute;
top:0;
left:0;
right:0;
bottom:0;
}
.sp-alpha-enabled .sp-top {
margin-bottom: 18px;
}
.sp-alpha-enabled .sp-alpha {
display: block;
}
.sp-alpha-handle {
position:absolute;
top:-4px;
bottom: -4px;
width: 6px;
left: 50%;
cursor: pointer;
border: 1px solid black;
background: white;
opacity: .8;
}
.sp-alpha {
display: none;
position: absolute;
bottom: -14px;
right: 0;
left: 0;
height: 8px;
}
.sp-alpha-inner {
border: solid 1px #333;
}
.sp-clear {
display: none;
}
.sp-clear.sp-clear-display {
background-position: center;
}
.sp-clear-enabled .sp-clear {
display: block;
position:absolute;
top:0px;
right:0;
bottom:0;
left:84%;
height: 28px;
}
/* Don't allow text selection */
.sp-container, .sp-replacer, .sp-preview, .sp-dragger, .sp-slider, .sp-alpha, .sp-clear, .sp-alpha-handle, .sp-container.sp-dragging .sp-input, .sp-container button {
-webkit-user-select:none;
-moz-user-select: -moz-none;
-o-user-select:none;
user-select: none;
}
.sp-container.sp-input-disabled .sp-input-container {
display: none;
}
.sp-container.sp-buttons-disabled .sp-button-container {
display: none;
}
.sp-container.sp-palette-buttons-disabled .sp-palette-button-container {
display: none;
}
.sp-palette-only .sp-picker-container {
display: none;
}
.sp-palette-disabled .sp-palette-container {
display: none;
}
.sp-initial-disabled .sp-initial {
display: none;
}
/* Gradients for hue, saturation and value instead of images. Not pretty... but it works */
.sp-sat {
background-image: -webkit-gradient(linear, 0 0, 100% 0, from(#FFF), to(rgba(204, 154, 129, 0)));
background-image: -webkit-linear-gradient(left, #FFF, rgba(204, 154, 129, 0));
background-image: -moz-linear-gradient(left, #fff, rgba(204, 154, 129, 0));
background-image: -o-linear-gradient(left, #fff, rgba(204, 154, 129, 0));
background-image: -ms-linear-gradient(left, #fff, rgba(204, 154, 129, 0));
background-image: linear-gradient(to right, #fff, rgba(204, 154, 129, 0));
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr=#FFFFFFFF, endColorstr=#00CC9A81)";
filter : progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr='#FFFFFFFF', endColorstr='#00CC9A81');
}
.sp-val {
background-image: -webkit-gradient(linear, 0 100%, 0 0, from(#000000), to(rgba(204, 154, 129, 0)));
background-image: -webkit-linear-gradient(bottom, #000000, rgba(204, 154, 129, 0));
background-image: -moz-linear-gradient(bottom, #000, rgba(204, 154, 129, 0));
background-image: -o-linear-gradient(bottom, #000, rgba(204, 154, 129, 0));
background-image: -ms-linear-gradient(bottom, #000, rgba(204, 154, 129, 0));
background-image: linear-gradient(to top, #000, rgba(204, 154, 129, 0));
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#00CC9A81, endColorstr=#FF000000)";
filter : progid:DXImageTransform.Microsoft.gradient(startColorstr='#00CC9A81', endColorstr='#FF000000');
}
.sp-hue {
background: -moz-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
background: -ms-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
background: -o-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
background: -webkit-gradient(linear, left top, left bottom, from(#ff0000), color-stop(0.17, #ffff00), color-stop(0.33, #00ff00), color-stop(0.5, #00ffff), color-stop(0.67, #0000ff), color-stop(0.83, #ff00ff), to(#ff0000));
background: -webkit-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
background: linear-gradient(to bottom, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
}
/* IE filters do not support multiple color stops.
Generate 6 divs, line them up, and do two color gradients for each.
Yes, really.
*/
.sp-1 {
height:17%;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0000', endColorstr='#ffff00');
}
.sp-2 {
height:16%;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff00', endColorstr='#00ff00');
}
.sp-3 {
height:17%;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ff00', endColorstr='#00ffff');
}
.sp-4 {
height:17%;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ffff', endColorstr='#0000ff');
}
.sp-5 {
height:16%;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0000ff', endColorstr='#ff00ff');
}
.sp-6 {
height:17%;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff00ff', endColorstr='#ff0000');
}
.sp-hidden {
display: none !important;
}
/* Clearfix hack */
.sp-cf:before, .sp-cf:after { content: ""; display: table; }
.sp-cf:after { clear: both; }
.sp-cf { *zoom: 1; }
/* Mobile devices, make hue slider bigger so it is easier to slide */
@media (max-device-width: 480px) {
.sp-color { right: 40%; }
.sp-hue { left: 63%; }
.sp-fill { padding-top: 60%; }
}
.sp-dragger {
border-radius: 5px;
height: 5px;
width: 5px;
border: 1px solid #fff;
background: #000;
cursor: pointer;
position:absolute;
top:0;
left: 0;
}
.sp-slider {
position: absolute;
top:0;
cursor:pointer;
height: 3px;
left: -1px;
right: -1px;
border: 1px solid #000;
background: white;
opacity: .8;
}
/*
Theme authors:
Here are the basic themeable display options (colors, fonts, global widths).
See http://bgrins.github.io/spectrum/themes/ for instructions.
*/
.sp-container {
border-radius: 0;
background-color: #ECECEC;
border: solid 1px #f0c49B;
padding: 0;
}
.sp-container, .sp-container button, .sp-container input, .sp-color, .sp-hue, .sp-clear {
font: normal 12px "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Geneva, Verdana, sans-serif;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
}
.sp-top {
margin-bottom: 3px;
}
.sp-color, .sp-hue, .sp-clear {
border: solid 1px #666;
}
/* Input */
.sp-input-container {
float:right;
width: 100px;
margin-bottom: 4px;
}
.sp-initial-disabled .sp-input-container {
width: 100%;
}
.sp-input {
font-size: 12px !important;
border: 1px inset;
padding: 4px 5px;
margin: 0;
width: 100%;
background:transparent;
border-radius: 3px;
color: #222;
}
.sp-input:focus {
border: 1px solid orange;
}
.sp-input.sp-validation-error {
border: 1px solid red;
background: #fdd;
}
.sp-picker-container , .sp-palette-container {
float:left;
position: relative;
padding: 10px;
padding-bottom: 300px;
margin-bottom: -290px;
}
.sp-picker-container {
width: 172px;
border-left: solid 1px #fff;
}
/* Palettes */
.sp-palette-container {
border-right: solid 1px #ccc;
}
.sp-palette-only .sp-palette-container {
border: 0;
}
.sp-palette .sp-thumb-el {
display: block;
position:relative;
float:left;
width: 24px;
height: 15px;
margin: 3px;
cursor: pointer;
border:solid 2px transparent;
}
.sp-palette .sp-thumb-el:hover, .sp-palette .sp-thumb-el.sp-thumb-active {
border-color: orange;
}
.sp-thumb-el {
position:relative;
}
/* Initial */
.sp-initial {
float: left;
border: solid 1px #333;
}
.sp-initial span {
width: 30px;
height: 25px;
border:none;
display:block;
float:left;
margin:0;
}
.sp-initial .sp-clear-display {
background-position: center;
}
/* Buttons */
.sp-palette-button-container,
.sp-button-container {
float: right;
}
/* Replacer (the little preview div that shows up instead of the <input>) */
.sp-replacer {
margin:0;
overflow:hidden;
cursor:pointer;
padding: 4px;
display:inline-block;
*zoom: 1;
*display: inline;
border: solid 1px #91765d;
background: #eee;
color: #333;
vertical-align: middle;
}
.sp-replacer:hover, .sp-replacer.sp-active {
border-color: #F0C49B;
color: #111;
}
.sp-replacer.sp-disabled {
cursor:default;
border-color: silver;
color: silver;
}
.sp-dd {
padding: 2px 0;
height: 16px;
line-height: 16px;
float:left;
font-size:10px;
}
.sp-preview {
position:relative;
width:25px;
height: 20px;
border: solid 1px #222;
margin-right: 5px;
float:left;
z-index: 0;
}
.sp-palette {
*width: 220px;
max-width: 220px;
}
.sp-palette .sp-thumb-el {
width:16px;
height: 16px;
margin:2px 1px;
border: solid 1px #d0d0d0;
}
.sp-container {
padding-bottom:0;
}
/* Buttons: http://hellohappy.org/css3-buttons/ */
.sp-container button {
background-color: #eeeeee;
background-image: -webkit-linear-gradient(top, #eeeeee, #cccccc);
background-image: -moz-linear-gradient(top, #eeeeee, #cccccc);
background-image: -ms-linear-gradient(top, #eeeeee, #cccccc);
background-image: -o-linear-gradient(top, #eeeeee, #cccccc);
background-image: linear-gradient(to bottom, #eeeeee, #cccccc);
border: 1px solid #ccc;
border-bottom: 1px solid #bbb;
border-radius: 3px;
color: #333;
font-size: 14px;
line-height: 1;
padding: 5px 4px;
text-align: center;
text-shadow: 0 1px 0 #eee;
vertical-align: middle;
}
.sp-container button:hover {
background-color: #dddddd;
background-image: -webkit-linear-gradient(top, #dddddd, #bbbbbb);
background-image: -moz-linear-gradient(top, #dddddd, #bbbbbb);
background-image: -ms-linear-gradient(top, #dddddd, #bbbbbb);
background-image: -o-linear-gradient(top, #dddddd, #bbbbbb);
background-image: linear-gradient(to bottom, #dddddd, #bbbbbb);
border: 1px solid #bbb;
border-bottom: 1px solid #999;
cursor: pointer;
text-shadow: 0 1px 0 #ddd;
}
.sp-container button:active {
border: 1px solid #aaa;
border-bottom: 1px solid #888;
-webkit-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
-moz-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
-ms-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
-o-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
}
.sp-cancel {
font-size: 11px;
color: #d93f3f !important;
margin:0;
padding:2px;
margin-right: 5px;
vertical-align: middle;
text-decoration:none;
}
.sp-cancel:hover {
color: #d93f3f !important;
text-decoration: underline;
}
.sp-palette span:hover, .sp-palette span.sp-thumb-active {
border-color: #000;
}
.sp-preview, .sp-alpha, .sp-thumb-el {
position:relative;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==);
}
.sp-preview-inner, .sp-alpha-inner, .sp-thumb-inner {
display:block;
position:absolute;
top:0;left:0;bottom:0;right:0;
}
.sp-palette .sp-thumb-inner {
background-position: 50% 50%;
background-repeat: no-repeat;
}
.sp-palette .sp-thumb-light.sp-thumb-active .sp-thumb-inner {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAIVJREFUeNpiYBhsgJFMffxAXABlN5JruT4Q3wfi/0DsT64h8UD8HmpIPCWG/KemIfOJCUB+Aoacx6EGBZyHBqI+WsDCwuQ9mhxeg2A210Ntfo8klk9sOMijaURm7yc1UP2RNCMbKE9ODK1HM6iegYLkfx8pligC9lCD7KmRof0ZhjQACDAAceovrtpVBRkAAAAASUVORK5CYII=);
}
.sp-palette .sp-thumb-dark.sp-thumb-active .sp-thumb-inner {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAMdJREFUOE+tkgsNwzAMRMugEAahEAahEAZhEAqlEAZhEAohEAYh81X2dIm8fKpEspLGvudPOsUYpxE2BIJCroJmEW9qJ+MKaBFhEMNabSy9oIcIPwrB+afvAUFoK4H0tMaQ3XtlrggDhOVVMuT4E5MMG0FBbCEYzjYT7OxLEvIHQLY2zWwQ3D+9luyOQTfKDiFD3iUIfPk8VqrKjgAiSfGFPecrg6HN6m/iBcwiDAo7WiBeawa+Kwh7tZoSCGLMqwlSAzVDhoK+6vH4G0P5wdkAAAAASUVORK5CYII=);
}
.sp-clear-display {
background-repeat:no-repeat;
background-position: center;
background-image: url(data:image/gif;base64,R0lGODlhFAAUAPcAAAAAAJmZmZ2dnZ6enqKioqOjo6SkpKWlpaampqenp6ioqKmpqaqqqqurq/Hx8fLy8vT09PX19ff39/j4+Pn5+fr6+vv7+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAP8ALAAAAAAUABQAAAihAP9FoPCvoMGDBy08+EdhQAIJCCMybCDAAYUEARBAlFiQQoMABQhKUJBxY0SPICEYHBnggEmDKAuoPMjS5cGYMxHW3IiT478JJA8M/CjTZ0GgLRekNGpwAsYABHIypcAgQMsITDtWJYBR6NSqMico9cqR6tKfY7GeBCuVwlipDNmefAtTrkSzB1RaIAoXodsABiZAEFB06gIBWC1mLVgBa0AAOw==);
}

2323
vendor/bgrins/spectrum.js vendored Normal file

File diff suppressed because it is too large Load diff

341
vendor/bitjs/archive/archive.js vendored Normal file
View file

@ -0,0 +1,341 @@
/**
* archive.js
*
* Provides base functionality for unarchiving.
*
* Licensed under the MIT License
*
* Copyright(c) 2011 Google Inc.
*/
var bitjs = bitjs || {};
bitjs.archive = bitjs.archive || {};
/**
* An unarchive event.
*/
bitjs.archive.UnarchiveEvent = class {
/**
* @param {string} type The event type.
*/
constructor(type) {
/**
* The event type.
* @type {string}
*/
this.type = type;
}
}
/**
* The UnarchiveEvent types.
*/
bitjs.archive.UnarchiveEvent.Type = {
START: 'start',
PROGRESS: 'progress',
EXTRACT: 'extract',
FINISH: 'finish',
INFO: 'info',
ERROR: 'error'
};
/**
* Useful for passing info up to the client (for debugging).
*/
bitjs.archive.UnarchiveInfoEvent = class extends bitjs.archive.UnarchiveEvent {
/**
* @param {string} msg The info message.
*/
constructor(msg) {
super(bitjs.archive.UnarchiveEvent.Type.INFO);
/**
* The information message.
* @type {string}
*/
this.msg = msg;
}
}
/**
* An unrecoverable error has occured.
*/
bitjs.archive.UnarchiveErrorEvent = class extends bitjs.archive.UnarchiveEvent {
/**
* @param {string} msg The error message.
*/
constructor(msg) {
super(bitjs.archive.UnarchiveEvent.Type.ERROR);
/**
* The information message.
* @type {string}
*/
this.msg = msg;
}
}
/**
* Start event.
*/
bitjs.archive.UnarchiveStartEvent = class extends bitjs.archive.UnarchiveEvent {
constructor() {
super(bitjs.archive.UnarchiveEvent.Type.START);
}
}
/**
* Finish event.
*/
bitjs.archive.UnarchiveFinishEvent = class extends bitjs.archive.UnarchiveEvent {
constructor() {
super(bitjs.archive.UnarchiveEvent.Type.FINISH);
}
}
/**
* Progress event.
*/
bitjs.archive.UnarchiveProgressEvent = class extends bitjs.archive.UnarchiveEvent {
/**
* @param {string} currentFilename
* @param {number} currentFileNumber
* @param {number} currentBytesUnarchivedInFile
* @param {number} currentBytesUnarchived
* @param {number} totalUncompressedBytesInArchive
* @param {number} totalFilesInArchive
*/
constructor(currentFilename, currentFileNumber, currentBytesUnarchivedInFile,
currentBytesUnarchived, totalUncompressedBytesInArchive, totalFilesInArchive) {
super(bitjs.archive.UnarchiveEvent.Type.PROGRESS);
this.currentFilename = currentFilename;
this.currentFileNumber = currentFileNumber;
this.currentBytesUnarchivedInFile = currentBytesUnarchivedInFile;
this.totalFilesInArchive = totalFilesInArchive;
this.currentBytesUnarchived = currentBytesUnarchived;
this.totalUncompressedBytesInArchive = totalUncompressedBytesInArchive;
}
}
/**
* Extract event.
*/
bitjs.archive.UnarchiveExtractEvent = class extends bitjs.archive.UnarchiveEvent {
/**
* @param {UnarchivedFile} unarchivedFile
*/
constructor(unarchivedFile) {
super(bitjs.archive.UnarchiveEvent.Type.EXTRACT);
/**
* @type {UnarchivedFile}
*/
this.unarchivedFile = unarchivedFile;
}
}
/**
* All extracted files returned by an Unarchiver will implement
* the following interface:
*
* interface UnarchivedFile {
* string filename
* TypedArray fileData
* }
*
*/
/**
* Base class for all Unarchivers.
*/
bitjs.archive.Unarchiver = class {
/**
* @param {ArrayBuffer} arrayBuffer The Array Buffer.
* @param {string} opt_pathToBitJS Optional string for where the BitJS files are located.
*/
constructor(arrayBuffer, opt_pathToBitJS) {
/**
* The ArrayBuffer object.
* @type {ArrayBuffer}
* @protected
*/
this.ab = arrayBuffer;
/**
* The path to the BitJS files.
* @type {string}
* @private
*/
this.pathToBitJS_ = opt_pathToBitJS || '/';
/**
* A map from event type to an array of listeners.
* @type {Map.<string, Array>}
*/
this.listeners_ = {};
for (let type in bitjs.archive.UnarchiveEvent.Type) {
this.listeners_[bitjs.archive.UnarchiveEvent.Type[type]] = [];
}
/**
* Private web worker initialized during start().
* @type {Worker}
* @private
*/
this.worker_ = null;
}
/**
* This method must be overridden by the subclass to return the script filename.
* @return {string} The script filename.
* @protected.
*/
getScriptFileName() {
throw 'Subclasses of AbstractUnarchiver must overload getScriptFileName()';
}
/**
* Adds an event listener for UnarchiveEvents.
*
* @param {string} Event type.
* @param {function} An event handler function.
*/
addEventListener(type, listener) {
if (type in this.listeners_) {
if (this.listeners_[type].indexOf(listener) == -1) {
this.listeners_[type].push(listener);
}
}
}
/**
* Removes an event listener.
*
* @param {string} Event type.
* @param {EventListener|function} An event listener or handler function.
*/
removeEventListener(type, listener) {
if (type in this.listeners_) {
const index = this.listeners_[type].indexOf(listener);
if (index != -1) {
this.listeners_[type].splice(index, 1);
}
}
}
/**
* Receive an event and pass it to the listener functions.
*
* @param {bitjs.archive.UnarchiveEvent} e
* @private
*/
handleWorkerEvent_(e) {
if ((e instanceof bitjs.archive.UnarchiveEvent || e.type) &&
this.listeners_[e.type] instanceof Array) {
this.listeners_[e.type].forEach(function (listener) { listener(e) });
if (e.type == bitjs.archive.UnarchiveEvent.Type.FINISH) {
this.worker_.terminate();
}
} else {
console.log(e);
}
}
/**
* Starts the unarchive in a separate Web Worker thread and returns immediately.
*/
start() {
const me = this;
const scriptFileName = this.pathToBitJS_ + this.getScriptFileName();
if (scriptFileName) {
this.worker_ = new Worker(scriptFileName);
this.worker_.onerror = function(e) {
console.log('Worker error: message = ' + e.message);
throw e;
};
this.worker_.onmessage = function(e) {
if (typeof e.data == 'string') {
// Just log any strings the workers pump our way.
console.log(e.data);
} else {
// Assume that it is an UnarchiveEvent. Some browsers preserve the 'type'
// so that instanceof UnarchiveEvent returns true, but others do not.
me.handleWorkerEvent_(e.data);
}
};
this.worker_.postMessage({file: this.ab});
}
}
/**
* Terminates the Web Worker for this Unarchiver and returns immediately.
*/
stop() {
if (this.worker_) {
this.worker_.terminate();
}
}
}
/**
* Unzipper
*/
bitjs.archive.Unzipper = class extends bitjs.archive.Unarchiver {
constructor(arrayBuffer, opt_pathToBitJS) {
super(arrayBuffer, opt_pathToBitJS);
}
getScriptFileName() { return 'archive/unzip.js'; }
}
/**
* Unrarrer
*/
bitjs.archive.Unrarrer = class extends bitjs.archive.Unarchiver {
constructor(arrayBuffer, opt_pathToBitJS) {
super(arrayBuffer, opt_pathToBitJS);
}
getScriptFileName() { return 'archive/unrar.js'; }
}
/**
* Untarrer
* @extends {bitjs.archive.Unarchiver}
* @constructor
*/
bitjs.archive.Untarrer = class extends bitjs.archive.Unarchiver {
constructor(arrayBuffer, opt_pathToBitJS) {
super(arrayBuffer, opt_pathToBitJS);
}
getScriptFileName() { return 'archive/untar.js'; };
}
/**
* Factory method that creates an unarchiver based on the byte signature found
* in the arrayBuffer.
* @param {ArrayBuffer} ab
* @param {string=} opt_pathToBitJS Path to the unarchiver script files.
* @return {bitjs.archive.Unarchiver}
*/
bitjs.archive.GetUnarchiver = function(ab, opt_pathToBitJS) {
let unarchiver = null;
const pathToBitJS = opt_pathToBitJS || '';
const h = new Uint8Array(ab, 0, 10);
if (h[0] == 0x52 && h[1] == 0x61 && h[2] == 0x72 && h[3] == 0x21) { // Rar!
unarchiver = new bitjs.archive.Unrarrer(ab, pathToBitJS);
} else if (h[0] == 0x50 && h[1] == 0x4B) { // PK (Zip)
unarchiver = new bitjs.archive.Unzipper(ab, pathToBitJS);
} else { // Try with tar
unarchiver = new bitjs.archive.Untarrer(ab, pathToBitJS);
}
return unarchiver;
};

1009
vendor/bitjs/archive/rarvm.js vendored Normal file

File diff suppressed because it is too large Load diff

3065
vendor/bitjs/archive/unrar.js vendored Normal file

File diff suppressed because it is too large Load diff

168
vendor/bitjs/archive/untar.js vendored Normal file
View file

@ -0,0 +1,168 @@
/**
* untar.js
*
* Licensed under the MIT License
*
* Copyright(c) 2011 Google Inc.
*
* Reference Documentation:
*
* TAR format: http://www.gnu.org/software/automake/manual/tar/Standard.html
*/
// This file expects to be invoked as a Worker (see onmessage below).
importScripts('../io/bytestream.js');
importScripts('archive.js');
// Progress variables.
let currentFilename = "";
let currentFileNumber = 0;
let currentBytesUnarchivedInFile = 0;
let currentBytesUnarchived = 0;
let totalUncompressedBytesInArchive = 0;
let totalFilesInArchive = 0;
// Helper functions.
const info = function(str) {
postMessage(new bitjs.archive.UnarchiveInfoEvent(str));
};
const err = function(str) {
postMessage(new bitjs.archive.UnarchiveErrorEvent(str));
};
const postProgress = function() {
postMessage(new bitjs.archive.UnarchiveProgressEvent(
currentFilename,
currentFileNumber,
currentBytesUnarchivedInFile,
currentBytesUnarchived,
totalUncompressedBytesInArchive,
totalFilesInArchive));
};
// Removes all characters from the first zero-byte in the string onwards.
const readCleanString = function(bstr, numBytes) {
const str = bstr.readString(numBytes);
const zIndex = str.indexOf(String.fromCharCode(0));
return zIndex != -1 ? str.substr(0, zIndex) : str;
};
class TarLocalFile {
// takes a ByteStream and parses out the local file information
constructor(bstream) {
this.isValid = false;
// Read in the header block
this.name = readCleanString(bstream, 100);
this.mode = readCleanString(bstream, 8);
this.uid = readCleanString(bstream, 8);
this.gid = readCleanString(bstream, 8);
this.size = parseInt(readCleanString(bstream, 12), 8);
this.mtime = readCleanString(bstream, 12);
this.chksum = readCleanString(bstream, 8);
this.typeflag = readCleanString(bstream, 1);
this.linkname = readCleanString(bstream, 100);
this.maybeMagic = readCleanString(bstream, 6);
if (this.maybeMagic == "ustar") {
this.version = readCleanString(bstream, 2);
this.uname = readCleanString(bstream, 32);
this.gname = readCleanString(bstream, 32);
this.devmajor = readCleanString(bstream, 8);
this.devminor = readCleanString(bstream, 8);
this.prefix = readCleanString(bstream, 155);
if (this.prefix.length) {
this.name = this.prefix + this.name;
}
bstream.readBytes(12); // 512 - 500
} else {
bstream.readBytes(255); // 512 - 257
}
// Done header, now rest of blocks are the file contents.
this.filename = this.name;
this.fileData = null;
info("Untarring file '" + this.filename + "'");
info(" size = " + this.size);
info(" typeflag = " + this.typeflag);
// A regular file.
if (this.typeflag == 0) {
info(" This is a regular file.");
const sizeInBytes = parseInt(this.size);
this.fileData = new Uint8Array(bstream.readBytes(sizeInBytes));
if (this.name.length > 0 && this.size > 0 && this.fileData && this.fileData.buffer) {
this.isValid = true;
}
bstream.readBytes(this.size);
// Round up to 512-byte blocks.
const remaining = 512 - bstream.ptr % 512;
if (remaining > 0 && remaining < 512) {
bstream.readBytes(remaining);
}
} else if (this.typeflag == 5) {
info(" This is a directory.")
}
}
}
// Takes an ArrayBuffer of a tar file in
// returns null on error
// returns an array of DecompressedFile objects on success
const untar = function(arrayBuffer) {
currentFilename = "";
currentFileNumber = 0;
currentBytesUnarchivedInFile = 0;
currentBytesUnarchived = 0;
totalUncompressedBytesInArchive = 0;
totalFilesInArchive = 0;
postMessage(new bitjs.archive.UnarchiveStartEvent());
const bstream = new bitjs.io.ByteStream(arrayBuffer);
const localFiles = [];
// While we don't encounter an empty block, keep making TarLocalFiles.
while (bstream.peekNumber(4) != 0) {
const oneLocalFile = new TarLocalFile(bstream);
if (oneLocalFile && oneLocalFile.isValid) {
localFiles.push(oneLocalFile);
totalUncompressedBytesInArchive += oneLocalFile.size;
}
}
totalFilesInArchive = localFiles.length;
// got all local files, now sort them
localFiles.sort((a,b) => a.filename > b.filename ? 1 : -1);
// report # files and total length
if (localFiles.length > 0) {
postProgress();
}
// now do the shipping of each file
for (let i = 0; i < localFiles.length; ++i) {
const localfile = localFiles[i];
info("Sending file '" + localfile.filename + "' up");
// update progress
currentFilename = localfile.filename;
currentFileNumber = i;
currentBytesUnarchivedInFile = localfile.size;
currentBytesUnarchived += localfile.size;
postMessage(new bitjs.archive.UnarchiveExtractEvent(localfile));
postProgress();
}
postProgress();
postMessage(new bitjs.archive.UnarchiveFinishEvent());
};
// event.data.file has the ArrayBuffer.
onmessage = function(event) {
const ab = event.data.file;
untar(ab);
};

1467
vendor/bitjs/archive/unzip.js vendored Normal file

File diff suppressed because it is too large Load diff

222
vendor/bitjs/io/bitstream.js vendored Normal file
View file

@ -0,0 +1,222 @@
/*
* bitstream.js
*
* Provides readers for bitstreams.
*
* Licensed under the MIT License
*
* Copyright(c) 2011 Google Inc.
* Copyright(c) 2011 antimatter15
*/
var bitjs = bitjs || {};
bitjs.io = bitjs.io || {};
/**
* This bit stream peeks and consumes bits out of a binary stream.
*/
bitjs.io.BitStream = class {
/**
* @param {ArrayBuffer} ab An ArrayBuffer object or a Uint8Array.
* @param {boolean} rtl Whether the stream reads bits from the byte starting
* from bit 7 to 0 (true) or bit 0 to 7 (false).
* @param {Number} opt_offset The offset into the ArrayBuffer
* @param {Number} opt_length The length of this BitStream
*/
constructor(ab, rtl, opt_offset, opt_length) {
if (!ab || !ab.toString || ab.toString() !== "[object ArrayBuffer]") {
throw "Error! BitArray constructed with an invalid ArrayBuffer object";
}
const offset = opt_offset || 0;
const length = opt_length || ab.byteLength;
this.bytes = new Uint8Array(ab, offset, length);
this.bytePtr = 0; // tracks which byte we are on
this.bitPtr = 0; // tracks which bit we are on (can have values 0 through 7)
this.peekBits = rtl ? this.peekBits_rtl : this.peekBits_ltr;
}
/**
* byte0 byte1 byte2 byte3
* 7......0 | 7......0 | 7......0 | 7......0
*
* The bit pointer starts at bit0 of byte0 and moves left until it reaches
* bit7 of byte0, then jumps to bit0 of byte1, etc.
* @param {number} n The number of bits to peek.
* @param {boolean=} movePointers Whether to move the pointer, defaults false.
* @return {number} The peeked bits, as an unsigned number.
*/
peekBits_ltr(n, opt_movePointers) {
if (n <= 0 || typeof n != typeof 1) {
return 0;
}
const movePointers = opt_movePointers || false;
const bytes = this.bytes;
let bytePtr = this.bytePtr;
let bitPtr = this.bitPtr;
let result = 0;
let bitsIn = 0;
// keep going until we have no more bits left to peek at
// TODO: Consider putting all bits from bytes we will need into a variable and then
// shifting/masking it to just extract the bits we want.
// This could be considerably faster when reading more than 3 or 4 bits at a time.
while (n > 0) {
if (bytePtr >= bytes.length) {
throw "Error! Overflowed the bit stream! n=" + n + ", bytePtr=" + bytePtr + ", bytes.length=" +
bytes.length + ", bitPtr=" + bitPtr;
return -1;
}
const numBitsLeftInThisByte = (8 - bitPtr);
if (n >= numBitsLeftInThisByte) {
const mask = (bitjs.io.BitStream.BITMASK[numBitsLeftInThisByte] << bitPtr);
result |= (((bytes[bytePtr] & mask) >> bitPtr) << bitsIn);
bytePtr++;
bitPtr = 0;
bitsIn += numBitsLeftInThisByte;
n -= numBitsLeftInThisByte;
}
else {
const mask = (bitjs.io.BitStream.BITMASK[n] << bitPtr);
result |= (((bytes[bytePtr] & mask) >> bitPtr) << bitsIn);
bitPtr += n;
bitsIn += n;
n = 0;
}
}
if (movePointers) {
this.bitPtr = bitPtr;
this.bytePtr = bytePtr;
}
return result;
}
/**
* byte0 byte1 byte2 byte3
* 7......0 | 7......0 | 7......0 | 7......0
*
* The bit pointer starts at bit7 of byte0 and moves right until it reaches
* bit0 of byte0, then goes to bit7 of byte1, etc.
* @param {number} n The number of bits to peek.
* @param {boolean=} movePointers Whether to move the pointer, defaults false.
* @return {number} The peeked bits, as an unsigned number.
*/
peekBits_rtl(n, opt_movePointers) {
if (n <= 0 || typeof n != typeof 1) {
return 0;
}
const movePointers = opt_movePointers || false;
const bytes = this.bytes;
let bytePtr = this.bytePtr;
let bitPtr = this.bitPtr;
let result = 0;
// keep going until we have no more bits left to peek at
// TODO: Consider putting all bits from bytes we will need into a variable and then
// shifting/masking it to just extract the bits we want.
// This could be considerably faster when reading more than 3 or 4 bits at a time.
while (n > 0) {
if (bytePtr >= bytes.length) {
throw "Error! Overflowed the bit stream! n=" + n + ", bytePtr=" + bytePtr + ", bytes.length=" +
bytes.length + ", bitPtr=" + bitPtr;
return -1;
}
const numBitsLeftInThisByte = (8 - bitPtr);
if (n >= numBitsLeftInThisByte) {
result <<= numBitsLeftInThisByte;
result |= (bitjs.io.BitStream.BITMASK[numBitsLeftInThisByte] & bytes[bytePtr]);
bytePtr++;
bitPtr = 0;
n -= numBitsLeftInThisByte;
}
else {
result <<= n;
result |= ((bytes[bytePtr] & (bitjs.io.BitStream.BITMASK[n] << (8 - n - bitPtr))) >> (8 - n - bitPtr));
bitPtr += n;
n = 0;
}
}
if (movePointers) {
this.bitPtr = bitPtr;
this.bytePtr = bytePtr;
}
return result;
}
/**
* Peek at 16 bits from current position in the buffer.
* Bit at (bytePtr,bitPtr) has the highest position in returning data.
* Taken from getbits.hpp in unrar.
* TODO: Move this out of BitStream and into unrar.
*/
getBits() {
return (((((this.bytes[this.bytePtr] & 0xff) << 16) +
((this.bytes[this.bytePtr+1] & 0xff) << 8) +
((this.bytes[this.bytePtr+2] & 0xff))) >>> (8-this.bitPtr)) & 0xffff);
}
/**
* Reads n bits out of the stream, consuming them (moving the bit pointer).
* @param {number} n The number of bits to read.
* @return {number} The read bits, as an unsigned number.
*/
readBits(n) {
return this.peekBits(n, true);
}
/**
* This returns n bytes as a sub-array, advancing the pointer if movePointers
* is true. Only use this for uncompressed blocks as this throws away remaining
* bits in the current byte.
* @param {number} n The number of bytes to peek.
* @param {boolean=} movePointers Whether to move the pointer, defaults false.
* @return {Uint8Array} The subarray.
*/
peekBytes(n, opt_movePointers) {
if (n <= 0 || typeof n != typeof 1) {
return 0;
}
// from http://tools.ietf.org/html/rfc1951#page-11
// "Any bits of input up to the next byte boundary are ignored."
while (this.bitPtr != 0) {
this.readBits(1);
}
const movePointers = opt_movePointers || false;
let bytePtr = this.bytePtr;
let bitPtr = this.bitPtr;
const result = this.bytes.subarray(bytePtr, bytePtr + n);
if (movePointers) {
this.bytePtr += n;
}
return result;
}
/**
* @param {number} n The number of bytes to read.
* @return {Uint8Array} The subarray.
*/
readBytes(n) {
return this.peekBytes(n, true);
}
}
// mask for getting N number of bits (0-8)
bitjs.io.BitStream.BITMASK = [0, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF ];

117
vendor/bitjs/io/bytebuffer.js vendored Normal file
View file

@ -0,0 +1,117 @@
/*
* bytestream.js
*
* Provides a writer for bytes.
*
* Licensed under the MIT License
*
* Copyright(c) 2011 Google Inc.
* Copyright(c) 2011 antimatter15
*/
var bitjs = bitjs || {};
bitjs.io = bitjs.io || {};
/**
* A write-only Byte buffer which uses a Uint8 Typed Array as a backing store.
*/
bitjs.io.ByteBuffer = class {
/**
* @param {number} numBytes The number of bytes to allocate.
*/
constructor(numBytes) {
if (typeof numBytes != typeof 1 || numBytes <= 0) {
throw "Error! ByteBuffer initialized with '" + numBytes + "'";
}
this.data = new Uint8Array(numBytes);
this.ptr = 0;
}
/**
* @param {number} b The byte to insert.
*/
insertByte(b) {
// TODO: throw if byte is invalid?
this.data[this.ptr++] = b;
}
/**
* @param {Array.<number>|Uint8Array|Int8Array} bytes The bytes to insert.
*/
insertBytes(bytes) {
// TODO: throw if bytes is invalid?
this.data.set(bytes, this.ptr);
this.ptr += bytes.length;
}
/**
* Writes an unsigned number into the next n bytes. If the number is too large
* to fit into n bytes or is negative, an error is thrown.
* @param {number} num The unsigned number to write.
* @param {number} numBytes The number of bytes to write the number into.
*/
writeNumber(num, numBytes) {
if (numBytes < 1) {
throw 'Trying to write into too few bytes: ' + numBytes;
}
if (num < 0) {
throw 'Trying to write a negative number (' + num +
') as an unsigned number to an ArrayBuffer';
}
if (num > (Math.pow(2, numBytes * 8) - 1)) {
throw 'Trying to write ' + num + ' into only ' + numBytes + ' bytes';
}
// Roll 8-bits at a time into an array of bytes.
const bytes = [];
while (numBytes-- > 0) {
const eightBits = num & 255;
bytes.push(eightBits);
num >>= 8;
}
this.insertBytes(bytes);
}
/**
* Writes a signed number into the next n bytes. If the number is too large
* to fit into n bytes, an error is thrown.
* @param {number} num The signed number to write.
* @param {number} numBytes The number of bytes to write the number into.
*/
writeSignedNumber(num, numBytes) {
if (numBytes < 1) {
throw 'Trying to write into too few bytes: ' + numBytes;
}
const HALF = Math.pow(2, (numBytes * 8) - 1);
if (num >= HALF || num < -HALF) {
throw 'Trying to write ' + num + ' into only ' + numBytes + ' bytes';
}
// Roll 8-bits at a time into an array of bytes.
const bytes = [];
while (numBytes-- > 0) {
const eightBits = num & 255;
bytes.push(eightBits);
num >>= 8;
}
this.insertBytes(bytes);
}
/**
* @param {string} str The ASCII string to write.
*/
writeASCIIString(str) {
for (let i = 0; i < str.length; ++i) {
const curByte = str.charCodeAt(i);
if (curByte < 0 || curByte > 255) {
throw 'Trying to write a non-ASCII string!';
}
this.insertByte(curByte);
}
};
}

159
vendor/bitjs/io/bytestream.js vendored Normal file
View file

@ -0,0 +1,159 @@
/*
* bytestream.js
*
* Provides readers for byte streams.
*
* Licensed under the MIT License
*
* Copyright(c) 2011 Google Inc.
* Copyright(c) 2011 antimatter15
*/
var bitjs = bitjs || {};
bitjs.io = bitjs.io || {};
/**
* This object allows you to peek and consume bytes as numbers and strings
* out of an ArrayBuffer. In this buffer, everything must be byte-aligned.
*/
bitjs.io.ByteStream = class {
/**
* @param {ArrayBuffer} ab The ArrayBuffer object.
* @param {number=} opt_offset The offset into the ArrayBuffer
* @param {number=} opt_length The length of this BitStream
*/
constructor(ab, opt_offset, opt_length) {
const offset = opt_offset || 0;
const length = opt_length || ab.byteLength;
this.bytes = new Uint8Array(ab, offset, length);
this.ptr = 0;
}
/**
* Peeks at the next n bytes as an unsigned number but does not advance the
* pointer
* TODO: This apparently cannot read more than 4 bytes as a number?
* @param {number} n The number of bytes to peek at.
* @return {number} The n bytes interpreted as an unsigned number.
*/
peekNumber(n) {
// TODO: return error if n would go past the end of the stream?
if (n <= 0 || typeof n != typeof 1) {
return -1;
}
let result = 0;
// read from last byte to first byte and roll them in
let curByte = this.ptr + n - 1;
while (curByte >= this.ptr) {
result <<= 8;
result |= this.bytes[curByte];
--curByte;
}
return result;
}
/**
* Returns the next n bytes as an unsigned number (or -1 on error)
* and advances the stream pointer n bytes.
* @param {number} n The number of bytes to read.
* @return {number} The n bytes interpreted as an unsigned number.
*/
readNumber(n) {
const num = this.peekNumber( n );
this.ptr += n;
return num;
}
/**
* Returns the next n bytes as a signed number but does not advance the
* pointer.
* @param {number} n The number of bytes to read.
* @return {number} The bytes interpreted as a signed number.
*/
peekSignedNumber(n) {
let num = this.peekNumber(n);
const HALF = Math.pow(2, (n * 8) - 1);
const FULL = HALF * 2;
if (num >= HALF) num -= FULL;
return num;
}
/**
* Returns the next n bytes as a signed number and advances the stream pointer.
* @param {number} n The number of bytes to read.
* @return {number} The bytes interpreted as a signed number.
*/
readSignedNumber(n) {
const num = this.peekSignedNumber(n);
this.ptr += n;
return num;
}
/**
* This returns n bytes as a sub-array, advancing the pointer if movePointers
* is true.
* @param {number} n The number of bytes to read.
* @param {boolean} movePointers Whether to move the pointers.
* @return {Uint8Array} The subarray.
*/
peekBytes(n, movePointers) {
if (n <= 0 || typeof n != typeof 1) {
return null;
}
const result = this.bytes.subarray(this.ptr, this.ptr + n);
if (movePointers) {
this.ptr += n;
}
return result;
}
/**
* Reads the next n bytes as a sub-array.
* @param {number} n The number of bytes to read.
* @return {Uint8Array} The subarray.
*/
readBytes(n) {
return this.peekBytes(n, true);
}
/**
* Peeks at the next n bytes as a string but does not advance the pointer.
* @param {number} n The number of bytes to peek at.
* @return {string} The next n bytes as a string.
*/
peekString(n) {
if (n <= 0 || typeof n != typeof 1) {
return "";
}
let result = "";
for (let p = this.ptr, end = this.ptr + n; p < end; ++p) {
result += String.fromCharCode(this.bytes[p]);
}
return result;
}
/**
* Returns the next n bytes as an ASCII string and advances the stream pointer
* n bytes.
* @param {number} n The number of bytes to read.
* @return {string} The next n bytes as a string.
*/
readString(n) {
const strToReturn = this.peekString(n);
this.ptr += n;
return strToReturn;
}
}

1478
vendor/cbrjs/cbr.js vendored Normal file

File diff suppressed because it is too large Load diff

448
vendor/cbrjs/css/cbr.css vendored Normal file
View file

@ -0,0 +1,448 @@
/* reader */
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, font, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td {
margin: 0;
padding: 0;
border: 0;
outline: 0;
font-size: 100%;
vertical-align: baseline;
background: transparent;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
/* remember to define focus styles! */
:focus {
outline: 0;
}
/* remember to highlight inserts somehow! */
ins {
text-decoration: none;
}
del {
text-decoration: line-through;
}
/* tables still need 'cellspacing="0"' in the markup */
table {
border-collapse: collapse;
border-spacing: 0;
}
.cbr-control {
font-family: helvetica, arial, sans-serif;
font-size: 12px;
}
.cbr-control {
color: #fff;
background-color: #111;
padding: 10px;
position: fixed !important;
box-shadow: 0 0 4px #000;
}
.navigate {
top: 0;
margin: 0;
cursor: pointer;
width: 20%;
opacity: 0;
background: center no-repeat;
box-shadow: none;
padding: 0 3em;
}
.navigate > span {
color: #000;
font-size: 10em;
background-color: rgba(255, 255, 255, 0.8);
border-radius: 1em;
top: 45%;
position: relative;
}
body:not(.mobile) .navigate:hover {
opacity: 1;
}
.navigate-left {
left: 0;
}
.navigate-left > span {
float: left;
}
.navigate-right {
right: 0;
}
.navigate-right > span {
float: right;
}
.toggle-controls {
cursor: pointer;
width: 20%;
height: 20%;
left: 40%;
top: 40%;
border: none;
position: fixed;
}
#cbr-loading-overlay {
z-index: 100;
background: #000 url("img/loading.gif") no-repeat center;
}
.overlay {
opacity: 0.7;
box-shadow: none;
}
#cbr-status {
z-index: 101;
font-size: 12px;
right: 0;
bottom: 0;
margin: 8px;
border-radius: 4px;
}
#cbr-progress-bar {
width: 200px;
}
#cbr-progress-bar,
#cbr-progress-bar .progressbar-value {
height: 3px;
}
#cbr-progress-bar .progressbar-value {
width: 0;
background: #86C441;
border-color: #3E7600;
}
* {
-webkit-user-select: none;
-webkit-touch-callout: none;
-webkit-tap-highlight-color: rgba(0,0,0,0);
}
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 12px;
line-height: 20px;
color: #333;
}
button,
input,
label {
cursor: pointer;
}
.pull-left {
float: left;
}
.pull-right {
float: right;
}
.toolbar,
.panels {
position: absolute;
color: white;
/* overflow: visible; */
background: #4e4e4e;
/* left: 0; */
/* right: 0; */
width: 100%;
}
.toolbar {
/* position: fixed; */
z-index: 99;
/* margin-bottom: 0; */
box-shadow: 0 1px 10px rgba(0, 0, 0, 0.4);
opacity: 0;
transition: opacity 0.1s ease-in-out;
text-align: center;
}
.toolbar .metainfo {
font-size: 1.2em;
top: 0.5em;
}
.metainfo span {
margin: 0 0.5em;
}
.mobile .metainfo .book-title,
.mobile .metainfo .title-separator {
display: none;
}
body:not(.mobile) .toolbar:hover,
.mobile .toolbar,
.toolbar.open {
opacity: 1;
}
.toolbar div {
display: inline-block;
position: relative;
}
.toolbar .separator {
/* border: solid 1px; */
height: 1em;
opacity: 0.5;
}
.toolbar button, .sidebar button {
color: white;
border: none;
background-color: transparent;
padding: 0;
}
.toolbar div > button,
.sidebar div > button {
font-size: 1.5em;
padding: 0.5em;
margin: 0;
}
.mobile .toolbar div > button,
.mobile .sidebar div > button {
padding: 0.5em;
margin: 0;
}
body:not(.mobile) .toolbar div > button:hover,
body:not(.mobile) .sidebar div > button:hover {
color: #8CC746;
}
body:not(.mobile) .toolbar button[data-action=close]:hover {
color: #FF6464;
}
.hide {
display: none !important;
}
/* sidebar */
.sidebar.open {
box-shadow: 3px 0px 3px 0px rgba(0, 0, 0, 0.4);
display: block;
}
.sidebar {
background: #6b6b6b;
position: fixed;
top: 0;
min-width: 25em;
height: 100%;
overflow: hidden;
display: none;
z-index: 100;
}
.sidebar.wide {
width: 20%;
}
.panels {
overflow: hidden;
}
.panels .open {
background-color: #6B6B6B;
}
.view.open {
display: block !important;
}
#toc-populate.open {
display: inline-block !important;
background-color: #4e4e4e;
}
.view {
overflow-y: scroll;
display: none !important;
width: 100%;
position: absolute;
top: 3em;
bottom: 0;
text-align: center;
}
.toc-view li {
margin: 1em;
font-family: Georgia, "Times New Roman", Times, serif;
}
.toc-view img, .placeholder {
width: 100%;
position: relative;
background-color: #999;
}
.toc-view span {
position: absolute;
transform: translate3d(-3em, 3em, 0);
font-size: 5em;
font-weight: bold;
color: #F8F8F8;
text-shadow: 0.05em 0.05em 0.02em rgba(70, 70, 70, 0.8);
-webkit-text-stroke: 2px black;
background-color: rgba(255,255,255,0.7);
border-radius: 1em;
box-shadow: 0 0 0.3em rgba(255,255,255,1);
padding: 0.5em;
}
.settings-container {
text-align: left;
display: inline-block;
width: 95%;
font-size: 1em;
background: #F8F8F8;
color: #111;
padding-top: 1em;
padding-bottom: 1em;
margin-top: 1em;
border-radius: 4px;
box-shadow: 0 1px 10px rgba(0, 0, 0, 0.4);
}
.settings-container label {
margin-right: 1em;
}
.settings-container > label {
font-weight: bold;
width: 100%;
display: inline-block;
margin-bottom: 1em;
text-align: center;
}
.view .control-group input[type=range] {
width: 80%;
float: right;
margin: 0;
}
.view .control-group {
padding: 1em;
}
.view .sliders {
font-size: 1.5em;
}
.view .control-group span {
float: left;
margin: 0 2px;
clear: both;
}
.view .control-group input[type=reset] {
float: right;
}
.metadata {
padding: 1em;
margin: 1em;
}
.metadata table {
font-size: 1.2em;
color: #F8F8F8;
}
.metadata td:nth-child(1) {
font-weight: bold;
padding-right: 1em;
}
/* END sidebar */
/* progressbar (loading/unarchiving) */
.progress, .bar {
width: 100%;
height: 0.3em;
margin: 0;
padding: 0;
display: inline-block;
}
.progress {
border: none;
}
.bar {
width: 0;
background-color: red;
box-shadow: 0px 1px 3px rgba(0,0,0,.6);
}
.message {
margin: 3em;
}
.message-icons {
font-size: 3em;
color: lightgrey;
vertical-align: middle;
}
.message-text {
font-size: 1.5em;
color: #666;
}
.active {
color:black;
}
.ok {
color:green;
}
.error {
color:red;
}
/* END progressbar */

4
vendor/cbrjs/css/idevice.css vendored Normal file
View file

@ -0,0 +1,4 @@
.view {
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
}

BIN
vendor/cbrjs/img/loading.gif vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

8
vendor/epubjs/css/annotations.css vendored Normal file
View file

@ -0,0 +1,8 @@
.ui-loader {
display: none;
}
.annotator-hl {
box-shadow: none !important;
cursor: pointer !important;
}

BIN
vendor/epubjs/css/font/fontello.eot vendored Normal file

Binary file not shown.

33
vendor/epubjs/css/font/fontello.svg vendored Normal file
View file

@ -0,0 +1,33 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>Copyright (C) 2013 by original authors @ fontello.com</metadata>
<defs>
<font id="fontello" horiz-adv-x="1000" >
<font-face font-family="fontello" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
<missing-glyph horiz-adv-x="1000" />
<glyph glyph-name="search" unicode="&#xe807;" d="m643 386q0 103-74 176t-176 74t-177-74t-73-176t73-177t177-73t176 73t74 177z m286-465q0-29-22-50t-50-21q-30 0-50 21l-191 191q-100-69-223-69q-80 0-153 31t-125 84t-84 125t-31 153t31 152t84 126t125 84t153 31t152-31t126-84t84-126t31-152q0-123-69-223l191-191q21-21 21-51z" horiz-adv-x="928.6" />
<glyph glyph-name="resize-full-1" unicode="&#xe804;" d="m784 111l127 128l0-336l-335 0l128 130l-128 127l79 79z m-431 686l-129-127l128-127l-80-80l-126 128l-128-129l0 335l335 0z m0-637l-129-127l129-130l-335 0l0 336l128-128l128 128z m558 637l0-335l-127 129l-128-128l-79 80l127 127l-128 127l335 0z" horiz-adv-x="928" />
<glyph glyph-name="cancel-circled2" unicode="&#xe80f;" d="m612 248l-81-82q-6-5-13-5t-13 5l-76 77l-77-77q-5-5-13-5t-13 5l-81 82q-6 5-6 13t6 13l76 76l-76 76q-6 6-6 13t6 13l81 82q6 5 13 5t13-5l77-77l76 77q6 5 13 5t13-5l81-82q6-5 6-13t-6-13l-76-76l76-76q6-6 6-13t-6-13z m120 102q0 83-41 152t-110 111t-152 41t-153-41t-110-111t-41-152t41-152t110-111t153-41t152 41t110 111t41 152z m125 0q0-117-57-215t-156-156t-215-58t-216 58t-155 156t-58 215t58 215t155 156t216 58t215-58t156-156t57-215z" horiz-adv-x="857.1" />
<glyph glyph-name="link" unicode="&#xe80d;" d="m812 171q0 23-15 38l-116 116q-16 16-38 16q-24 0-40-18q1-1 10-10t12-12t9-11t7-14t2-15q0-23-16-38t-38-16q-8 0-15 2t-14 7t-11 9t-12 12t-10 10q-19-17-19-40q0-23 16-38l115-116q15-15 38-15q22 0 38 15l82 81q15 16 15 37z m-392 394q0 22-15 38l-115 115q-16 16-38 16q-22 0-38-15l-82-82q-16-15-16-37q0-22 16-38l116-116q15-15 38-15q23 0 40 17q-2 2-11 11t-12 12t-8 10t-7 14t-2 16q0 22 15 38t38 15q9 0 16-2t14-7t10-8t12-12t11-11q18 17 18 41z m500-394q0-67-48-113l-82-81q-46-47-113-47q-68 0-114 48l-115 115q-46 47-46 114q0 68 49 116l-49 49q-48-49-116-49q-67 0-114 47l-116 116q-47 47-47 114t47 113l82 82q47 46 114 46q67 0 114-47l114-116q47-46 47-113q0-69-49-117l49-49q48 49 116 49q67 0 114-47l116-116q47-47 47-114z" horiz-adv-x="928.6" />
<glyph glyph-name="bookmark" unicode="&#xe805;" d="m650 779q12 0 24-5q19-8 29-23t11-35v-719q0-19-11-35t-29-23q-10-4-24-4q-27 0-47 18l-246 236l-246-236q-20-19-46-19q-13 0-25 5q-18 7-29 23t-11 35v719q0 19 11 35t29 23q12 5 25 5h585z" horiz-adv-x="714.3" />
<glyph glyph-name="bookmark-empty" unicode="&#xe806;" d="m643 707h-572v-693l237 227l49 47l50-47l236-227v693z m7 72q12 0 24-5q19-8 29-23t11-35v-719q0-19-11-35t-29-23q-10-4-24-4q-27 0-47 18l-246 236l-246-236q-20-19-46-19q-13 0-25 5q-18 7-29 23t-11 35v719q0 19 11 35t29 23q12 5 25 5h585z" horiz-adv-x="714.3" />
<glyph glyph-name="download-cloud" unicode="&#xe811;" d="m714 332q0 8-5 13t-13 5h-125v196q0 8-5 13t-12 5h-108q-7 0-12-5t-5-13v-196h-125q-8 0-13-5t-5-13q0-8 5-13l196-196q5-5 13-5t13 5l196 196q5 6 5 13z m357-125q0-89-62-151t-152-63h-607q-103 0-177 73t-73 177q0 72 39 134t105 92q-1 17-1 24q0 118 84 202t202 84q87 0 159-49t105-129q40 35 93 35q59 0 101-42t42-101q0-43-23-77q72-17 119-76t46-133z" horiz-adv-x="1071.4" />
<glyph glyph-name="edit" unicode="&#xe814;" d="m496 189l64 65l-85 85l-64-65v-31h53v-54h32z m245 402q-9 9-18 0l-196-196q-9-9 0-18t18 0l196 196q9 9 0 18z m45-331v-106q0-67-47-114t-114-47h-464q-67 0-114 47t-47 114v464q0 66 47 113t114 48h464q35 0 65-14q9-4 10-13q2-10-5-16l-27-28q-8-8-18-4q-13 3-25 3h-464q-37 0-63-26t-27-63v-464q0-37 27-63t63-27h464q37 0 63 27t26 63v70q0 7 5 12l36 36q8 8 20 4t11-16z m-54 411l161-160l-375-375h-161v160z m248-73l-51-52l-161 161l51 51q16 16 38 16t38-16l85-84q16-16 16-38t-16-38z" horiz-adv-x="1000" />
<glyph glyph-name="menu" unicode="&#xe802;" d="m857 100v-71q0-15-10-25t-26-11h-785q-15 0-25 11t-11 25v71q0 15 11 25t25 11h785q15 0 26-11t10-25z m0 286v-72q0-14-10-25t-26-10h-785q-15 0-25 10t-11 25v72q0 14 11 25t25 10h785q15 0 26-10t10-25z m0 285v-71q0-15-10-25t-26-11h-785q-15 0-25 11t-11 25v71q0 15 11 26t25 10h785q15 0 26-10t10-26z" horiz-adv-x="857.1" />
<glyph glyph-name="cog" unicode="&#xe813;" d="m571 350q0 59-41 101t-101 42t-101-42t-42-101t42-101t101-42t101 42t41 101z m286 61v-124q0-7-4-13t-11-7l-104-16q-10-30-21-51q19-27 59-77q6-6 6-13t-5-13q-15-21-55-61t-53-39q-7 0-14 5l-77 60q-25-13-51-21q-9-76-16-104q-4-16-20-16h-124q-8 0-14 5t-6 12l-16 103q-27 9-50 21l-79-60q-6-5-14-5q-8 0-14 6q-70 64-92 94q-4 5-4 13q0 6 5 12q8 12 28 37t30 40q-15 28-23 55l-102 15q-7 1-11 7t-5 13v124q0 7 5 13t10 7l104 16q8 25 22 51q-23 32-60 77q-6 7-6 14q0 5 5 12q15 20 55 60t53 40q7 0 15-5l77-60q24 13 50 21q9 76 17 104q3 15 20 15h124q7 0 13-4t7-12l15-103q28-9 50-21l80 60q5 5 13 5q7 0 14-5q72-67 92-95q4-5 4-13q0-6-4-12q-9-12-29-38t-30-39q14-28 23-55l102-15q7-1 12-7t4-13z" horiz-adv-x="857.1" />
<glyph glyph-name="resize-full" unicode="&#xe812;" d="m421 261q0-8-5-13l-185-185l80-81q10-10 10-25t-10-25t-25-11h-250q-15 0-25 11t-11 25v250q0 15 11 25t25 11t25-11l80-80l185 185q6 6 13 6t13-6l64-63q5-6 5-13z m436 482v-250q0-15-10-25t-26-11t-25 11l-80 80l-185-185q-6-6-13-6t-13 6l-64 63q-5 6-5 13t5 13l186 185l-81 81q-10 10-10 25t10 25t25 11h250q15 0 26-11t10-25z" horiz-adv-x="857.1" />
<glyph glyph-name="cancel-circled" unicode="&#xe80e;" d="m641 224q0 14-10 25l-101 101l101 101q10 11 10 25q0 15-10 26l-51 50q-10 11-25 11q-15 0-25-11l-101-101l-101 101q-11 11-26 11q-15 0-25-11l-50-50q-11-11-11-26q0-14 11-25l101-101l-101-101q-11-11-11-25q0-15 11-26l50-50q10-11 25-11q15 0 26 11l101 101l101-101q10-11 25-11q15 0 25 11l51 50q10 11 10 26z m216 126q0-117-57-215t-156-156t-215-58t-216 58t-155 156t-58 215t58 215t155 156t216 58t215-58t156-156t57-215z" horiz-adv-x="857.1" />
<glyph glyph-name="up-dir" unicode="&#xe80c;" d="m571 171q0-14-10-25t-25-10h-500q-15 0-25 10t-11 25t11 26l250 250q10 10 25 10t25-10l250-250q10-11 10-26z" horiz-adv-x="571.4" />
<glyph glyph-name="right-dir" unicode="&#xe80b;" d="m321 350q0-14-10-25l-250-250q-11-11-25-11t-25 11t-11 25v500q0 15 11 25t25 11t25-11l250-250q10-10 10-25z" horiz-adv-x="357.1" />
<glyph glyph-name="angle-right" unicode="&#xe809;" d="m332 314q0-7-6-13l-260-260q-5-5-12-5t-13 5l-28 28q-6 6-6 13t6 13l219 219l-219 220q-6 5-6 12t6 13l28 28q5 6 13 6t12-6l260-260q6-5 6-13z" horiz-adv-x="357.1" />
<glyph glyph-name="angle-down" unicode="&#xe80a;" d="m600 439q0-7-6-13l-260-260q-5-5-13-5t-12 5l-260 260q-6 6-6 13t6 13l27 28q6 6 13 6t13-6l219-219l220 219q5 6 13 6t12-6l28-28q6-5 6-13z" horiz-adv-x="642.9" />
<glyph glyph-name="right" unicode="&#xe815;" d="m1000 404v-108q0-7-5-12t-13-5h-696v-125q0-12-11-17t-19 3l-215 196q-5 5-5 12q0 8 5 14l215 197q9 8 19 4q11-5 11-17v-125h696q8 0 13-5t5-12z" horiz-adv-x="1000" />
<glyph glyph-name="list-1" unicode="&#xe803;" d="m143 118v-107q0-7-5-13t-13-5h-107q-7 0-13 5t-5 13v107q0 7 5 12t13 6h107q7 0 13-6t5-12z m0 214v-107q0-7-5-13t-13-5h-107q-7 0-13 5t-5 13v107q0 7 5 13t13 5h107q7 0 13-5t5-13z m0 214v-107q0-7-5-12t-13-6h-107q-7 0-13 6t-5 12v107q0 8 5 13t13 5h107q7 0 13-5t5-13z m857-428v-107q0-7-5-13t-13-5h-750q-7 0-12 5t-6 13v107q0 7 6 12t12 6h750q7 0 13-6t5-12z m-857 643v-107q0-8-5-13t-13-5h-107q-7 0-13 5t-5 13v107q0 7 5 12t13 6h107q7 0 13-6t5-12z m857-429v-107q0-7-5-13t-13-5h-750q-7 0-12 5t-6 13v107q0 7 6 13t12 5h750q7 0 13-5t5-13z m0 214v-107q0-7-5-12t-13-6h-750q-7 0-12 6t-6 12v107q0 8 6 13t12 5h750q7 0 13-5t5-13z m0 215v-107q0-8-5-13t-13-5h-750q-7 0-12 5t-6 13v107q0 7 6 12t12 6h750q7 0 13-6t5-12z" horiz-adv-x="1000" />
<glyph glyph-name="list-numbered" unicode="&#xe801;" d="m213-54q0-45-31-70t-75-26q-60 0-96 37l31 49q28-25 60-25q16 0 28 8t12 24q0 35-59 31l-14 31q4 6 18 24t24 31t20 21v1q-9 0-27-1t-27 0v-30h-59v85h186v-49l-53-65q28-6 45-27t17-49z m1 350v-89h-202q-4 20-4 30q0 29 14 52t31 38t37 27t31 24t14 25q0 14-9 22t-22 7q-25 0-45-32l-47 33q13 28 40 44t59 16q40 0 68-23t28-63q0-28-19-51t-42-36t-42-28t-20-30h71v34h59z m786-178v-107q0-8-5-13t-13-5h-678q-8 0-13 5t-5 13v107q0 8 5 13t13 5h678q7 0 13-6t5-12z m-786 502v-56h-187v56h60q0 22 0 68t1 67v7h-1q-5-10-28-30l-40 42l76 71h59v-225h60z m786-216v-108q0-7-5-12t-13-5h-678q-8 0-13 5t-5 12v108q0 7 5 12t13 5h678q7 0 13-5t5-12z m0 285v-107q0-7-5-12t-13-6h-678q-8 0-13 6t-5 12v107q0 8 5 13t13 5h678q7 0 13-5t5-13z" horiz-adv-x="1000" />
<glyph glyph-name="columns" unicode="&#xe810;" d="m89-7h340v643h-358v-625q0-8 6-13t12-5z m768 18v625h-357v-643h339q8 0 13 5t5 13z m72 678v-678q0-37-27-63t-63-27h-750q-36 0-63 27t-26 63v678q0 37 26 63t63 27h750q37 0 63-27t27-63z" horiz-adv-x="928.6" />
<glyph glyph-name="list" unicode="&#xe800;" d="m100 200q20 0 35-15t15-35t-15-35t-35-15l-50 0q-20 0-35 15t-15 35t14 35t36 15l50 0z m0 200q20 0 35-15t15-35t-15-35t-35-15l-50 0q-20 0-35 15t-15 35t14 35t36 15l50 0z m0 200q20 0 35-15t15-35t-15-35t-35-15l-50 0q-20 0-35 15t-15 35t14 35t36 15l50 0z m200-100q-20 0-35 15t-15 35t15 35t35 15l350 0q22 0 36-15t14-35t-15-35t-35-15l-350 0z m350-100q22 0 36-15t14-35t-15-35t-35-15l-350 0q-20 0-35 15t-15 35t15 35t35 15l350 0z m0-200q22 0 36-15t14-35t-15-35t-35-15l-350 0q-20 0-35 15t-15 35t15 35t35 15l350 0z" horiz-adv-x="700" />
<glyph glyph-name="resize-small" unicode="&#xe808;" d="m429 314v-250q0-14-11-25t-25-10t-25 10l-81 81l-185-186q-5-5-13-5t-13 5l-63 64q-6 5-6 13t6 13l185 185l-80 80q-11 11-11 25t11 25t25 11h250q14 0 25-11t11-25z m421 375q0-7-6-13l-185-185l80-80q11-11 11-25t-11-25t-25-11h-250q-14 0-25 11t-10 25v250q0 14 10 25t25 10t25-10l81-81l185 186q6 5 13 5t13-5l63-64q6-5 6-13z" horiz-adv-x="857.1" />
</font>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 9.4 KiB

BIN
vendor/epubjs/css/font/fontello.ttf vendored Normal file

Binary file not shown.

BIN
vendor/epubjs/css/font/fontello.woff vendored Normal file

Binary file not shown.

14
vendor/epubjs/css/idevice.css vendored Normal file
View file

@ -0,0 +1,14 @@
.notes,
.search-results,
.view {
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
}
.search-results {
height: calc(100% - 5em);
}
.notes {
height: calc(100% - 9em);
}

347
vendor/epubjs/css/main.css vendored Normal file
View file

@ -0,0 +1,347 @@
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, font, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
fieldset {
margin: 0;
padding: 0;
border: 0;
outline: 0;
font-size: 100%;
vertical-align: baseline;
background: transparent;
}
body {
background: #4e4e4e;
overflow: hidden;
font-style:
}
#main {
position: absolute;
width: 100%;
height: 100%;
right: 0;
border-radius: 5px;
background: #fff;
overflow: hidden;
-webkit-transition: -webkit-transform .4s, width .2s;
-moz-transition: -webkit-transform .4s, width .2s;
-moz-box-shadow: inset 0 0 50px rgba(0,0,0,.1);
-webkit-box-shadow: inset 0 0 50px rgba(0,0,0,.1);
box-shadow: inset 0 0 50px rgba(0,0,0,.1);
}
#titlebar {
padding: 0.5em;
color: #4f4f4f;
font-weight: 100;
font-family: Georgia, "Times New Roman", Times, serif;
opacity: .5;
text-align: center;
-webkit-transition: opacity .5s;
-moz-transition: opacity .5s;
z-index: 10;
position: fixed;
width: 100%;
}
#titlebar:hover {
opacity: 1;
}
#titlebar a {
width: 1em;
height: 1em;
overflow: hidden;
display: inline-block;
opacity: .5;
padding: 0.2em;
border-radius: 0.2em;
border: 1px rgba(0,0,0,0) solid;
}
#titlebar a::before {
visibility: visible;
}
#titlebar a:hover {
opacity: .8;
border: 1px rgba(0,0,0,.2) solid;
}
#titlebar a:active {
opacity: 1;
color: rgba(0,0,0,.6);
box-shadow: inset 0 0 6px rgba(155,155,155,.8);
}
#book-title {
font-weight: 600;
}
#title-separator {
display: none;
}
#title-controls,
#opener {
margin-left: 0.3em;
margin-right: 0.3em;
position: fixed;
top: 0.3em;
}
#opener {
left: 0;
}
#metainfo {
position: fixed;
/* width: 80%;
left: 10%; */
width: 50%;
width: calc(100% - 7.5em);
left: 1.5em;
top: 0.3em;
padding: 0.2em;
height: 1em;
overflow: hidden;
text-align: center;
}
#title-controls {
right: 0;
}
#viewer {
width: 80%;
height: 80%;
top: 10%;
margin: auto;
max-width: 72em;
z-index: 2;
position: relative;
overflow: hidden;
}
#viewer iframe {
border: none;
}
#prev, #next {
position: absolute;
top: 10%;
height: 80%;
margin: 0;
}
.touch_nav {
width: 35%;
}
.arrow div {
display: table-cell;
vertical-align: middle;
}
#prev {
left: 0;
padding-left: 2em;
}
#next {
right: 0;
padding-right: 2em;
text-align: right;
}
.arrow {
font-size: 64px;
/* color: #E2E2E2; */
font-family: arial, sans-serif;
font-weight: bold;
cursor: pointer;
display: table;
z-index: 3;
opacity: 0.2;
}
.arrow:hover {
/* color: #777; */
opacity: 0.5;
}
.arrow:active,
.arrow.active {
color: #000;
}
#main.closed {
transform: translate(25em, 0);
}
#main.single {
width: calc(100% - 25em);
}
#divider {
position: absolute;
width: 1px;
border-right: 1px #000 solid;
height: 80%;
z-index: 100;
left: 50%;
margin-left: -1px;
top: 10%;
opacity: .15;
box-shadow: -2px 0 15px rgba(0, 0, 0, 1);
display: none;
}
#divider.show {
display: block;
}
#loader {
position: absolute;
z-index: 10;
left: 50%;
top: 50%;
margin: -33px 0 0 -33px;
}
.pull-left {
float: left;
}
.pull-right {
float: right;
}
.highlight {
background-color: yellow;
}
.overlay {
position: fixed;
width: 100%;
height: 100%;
visibility: hidden;
top: 0;
left: 0;
z-index: 1000;
opacity: 0;
background: rgba(255,255,255,0.8);
-webkit-transition: all 0.3s;
-moz-transition: all 0.3s;
transition: all 0.3s;
}
.hide {
display: none !important;
}
.translucent {
opacity: 0 !important;
}
@media only screen and (max-width: 1040px) {
/*
#viewer{
width: 50%;
margin-left: 25%;
}
*/
#divider,
#divider.show {
display: none;
}
}
@media only screen and (max-width: 900px) {
/*
#viewer{
width: 60%;
margin-left: 20%;
}
*/
#prev {
padding-left: 20px;
}
#next {
padding-right: 20px;
}
}
@media only screen and (max-width: 550px) {
/*
#viewer{
width: 80%;
margin-left: 10%;
}
*/
#viewer {
width: 95%;
}
#prev {
padding-left: 0;
}
#next {
padding-right: 0;
}
.arrow div {
text-indent: 100%;
white-space: nowrap;
overflow: hidden;
}
/*
#main {
-webkit-transform: translate(0, 0);
-moz-transform: translate(0, 0);
-webkit-transition: -webkit-transform .3s;
-moz-transition: -moz-transform .3s;
}
#main.closed {
-webkit-transform: translate(260px, 0);
-moz-transform: translate(260px, 0);
}
*/
#titlebar {
/* font-size: 16px; */
/* margin: 0 50px 0 50px; */
}
#metainfo span {
font-size: 0.5em;
}
/*
#tocView {
width: 260px;
}
#tocView li {
font-size: 12px;
}
#tocView > ul{
padding-left: 10px;
-webkit-padding-start:;
}
*/
}

505
vendor/epubjs/css/normalize.css vendored Normal file
View file

@ -0,0 +1,505 @@
/*! normalize.css v1.0.1 | MIT License | git.io/normalize */
/* ==========================================================================
HTML5 display definitions
========================================================================== */
/*
* Corrects `block` display not defined in IE 6/7/8/9 and Firefox 3.
*/
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
nav,
section,
summary {
display: block;
}
/*
* Corrects `inline-block` display not defined in IE 6/7/8/9 and Firefox 3.
*/
audio,
canvas,
video {
display: inline-block;
*display: inline;
*zoom: 1;
}
/*
* Prevents modern browsers from displaying `audio` without controls.
* Remove excess height in iOS 5 devices.
*/
audio:not([controls]) {
display: none;
height: 0;
}
/*
* Addresses styling for `hidden` attribute not present in IE 7/8/9, Firefox 3,
* and Safari 4.
* Known issue: no IE 6 support.
*/
[hidden] {
display: none;
}
/* ==========================================================================
Base
========================================================================== */
/*
* 1. Corrects text resizing oddly in IE 6/7 when body `font-size` is set using
* `em` units.
* 2. Prevents iOS text size adjust after orientation change, without disabling
* user zoom.
*/
html {
font-size: 100%; /* 1 */
-webkit-text-size-adjust: 100%; /* 2 */
-ms-text-size-adjust: 100%; /* 2 */
}
/*
* Addresses `font-family` inconsistency between `textarea` and other form
* elements.
*/
html,
button,
input,
select,
textarea {
font-family: sans-serif;
}
/*
* Addresses margins handled incorrectly in IE 6/7.
*/
body {
margin: 0;
}
/* ==========================================================================
Links
========================================================================== */
/*
* Addresses `outline` inconsistency between Chrome and other browsers.
*/
a:focus {
outline: thin dotted;
}
/*
* Improves readability when focused and also mouse hovered in all browsers.
*/
a:active,
a:hover {
outline: 0;
}
/* ==========================================================================
Typography
========================================================================== */
/*
* Addresses font sizes and margins set differently in IE 6/7.
* Addresses font sizes within `section` and `article` in Firefox 4+, Safari 5,
* and Chrome.
*/
h1 {
font-size: 2em;
margin: 0.67em 0;
}
h2 {
font-size: 1.5em;
margin: 0.83em 0;
}
h3 {
font-size: 1.17em;
margin: 1em 0;
}
h4 {
font-size: 1em;
margin: 1.33em 0;
}
h5 {
font-size: 0.83em;
margin: 1.67em 0;
}
h6 {
font-size: 0.75em;
margin: 2.33em 0;
}
/*
* Addresses styling not present in IE 7/8/9, Safari 5, and Chrome.
*/
abbr[title] {
border-bottom: 1px dotted;
}
/*
* Addresses style set to `bolder` in Firefox 3+, Safari 4/5, and Chrome.
*/
b,
strong {
font-weight: bold;
}
blockquote {
margin: 1em 40px;
}
/*
* Addresses styling not present in Safari 5 and Chrome.
*/
dfn {
font-style: italic;
}
/*
* Addresses styling not present in IE 6/7/8/9.
*/
mark {
background: #ff0;
color: #000;
}
/*
* Addresses margins set differently in IE 6/7.
*/
p,
pre {
margin: 1em 0;
}
/*
* Corrects font family set oddly in IE 6, Safari 4/5, and Chrome.
*/
code,
kbd,
pre,
samp {
font-family: monospace, serif;
_font-family: 'courier new', monospace;
font-size: 1em;
}
/*
* Improves readability of pre-formatted text in all browsers.
*/
pre {
white-space: pre;
white-space: pre-wrap;
word-wrap: break-word;
}
/*
* Addresses CSS quotes not supported in IE 6/7.
*/
q {
quotes: none;
}
/*
* Addresses `quotes` property not supported in Safari 4.
*/
q:before,
q:after {
content: '';
content: none;
}
/*
* Addresses inconsistent and variable font size in all browsers.
*/
small {
font-size: 80%;
}
/*
* Prevents `sub` and `sup` affecting `line-height` in all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sup {
top: -0.5em;
}
sub {
bottom: -0.25em;
}
/* ==========================================================================
Lists
========================================================================== */
/*
* Addresses margins set differently in IE 6/7.
*/
dl,
menu,
ol,
ul {
margin: 1em 0;
}
dd {
margin: 0 0 0 40px;
}
/*
* Addresses paddings set differently in IE 6/7.
*/
menu,
ol,
ul {
padding: 0 0 0 40px;
}
/*
* Corrects list images handled incorrectly in IE 7.
*/
nav ul,
nav ol {
list-style: none;
list-style-image: none;
}
/* ==========================================================================
Embedded content
========================================================================== */
/*
* 1. Removes border when inside `a` element in IE 6/7/8/9 and Firefox 3.
* 2. Improves image quality when scaled in IE 7.
*/
img {
border: 0; /* 1 */
-ms-interpolation-mode: bicubic; /* 2 */
}
/*
* Corrects overflow displayed oddly in IE 9.
*/
svg:not(:root) {
overflow: hidden;
}
/* ==========================================================================
Figures
========================================================================== */
/*
* Addresses margin not present in IE 6/7/8/9, Safari 5, and Opera 11.
*/
figure {
margin: 0;
}
/* ==========================================================================
Forms
========================================================================== */
/*
* Corrects margin displayed oddly in IE 6/7.
*/
form {
margin: 0;
}
/*
* Define consistent border, margin, and padding.
*/
fieldset {
border: 1px solid #c0c0c0;
margin: 0 2px;
padding: 0.35em 0.625em 0.75em;
}
/*
* 1. Corrects color not being inherited in IE 6/7/8/9.
* 2. Corrects text not wrapping in Firefox 3.
* 3. Corrects alignment displayed oddly in IE 6/7.
*/
legend {
border: 0; /* 1 */
padding: 0;
white-space: normal; /* 2 */
*margin-left: -7px; /* 3 */
}
/*
* 1. Corrects font size not being inherited in all browsers.
* 2. Addresses margins set differently in IE 6/7, Firefox 3+, Safari 5,
* and Chrome.
* 3. Improves appearance and consistency in all browsers.
*/
button,
input,
select,
textarea {
font-size: 100%; /* 1 */
margin: 0; /* 2 */
vertical-align: baseline; /* 3 */
*vertical-align: middle; /* 3 */
}
/*
* Addresses Firefox 3+ setting `line-height` on `input` using `!important` in
* the UA stylesheet.
*/
button,
input {
line-height: normal;
}
/*
* 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
* and `video` controls.
* 2. Corrects inability to style clickable `input` types in iOS.
* 3. Improves usability and consistency of cursor style between image-type
* `input` and others.
* 4. Removes inner spacing in IE 7 without affecting normal text inputs.
* Known issue: inner spacing remains in IE 6.
*/
button,
html input[type="button"], /* 1 */
input[type="reset"],
input[type="submit"] {
-webkit-appearance: button; /* 2 */
cursor: pointer; /* 3 */
*overflow: visible; /* 4 */
}
/*
* Re-set default cursor for disabled elements.
*/
button[disabled],
input[disabled] {
cursor: default;
}
/*
* 1. Addresses box sizing set to content-box in IE 8/9.
* 2. Removes excess padding in IE 8/9.
* 3. Removes excess padding in IE 7.
* Known issue: excess padding remains in IE 6.
*/
input[type="checkbox"],
input[type="radio"] {
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
*height: 13px; /* 3 */
*width: 13px; /* 3 */
}
/*
* 1. Addresses `appearance` set to `searchfield` in Safari 5 and Chrome.
* 2. Addresses `box-sizing` set to `border-box` in Safari 5 and Chrome
* (include `-moz` to future-proof).
*/
/*
input[type="search"] {
-webkit-appearance: textfield;
-moz-box-sizing: content-box;
-webkit-box-sizing: content-box;
box-sizing: content-box;
}
*/
/*
* Removes inner padding and search cancel button in Safari 5 and Chrome
* on OS X.
*/
/* input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
} */
/*
* Removes inner padding and border in Firefox 3+.
*/
button::-moz-focus-inner,
input::-moz-focus-inner {
border: 0;
padding: 0;
}
/*
* 1. Removes default vertical scrollbar in IE 6/7/8/9.
* 2. Improves readability and alignment in all browsers.
*/
textarea {
overflow: auto; /* 1 */
vertical-align: top; /* 2 */
}
/* ==========================================================================
Tables
========================================================================== */
/*
* Remove most spacing between table cells.
*/
table {
border-collapse: collapse;
border-spacing: 0;
}

109
vendor/epubjs/css/popup.css vendored Normal file
View file

@ -0,0 +1,109 @@
/* http://davidwalsh.name/css-tooltips */
/* base CSS element */
.popup {
background: #eee;
border: 1px solid #ccc;
padding: 10px;
border-radius: 8px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
position: fixed;
max-width: 300px;
font-size: 12px;
display: none;
margin-left: 2px;
margin-top: 30px;
}
.popup.above {
margin-top: -10px;
}
.popup.left {
margin-left: -20px;
}
.popup.right {
margin-left: 40px;
}
.pop_content {
max-height: 225px;
overflow-y: auto;
}
.pop_content > p {
margin-top: 0;
}
/* below */
.popup:before {
position: absolute;
display: inline-block;
border-bottom: 10px solid #eee;
border-right: 10px solid transparent;
border-left: 10px solid transparent;
border-bottom-color: rgba(0, 0, 0, 0.2);
left: 50%;
top: -10px;
margin-left: -6px;
content: '';
}
.popup:after {
position: absolute;
display: inline-block;
border-bottom: 9px solid #eee;
border-right: 9px solid transparent;
border-left: 9px solid transparent;
left: 50%;
top: -9px;
margin-left: -5px;
content: '';
}
/* above */
.popup.above:before {
border-bottom: none;
border-top: 10px solid #eee;
border-top-color: rgba(0, 0, 0, 0.2);
top: 100%;
}
.popup.above:after {
border-bottom: none;
border-top: 9px solid #eee;
top: 100%;
}
.popup.left:before,
.popup.left:after
{
left: 20px;
}
.popup.right:before,
.popup.right:after
{
left: auto;
right: 20px;
}
.popup.show, .popup.on {
display: block;
}
.note-marker,
.EPUBJS-CFI-MARKER,
.EPUBJS-CFI-SPLIT {
vertical-align: super;
font-size: 0.75em;
line-height: 1em;
padding: 0.1em;
background-color: #fffa96;
border-radius: 5px;
cursor: pointer;
}

494
vendor/epubjs/css/sidebar.css vendored Normal file
View file

@ -0,0 +1,494 @@
/* sidebar */
.sidebar.open {
box-shadow: 3px 0px 3px 0px rgba(0, 0, 0, 0.4);
display: block;
}
.sidebar {
background: #6b6b6b;
position: fixed;
top: 0;
min-width: 25em;
height: 100%;
overflow: hidden;
display: none;
z-index: 100;
}
.sidebar.wide {
width: 20%;
}
.toolbar,
.panels {
position: absolute;
width: 100%;
height: 2em;
background: #4e4e4e;
/* above titlebar controls */
z-index: 3;
}
.toolbar {
text-align: center;
}
.toolbar .metainfo {
font-size: 1.2em;
top: 0.5em;
}
.toolbar div {
display: inline-block;
position: relative;
}
.toolbar .separator {
/* border: solid 1px; */
height: 1em;
opacity: 0.5;
}
.toolbar button, .sidebar button {
color: white;
border: none;
background-color: transparent;
padding: 0;
}
.sidebar div > button {
/* font-size: 1.5em; */
/* font-size: 1em; */
padding: 0.4em;
margin: 0;
}
.mobile .sidebar div > button {
padding: 0.5em;
margin: 0;
}
.sidebar div > button:hover {
color: #8CC746;
}
.panels .open {
background-color: #6B6B6B;
}
.view.open {
display: block !important;
}
.view {
overflow-x: hidden;
display: none !important;
width: 100%;
position: absolute;
top: 2em;
bottom: 0;
}
.list_item a {
color: #AAA;
text-decoration: none;
}
.list_item a.chapter {
font-size: 1em;
}
.list_item a.section {
font-size: .8em;
}
.list_item.currentChapter > a,
.list_item a:hover {
color: #f1f1f1
}
.list_item a:hover {
color: #E2E2E2;
}
.list_item ul {
display: none;
}
.list_item.currentChapter > ul,
.list_item.openChapter > ul {
display: block;
}
legend {
margin-left: 1em;
padding: 0.5em;
box-shadow: 0 1px 10px rgba(0, 0, 0, 0.4);
}
.settings-container {
text-align: left;
margin: 1em;
background: #F8F8F8;
color: #111;
border-radius: 4px;
box-shadow: 0 1px 10px rgba(0, 0, 0, 0.4);
}
.settings-container > legend {
position: relative;
top: 1em;
margin-bottom: 1em;
text-align: center;
font-weight: 600;
box-shadow: none;
}
.settings-container label {
margin-right: 1em;
}
.center-box {
text-align: center;
margin: 1em;
}
.font_example {
margin: 1em;
text-align: center;
box-shadow: inset 0 1px 10px rgba(0, 0, 0, 0.4);
}
.font_example div {
padding: 1em;
}
.view .control-group input[type=range] {
width: 90%;
float: right;
margin: 0;
}
.view .control-group {
padding: 1em;
}
.view .sliders {
font-size: 1.5em;
}
.view .control-group span {
float: left;
margin: 0 2px;
clear: both;
}
.view .control-group input[type=reset] {
float: right;
}
.metadata {
padding: 1em;
margin: 1em;
}
.metadata table {
font-size: 1.2em;
color: #F8F8F8;
}
.metadata td:nth-child(1) {
font-weight: bold;
padding-right: 1em;
}
/* panels */
.panels a {
visibility: hidden;
overflow: hidden;
display: inline-block;
color: #ccc;
}
.panels a::before {
visibility: visible;
}
.panels a:hover {
color: #AAA;
}
.panels a:active {
color: #AAA;
margin: 1px 0 -1px 6px;
}
.panels a.active,
.panels a.active:hover {
color: #AAA;
}
/* END panels */
/* TOC (and search, and bookmarks) */
.toc_toggle {
display: inline-block;
width: 14px;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
.toc_toggle:before {
content: '▸';
color: #fff;
margin-right: -4px;
}
.currentChapter > .toc_toggle:before,
.openChapter > .toc_toggle:before {
content: '▾';
}
#toc-populate.open {
display: inline-block !important;
background-color: #4e4e4e;
}
.toc-view li,
.bookmarks-view li,
.search-view li {
margin: 1em;
font-family: Georgia, "Times New Roman", Times, serif;
list-style: none;
}
.toc-view li {
text-transform: capitalize;
}
.toc-vew.hidden {
display: none;
}
.bookmark_link_text {
float: right;
font-size: 75%;
margin: 1em;
color: #AAA;
}
/* END TOC */
/* search */
.search-view,
.notes-view {
overflow: hidden;
}
.search-results {
overflow-y: scroll;
height: 95%;
height: calc(100vh - 5em);
}
.search-input {
padding-top: 1em;
padding-bottom: 1em;
box-shadow: 0 1px 10px rgba(0, 0, 0, 0.4);
}
.searchbox {
width: 80%;
float: left;
margin-left: 1em;
}
.searchbox + span {
position: relative;
left: -1em;
visibility: hidden;
font-weight: bold;
font-family: sans-serif;
cursor: pointer;
}
.searchbox + span:hover {
color: red;
}
#clear_search {
padding: 0;
padding-right: 0.5em;
}
/* END search */
/* notes */
.notes-input {
padding-top: 1em;
padding-bottom: 2em;
box-shadow: 0 1px 10px rgba(0, 0, 0, 0.4);
}
.notes {
overflow-y: scroll;
height: 95%;
height: calc(100vh - 11em);
}
.notes li,
.bookmarks li {
margin: 1em 1em 1em 0.5em;
padding: 0.25em 0 0 0.5em;
font-family: Georgia, "Times New Roman", Times, serif;
/* border-top: 1px #eee dotted; */
color: #ccc;
padding-bottom: 0.5em;
border-left: 0.5em solid transparent;
}
.notes li:hover,
.bookmarks li:hover {
border-left: 0.5em solid #eee;
}
.notes li:hover span,
.notes li:hover a,
.bookmarks li:hover span,
.bookmarks li:hover a {
color: #fff;
}
.item-date {
text-align: right;
font-size: 0.8em;
padding-top: 0.5em;
color: #bbb;
}
.item-delete,
.item-edit,
.item-save,
.item-cancel,
.note-link {
color: #999;
display: inline-block;
text-decoration: none;
margin-right: 0.5em;
margin-top: 0.5em;
cursor: pointer;
}
.item-save,
.item-cancel {
background-color: #ccc;
padding: 0.2em 0.4em;
border: 1px solid #ccc;
border-radius: 0.2em;
}
.item-save:hover,
.item-cancel:hover {
background-color: #eee;
border: 1px solid white;
}
.item-save {
color: green !important;
}
.item-cancel {
color: red !important;
}
.note-link {
float: right;
margin-right: 0;
}
.note-delete,
.note-edit {
float: left;
}
div.editable {
background-color: #EEE;
color: #111;
/* border: 1px dotted white; */
border-radius: 0.2em;
padding: 0.25em;
box-shadow: inset 0 1px 10px rgba(0, 0, 0, 0.4);
}
.notes li a:hover,
.bookmarks li a:hover {
text-decoration: underline;
}
.notes li img {
}
.note-text {
text-align: left;
display: block;
width: calc(100% - 2em);
height: 6em;
margin-left: 1em;
margin-right: 1em;
margin-bottom: 1em;
border-radius: 4px;
}
.note-text[disabled], #note-text[disabled="disabled"]{
opacity: .5;
}
.note-anchor {
font-size: 1.5em;
padding: 0 !important;
margin-right: 0.5em !important;
}
.note-marker {
vertical-align: super;
font-size: 0.75em;
line-height: 1em;
padding: 0.1em;
background-color: #fffa96;
border-radius: 5px;
cursor: pointer;
}
/* END notes */
/* margins */
.margin-icon {
float: none !important;
font-size: 3em;
vertical-align: middle;
}
/* media-specific rules */
@media only screen and (max-width: 25em) {
.sidebar {
min-width: 10em;
width: 80%;
}
#main.single {
width: 100% !important;
}
}
/* END sidebar */

778
vendor/epubjs/epub.main.css vendored Normal file
View file

@ -0,0 +1,778 @@
@font-face {
font-family: 'fontello';
src: url('font/fontello.eot?60518104');
src: url('font/fontello.eot?60518104#iefix') format('embedded-opentype'),
url('font/fontello.woff?60518104') format('woff'),
url('font/fontello.ttf?60518104') format('truetype'),
url('font/fontello.svg?60518104#fontello') format('svg');
font-weight: normal;
font-style: normal;
}
body {
background: #4e4e4e;
overflow: hidden;
}
#main {
/* height: 500px; */
position: absolute;
width: 100%;
height: 100%;
right: 0;
/* left: 40px; */
/* -webkit-transform: translate(40px, 0);
-moz-transform: translate(40px, 0); */
/* border-radius: 5px 0px 0px 5px; */
border-radius: 5px;
background: #fff;
overflow: hidden;
-webkit-transition: -webkit-transform .4s, width .2s;
-moz-transition: -webkit-transform .4s, width .2s;
-moz-box-shadow: inset 0 0 50px rgba(0,0,0,.1);
-webkit-box-shadow: inset 0 0 50px rgba(0,0,0,.1);
box-shadow: inset 0 0 50px rgba(0,0,0,.1);
}
#titlebar {
height: 8%;
min-height: 20px;
padding: 10px;
/* margin: 0 50px 0 50px; */
position: relative;
color: #4f4f4f;
font-weight: 100;
font-family: Georgia, "Times New Roman", Times, serif;
opacity: .5;
text-align: center;
-webkit-transition: opacity .5s;
-moz-transition: opacity .5s;
z-index: 10;
}
#titlebar:hover {
opacity: 1;
}
#titlebar a {
width: 18px;
height: 19px;
line-height: 20px;
overflow: hidden;
display: inline-block;
opacity: .5;
padding: 4px;
border-radius: 4px;
}
#titlebar a::before {
visibility: visible;
}
#titlebar a:hover {
opacity: .8;
border: 1px rgba(0,0,0,.2) solid;
padding: 3px;
}
#titlebar a:active {
opacity: 1;
color: rgba(0,0,0,.6);
/* margin: 1px -1px -1px 1px; */
-moz-box-shadow: inset 0 0 6px rgba(155,155,155,.8);
-webkit-box-shadow: inset 0 0 6px rgba(155,155,155,.8);
box-shadow: inset 0 0 6px rgba(155,155,155,.8);
}
#book-title {
font-weight: 600;
}
#title-seperator {
display: none;
}
#viewer {
width: 80%;
height: 80%;
/* margin-left: 10%; */
margin: 0 auto;
max-width: 1250px;
z-index: 2;
position: relative;
overflow: hidden;
}
#viewer iframe {
border: none;
}
#prev, #next {
position: absolute;
top: 10%;
height: 85%;
margin: 0;
}
.touch_nav {
width: 35%;
}
.arrow div {
display: table-cell;
vertical-align: middle;
}
#prev {
left: 0;
padding-left: 40px;
}
#next {
right: 0;
padding-right: 40px;
text-align: right;
}
.arrow {
/* position: relative;
top: 50%;
margin-top: -32px; */
font-size: 64px;
color: #E2E2E2;
font-family: arial, sans-serif;
font-weight: bold;
cursor: pointer;
display: table;
z-index: 3;
}
.arrow:hover {
color: #777;
}
.arrow:active,
.arrow.active {
color: #000;
}
#sidebar {
background: #6b6b6b;
position: absolute;
/* left: -260px; */
/* -webkit-transform: translate(-260px, 0);
-moz-transform: translate(-260px, 0); */
top: 0;
min-width: 300px;
width: 25%;
height: 100%;
-webkit-transition: -webkit-transform .5s;
-moz-transition: -moz-transform .5s;
overflow: hidden;
}
#sidebar.open {
/* left: 0; */
/* -webkit-transform: translate(0, 0);
-moz-transform: translate(0, 0); */
}
#main.closed {
/* left: 300px; */
-webkit-transform: translate(300px, 0);
-moz-transform: translate(300px, 0);
}
#main.single {
width: 75%;
}
#main.single #viewer {
/* width: 60%;
margin-left: 20%; */
}
#panels {
background: #4e4e4e;
position: absolute;
left: 0;
top: 0;
width: 100%;
padding: 13px 0;
height: 14px;
-moz-box-shadow: 0px 1px 3px rgba(0,0,0,.6);
-webkit-box-shadow: 0px 1px 3px rgba(0,0,0,.6);
box-shadow: 0px 1px 3px rgba(0,0,0,.6);
}
#opener {
/* padding: 10px 10px; */
float: left;
}
/* #opener #slider {
width: 25px;
} */
#metainfo {
display: inline-block;
text-align: center;
max-width: 80%;
}
#title-controls {
float: right;
}
#panels a {
visibility: hidden;
width: 18px;
height: 20px;
overflow: hidden;
display: inline-block;
color: #ccc;
margin-left: 6px;
}
#panels a::before {
visibility: visible;
}
#panels a:hover {
color: #AAA;
}
#panels a:active {
color: #AAA;
margin: 1px 0 -1px 6px;
}
#panels a.active,
#panels a.active:hover {
color: #AAA;
}
.searchbox {
position: inline-block;
width: 50%;
float: left;
margin-left: 1em;
}
.searchbox + span {
position: relative;
left: -1em;
visibility: hidden;
font-weight: bold;
}
input::-webkit-input-placeholder {
color: #454545;
}
input:-moz-placeholder {
color: #454545;
}
#divider {
position: absolute;
width: 1px;
border-right: 1px #000 solid;
height: 80%;
z-index: 1;
left: 50%;
margin-left: -1px;
top: 10%;
opacity: .15;
box-shadow: -2px 0 15px rgba(0, 0, 0, 1);
display: none;
}
#divider.show {
display: block;
}
#loader {
position: absolute;
z-index: 10;
left: 50%;
top: 50%;
margin: -33px 0 0 -33px;
}
#tocView,
#bookmarksView {
overflow-x: hidden;
overflow-y: hidden;
min-width: 300px;
width: 25%;
height: 100%;
visibility: hidden;
-webkit-transition: visibility 0 ease .5s;
-moz-transition: visibility 0 ease .5s;
}
#sidebar.open #tocView,
#sidebar.open #bookmarksView {
overflow-y: auto;
visibility: visible;
-webkit-transition: visibility 0 ease 0;
-moz-transition: visibility 0 ease 0;
}
#sidebar.open #tocView {
display: block;
}
#tocView > ul,
#bookmarksView > ul {
margin-top: 15px;
margin-bottom: 50px;
padding-left: 20px;
display: block;
}
#tocView li,
#bookmarksView li {
margin-bottom:10px;
width: 225px;
font-family: Georgia, "Times New Roman", Times, serif;
list-style: none;
text-transform: capitalize;
}
#tocView li:active,
#tocView li.currentChapter
{
list-style: none;
}
.list_item a {
color: #AAA;
text-decoration: none;
}
.list_item a.chapter {
font-size: 1em;
}
.list_item a.section {
font-size: .8em;
}
.list_item.currentChapter > a,
.list_item a:hover {
color: #f1f1f1
}
/* #tocView li.openChapter > a, */
.list_item a:hover {
color: #E2E2E2;
}
.list_item ul {
padding-left:10px;
margin-top: 8px;
display: none;
}
.list_item.currentChapter > ul,
.list_item.openChapter > ul {
display: block;
}
#tocView.hidden {
display: none;
}
.toc_toggle {
display: inline-block;
width: 14px;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
.toc_toggle:before {
content: '▸';
color: #fff;
margin-right: -4px;
}
.currentChapter > .toc_toggle:before,
.openChapter > .toc_toggle:before {
content: '▾';
}
.view {
width: 300px;
height: 100%;
display: none;
padding-top: 50px;
overflow-y: auto;
}
#searchResults {
margin-bottom: 50px;
padding-left: 20px;
display: block;
}
#searchResults li {
margin-bottom:10px;
width: 225px;
font-family: Georgia, "Times New Roman", Times, serif;
list-style: none;
}
#searchResults a {
color: #AAA;
text-decoration: none;
}
#searchResults p {
text-decoration: none;
font-size: 12px;
line-height: 16px;
}
#searchResults p .match {
background: #ccc;
color: #000;
}
#searchResults li > p {
color: #AAA;
}
#searchResults li a:hover {
color: #E2E2E2;
}
#searchView.shown {
display: block;
overflow-y: scroll;
}
#notes {
padding: 0 0 0 34px;
}
#notes li {
color: #eee;
font-size: 12px;
width: 240px;
border-top: 1px #fff solid;
padding-top: 6px;
margin-bottom: 6px;
}
#notes li a {
color: #fff;
display: inline-block;
margin-left: 6px;
}
#notes li a:hover {
text-decoration: underline;
}
#notes li img {
max-width: 240px;
}
#note-text {
display: block;
width: 260px;
height: 80px;
margin: 0 auto;
padding: 5px;
border-radius: 5px;
}
#note-text[disabled], #note-text[disabled="disabled"]{
opacity: .5;
}
#note-anchor {
margin-left: 218px;
margin-top: 5px;
}
#settingsPanel {
display:none;
}
#settingsPanel h3 {
color:#f1f1f1;
font-family:Georgia, "Times New Roman", Times, serif;
margin-bottom:10px;
}
#settingsPanel ul {
margin-top:60px;
list-style-type:none;
}
#settingsPanel li {
font-size:1em;
color:#f1f1f1;
}
#settingsPanel .xsmall { font-size:x-small; }
#settingsPanel .small { font-size:small; }
#settingsPanel .medium { font-size:medium; }
#settingsPanel .large { font-size:large; }
#settingsPanel .xlarge { font-size:x-large; }
.highlight { background-color: yellow }
.modal {
position: fixed;
top: 50%;
left: 50%;
width: 50%;
width: 630px;
height: auto;
z-index: 2000;
visibility: hidden;
margin-left: -320px;
margin-top: -160px;
}
.overlay {
position: fixed;
width: 100%;
height: 100%;
visibility: hidden;
top: 0;
left: 0;
z-index: 1000;
opacity: 0;
background: rgba(255,255,255,0.8);
-webkit-transition: all 0.3s;
-moz-transition: all 0.3s;
transition: all 0.3s;
}
.md-show {
visibility: visible;
}
.md-show ~ .overlay {
opacity: 1;
visibility: visible;
}
/* Content styles */
.md-content {
color: #fff;
background: #6b6b6b;
position: relative;
border-radius: 3px;
margin: 0 auto;
height: 320px;
}
.md-content h3 {
margin: 0;
padding: 6px;
text-align: center;
font-size: 22px;
font-weight: 300;
opacity: 0.8;
background: rgba(0,0,0,0.1);
border-radius: 3px 3px 0 0;
}
.md-content > div {
padding: 15px 40px 30px;
margin: 0;
font-weight: 300;
font-size: 14px;
}
.md-content > div p {
margin: 0;
padding: 10px 0;
}
.md-content > div ul {
margin: 0;
padding: 0 0 30px 20px;
}
.md-content > div ul li {
padding: 5px 0;
}
.md-content button {
display: block;
margin: 0 auto;
font-size: 0.8em;
}
/* Effect 1: Fade in and scale up */
.md-effect-1 .md-content {
-webkit-transform: scale(0.7);
-moz-transform: scale(0.7);
-ms-transform: scale(0.7);
transform: scale(0.7);
opacity: 0;
-webkit-transition: all 0.3s;
-moz-transition: all 0.3s;
transition: all 0.3s;
}
.md-show.md-effect-1 .md-content {
-webkit-transform: scale(1);
-moz-transform: scale(1);
-ms-transform: scale(1);
transform: scale(1);
opacity: 1;
}
.md-content > .closer {
font-size: 18px;
position: absolute;
right: 0;
top: 0;
font-size: 24px;
padding: 4px;
}
@media only screen and (max-width: 1040px) {
#viewer{
width: 50%;
margin-left: 25%;
}
#divider,
#divider.show {
display: none;
}
}
@media only screen and (max-width: 900px) {
#viewer{
width: 60%;
margin-left: 20%;
}
#prev {
padding-left: 20px;
}
#next {
padding-right: 20px;
}
}
@media only screen and (max-width: 550px) {
#viewer{
width: 80%;
margin-left: 10%;
}
#prev {
padding-left: 0;
}
#next {
padding-right: 0;
}
.arrow div {
text-indent: 100%;
white-space: nowrap;
overflow: hidden;
}
#main {
-webkit-transform: translate(0, 0);
-moz-transform: translate(0, 0);
-webkit-transition: -webkit-transform .3s;
-moz-transition: -moz-transform .3s;
}
#main.closed {
-webkit-transform: translate(260px, 0);
-moz-transform: translate(260px, 0);
}
#titlebar {
/* font-size: 16px; */
/* margin: 0 50px 0 50px; */
}
#metainfo {
font-size: 10px;
}
#tocView {
width: 260px;
}
#tocView li {
font-size: 12px;
}
#tocView > ul{
padding-left: 10px;
webkit-padding-start:;
}
}
[class^="icon-"]:before, [class*=" icon-"]:before {
font-family: "fontello";
font-style: normal;
font-weight: normal;
speak: none;
display: inline-block;
text-decoration: inherit;
width: 1em;
margin-right: .2em;
text-align: center;
/* opacity: .8; */
/* For safety - reset parent styles, that can break glyph codes*/
font-variant: normal;
text-transform: none;
/* you can be more comfortable with increased icons size */
font-size: 112%;
}
.icon-search:before { content: '\e807'; } /* '' */
.icon-resize-full-1:before { content: '\e804'; } /* '' */
.icon-cancel-circled2:before { content: '\e80f'; } /* '' */
.icon-link:before { content: '\e80d'; } /* '' */
.icon-bookmark:before { content: '\e805'; } /* '' */
.icon-bookmark-empty:before { content: '\e806'; } /* '' */
.icon-download-cloud:before { content: '\e811'; } /* '' */
.icon-edit:before { content: '\e814'; } /* '' */
.icon-menu:before { content: '\e802'; } /* '' */
.icon-cog:before { content: '\e813'; } /* '' */
.icon-resize-full:before { content: '\e812'; } /* '' */
.icon-cancel-circled:before { content: '\e80e'; } /* '' */
.icon-up-dir:before { content: '\e80c'; } /* '' */
.icon-right-dir:before { content: '\e80b'; } /* '' */
.icon-angle-right:before { content: '\e809'; } /* '' */
.icon-angle-down:before { content: '\e80a'; } /* '' */
.icon-right:before { content: '\e815'; } /* '' */
.icon-list-1:before { content: '\e803'; } /* '' */
.icon-list-numbered:before { content: '\e801'; } /* '' */
.icon-columns:before { content: '\e810'; } /* '' */
.icon-list:before { content: '\e800'; } /* '' */
.icon-resize-small:before { content: '\e808'; } /* '' */

11
vendor/epubjs/epub.min.js vendored Normal file

File diff suppressed because one or more lines are too long

1
vendor/epubjs/epub.min.map vendored Normal file

File diff suppressed because one or more lines are too long

1
vendor/epubjs/hooks.min.js vendored Normal file
View file

@ -0,0 +1 @@
EPUBJS.Hooks.register("beforeChapterDisplay").endnotes=function(a,b){var c=b.contents.querySelectorAll("a[href]"),d=Array.prototype.slice.call(c),e="epub:type",f="noteref",g=(parent.location.origin+parent.location.pathname,EPUBJS.basePath+EPUBJS.cssPath||folder),h={};EPUBJS.core.addCss(g+"popup.css",!1,b.render.document.head),d.forEach(function(a){function c(){var c,e,f=b.height,j=b.width,o=225;n||(c=k.cloneNode(!0),n=c.querySelector("p")),h[id]||(h[id]=document.createElement("div"),h[id].setAttribute("class","popup"),pop_content=document.createElement("div"),h[id].appendChild(pop_content),pop_content.appendChild(n),pop_content.setAttribute("class","pop_content"),b.render.document.body.appendChild(h[id]),h[id].addEventListener("mouseover",d,!1),h[id].addEventListener("mouseout",g,!1),b.on("renderer:pageChanged",i,this),b.on("renderer:pageChanged",g,this)),c=h[id],e=a.getBoundingClientRect(),l=e.left,m=e.top,c.classList.add("show"),popRect=c.getBoundingClientRect(),c.style.left=l-popRect.width/2+"px",c.style.top=m+"px",o>f/2.5&&(o=f/2.5,pop_content.style.maxHeight=o+"px"),popRect.height+m>=f-25?(c.style.top=m-popRect.height+"px",c.classList.add("above")):c.classList.remove("above"),l-popRect.width<=0?(c.style.left=l+"px",c.classList.add("left")):c.classList.remove("left"),l+popRect.width/2>=j?(c.style.left=l-300+"px",popRect=c.getBoundingClientRect(),c.style.left=l-popRect.width+"px",popRect.height+m>=f-25?(c.style.top=m-popRect.height+"px",c.classList.add("above")):c.classList.remove("above"),c.classList.add("right")):c.classList.remove("right")}function d(){h[id].classList.add("on")}function g(){h[id].classList.remove("on")}function i(){setTimeout(function(){h[id].classList.remove("show")},100)}var j,k,l,m,n,o=a.getAttribute(e);o==f&&(j=a.getAttribute("href"),id=j.replace("#",""),k=b.render.document.getElementById(id),a.addEventListener("mouseover",c,!1),a.addEventListener("mouseout",i,!1))}),a&&a()},EPUBJS.Hooks.register("beforeChapterDisplay").mathml=function(a,b){if(b.currentChapter.manifestProperties.indexOf("mathml")!==-1){b.render.iframe.contentWindow.mathmlCallback=a;var c=document.createElement("script");c.type="text/x-mathjax-config",c.innerHTML=' MathJax.Hub.Register.StartupHook("End",function () { window.mathmlCallback(); }); MathJax.Hub.Config({jax: ["input/TeX","input/MathML","output/SVG"],extensions: ["tex2jax.js","mml2jax.js","MathEvents.js"],TeX: {extensions: ["noErrors.js","noUndefined.js","autoload-all.js"]},MathMenu: {showRenderer: false},menuSettings: {zoom: "Click"},messageStyle: "none"}); ',b.doc.body.appendChild(c),EPUBJS.core.addScript("http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML",null,b.doc.head)}else a&&a()},EPUBJS.Hooks.register("beforeChapterDisplay").smartimages=function(a,b){var c=b.contents.querySelectorAll("img"),d=Array.prototype.slice.call(c),e=b.height;return"reflowable"!=b.layoutSettings.layout?void a():(d.forEach(function(a){var c=function(){var c,d=a.getBoundingClientRect(),f=d.height,g=d.top,h=a.getAttribute("data-height"),i=h||f,j=Number(getComputedStyle(a,"").fontSize.match(/(\d*(\.\d*)?)px/)[1]),k=j?j/2:0;e=b.contents.clientHeight,g<0&&(g=0),i+g>=e?(g<e/2?(c=e-g-k,a.style.maxHeight=c+"px",a.style.width="auto"):(i>e&&(a.style.maxHeight=e+"px",a.style.width="auto",d=a.getBoundingClientRect(),i=d.height),a.style.display="block",a.style.WebkitColumnBreakBefore="always",a.style.breakBefore="column"),a.setAttribute("data-height",c)):(a.style.removeProperty("max-height"),a.style.removeProperty("margin-top"))},d=function(){b.off("renderer:resized",c),b.off("renderer:chapterUnload",this)};a.addEventListener("load",c,!1),b.on("renderer:resized",c),b.on("renderer:chapterUnload",d),c()}),void(a&&a()))},EPUBJS.Hooks.register("beforeChapterDisplay").transculsions=function(a,b){var c=b.contents.querySelectorAll("[transclusion]"),d=Array.prototype.slice.call(c);d.forEach(function(a){function c(){j=g,k=h,j>chapter.colWidth&&(d=chapter.colWidth/j,j=chapter.colWidth,k*=d),f.width=j,f.height=k}var d,e=a.getAttribute("ref"),f=document.createElement("iframe"),g=a.getAttribute("width"),h=a.getAttribute("height"),i=a.parentNode,j=g,k=h;c(),b.listenUntil("renderer:resized","renderer:chapterUnloaded",c),f.src=e,i.replaceChild(f,a)}),a&&a()};

1
vendor/epubjs/hooks.min.map vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,73 @@
EPUBJS.Hooks.register("beforeChapterDisplay").smartimages = function(callback, renderer){
var images = renderer.contents.querySelectorAll('img'),
items = Array.prototype.slice.call(images),
iheight = renderer.height,//chapter.bodyEl.clientHeight,//chapter.doc.body.getBoundingClientRect().height,
oheight;
if(renderer.layoutSettings.layout != "reflowable") {
callback();
return; //-- Only adjust images for reflowable text
}
items.forEach(function(item){
var size = function() {
var itemRect = item.getBoundingClientRect(),
rectHeight = itemRect.height,
top = itemRect.top,
oHeight = item.getAttribute('data-height'),
height = oHeight || rectHeight,
newHeight,
fontSize = Number(getComputedStyle(item, "").fontSize.match(/(\d*(\.\d*)?)px/)[1]),
fontAdjust = fontSize ? fontSize / 2 : 0;
iheight = renderer.contents.clientHeight;
if(top < 0) top = 0;
if(height + top >= iheight) {
if(top < iheight/2) {
// Remove top and half font-size from height to keep container from overflowing
newHeight = iheight - top - fontAdjust;
item.style.maxHeight = newHeight + "px";
item.style.width= "auto";
}else{
if(height > iheight) {
item.style.maxHeight = iheight + "px";
item.style.width= "auto";
itemRect = item.getBoundingClientRect();
height = itemRect.height;
}
item.style.display = "block";
item.style["WebkitColumnBreakBefore"] = "always";
item.style["breakBefore"] = "column";
}
item.setAttribute('data-height', newHeight);
}else{
item.style.removeProperty('max-height');
item.style.removeProperty('margin-top');
}
}
var unloaded = function(){
// item.removeEventListener('load', size); // crashes in IE
renderer.off("renderer:resized", size);
renderer.off("renderer:chapterUnload", this);
};
item.addEventListener('load', size, false);
renderer.on("renderer:resized", size);
renderer.on("renderer:chapterUnload", unloaded);
size();
});
if(callback) callback();
}

View file

@ -0,0 +1,14 @@
EPUBJS.Hooks.register("beforeChapterDisplay").highlight = function(callback, renderer){
// EPUBJS.core.addScript("js/libs/jquery.highlight.js", null, renderer.doc.head);
var s = document.createElement("style");
s.innerHTML =".highlight { background: yellow; font-weight: normal; }";
renderer.render.document.head.appendChild(s);
if(callback) callback();
}

4
vendor/epubjs/libs/jquery.min.js vendored Normal file

File diff suppressed because one or more lines are too long

7
vendor/epubjs/libs/screenfull.min.js vendored Normal file
View file

@ -0,0 +1,7 @@
/*!
* screenfull
* v1.1.0 - 2013-09-06
* https://github.com/sindresorhus/screenfull.js
* (c) Sindre Sorhus; MIT License
*/
!function(a,b){"use strict";var c="undefined"!=typeof Element&&"ALLOW_KEYBOARD_INPUT"in Element,d=function(){for(var a,c,d=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenchange","MSFullscreenerror"]],e=0,f=d.length,g={};f>e;e++)if(a=d[e],a&&a[1]in b){for(e=0,c=a.length;c>e;e++)g[d[0][e]]=a[e];return g}return!1}(),e={request:function(a){var e=d.requestFullscreen;a=a||b.documentElement,/5\.1[\.\d]* Safari/.test(navigator.userAgent)?a[e]():a[e](c&&Element.ALLOW_KEYBOARD_INPUT)},exit:function(){b[d.exitFullscreen]()},toggle:function(a){this.isFullscreen?this.exit():this.request(a)},onchange:function(){},onerror:function(){},raw:d};return d?(Object.defineProperties(e,{isFullscreen:{get:function(){return!!b[d.fullscreenElement]}},element:{enumerable:!0,get:function(){return b[d.fullscreenElement]}},enabled:{enumerable:!0,get:function(){return!!b[d.fullscreenEnabled]}}}),b.addEventListener(d.fullscreenchange,function(a){e.onchange.call(e,a)}),b.addEventListener(d.fullscreenerror,function(a){e.onerror.call(e,a)}),a.screenfull=e,void 0):(a.screenfull=!1,void 0)}(window,document);

14
vendor/epubjs/libs/zip.min.js vendored Normal file

File diff suppressed because one or more lines are too long

1
vendor/epubjs/reader.min.js vendored Normal file

File diff suppressed because one or more lines are too long

1
vendor/epubjs/reader.min.map vendored Normal file

File diff suppressed because one or more lines are too long

BIN
vendor/icomoon/fonts/icomoon.eot vendored Normal file

Binary file not shown.

127
vendor/icomoon/fonts/icomoon.svg vendored Normal file
View file

@ -0,0 +1,127 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>Generated by IcoMoon</metadata>
<defs>
<font id="icomoon" horiz-adv-x="1024">
<font-face units-per-em="1024" ascent="960" descent="-64" />
<missing-glyph horiz-adv-x="1024" />
<glyph unicode="&#x20;" horiz-adv-x="512" d="" />
<glyph unicode="&#xe039;" glyph-name="rotate_0" d="M854 426.667c0 188-154 342-342 342s-342-154-342-342c0-188 154-342 342-342s342 154 342 342zM86 426.667c0 236 190 426 426 426s426-190 426-426c0-236-190-426-426-426s-426 190-426 426zM704 340.667h-384l192 428z" />
<glyph unicode="&#xe03a;" glyph-name="rotate_90" d="M512 84.667c188 0 342 154 342 342s-154 342-342 342c-188 0-342-154-342-342s154-342 342-342zM512 852.667c236 0 426-190 426-426s-190-426-426-426c-236 0-426 190-426 426s190 426 426 426zM426 234.667v384l428-192z" />
<glyph unicode="&#xe03b;" glyph-name="rotate_180" d="M170 426.667c0-188 154-342 342-342s342 154 342 342c0 188-154 342-342 342s-342-154-342-342zM938 426.667c0-236-190-426-426-426s-426 190-426 426c0 236 190 426 426 426s426-190 426-426zM320 512.667h384l-192-428z" />
<glyph unicode="&#xe03c;" glyph-name="rotate_270" d="M512 768.667c-188 0-342-154-342-342s154-342 342-342c188 0 342 154 342 342s-154 342-342 342zM512 0.667c-236 0-426 190-426 426s190 426 426 426c236 0 426-190 426-426s-190-426-426-426zM598 618.667v-384l-428 192z" />
<glyph unicode="&#xe06d;" glyph-name="featured_play_list" d="M512 640.667v84h-384v-84h384zM512 468.667v86h-384v-86h384zM896 810.667c46 0 86-40 86-86v-596c0-46-40-86-86-86h-768c-46 0-86 40-86 86v596c0 46 40 86 86 86h768z" />
<glyph unicode="&#xe0b7;" glyph-name="chat" d="M768 596.667v86h-512v-86h512zM598 340.667v86h-342v-86h342zM256 554.667v-86h512v86h-512zM854 852.667c46 0 84-38 84-84v-512c0-46-38-86-84-86h-598l-170-170v768c0 46 38 84 84 84h684z" />
<glyph unicode="&#xe0b9;" glyph-name="comment" d="M768 596.667v86h-512v-86h512zM768 468.667v86h-512v-86h512zM768 340.667v86h-512v-86h512zM938 768.667v-768l-170 170h-598c-46 0-84 40-84 86v512c0 46 38 84 84 84h684c46 0 84-38 84-84z" />
<glyph unicode="&#xe0c7;" glyph-name="location_off" d="M500 448.667c118.353-116.98 236.568-234.098 354-352l-54-54-144 142c-72-106-144-184-144-184s-298 330-298 554c0 22 4 44 8 66l-136 136 54 54 356-356zM512 660.667c-32 0-58-14-78-36l-138 136c54 56 132 92 216 92 166 0 298-132 298-298 0-72-30-154-72-234l-154 156c22 20 34 46 34 78 0 58-48 106-106 106z" />
<glyph unicode="&#xe0c9;" glyph-name="message" d="M768 596.667v86h-512v-86h512zM768 468.667v86h-512v-86h512zM768 340.667v86h-512v-86h512zM854 852.667c46 0 84-38 84-84v-512c0-46-38-86-84-86h-598l-170-170v768c0 46 38 84 84 84h684z" />
<glyph unicode="&#xe0ca;" glyph-name="chat_bubble" d="M854 852.667c46 0 84-38 84-84v-512c0-46-38-86-84-86h-598l-170-170v768c0 46 38 84 84 84h684z" />
<glyph unicode="&#xe0cb;" glyph-name="chat_bubble_outline" d="M854 256.667v512h-684v-598l86 86h598zM854 852.667c46 0 84-38 84-84v-512c0-46-38-86-84-86h-598l-170-170v768c0 46 38 84 84 84h684z" />
<glyph unicode="&#xe14d;" glyph-name="content_copy" d="M810 42.667v598h-468v-598h468zM810 724.667c46 0 86-38 86-84v-598c0-46-40-86-86-86h-468c-46 0-86 40-86 86v598c0 46 40 84 86 84h468zM682 896.667v-86h-512v-598h-84v598c0 46 38 86 84 86h512z" />
<glyph unicode="&#xe153;" glyph-name="flag" d="M614 682.667h240v-426h-300l-16 84h-240v-298h-84v726h384z" />
<glyph unicode="&#xe157;" glyph-name="link2" d="M726 640.667c118 0 212-96 212-214s-94-214-212-214h-172v82h172c72 0 132 60 132 132s-60 132-132 132h-172v82h172zM342 384.667v84h340v-84h-340zM166 426.667c0-72 60-132 132-132h172v-82h-172c-118 0-212 96-212 214s94 214 212 214h172v-82h-172c-72 0-132-60-132-132z" />
<glyph unicode="&#xe161;" glyph-name="save" d="M640 554.667v170h-426v-170h426zM512 128.667c70 0 128 58 128 128s-58 128-128 128-128-58-128-128 58-128 128-128zM726 810.667l170-170v-512c0-46-40-86-86-86h-596c-48 0-86 40-86 86v596c0 46 38 86 86 86h512z" />
<glyph unicode="&#xe169;" glyph-name="unarchive" d="M218 724.667h588l-40 44h-512zM512 532.667l-234-234h148v-86h172v86h148zM876 716.667c12-14 20-36 20-56v-532c0-46-40-86-86-86h-596c-48 0-86 40-86 86v532c0 20 8 42 20 56l58 70c12 14 30 24 50 24h512c20 0 38-10 50-24z" />
<glyph unicode="&#xe1ac;" glyph-name="brightness_high" d="M512 596.667c94 0 170-76 170-170s-76-170-170-170-170 76-170 170 76 170 170 170zM512 170.667c142 0 256 114 256 256s-114 256-256 256-256-114-256-256 114-256 256-256zM854 568.667l140-142-140-142v-200h-200l-142-140-142 140h-200v200l-140 142 140 142v200h200l142 140 142-140h200v-200z" />
<glyph unicode="&#xe1ad;" glyph-name="brightness_low" d="M512 170.667c142 0 256 114 256 256s-114 256-256 256-256-114-256-256 114-256 256-256zM854 284.667v-200h-200l-142-140-142 140h-200v200l-140 142 140 142v200h200l142 140 142-140h200v-200l140-142z" />
<glyph unicode="&#xe1ae;" glyph-name="brightness_low2" d="M512 170.667c142 0 256 114 256 256s-114 256-256 256-256-114-256-256 114-256 256-256zM854 284.667v-200h-200l-142-140-142 140h-200v200l-140 142 140 142v200h200l142 140 142-140h200v-200l140-142z" />
<glyph unicode="&#xe1af;" glyph-name="brightness_medium" d="M512 170.667c142 0 256 114 256 256s-114 256-256 256v-512zM854 284.667v-200h-200l-142-140-142 140h-200v200l-140 142 140 142v200h200l142 140 142-140h200v-200l140-142z" />
<glyph unicode="&#xe226;" glyph-name="attach_file" d="M704 682.667h64v-490c0-130-104-236-234-236s-236 106-236 236v532c0 94 78 172 172 172s170-78 170-172v-448c0-58-48-106-106-106s-108 48-108 106v406h64v-406c0-24 20-42 44-42s42 18 42 42v448c0 58-48 108-106 108s-108-50-108-108v-532c0-94 78-172 172-172s170 78 170 172v490z" />
<glyph unicode="&#xe241;" glyph-name="format_list_bulleted" d="M298 724.667h598v-84h-598v84zM298 384.667v84h598v-84h-598zM298 128.667v84h598v-84h-598zM170 234.667c36 0 64-30 64-64s-30-64-64-64-64 30-64 64 28 64 64 64zM170 746.667c36 0 64-28 64-64s-28-64-64-64-64 28-64 64 28 64 64 64zM170 490.667c36 0 64-28 64-64s-28-64-64-64-64 28-64 64 28 64 64 64z" />
<glyph unicode="&#xe242;" glyph-name="format_list_numbered" d="M298 384.667v84h598v-84h-598zM298 128.667v84h598v-84h-598zM298 724.667h598v-84h-598v84zM86 468.667v44h128v-40l-78-88h78v-44h-128v40l76 88h-76zM128 596.667v128h-42v44h84v-172h-42zM86 212.667v44h128v-172h-128v44h84v20h-42v44h42v20h-84z" />
<glyph unicode="&#xe245;" glyph-name="format_size" d="M128 426.667v128h384v-128h-128v-298h-128v298h-128zM384 768.667h554v-128h-212v-512h-128v512h-214v128z" />
<glyph unicode="&#xe247;" glyph-name="format_textdirection_l_to_r" d="M896 170.667l-170-170v128h-512v84h512v128zM384 512.667c-94 0-170 76-170 170s76 170 170 170h342v-84h-86v-470h-86v470h-84v-470h-86v214z" />
<glyph unicode="&#xe248;" glyph-name="format_textdirection_r_to_l" d="M342 212.667h512v-84h-512v-128l-172 170 172 170v-128zM426 512.667c-94 0-170 76-170 170s76 170 170 170h342v-84h-86v-470h-84v470h-86v-470h-86v214z" />
<glyph unicode="&#xe254;" glyph-name="mode_edit" d="M884 638.667l-78-78-160 160 78 78c16 16 44 16 60 0l100-100c16-16 16-44 0-60zM128 202.667l472 472 160-160-472-472h-160v160z" />
<glyph unicode="&#xe2bc;" glyph-name="attachment" d="M86 404.667c0 130 104 236 234 236h448c94 0 170-78 170-172s-76-170-170-170h-362c-58 0-108 48-108 106s50 108 108 108h320v-86h-324c-24 0-24-42 0-42h366c46 0 86 38 86 84s-40 86-86 86h-448c-82 0-150-68-150-150s68-148 150-148h406v-86h-406c-130 0-234 104-234 234z" />
<glyph unicode="&#xe2c0;" glyph-name="cloud_download" d="M726 384.667h-128v170h-172v-170h-128l214-214zM826 510.667c110-8 198-100 198-212 0-118-96-214-214-214h-554c-142 0-256 114-256 256 0 132 100 240 228 254 54 102 160 174 284 174 156 0 284-110 314-258z" />
<glyph unicode="&#xe314;" glyph-name="keyboard_arrow_left" d="M658 252.667l-60-60-256 256 256 256 60-60-196-196z" />
<glyph unicode="&#xe315;" glyph-name="keyboard_arrow_right" d="M366 240.667l196 196-196 196 60 60 256-256-256-256z" />
<glyph unicode="&#xe316;" glyph-name="keyboard_arrow_left2" d="M658 252.667l-60-60-256 256 256 256 60-60-196-196z" />
<glyph unicode="&#xe3a6;" glyph-name="brightness_1" d="M86 426.667c0 236 190 426 426 426s426-190 426-426-190-426-426-426-426 190-426 426z" />
<glyph unicode="&#xe3a7;" glyph-name="brightness_2" d="M426 852.667c236 0 428-190 428-426s-192-426-428-426c-78 0-150 20-212 56 128 74 212 212 212 370s-84 296-212 370c62 36 134 56 212 56z" />
<glyph unicode="&#xe3a8;" glyph-name="brightness_3" d="M384 852.667c236 0 426-190 426-426s-190-426-426-426c-44 0-88 6-128 18 174 54 298 216 298 408s-124 354-298 408c40 12 84 18 128 18z" />
<glyph unicode="&#xe3a9;" glyph-name="brightness_4" d="M512 170.667c142 0 256 114 256 256s-114 256-256 256c-38 0-74-10-106-24 88-40 148-128 148-232s-60-192-148-232c32-14 68-24 106-24zM854 568.667l140-142-140-142v-200h-200l-142-140-142 140h-200v200l-140 142 140 142v200h200l142 140 142-140h200v-200z" />
<glyph unicode="&#xe3c2;" glyph-name="crop_free" d="M810 810.667c46 0 86-40 86-86v-170h-86v170h-170v86h170zM810 128.667v170h86v-170c0-46-40-86-86-86h-170v86h170zM214 298.667v-170h170v-86h-170c-46 0-86 40-86 86v170h86zM128 724.667c0 46 40 86 86 86h170v-86h-170v-170h-86v170z" />
<glyph unicode="&#xe3c5;" glyph-name="crop_portrait" d="M726 128.667v596h-428v-596h428zM726 810.667c46 0 84-40 84-86v-596c0-46-38-86-84-86h-428c-46 0-84 40-84 86v596c0 46 38 86 84 86h428z" />
<glyph unicode="&#xe3c7;" glyph-name="dehaze" d="M86 704.667h852v-86h-852v86zM86 490.667h852v-86h-852v86zM86 276.667h852v-84h-852v84z" />
<glyph unicode="&#xe408;" glyph-name="navigate_before" d="M658 622.667l-196-196 196-196-60-60-256 256 256 256z" />
<glyph unicode="&#xe409;" glyph-name="navigate_next" d="M426 682.667l256-256-256-256-60 60 196 196-196 196z" />
<glyph unicode="&#xe419;" glyph-name="rotate_left" d="M554 764.667c168-20 300-164 300-338s-132-318-300-338v86c122 20 214 126 214 252s-92 232-214 252v-166l-194 190 194 194v-132zM302 156.667l62 62c32-24 68-38 106-44v-86c-60 8-118 30-168 68zM260 384.667c6-38 20-74 42-106l-60-60c-38 50-60 106-68 166h86zM304 574.667c-22-32-38-68-44-106h-86c8 60 32 116 70 166z" />
<glyph unicode="&#xe41a;" glyph-name="rotate_right" d="M720 278.667c24 32 38 68 44 106h86c-8-60-30-116-68-166zM554 174.667c38 6 74 20 106 44l62-62c-50-38-108-60-168-68v86zM850 468.667h-86c-6 38-20 74-44 106l62 60c38-50 60-106 68-166zM664 702.667l-194-190v166c-122-20-214-126-214-252s92-232 214-252v-86c-168 20-300 164-300 338s132 318 300 338v132z" />
<glyph unicode="&#xe429;" glyph-name="tune" d="M640 554.667v256h86v-86h170v-84h-170v-86h-86zM896 384.667h-426v84h426v-84zM298 554.667h86v-256h-86v86h-170v84h170v86zM554 42.667h-84v256h84v-86h342v-84h-342v-86zM128 724.667h426v-84h-426v84zM128 212.667h256v-84h-256v84z" />
<glyph unicode="&#xe430;" glyph-name="wb_sunny" d="M152 146.667l76 78 60-60-76-78zM470-19.333v126h84v-126h-84zM512 704.667c142 0 256-114 256-256s-114-256-256-256-256 114-256 256 114 256 256 256zM854 490.667h128v-86h-128v86zM736 164.667l60 58 76-76-60-60zM872 748.667l-76-76-60 60 76 76zM554 914.667v-126h-84v126h84zM170 490.667v-86h-128v86h128zM288 732.667l-60-60-76 76 60 60z" />
<glyph unicode="&#xe54b;" glyph-name="local_library" d="M512 596.667c-70 0-128 58-128 128s58 128 128 128 128-58 128-128-58-128-128-128zM512 446.667c100 94 236 150 384 150v-468c-148 0-284-58-384-152-100 94-236 152-384 152v468c148 0 284-56 384-150z" />
<glyph unicode="&#xe560;" glyph-name="rate_review" d="M768 340.667v86h-234l-86-86h320zM256 340.667h106l294 294c8 8 8 22 0 30l-76 76c-8 8-22 8-30 0l-294-294v-106zM854 852.667c46 0 84-38 84-84v-512c0-46-38-86-84-86h-598l-170-170v768c0 46 38 84 84 84h684z" />
<glyph unicode="&#xe56b;" glyph-name="zoom_out_map" d="M896 298.667v-256h-256l98 98-124 122 62 62 122-124zM384 42.667h-256v256l98-98 122 124 62-62-124-122zM128 554.667v256h256l-98-98 124-122-62-62-122 124zM640 810.667h256v-256l-98 98-122-124-62 62 124 122z" />
<glyph unicode="&#xe5c4;" glyph-name="arrow_back" d="M854 468.667v-84h-520l238-240-60-60-342 342 342 342 60-60-238-240h520z" />
<glyph unicode="&#xe5c5;" glyph-name="arrow_back2" d="M854 468.667v-84h-520l238-240-60-60-342 342 342 342 60-60-238-240h520z" />
<glyph unicode="&#xe5c8;" glyph-name="arrow_forward" d="M512 768.667l342-342-342-342-60 60 238 240h-520v84h520l-238 240z" />
<glyph unicode="&#xe5c9;" glyph-name="cancel" d="M726 272.667l-154 154 154 154-60 60-154-154-154 154-60-60 154-154-154-154 60-60 154 154 154-154zM512 852.667c236 0 426-190 426-426s-190-426-426-426-426 190-426 426 190 426 426 426z" />
<glyph unicode="&#xe5ca;" glyph-name="check" d="M384 248.667l452 452 60-60-512-512-238 238 60 60z" />
<glyph unicode="&#xe5cd;" glyph-name="close" d="M810 664.667l-238-238 238-238-60-60-238 238-238-238-60 60 238 238-238 238 60 60 238-238 238 238z" />
<glyph unicode="&#xe5d0;" glyph-name="fullscreen" d="M598 724.667h212v-212h-84v128h-128v84zM726 212.667v128h84v-212h-212v84h128zM214 512.667v212h212v-84h-128v-128h-84zM298 340.667v-128h128v-84h-212v212h84z" />
<glyph unicode="&#xe5d1;" glyph-name="fullscreen_exit" d="M682 596.667h128v-84h-212v212h84v-128zM598 128.667v212h212v-84h-128v-128h-84zM342 596.667v128h84v-212h-212v84h128zM214 256.667v84h212v-212h-84v128h-128z" />
<glyph unicode="&#xe5d2;" glyph-name="menu" d="M128 682.667h768v-86h-768v86zM128 384.667v84h768v-84h-768zM128 170.667v86h768v-86h-768z" />
<glyph unicode="&#xe5d3;" glyph-name="fullscreen2" d="M598 724.667h212v-212h-84v128h-128v84zM726 212.667v128h84v-212h-212v84h128zM214 512.667v212h212v-84h-128v-128h-84zM298 340.667v-128h128v-84h-212v212h84z" />
<glyph unicode="&#xe5d4;" glyph-name="fullscreen_exit2" d="M682 596.667h128v-84h-212v212h84v-128zM598 128.667v212h212v-84h-128v-128h-84zM342 596.667v128h84v-212h-212v84h128zM214 256.667v84h212v-212h-84v128h-128z" />
<glyph unicode="&#xe5d5;" glyph-name="menu3" d="M128 682.667h768v-86h-768v86zM128 384.667v84h768v-84h-768zM128 170.667v86h768v-86h-768z" />
<glyph unicode="&#xe627;" glyph-name="sync" d="M512 170.667v128l170-170-170-172v128c-188 0-342 154-342 342 0 66 20 130 54 182l62-62c-20-36-30-76-30-120 0-142 114-256 256-256zM512 768.667c188 0 342-154 342-342 0-66-20-130-54-182l-62 62c20 36 30 76 30 120 0 142-114 256-256 256v-128l-170 170 170 172v-128z" />
<glyph unicode="&#xe7f9;" glyph-name="pages" d="M810 810.667c46 0 86-40 86-86v-256h-214l44 172-172-44v214h256zM726 212.667l-44 172h214v-256c0-46-40-86-86-86h-256v214zM342 384.667l-44-172 172 44v-214h-256c-46 0-86 40-86 86v256h214zM128 724.667c0 46 40 86 86 86h256v-214l-172 44 44-172h-214v256z" />
<glyph unicode="&#xe834;" glyph-name="check_box" d="M426 212.667l384 384-60 62-324-324-152 152-60-60zM810 810.667c48 0 86-40 86-86v-596c0-46-38-86-86-86h-596c-48 0-86 40-86 86v596c0 46 38 86 86 86h596z" />
<glyph unicode="&#xe838;" glyph-name="star" d="M512 202.667l-264-160 70 300-232 202 306 26 120 282 120-282 306-26-232-202 70-300z" />
<glyph unicode="&#xe839;" glyph-name="star_half" d="M512 280.667l160-96-42 182 142 124-188 16-72 172v-398zM938 544.667l-232-202 70-300-264 160-264-160 70 300-232 202 306 26 120 282 120-282z" />
<glyph unicode="&#xe83a;" glyph-name="star_border" d="M512 280.667l160-96-42 182 142 124-188 16-72 172-72-172-188-16 142-124-42-182zM938 544.667l-232-202 70-300-264 160-264-160 70 300-232 202 306 26 120 282 120-282z" />
<glyph unicode="&#xe85b;" glyph-name="icon-fit-window" d="M514.011 433.334v-13.333h13.333v13.333zM515.345 432h10.667v-10.667h-10.667zM512.678 429.334l-2.667-2.667 2.667-2.667zM528.678 429.334v-5.333l2.667 2.667zM215.333 727.797v-596.384h596.384v596.384zM274.972 668.159h477.107v-477.107h-477.107zM155.695 548.882l-119.277-119.277 119.277-119.277zM871.356 548.882v-238.554l119.277 119.277zM811.717 727.797h-596.384v-596.384h596.384zM752.079 668.159v-477.107h-477.107v477.107zM632.802 787.435l-119.277 119.277-119.277-119.277zM632.802 71.774h-238.554l119.277-119.277z" />
<glyph unicode="&#xe85c;" glyph-name="icon-fit-width" d="M514.011 433.334v-13.333h13.333v13.333zM515.345 432h10.667v-10.667h-10.667zM512.678 429.334l-2.667-2.667 2.667-2.667zM528.678 429.334v-5.333l2.667 2.667zM215.333 727.797v-596.384h596.384v596.384zM274.972 668.159h477.107v-477.107h-477.107zM155.695 548.882l-119.277-119.277 119.277-119.277zM871.356 548.882v-238.554l119.277 119.277z" />
<glyph unicode="&#xe869;" glyph-name="build" d="M968 128.667c18-12 18-42-4-60l-98-98c-18-18-42-18-60 0l-388 388c-98-38-212-18-294 64-86 86-108 214-56 316l188-184 128 128-184 184c102 46 230 30 316-56 82-82 102-196 64-294z" />
<glyph unicode="&#xe86d;" glyph-name="double_page_mode" d="M125.831 770.49c-46 0-86-40-86-86v-554c0-46 40-86 86-86h768c46 0 86 40 86 86v554c0 46-40 86-86 86h-768zM112.497 684.49h384v-554h-384v554zM523.164 684.49h384v-554h-384v554zM154.497 534.49v-64h300v64h-300zM565.164 534.49v-64h300v64h-300zM154.497 428.49v-64h300v64h-300zM565.164 428.49v-64h300v64h-300zM154.497 322.49v-64h300v64h-300zM565.164 322.49v-64h300v64h-300z" />
<glyph unicode="&#xe86e;" glyph-name="single_page_mode" d="M704 128.667v554h-384v-554zM896 768.667c46 0 86-40 86-86v-554c0-46-40-86-86-86h-768c-46 0-86 40-86 86v554c0 46 40 86 86 86zM362 320.667h300v-64h-300zM362 532.667h300v-64h-300zM362 426.667h300v-64h-300z" />
<glyph unicode="&#xe86f;" glyph-name="class" d="M256 768.667v-342l106 64 108-64v342h-214zM768 852.667c46 0 86-38 86-84v-684c0-46-40-84-86-84h-512c-46 0-86 38-86 84v684c0 46 40 84 86 84h512z" />
<glyph unicode="&#xe872;" glyph-name="delete" d="M810 768.667v-86h-596v86h148l44 42h212l44-42h148zM256 128.667v512h512v-512c0-46-40-86-86-86h-340c-46 0-86 40-86 86z" />
<glyph unicode="&#xe875;" glyph-name="dns" d="M298 554.667c46 0 86 40 86 86s-40 84-86 84-84-38-84-84 38-86 84-86zM854 810.667c24 0 42-18 42-42v-256c0-24-18-44-42-44h-684c-24 0-42 20-42 44v256c0 24 18 42 42 42h684zM298 128.667c46 0 86 38 86 84s-40 86-86 86-84-40-84-86 38-84 84-84zM854 384.667c24 0 42-20 42-44v-256c0-24-18-42-42-42h-684c-24 0-42 18-42 42v256c0 24 18 44 42 44h684z" />
<glyph unicode="&#xe879;" glyph-name="exit_to_app" d="M810 810.667c46 0 86-40 86-86v-596c0-46-40-86-86-86h-596c-48 0-86 40-86 86v170h86v-170h596v596h-596v-170h-86v170c0 46 38 86 86 86h596zM430 272.667l110 112h-412v84h412l-110 112 60 60 214-214-214-214z" />
<glyph unicode="&#xe880;" glyph-name="find_in_page" d="M384 384.667c0 70 58 128 128 128s128-58 128-128-58-128-128-128-128 58-128 128zM854 102.667l-164 164c22 34 36 74 36 118 0 118-96 212-214 212s-214-94-214-212 96-214 214-214c44 0 84 14 118 36l188-190c-14-10-30-16-50-16h-512c-46 0-86 38-86 84l2 684c0 46 38 84 84 84h342l256-256v-494z" />
<glyph unicode="&#xe893;" glyph-name="label_outline" d="M682 212.667l152 214-152 214h-468v-428h468zM752 688.667l186-262-186-262c-16-22-42-36-70-36h-468c-46 0-86 38-86 84v428c0 46 40 84 86 84h468c28 0 54-14 70-36z" />
<glyph unicode="&#xe896;" glyph-name="list" d="M298 640.667h598v-86h-598v86zM298 212.667v86h598v-86h-598zM298 384.667v84h598v-84h-598zM128 554.667v86h86v-86h-86zM128 212.667v86h86v-86h-86zM128 384.667v84h86v-84h-86z" />
<glyph unicode="&#xe89f;" glyph-name="open_with" d="M598 298.667v-128h128l-214-214-214 214h128v128h172zM982 426.667l-214-214v128h-128v172h128v128zM384 512.667v-172h-128v-128l-214 214 214 214v-128h128zM426 554.667v128h-128l214 214 214-214h-128v-128h-172z" />
<glyph unicode="&#xe8b4;" glyph-name="room" d="M512 448.667c58 0 106 48 106 106s-48 106-106 106-106-48-106-106 48-106 106-106zM512 852.667c166 0 298-132 298-298 0-224-298-554-298-554s-298 330-298 554c0 166 132 298 298 298z" />
<glyph unicode="&#xe8b6;" glyph-name="search" d="M406 340.667c106 0 192 86 192 192s-86 192-192 192-192-86-192-192 86-192 192-192zM662 340.667l212-212-64-64-212 212v34l-12 12c-48-42-112-66-180-66-154 0-278 122-278 276s124 278 278 278 276-124 276-278c0-68-24-132-66-180l12-12h34z" />
<glyph unicode="&#xe8b7;" glyph-name="search3" d="M406 340.667c106 0 192 86 192 192s-86 192-192 192-192-86-192-192 86-192 192-192zM662 340.667l212-212-64-64-212 212v34l-12 12c-48-42-112-66-180-66-154 0-278 122-278 276s124 278 278 278 276-124 276-278c0-68-24-132-66-180l12-12h34z" />
<glyph unicode="&#xe8b8;" glyph-name="settings" d="M512 276.667c82 0 150 68 150 150s-68 150-150 150-150-68-150-150 68-150 150-150zM830 384.667l90-70c8-6 10-18 4-28l-86-148c-6-10-16-12-26-8l-106 42c-22-16-46-32-72-42l-16-112c-2-10-10-18-20-18h-172c-10 0-18 8-20 18l-16 112c-26 10-50 24-72 42l-106-42c-10-4-20-2-26 8l-86 148c-6 10-4 22 4 28l90 70c-2 14-2 28-2 42s0 28 2 42l-90 70c-8 6-10 18-4 28l86 148c6 10 16 12 26 8l106-42c22 16 46 32 72 42l16 112c2 10 10 18 20 18h172c10 0 18-8 20-18l16-112c26-10 50-24 72-42l106 42c10 4 20 2 26-8l86-148c6-10 4-22-4-28l-90-70c2-14 2-28 2-42s0-28-2-42z" />
<glyph unicode="&#xe8c4;" glyph-name="settings_overscan" d="M896 126.667v600h-768v-600h768zM896 810.667c46 0 86-40 86-86v-596c0-46-40-86-86-86h-768c-46 0-86 40-86 86v596c0 46 40 86 86 86h768zM598 256.667l-86-108-86 108h172zM256 512.667v-172l-106 86zM768 512.667l106-86-106-86v172zM512 704.667l86-108h-172z" />
<glyph unicode="&#xe8d0;" glyph-name="stars" d="M692 170.667l-48 206 160 138-210 18-82 192-82-194-210-16 160-138-48-206 180 108zM512 852.667c236 0 426-190 426-426s-190-426-426-426-426 190-426 426 190 426 426 426z" />
<glyph unicode="&#xe8e6;" glyph-name="turned_in" d="M726 810.667c46 0 84-40 84-86v-682l-298 128-298-128v682c0 46 38 86 84 86h428z" />
<glyph unicode="&#xe8e7;" glyph-name="turned_in_not" d="M726 170.667v554h-428v-554l214 94zM726 810.667c46 0 84-40 84-86v-682l-298 128-298-128v682c0 46 38 86 84 86h428z" />
<glyph unicode="&#xe8e8;" glyph-name="turned_in2" d="M726 810.667c46 0 84-40 84-86v-682l-298 128-298-128v682c0 46 38 86 84 86h428z" />
<glyph unicode="&#xe8e9;" glyph-name="turned_in_not2" d="M726 170.667v554h-428v-554l214 94zM726 810.667c46 0 84-40 84-86v-682l-298 128-298-128v682c0 46 38 86 84 86h428z" />
<glyph unicode="&#xe8ff;" glyph-name="zoom_in" d="M512 512.667h-86v-86h-42v86h-86v42h86v86h42v-86h86v-42zM406 340.667c106 0 192 86 192 192s-86 192-192 192-192-86-192-192 86-192 192-192zM662 340.667l212-212-64-64-212 212v34l-12 12c-48-42-112-66-180-66-154 0-278 122-278 276s124 278 278 278 276-124 276-278c0-68-24-132-66-180l12-12h34z" />
<glyph unicode="&#xe900;" glyph-name="zoom_out" d="M298 554.667h214v-42h-214v42zM406 340.667c106 0 192 86 192 192s-86 192-192 192-192-86-192-192 86-192 192-192zM662 340.667l212-212-64-64-212 212v34l-12 12c-48-42-112-66-180-66-154 0-278 122-278 276s124 278 278 278 276-124 276-278c0-68-24-132-66-180l12-12h34z" />
<glyph unicode="&#xe901;" glyph-name="anchor, link, reference" d="M927.968 348.96l-36.352-247.328-73.568 71.36c-58.272-49.248-166.336-116.256-323.328-116.256-157.92 0-267.136 65.376-325.248 112.224l-67.136-65.12-38.336 245.088 252.576-37.184-69.6-67.552c48.832-36.256 125.44-79.968 201.728-79.968l-0.224 403.488c-55.712 19.392-95.808 70.624-95.808 131.36 0 77.376 64.608 140.096 144.32 140.096 79.68 0 144.32-62.72 144.32-140.096 0-61.664-41.344-113.44-98.368-132.128 0.352-78.72 1.632-404.224-0.128-404.224 72.96 0 148.288 47.488 197.344 85.888l-65.024 63.136 252.832 37.216zM571.392 701.344c0 39.872-33.312 72.224-74.4 72.224s-74.432-32.352-74.432-72.224c0-39.904 33.344-72.256 74.432-72.256s74.4 32.352 74.4 72.256z" />
<glyph unicode="&#xe902;" glyph-name="zoom_in2" d="M512 512.667h-86v-86h-42v86h-86v42h86v86h42v-86h86v-42zM406 340.667c106 0 192 86 192 192s-86 192-192 192-192-86-192-192 86-192 192-192zM662 340.667l212-212-64-64-212 212v34l-12 12c-48-42-112-66-180-66-154 0-278 122-278 276s124 278 278 278 276-124 276-278c0-68-24-132-66-180l12-12h34z" />
<glyph unicode="&#xe903;" glyph-name="zoom_out2" d="M298 554.667h214v-42h-214v42zM406 340.667c106 0 192 86 192 192s-86 192-192 192-192-86-192-192 86-192 192-192zM662 340.667l212-212-64-64-212 212v34l-12 12c-48-42-112-66-180-66-154 0-278 122-278 276s124 278 278 278 276-124 276-278c0-68-24-132-66-180l12-12h34z" />
<glyph unicode="&#xe90b;" glyph-name="droplet" d="M864.626 486.838c-65.754 183.44-205.11 348.15-352.626 473.162-147.516-125.012-286.87-289.722-352.626-473.162-40.664-113.436-44.682-236.562 12.584-345.4 65.846-125.14 198.632-205.438 340.042-205.438s274.196 80.298 340.040 205.44c57.27 108.838 53.25 231.962 12.586 345.398zM738.764 201.044c-43.802-83.252-132.812-137.044-226.764-137.044-55.12 0-108.524 18.536-152.112 50.652 13.242-1.724 26.632-2.652 40.112-2.652 117.426 0 228.668 67.214 283.402 171.242 44.878 85.292 40.978 173.848 23.882 244.338 14.558-28.15 26.906-56.198 36.848-83.932 22.606-63.062 40.024-156.34-5.368-242.604z" />
<glyph unicode="&#xe95f;" glyph-name="box-remove" d="M832 896h-640l-192-192v-672c0-17.674 14.326-32 32-32h960c17.672 0 32 14.326 32 32v672l-192 192zM640 320v-192h-256v192h-192l320 256 320-256h-192zM154.51 768l64 64h586.976l64-64h-714.976z" />
<glyph unicode="&#xe960;" glyph-name="download" d="M512 384l256 256h-192v256h-128v-256h-192zM744.726 488.728l-71.74-71.742 260.080-96.986-421.066-157.018-421.066 157.018 260.080 96.986-71.742 71.742-279.272-104.728v-256l512-192 512 192v256z" />
<glyph unicode="&#xe97a;" glyph-name="spinner" d="M384 832c0 70.692 57.308 128 128 128s128-57.308 128-128c0-70.692-57.308-128-128-128s-128 57.308-128 128zM655.53 719.53c0 70.692 57.308 128 128 128s128-57.308 128-128c0-70.692-57.308-128-128-128s-128 57.308-128 128zM832 448c0 35.346 28.654 64 64 64s64-28.654 64-64c0-35.346-28.654-64-64-64s-64 28.654-64 64zM719.53 176.47c0 35.346 28.654 64 64 64s64-28.654 64-64c0-35.346-28.654-64-64-64s-64 28.654-64 64zM448.002 64c0 0 0 0 0 0 0 35.346 28.654 64 64 64s64-28.654 64-64c0 0 0 0 0 0 0-35.346-28.654-64-64-64s-64 28.654-64 64zM176.472 176.47c0 0 0 0 0 0 0 35.346 28.654 64 64 64s64-28.654 64-64c0 0 0 0 0 0 0-35.346-28.654-64-64-64s-64 28.654-64 64zM144.472 719.53c0 0 0 0 0 0 0 53.019 42.981 96 96 96s96-42.981 96-96c0 0 0 0 0 0 0-53.019-42.981-96-96-96s-96 42.981-96 96zM56 448c0 39.765 32.235 72 72 72s72-32.235 72-72c0-39.765-32.235-72-72-72s-72 32.235-72 72z" />
<glyph unicode="&#xe97c;" glyph-name="spinner3" d="M512 656.904c-32.964 0-59.686 26.724-59.686 59.686v179.060c0 32.964 26.722 59.686 59.686 59.686 32.962 0 59.688-26.722 59.688-59.686v-179.060c0-32.964-26.726-59.686-59.688-59.686zM512-36.956c-20.602 0-37.304 16.702-37.304 37.304v179.060c0 20.602 16.702 37.304 37.304 37.304 20.604 0 37.304-16.704 37.304-37.304v-179.060c0-20.602-16.7-37.304-37.304-37.304zM377.756 624.64c-19.34 0-38.146 10.034-48.512 27.988l-89.53 155.070c-15.452 26.764-6.282 60.986 20.482 76.438 26.762 15.45 60.986 6.284 76.438-20.482l89.53-155.072c15.452-26.764 6.282-60.986-20.482-76.438-8.81-5.084-18.432-7.504-27.926-7.504zM735.856 26.744c-11.602 0-22.886 6.022-29.108 16.792l-89.53 155.070c-9.27 16.056-3.77 36.592 12.29 45.864 16.056 9.264 36.59 3.77 45.864-12.292l89.532-155.068c9.27-16.058 3.768-36.592-12.292-45.864-5.286-3.048-11.060-4.502-16.756-4.502zM279.344 530.060c-8.86 0-17.838 2.256-26.064 7.006l-155.072 89.53c-24.978 14.422-33.538 46.362-19.116 71.342 14.42 24.978 46.364 33.538 71.342 19.116l155.070-89.53c24.98-14.422 33.538-46.362 19.116-71.34-9.668-16.756-27.226-26.124-45.276-26.124zM899.648 194.326c-5.064 0-10.196 1.29-14.894 4.004l-155.068 89.53c-14.274 8.24-19.164 26.494-10.924 40.768 8.242 14.276 26.496 19.166 40.766 10.924l155.070-89.532c14.274-8.24 19.164-26.492 10.924-40.766-5.53-9.574-15.562-14.928-25.874-14.928zM243.41 399.504h-179.060c-26.784 0-48.496 21.712-48.496 48.496s21.712 48.496 48.496 48.496h179.060c26.784 0 48.496-21.712 48.496-48.496s-21.712-48.496-48.496-48.496zM959.65 418.156c-0.002 0 0 0 0 0h-179.060c-16.482 0.002-29.844 13.364-29.844 29.844s13.364 29.844 29.844 29.844c0.002 0 0 0 0 0h179.060c16.482 0 29.844-13.362 29.844-29.844 0-16.48-13.364-29.844-29.844-29.844zM124.366 179.402c-15.472 0-30.518 8.028-38.81 22.39-12.362 21.41-5.026 48.79 16.384 61.148l155.072 89.532c21.41 12.368 48.79 5.028 61.15-16.384 12.362-21.412 5.026-48.79-16.384-61.15l-155.072-89.53c-7.050-4.070-14.748-6.006-22.34-6.006zM744.632 552.448c-10.314 0-20.346 5.352-25.874 14.926-8.24 14.274-3.35 32.526 10.924 40.768l155.070 89.528c14.272 8.236 32.526 3.352 40.768-10.922 8.24-14.274 3.35-32.526-10.924-40.768l-155.070-89.528c-4.7-2.714-9.83-4.004-14.894-4.004zM288.136 19.284c-6.962 0-14.016 1.774-20.48 5.504-19.626 11.332-26.35 36.428-15.020 56.054l89.53 155.070c11.33 19.628 36.426 26.352 56.054 15.022 19.626-11.332 26.35-36.43 15.020-56.054l-89.53-155.072c-7.598-13.166-21.392-20.524-35.574-20.524zM646.266 650.758c-5.062 0-10.196 1.29-14.894 4.002-14.274 8.242-19.164 26.494-10.924 40.766l89.534 155.070c8.24 14.274 26.492 19.166 40.766 10.922 14.274-8.242 19.164-26.494 10.924-40.766l-89.532-155.070c-5.53-9.57-15.56-14.924-25.874-14.924z" />
<glyph unicode="&#xe97f;" glyph-name="spinner6" d="M384 832c0 70.692 57.308 128 128 128s128-57.308 128-128c0-70.692-57.308-128-128-128s-128 57.308-128 128zM790.994 448c0 0 0 0 0 0 0 57.993 47.013 105.006 105.006 105.006s105.006-47.013 105.006-105.006c0 0 0 0 0 0 0-57.993-47.013-105.006-105.006-105.006s-105.006 47.013-105.006 105.006zM688.424 176.47c0 52.526 42.58 95.106 95.106 95.106s95.106-42.58 95.106-95.106c0-52.526-42.58-95.106-95.106-95.106s-95.106 42.58-95.106 95.106zM425.862 64c0 47.573 38.565 86.138 86.138 86.138s86.138-38.565 86.138-86.138c0-47.573-38.565-86.138-86.138-86.138s-86.138 38.565-86.138 86.138zM162.454 176.47c0 43.088 34.93 78.018 78.018 78.018s78.018-34.93 78.018-78.018c0-43.088-34.93-78.018-78.018-78.018s-78.018 34.93-78.018 78.018zM57.338 448c0 39.026 31.636 70.662 70.662 70.662s70.662-31.636 70.662-70.662c0-39.026-31.636-70.662-70.662-70.662s-70.662 31.636-70.662 70.662zM176.472 719.528c0 0 0 0 0 0 0 35.346 28.654 64 64 64s64-28.654 64-64c0 0 0 0 0 0 0-35.346-28.654-64-64-64s-64 28.654-64 64zM899.464 719.528c0-64.024-51.906-115.934-115.936-115.934-64.024 0-115.936 51.91-115.936 115.934 0 64.032 51.912 115.934 115.936 115.934 64.030 0 115.936-51.902 115.936-115.934z" />
<glyph unicode="&#xe982;" glyph-name="spinner9" d="M512 960c-278.748 0-505.458-222.762-511.848-499.974 5.92 241.864 189.832 435.974 415.848 435.974 229.75 0 416-200.576 416-448 0-53.020 42.98-96 96-96s96 42.98 96 96c0 282.77-229.23 512-512 512zM512-64c278.748 0 505.458 222.762 511.848 499.974-5.92-241.864-189.832-435.974-415.848-435.974-229.75 0-416 200.576-416 448 0 53.020-42.98 96-96 96s-96-42.98-96-96c0-282.77 229.23-512 512-512z" />
<glyph unicode="&#xe984;" glyph-name="spinner11" d="M1024 576h-384l143.53 143.53c-72.53 72.526-168.96 112.47-271.53 112.47s-199-39.944-271.53-112.47c-72.526-72.53-112.47-168.96-112.47-271.53s39.944-199 112.47-271.53c72.53-72.526 168.96-112.47 271.53-112.47s199 39.944 271.528 112.472c6.056 6.054 11.86 12.292 17.456 18.668l96.32-84.282c-93.846-107.166-231.664-174.858-385.304-174.858-282.77 0-512 229.23-512 512s229.23 512 512 512c141.386 0 269.368-57.326 362.016-149.984l149.984 149.984v-384z" />
<glyph unicode="&#xe986;" glyph-name="search2" d="M992.262 88.604l-242.552 206.294c-25.074 22.566-51.89 32.926-73.552 31.926 57.256 67.068 91.842 154.078 91.842 249.176 0 212.078-171.922 384-384 384-212.076 0-384-171.922-384-384s171.922-384 384-384c95.098 0 182.108 34.586 249.176 91.844-1-21.662 9.36-48.478 31.926-73.552l206.294-242.552c35.322-39.246 93.022-42.554 128.22-7.356s31.892 92.898-7.354 128.22zM384 320c-141.384 0-256 114.616-256 256s114.616 256 256 256 256-114.616 256-256-114.614-256-256-256z" />
<glyph unicode="&#xe989;" glyph-name="enlarge" d="M1024 960h-416l160-160-192-192 96-96 192 192 160-160zM1024-64v416l-160-160-192 192-96-96 192-192-160-160zM0-64h416l-160 160 192 192-96 96-192-192-160 160zM0 960v-416l160 160 192-192 96 96-192 192 160 160z" />
<glyph unicode="&#xe98b;" glyph-name="enlarge2" d="M1024 960v-416l-160 160-192-192-96 96 192 192-160 160zM448 288l-192-192 160-160h-416v416l160-160 192 192z" />
<glyph unicode="&#xe992;" glyph-name="equalizer" d="M448 832v16c0 26.4-21.6 48-48 48h-160c-26.4 0-48-21.6-48-48v-16h-192v-128h192v-16c0-26.4 21.6-48 48-48h160c26.4 0 48 21.6 48 48v16h576v128h-576zM256 704v128h128v-128h-128zM832 528c0 26.4-21.6 48-48 48h-160c-26.4 0-48-21.6-48-48v-16h-576v-128h576v-16c0-26.4 21.6-48 48-48h160c26.4 0 48 21.6 48 48v16h192v128h-192v16zM640 384v128h128v-128h-128zM448 208c0 26.4-21.6 48-48 48h-160c-26.4 0-48-21.6-48-48v-16h-192v-128h192v-16c0-26.4 21.6-48 48-48h160c26.4 0 48 21.6 48 48v16h576v128h-576v16zM256 64v128h128v-128h-128z" />
<glyph unicode="&#xe994;" glyph-name="cog" d="M933.79 349.75c-53.726 93.054-21.416 212.304 72.152 266.488l-100.626 174.292c-28.75-16.854-62.176-26.518-97.846-26.518-107.536 0-194.708 87.746-194.708 195.99h-201.258c0.266-33.41-8.074-67.282-25.958-98.252-53.724-93.056-173.156-124.702-266.862-70.758l-100.624-174.292c28.97-16.472 54.050-40.588 71.886-71.478 53.638-92.908 21.512-211.92-71.708-266.224l100.626-174.292c28.65 16.696 61.916 26.254 97.4 26.254 107.196 0 194.144-87.192 194.7-194.958h201.254c-0.086 33.074 8.272 66.57 25.966 97.218 53.636 92.906 172.776 124.594 266.414 71.012l100.626 174.29c-28.78 16.466-53.692 40.498-71.434 71.228zM512 240.668c-114.508 0-207.336 92.824-207.336 207.334 0 114.508 92.826 207.334 207.336 207.334 114.508 0 207.332-92.826 207.332-207.334-0.002-114.51-92.824-207.334-207.332-207.334z" />
<glyph unicode="&#xe9bd;" glyph-name="menu2" d="M64 768h896v-192h-896zM64 512h896v-192h-896zM64 256h896v-192h-896z" />
<glyph unicode="&#xe9d5;" glyph-name="contrast" d="M512 960c-282.77 0-512-229.23-512-512s229.23-512 512-512 512 229.23 512 512-229.23 512-512 512zM128 448c0 212.078 171.922 384 384 384v-768c-212.078 0-384 171.922-384 384z" />
<glyph unicode="&#xea0d;" glyph-name="cancel-circle" d="M512 960c-282.77 0-512-229.23-512-512s229.23-512 512-512 512 229.23 512 512-229.23 512-512 512zM512 32c-229.75 0-416 186.25-416 416s186.25 416 416 416 416-186.25 416-416-186.25-416-416-416zM672 704l-160-160-160 160-96-96 160-160-160-160 96-96 160 160 160-160 96 96-160 160 160 160z" />
<glyph unicode="&#xea14;" glyph-name="exit" d="M768 320v128h-320v128h320v128l192-192zM704 384v-256h-320v-192l-384 192v832h704v-320h-64v256h-512l256-128v-576h256v192z" />
<glyph unicode="&#xea34;" glyph-name="arrow-right" d="M992 448l-480 480v-288h-512v-384h512v-288z" />
<glyph unicode="&#xea38;" glyph-name="arrow-left" d="M32 448l480-480v288h512v384h-512v288z" />
<glyph unicode="&#xea3c;" glyph-name="arrow-right2" d="M621.254 82.746l320 320c24.994 24.992 24.994 65.516 0 90.51l-320 320c-24.994 24.992-65.516 24.992-90.51 0-24.994-24.994-24.994-65.516 0-90.51l210.746-210.746h-613.49c-35.346 0-64-28.654-64-64s28.654-64 64-64h613.49l-210.746-210.746c-12.496-12.496-18.744-28.876-18.744-45.254s6.248-32.758 18.744-45.254c24.994-24.994 65.516-24.994 90.51 0z" />
<glyph unicode="&#xea40;" glyph-name="arrow-left2" d="M402.746 82.746l-320 320c-24.994 24.992-24.994 65.516 0 90.51l320 320c24.994 24.992 65.516 24.992 90.51 0 24.994-24.994 24.994-65.516 0-90.51l-210.746-210.746h613.49c35.346 0 64-28.654 64-64s-28.654-64-64-64h-613.49l210.746-210.746c12.496-12.496 18.744-28.876 18.744-45.254s-6.248-32.758-18.744-45.254c-24.994-24.994-65.516-24.994-90.51 0z" />
<glyph unicode="&#xea42;" glyph-name="circle-right" d="M512 960c-282.77 0-512-229.23-512-512s229.23-512 512-512 512 229.23 512 512-229.23 512-512 512zM512 32c-229.75 0-416 186.25-416 416s186.25 416 416 416 416-186.25 416-416-186.25-416-416-416zM354.744 253.256l90.512-90.512 285.254 285.256-285.256 285.254-90.508-90.508 194.744-194.746z" />
<glyph unicode="&#xea44;" glyph-name="circle-left" d="M512-64c282.77 0 512 229.23 512 512s-229.23 512-512 512-512-229.23-512-512 229.23-512 512-512zM512 864c229.75 0 416-186.25 416-416s-186.25-416-416-416-416 186.25-416 416 186.25 416 416 416zM669.256 642.744l-90.512 90.512-285.254-285.256 285.256-285.254 90.508 90.508-194.744 194.746z" />
</font></defs></svg>

After

Width:  |  Height:  |  Size: 35 KiB

BIN
vendor/icomoon/fonts/icomoon.ttf vendored Normal file

Binary file not shown.

BIN
vendor/icomoon/fonts/icomoon.woff vendored Normal file

Binary file not shown.

387
vendor/icomoon/style.css vendored Normal file
View file

@ -0,0 +1,387 @@
@font-face {
font-family: 'icomoon';
src: url('fonts/icomoon.eot?gvtfq1');
src: url('fonts/icomoon.eot?gvtfq1#iefix') format('embedded-opentype'),
url('fonts/icomoon.ttf?gvtfq1') format('truetype'),
url('fonts/icomoon.woff?gvtfq1') format('woff'),
url('fonts/icomoon.svg?gvtfq1#icomoon') format('svg');
font-weight: normal;
font-style: normal;
}
[class^="icon-"], [class*=" icon-"] {
/* use !important to prevent issues with browser extensions that change fonts */
font-family: 'icomoon' !important;
speak: none;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;
/* Better Font Rendering =========== */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
/* slightly bigger icons */
font-size: 1.2em;
}
.icon-anchor:before {
content: "\e901";
}
.icon-link:before {
content: "\e901";
}
.icon-reference:before {
content: "\e901";
}
.icon-arrow_back2:before {
content: "\e5c5";
}
.icon-flag:before {
content: "\e153";
}
.icon-attach_file:before {
content: "\e226";
}
.icon-attachment:before {
content: "\e2bc";
}
.icon-class:before {
content: "\e86f";
}
.icon-turned_in2:before {
content: "\e8e8";
}
.icon-turned_in_not2:before {
content: "\e8e9";
}
.icon-brightness_1:before {
content: "\e3a6";
}
.icon-brightness_2:before {
content: "\e3a7";
}
.icon-brightness_3:before {
content: "\e3a8";
}
.icon-brightness_4:before {
content: "\e3a9";
}
.icon-brightness_low2:before {
content: "\e1ae";
}
.icon-brightness_medium:before {
content: "\e1af";
}
.icon-brightness_high:before {
content: "\e1ac";
}
.icon-chat:before {
content: "\e0b7";
}
.icon-chat_bubble:before {
content: "\e0ca";
}
.icon-chat_bubble_outline:before {
content: "\e0cb";
}
.icon-check:before {
content: "\e5ca";
}
.icon-check_box:before {
content: "\e834";
}
.icon-double_page_mode:before {
content: "\e86d";
}
.icon-single_page_mode:before {
content: "\e86e";
}
.icon-comment:before {
content: "\e0b9";
}
.icon-delete:before {
content: "\e872";
}
.icon-find_in_page:before {
content: "\e880";
}
.icon-format_size:before {
content: "\e245";
}
.icon-fullscreen2:before {
content: "\e5d3";
}
.icon-fullscreen_exit2:before {
content: "\e5d4";
}
.icon-star:before {
content: "\e838";
}
.icon-link2:before {
content: "\e157";
}
.icon-keyboard_arrow_left2:before {
content: "\e316";
}
.icon-label_outline:before {
content: "\e893";
}
.icon-local_library:before {
content: "\e54b";
}
.icon-location_off:before {
content: "\e0c7";
}
.icon-room:before {
content: "\e8b4";
}
.icon-menu3:before {
content: "\e5d5";
}
.icon-message:before {
content: "\e0c9";
}
.icon-rate_review:before {
content: "\e560";
}
.icon-save:before {
content: "\e161";
}
.icon-search3:before {
content: "\e8b7";
}
.icon-star_border:before {
content: "\e83a";
}
.icon-star_half:before {
content: "\e839";
}
.icon-stars:before {
content: "\e8d0";
}
.icon-zoom_in2:before {
content: "\e902";
}
.icon-zoom_out2:before {
content: "\e903";
}
.icon-arrow_back:before {
content: "\e5c4";
}
.icon-arrow_forward:before {
content: "\e5c8";
}
.icon-icon-fit-window:before {
content: "\e85b";
}
.icon-icon-fit-width:before {
content: "\e85c";
}
.icon-turned_in:before {
content: "\e8e6";
}
.icon-turned_in_not:before {
content: "\e8e7";
}
.icon-brightness_low:before {
content: "\e1ad";
}
.icon-build:before {
content: "\e869";
}
.icon-cancel:before {
content: "\e5c9";
}
.icon-navigate_before:before {
content: "\e408";
}
.icon-navigate_next:before {
content: "\e409";
}
.icon-close:before {
content: "\e5cd";
}
.icon-cloud_download:before {
content: "\e2c0";
}
.icon-content_copy:before {
content: "\e14d";
}
.icon-mode_edit:before {
content: "\e254";
}
.icon-crop_free:before {
content: "\e3c2";
}
.icon-crop_portrait:before {
content: "\e3c5";
}
.icon-dehaze:before {
content: "\e3c7";
}
.icon-dns:before {
content: "\e875";
}
.icon-exit_to_app:before {
content: "\e879";
}
.icon-featured_play_list:before {
content: "\e06d";
}
.icon-format_list_bulleted:before {
content: "\e241";
}
.icon-format_list_numbered:before {
content: "\e242";
}
.icon-format_textdirection_l_to_r:before {
content: "\e247";
}
.icon-format_textdirection_r_to_l:before {
content: "\e248";
}
.icon-fullscreen:before {
content: "\e5d0";
}
.icon-fullscreen_exit:before {
content: "\e5d1";
}
.icon-keyboard_arrow_left:before {
content: "\e314";
}
.icon-keyboard_arrow_right:before {
content: "\e315";
}
.icon-list:before {
content: "\e896";
}
.icon-sync:before {
content: "\e627";
}
.icon-menu:before {
content: "\e5d2";
}
.icon-open_with:before {
content: "\e89f";
}
.icon-pages:before {
content: "\e7f9";
}
.icon-search:before {
content: "\e8b6";
}
.icon-settings:before {
content: "\e8b8";
}
.icon-settings_overscan:before {
content: "\e8c4";
}
.icon-tune:before {
content: "\e429";
}
.icon-unarchive:before {
content: "\e169";
}
.icon-wb_sunny:before {
content: "\e430";
}
.icon-zoom_in:before {
content: "\e8ff";
}
.icon-zoom_out:before {
content: "\e900";
}
.icon-zoom_out_map:before {
content: "\e56b";
}
.icon-rotate_0:before {
content: "\e039";
}
.icon-rotate_90:before {
content: "\e03a";
}
.icon-rotate_180:before {
content: "\e03b";
}
.icon-rotate_270:before {
content: "\e03c";
}
.icon-rotate_left:before {
content: "\e419";
}
.icon-rotate_right:before {
content: "\e41a";
}
.icon-droplet:before {
content: "\e90b";
}
.icon-box-remove:before {
content: "\e95f";
}
.icon-download:before {
content: "\e960";
}
.icon-spinner:before {
content: "\e97a";
}
.icon-spinner3:before {
content: "\e97c";
}
.icon-spinner6:before {
content: "\e97f";
}
.icon-spinner9:before {
content: "\e982";
}
.icon-spinner11:before {
content: "\e984";
}
.icon-search2:before {
content: "\e986";
}
.icon-enlarge:before {
content: "\e989";
}
.icon-enlarge2:before {
content: "\e98b";
}
.icon-equalizer:before {
content: "\e992";
}
.icon-cog:before {
content: "\e994";
}
.icon-menu2:before {
content: "\e9bd";
}
.icon-contrast:before {
content: "\e9d5";
}
.icon-cancel-circle:before {
content: "\ea0d";
}
.icon-exit:before {
content: "\ea14";
}
.icon-arrow-right:before {
content: "\ea34";
}
.icon-arrow-left:before {
content: "\ea38";
}
.icon-arrow-right2:before {
content: "\ea3c";
}
.icon-arrow-left2:before {
content: "\ea40";
}
.icon-circle-right:before {
content: "\ea42";
}
.icon-circle-left:before {
content: "\ea44";
}

2
vendor/jquery/jquery.min.js vendored Normal file

File diff suppressed because one or more lines are too long

1
vendor/jquery/jquery.min.map vendored Normal file

File diff suppressed because one or more lines are too long

18
vendor/jquery/put-delete.js vendored Normal file
View file

@ -0,0 +1,18 @@
jQuery.each( [ "put", "delete" ], function( i, method ) {
jQuery[ method ] = function( url, data, callback, type ) {
if ( jQuery.isFunction( data ) ) {
type = type || callback;
callback = data;
data = undefined;
}
return jQuery.ajax({
url: url,
type: method,
dataType: type,
data: data,
success: callback
});
};
});

View file

@ -0,0 +1,59 @@
PDFJS.Reader.AnnotationLayerController = function (options, reader) {
this.reader = reader;
this.annotationDiv = options.annotationDiv;
this.pdfPage = options.pdfPage;
this.renderInteractiveForms = options.renderInteractiveForms;
this.linkService = options.linkService;
this.downloadManager = options.downloadManager;
this.div = null;
return this;
};
PDFJS.Reader.AnnotationLayerController.prototype.render = function (viewport, intent) {
var self = this;
var parameters = {
intent: (intent === undefined ? 'display' : intent),
};
this.pdfPage.getAnnotations(parameters).then(function (annotations) {
viewport = viewport.clone({ dontFlip: true });
parameters = {
viewport: viewport,
div: self.div,
annotations: annotations,
page: self.pdfPage,
renderInteractiveForms: self.renderInteractiveForms,
linkService: self.linkService,
downloadManager: self.downloadManager,
};
if (self.div) {
// If an annotationLayer already exists, refresh its children's
// transformation matrices.
PDFJS.AnnotationLayer.update(parameters);
} else {
// Create an annotation layer div and render the annotations
// if there is at least one annotation.
if (annotations.length === 0) {
return;
}
self.div = self.annotationDiv;
parameters.div = self.div;
PDFJS.AnnotationLayer.render(parameters);
}
});
};
PDFJS.Reader.AnnotationLayerController.prototype.hide = function () {
if (!this.div) {
return;
}
this.div.setAttribute('hidden', 'true');
};

View file

@ -0,0 +1,72 @@
PDFJS.reader.BookmarksController = function() {
var reader = this,
eventBus = this.eventBus,
book = this.book,
annotations = reader.settings.annotations;
var $bookmarks = $("#bookmarksView"),
$list = $bookmarks.find("#bookmarks"),
$bookmark = $("#bookmark");
var show = function() {
$bookmarks.addClass('open');
};
var hide = function() {
$bookmarks.removeClass('open');
};
var addBookmarkItem = function (bookmark) {
$list.append(reader.NotesController.createItem(bookmark));
//reader.settings.session.setBookmark(bookmark.id, bookmark.anchor, bookmark.type, bookmark);
};
eventBus.on('bookmarkcreated', function createBookmark1(e) {
var id = e.id,
$item = $("#"+id);
addBookmarkItem(reader.getAnnotation(id));
if (id === reader.pageToId(reader.settings.currentPage))
$bookmark
.addClass("icon-turned_in")
.removeClass("icon-turned_in_not");
});
eventBus.on('bookmarkremoved', function removeBookmark1(e) {
var id = e.id,
$item = $("#"+id);
console.log($item);
console.log("event bookmarkremoved caught:",e,id);
if (reader.isBookmarked(id)) {
//delete reader.settings.annotations[id];
//reader.settings.session.deleteBookmark(id);
console.log("removing bookmark ", $item, reader.pageToId(reader.settings.currentPage), id);
$item.remove();
$item.remove();
$item.remove();
$item.remove();
if (id === reader.pageToId(reader.settings.currentPage))
$bookmark
.removeClass("icon-turned_in")
.addClass("icon-turned_in_not");
}
});
for (var bookmark in annotations) {
if (annotations.hasOwnProperty(bookmark) && (annotations[bookmark].type === "bookmark"))
addBookmarkItem(annotations[bookmark]);
};
return {
"show" : show,
"hide" : hide,
"addItem" : addBookmarkItem,
};
};

View file

@ -0,0 +1,344 @@
PDFJS.reader.ControlsController = function(book) {
var reader = this,
eventBus = this.eventBus,
settings = reader.settings,
customStyles = reader.settings.customStyles,
activeStyles = reader.settings.activeStyles;
var $store = $("#store"),
$viewer = $("#viewer"),
$fullscreen = $("#fullscreen"),
$fullscreenicon = $("#fullscreenicon"),
$cancelfullscreenicon = $("#cancelfullscreenicon"),
$slider = $("#slider"),
$main = $("#main"),
$sidebar = $("#sidebar"),
$titlebar = $("#titlebar"),
$settings = $("#setting"),
$bookmark = $("#bookmark"),
$note = $("#note"),
$togglelayout = $("#toggle-layout"),
$zoom_icon = $("#zoom_icon"),
$zoom_options = $("#zoom_options"),
$zoom_option = $(".zoom_option"),
$rotate_icon = $("#rotate_icon"),
$rotate_options = $("#rotate_options"),
$rotate_option = $(".rotate_option"),
$rotate_left = $("#rotate_left"),
$rotate_right = $("#rotate_right"),
$page_num = $("#page_num"),
$total_pages = $("#total_pages"),
$status_message_left = $("#status_message_left"),
$status_message_right = $("#status_message_right"),
$nightmode = $("#nightmode"),
$nightshift = $(".nightshift");
var STATUS_MESSAGE_LENGTH = 30,
STATUS_MESSAGE_TIMEOUT = 3000,
status_timeout_left,
status_timeout_right;
if (reader.isMobile() === true) {
$titlebar.addClass("background_visible");
}
var show = function () {
$titlebar.removeClass("hide");
};
var hide = function () {
$titlebar.addClass("hide");
};
var toggle = function () {
$titlebar.toggleClass("hide");
};
$viewer.on("touchstart", function(e) {
reader.ControlsController.toggle();
});
var setStatus = function (message, right) {
$status_message = (right) ? $status_message_right : $status_message_left;
status_timeout = (right) ? status_timeout_right : status_timeout_left;
$status_message[0].textContent = reader.ellipsize(message, STATUS_MESSAGE_LENGTH);
//$status_message[0].textContent = message;
if (typeof status_timeout === "number") {
clearTimeout(status_timeout);
status_timeout = undefined;
}
status_timeout = setTimeout(function () {
$status_message[0].textContent = "";
}, STATUS_MESSAGE_TIMEOUT);
if (right) {
status_timeout_right = status_timeout;
} else {
status_timeout_left = status_timeout;
}
};
var fullscreen = false;
$slider.on("click", function () {
if(reader.sidebarOpen) {
reader.SidebarController.hide();
} else {
reader.SidebarController.show();
}
});
if(typeof screenfull !== 'undefined') {
$fullscreen.on("click", function() {
screenfull.toggle($('#container')[0]);
});
if(screenfull.raw) {
document.addEventListener(screenfull.raw.fullscreenchange, function() {
fullscreen = screenfull.isFullscreen;
if(fullscreen) {
$fullscreen
.addClass("icon-fullscreen_exit")
.removeClass("icon-fullscreen");
} else {
$fullscreen
.addClass("icon-fullscreen")
.removeClass("icon-fullscreen_exit");
}
});
}
}
$settings.on("click", function() {
reader.SettingsController.show();
});
$note.on("click", function() {
reader.SidebarController.changePanelTo("Notes");
});
$bookmark.on("click", function() {
var currentPage = reader.settings.currentPage,
id = reader.pageToId(currentPage);
if (!reader.isBookmarked(id))
reader.addBookmark(currentPage)
else
reader.removeBookmark(currentPage);
});
/* select works fine on most browsers, but - of course - apple mobile has 'special needs' so
* a custom select is needed...
*/
/* custom select, supports icons in drop-down list */
// zooooooooooooooom
$zoom_icon.on("click", function () {
var offset = $(this).offset();
$zoom_options.css("opacity", 0);
$zoom_options.toggleClass("hide");
$zoom_options.css({
'left': parseInt(offset.left - ($zoom_options.width() / 2)) + "px",
'top' : parseInt(parseInt(offset.top) + parseInt($zoom_icon.height())) + "px"
});
$zoom_options.css("opacity", "");
});
var setZoomIcon = function(zoom) {
$zoom_icon[0].className="";
var $current_zoom_option = $zoom_options.find("[data-value='" + zoom + "']");
if ($current_zoom_option.data("class")) {
$zoom_icon.addClass($current_zoom_option.data("class"));
} else {
$zoom_icon[0].textContent = $current_zoom_option.data("text");
}
};
setZoomIcon(settings.zoomLevel);
$zoom_option.on("click", function () {
var $this = $(this);
reader.setZoom($this.data("value"));
$zoom_icon[0].className="";
$zoom_icon[0].textContent = "";
if ($this.data("class")) {
$zoom_icon.addClass($this.data("class"));
} else {
$zoom_icon[0].textContent = $this.data("text");
}
$zoom_options.addClass("hide");
});
// rotate
var setRotateIcon = function (rotation) {
$rotate_icon[0].className = "";
$rotate_icon[0].className = "icon-rotate_" + rotation;
};
setRotateIcon(settings.rotation);
$rotate_icon.on("click", function () {
var offset = $(this).offset();
$rotate_options.css("opacity", 0);
$rotate_options.toggleClass("hide");
$rotate_options.css({
'left': parseInt(offset.left - ($rotate_options.width() / 2)) + "px",
'top' : parseInt(parseInt(offset.top) + parseInt($rotate_icon.height())) + "px"
});
$rotate_options.css("opacity", "");
});
$rotate_option.on("click", function () {
var $this = $(this);
reader.setRotation($this.data("value"));
$rotate_icon[0].className="";
$rotate_icon[0].textContent = "";
if ($this.data("class")) {
$rotate_icon.addClass($this.data("class"));
} else {
$rotate_icon[0].textContent = $this.data("text");
}
$rotate_options.addClass("hide");
});
$rotate_left.on("click", function () {
// add 360 to avoid negative rotation value
var rotation = (settings.rotation - 90 + 360) % 360;
reader.setRotation(rotation);
$rotate_icon[0].className = "";
$rotate_icon[0].className = "icon-rotate_" + rotation;
});
$rotate_right.on("click", function () {
var rotation = (settings.rotation + 90) % 360;
reader.setRotation(rotation);
$rotate_icon[0].className = "";
$rotate_icon[0].className = "icon-rotate_" + rotation;
});
/* end custom select */
var setNightmodeIcon = function (mode) {
if (mode)
$nightmode.removeClass("icon-brightness_low2").addClass("icon-brightness_4");
else
$nightmode.removeClass("icon-brightness_4").addClass("icon-brightness_low2");
};
$nightshift.off('click').on('click', function () {
if (settings.nightMode) {
reader.disableStyle(customStyles.nightMode);
settings.nightMode = false;
} else {
reader.enableStyle(customStyles.nightMode);
settings.nightMode = true;
}
setNightmodeIcon(settings.nightMode);
});
var enterPageNum = function(e) {
var text = e.target,
page;
switch (e.keyCode) {
case 27: // escape - cancel, discard changes
$page_num[0].removeEventListener("keydown", enterPageNum, false);
$page_num.removeClass("editable");
$page_num.prop("contenteditable",false);
$page_num.text($page_num.data("content"));
break;
case 13: // enter - accept changes
$page_num[0].removeEventListener("keydown", enterPageNum, false);
$page_num.removeClass("editable");
$page_num.attr("contenteditable", false);
page = parseInt($page_num.text());
if (page > 0 && page <= reader.settings.numPages) {
reader.queuePage(page);
} else {
$page_num.text($page_num.data("content"));
}
break;
}
e.stopPropagation();
};
$page_num.on("click", function() {
$page_num.data("content", $page_num.text());
$page_num.text("");
$page_num.prop("contenteditable", true);
$page_num.addClass("editable");
$page_num[0].addEventListener("keydown", enterPageNum, false);
});
eventBus.on("renderer:pagechanged", function toggleControls1(e) {
var page = e.pageNum,
id = reader.pageToId(page);
if (reader.isBookmarked(id))
$bookmark
.addClass("icon-turned_in")
.removeClass("icon-turned_in_not");
else
$bookmark
.removeClass("icon-turned_in")
.addClass("icon-turned_in_not");
});
var setPageCount = function (_numPages) {
var numPages = _numPages || reader.settings.numPages;
$total_pages[0].textContent = parseInt(numPages).toString();
};
var setCurrentPage = function (_page) {
var page = _page || reader.settings.currentPage,
zoom = reader.settings.zoomLevel,
oddPageRight = reader.settings.oddPageRight,
total_pages = reader.settings.numPages,
text;
if (zoom === "spread") {
if (oddPageRight === true) {
page -= page % 2;
} else {
page -= (page + 1) % 2;
}
if (page >= 0 && page <= total_pages) {
if (page === total_pages) {
text = reader.getPageLabel(page);
} else if (page === 0) {
text = reader.getPageLabel(page + 1);
} else {
text = reader.getPageLabel(page) + "-" + reader.getPageLabel(page + 1);
}
}
} else {
text = reader.getPageLabel(page);
}
$page_num[0].textContent = text;
};
return {
"show": show,
"hide": hide,
"toggle": toggle,
"setZoomIcon": setZoomIcon,
"setRotateIcon": setRotateIcon,
"setNightmodeIcon": setNightmodeIcon,
"setCurrentPage": setCurrentPage,
"setPageCount": setPageCount,
"setStatus": setStatus
};
};

View file

@ -0,0 +1,14 @@
PDFJS.reader.MetaController = function(meta) {
var title = meta.bookTitle,
author = meta.creator;
var $title = $("#book-title"),
$author = $("#chapter-title"),
$dash = $("#title-seperator");
document.title = title+" "+author;
$title.html(title);
$author.html(author);
$dash.show();
};

View file

@ -0,0 +1,427 @@
PDFJS.reader.NotesController = function(book) {
var book = this.book,
reader = this,
eventBus = this.eventBus,
$notesView = $("#notesView"),
$notes = $("#notes"),
$text = $("#note-text"),
$anchor = $("#note-anchor"),
$next = $("#next"),
$prev = $("#prev"),
$touch_nav = $("#touch_nav"),
$viewer = $("#viewer"),
annotations = reader.settings.annotations,
renderer = book.renderer,
popups = [];
var show = function() {
$notesView.addClass('open');
$text.focus();
};
var hide = function() {
$notesView.removeClass('open');
};
$text.on("keydown", function(e) {
e.stopPropagation();
});
var insertAtPoint = function(e) {
var range,
textNode,
offset,
doc = document,
loc,
annotation;
// standard
if (doc.caretPositionFromPoint) {
range = doc.caretPositionFromPoint(e.clientX, e.clientY);
textNode = range.offsetNode;
offset = range.offset;
// WebKit
} else if (doc.caretRangeFromPoint) {
range = doc.caretRangeFromPoint(e.clientX, e.clientY);
textNode = range.startContainer;
offset = range.startOffset;
}
console.log("textNode", textNode, "offset", offset);
console.log(e);
if (textNode.nodeType !== 3) {
for (var i=0; i < textNode.childNodes.length; i++) {
if (textNode.childNodes[i].nodeType == 3) {
textNode = textNode.childNodes[i];
break;
}
}
}
// Find the end of the sentence
offset = textNode.textContent.indexOf(".", offset);
if(offset === -1){
offset = textNode.length; // Last item
} else {
offset += 1; // After the period
}
loc = "";
annotation = new reader.Annotation('annotation', loc, $text.val());
// save...
reader.addAnnotation(annotation);
// show...
addAnnotationItem(annotation);
// add marker...
placeMarker(annotation);
// clear entry
$text.val('');
$anchor.removeClass("icon-location_off");
$anchor.addClass("icon-room");
$text.prop("disabled", false);
book.off("renderer:click", insertAtPoint);
};
var addAnnotationItem = function(annotation) {
$notes.append(createItem(annotation));
//reader.settings.session.setBookmark(annotation.id, annotation.anchor, annotation.type, annotation);
};
var removeAnnotation = function (id) {
if (annotations[id] !== undefined) {
if (annotations[id].type == "bookmark")
eventBus.dispatch("bookmarkremoved", {
source: this,
id: id
});
deleteAnnotationItem(id);
delete annotations[id];
reader.settings.session.deleteBookmark(id);
}
};
var deleteAnnotationItem = function (id) {
var item = document.getElementById(id);
if (item)
item.remove();
};
/* items are HTML-representations of annotations */
var createItem = function(annotation){
var item = document.createElement("li");
var text = document.createElement("div");
var date = document.createElement("div");
var edit = document.createElement("span");
var del = document.createElement("span");
var link = document.createElement("a");
var div = document.createElement("div");
var save = document.createElement("span");
var cancel = document.createElement("span");
text.textContent = annotation.body;
date.textContent = new Date(annotation.edited).toUTCString();
item.classList.add("note");
del.classList.add("item-delete", "item-control", "icon-delete");
edit.classList.add("item-edit", "item-control", "icon-rate_review");
link.classList.add("note-link");
//link.classList.add("note-link", "icon-link2");
date.classList.add("item-date");
del.setAttribute("title", "delete");
edit.setAttribute("title", "edit");
link.setAttribute("title", "context");
item.setAttribute("id", annotation.id);
save.classList.add("item-save", "edit-control", "hide", "icon-check");
cancel.classList.add("item-cancel", "edit-control", "hide", "icon-close");
save.setAttribute("display", "none");
cancel.setAttribute("display", "none");
link.href = "#"+annotation.anchor;
link.textContent = "Page " + annotation.anchor;
link.onclick = function(){
reader.queuePage(annotation.anchor);
return false;
};
if (!annotation.readonly) {
del.onclick = function() {
var id = this.parentNode.parentNode.getAttribute("id");
deleteAnnotationItem(id);
reader.removeAnnotation(id);
};
save.onclick = function() {
var id = this.parentNode.parentNode.getAttribute("id");
var annotation = annotations[id];
var text = this.parentNode.parentNode.firstChild;
try {
annotation.body = text.textContent;
reader.updateAnnotation(annotation);
} catch (e) {
console.log("Updating annotation failed: " + e);
}
closeEditor(id);
};
cancel.onclick = function () {
var id = this.parentNode.parentNode.getAttribute("id");
var text = this.parentNode.parentNode.firstChild;
text.textContent = annotations[id].body;
closeEditor(id);
};
edit.onclick = function() {
openEditor(this.parentNode.parentNode.getAttribute("id"));
};
div.appendChild(cancel);
div.appendChild(save);
div.appendChild(del);
div.appendChild(edit);
}
div.appendChild(link);
item.appendChild(text);
if (!annotation.readonly)
item.appendChild(date);
item.appendChild(div);
return item;
};
var editAnnotation = function (e) {
var text = e.target;
var id = text.parentNode.getAttribute("id");
if (e.keyCode === 27) { // escape - cancel editor, discard changes
text.textContent = annotations[id].body;
closeEditor(id);
}
e.stopPropagation();
};
var openEditor = function(id) {
var item = document.getElementById(id);
var text = item.firstChild;
$(item).find(".item-control").toggleClass("hide");
$(item).find(".edit-control").toggleClass("hide");
text.setAttribute("contenteditable", "true");
text.classList.add("editable");
text.addEventListener("keydown", editAnnotation, false);
};
var closeEditor = function (id) {
var item = document.getElementById(id);
var text = item.firstChild;
$(item).find(".item-control").toggleClass("hide");
$(item).find(".edit-control").toggleClass("hide");
text.classList.remove("editable");
text.removeAttribute("contenteditable");
text.removeEventListener("keydown", editAnnotation, false);
};
var findIndex = function (id) {
// list has items
var i,
list = $notes[0].getElementsByTagName("li");
for (i = 0; i < list.length; i++) {
if (list[i].getAttribute("id") === id)
break;
}
return i+1;
};
var placeMarker = function(annotation){
var doc = book.renderer.doc,
marker = document.createElement("span"),
mark = document.createElement("a");
marker.classList.add("note-marker", "footnotesuperscript", "reader_generated");
marker.id = "note-" + annotation.id;
mark.innerHTML = findIndex(annotation.id) + "[Reader]";
marker.appendChild(mark);
// epubcfi.addMarker(annotation.anchor, doc, marker);
markerEvents(marker, annotation.body);
renumberMarkers();
}
var markerEvents = function(item, txt){
var id = item.id;
var showPop = function(){
var poppos,
iheight = renderer.height,
iwidth = renderer.width,
tip,
pop,
maxHeight = 225,
itemRect,
left,
top,
pos;
//-- create a popup with endnote inside of it
if(!popups[id]) {
popups[id] = document.createElement("div");
popups[id].setAttribute("class", "popup");
pop_content = document.createElement("div");
popups[id].appendChild(pop_content);
pop_content.innerHTML = txt;
pop_content.setAttribute("class", "pop_content");
renderer.render.document.body.appendChild(popups[id]);
//-- TODO: will these leak memory? - Fred
popups[id].addEventListener("mouseover", onPop, false);
popups[id].addEventListener("mouseout", offPop, false);
//-- Add hide on page change
renderer.on("renderer:locationChanged", hidePop, this);
renderer.on("renderer:locationChanged", offPop, this);
// chapter.book.on("renderer:chapterDestroy", hidePop, this);
}
pop = popups[id];
//-- get location of item
itemRect = item.getBoundingClientRect();
left = itemRect.left;
top = itemRect.top;
//-- show the popup
pop.classList.add("show");
//-- locations of popup
popRect = pop.getBoundingClientRect();
//-- position the popup
pop.style.left = left - popRect.width / 2 + "px";
pop.style.top = top + "px";
//-- Adjust max height
if(maxHeight > iheight / 2.5) {
maxHeight = iheight / 2.5;
pop_content.style.maxHeight = maxHeight + "px";
}
//-- switch above / below
if(popRect.height + top >= iheight - 25) {
pop.style.top = top - popRect.height + "px";
pop.classList.add("above");
}else{
pop.classList.remove("above");
}
//-- switch left
if(left - popRect.width <= 0) {
pop.style.left = left + "px";
pop.classList.add("left");
}else{
pop.classList.remove("left");
}
//-- switch right
if(left + popRect.width / 2 >= iwidth) {
//-- TEMP MOVE: 300
pop.style.left = left - 300 + "px";
popRect = pop.getBoundingClientRect();
pop.style.left = left - popRect.width + "px";
//-- switch above / below again
if(popRect.height + top >= iheight - 25) {
pop.style.top = top - popRect.height + "px";
pop.classList.add("above");
}else{
pop.classList.remove("above");
}
pop.classList.add("right");
}else{
pop.classList.remove("right");
}
}
var onPop = function(){
popups[id].classList.add("on");
}
var offPop = function(){
popups[id].classList.remove("on");
}
var hidePop = function(){
setTimeout(function(){
popups[id].classList.remove("show");
}, 100);
}
var openSidebar = function(){
reader.SidebarController.changePanelTo('Notes');
reader.SidebarController.show();
};
item.addEventListener("mouseover", showPop, false);
item.addEventListener("mouseout", hidePop, false);
item.addEventListener("click", openSidebar, false);
}
$anchor.on("click", function(e){
if ($anchor[0].classList.contains("icon-room")) {
$anchor.removeClass("icon-room");
$anchor.addClass("icon-location_off");
$text.prop("disabled", true);
// disable extra-wide navigation as it interferes with anchor placment
if ($prev.hasClass("touch_nav")) {
$prev.removeClass("touch_nav");
$next.removeClass("touch_nav");
$prev.addClass("restore_touch_nav");
}
// listen for selection
$viewer.on("click", insertAtPoint);
} else {
$text.prop("disabled", false);
$anchor.removeClass("icon-location_off");
$anchor.addClass("icon-room");
if ($prev.hasClass("restore_touch_nav")) {
$prev.removeClass("restore_touch_nav");
$prev.addClass("touch_nav");
$next.addClass("touch_nav");
}
$viewer.off("click", insertAtPoint);
}
});
for (var note in annotations) {
if (annotations.hasOwnProperty(note) && (annotations[note].type === "annotation"))
addAnnotationItem(annotations[note]);
};
return {
"show" : show,
"hide" : hide,
"createItem": createItem,
"addItem" : addAnnotationItem,
"removeAnnotation" : removeAnnotation
};
};

View file

@ -0,0 +1,74 @@
PDFJS.reader.OutlineController = function(_outline) {
var reader = this,
book = this.book,
outline = _outline || [];
var outlineView = document.getElementById("outlineView");
var DEFAULT_TITLE = '\u2013';
var generateOutlineItems = function (outline, level) {
var container = document.createElement("ul");
if(!level) level = 1;
outline.forEach(function (chapter) {
var listitem = document.createElement("li"),
link = document.createElement("a"),
toggle = document.createElement("a"),
subitems;
listitem.id = "outline-"+chapter.dest;
listitem.classList.add('list_item');
link.textContent = PDFJS.removeNullCharacters(chapter.title) || DEFAULT_TITLE;
reader.bindLink(link, chapter);
reader.setStyles(link, chapter);
link.classList.add('outline_link');
listitem.appendChild(link);
if(chapter.items.length > 0) {
level++;
subitems = generateOutlineItems(chapter.items, level);
toggle.classList.add('outline_toggle');
listitem.insertBefore(toggle, link);
listitem.appendChild(subitems);
}
container.appendChild(listitem);
});
return container;
}
var onShow = function() {
outlineView.classList.add('open');
};
var onHide = function() {
outlineView.classList.remove('open');
};
outlineView.appendChild(generateOutlineItems(outline));
$(outlineView).find(".outline_toggle").on("click", function(event){
var $el = $(this).parent('li'),
open = $el.hasClass("openChapter");
event.preventDefault();
if(open){
$el.removeClass("openChapter");
} else {
$el.addClass("openChapter");
}
});
return {
"show" : onShow,
"hide" : onHide
};
};

View file

@ -0,0 +1,57 @@
PDFJS.reader.ProgressController = function() {
var reader = this,
settings = reader.settings,
percentage = 0;
var $progress = $("#progress"),
$bar = $(".bar"),
$download_icon = $("#download_icon"),
$message = $(".message-text");
var show = function () {
$progress.removeClass("hide");
};
var hide = function () {
$progress.addClass("hide");
};
var setSize = function (size) {
settings.fileSize = size;
};
var setProgress = function (progress) {
if (percentage < 1)
$download_icon.addClass("active");
percentage = Math.floor((progress.loaded / progress.total) * 100);
$bar.css("width", percentage + "%");
if (percentage === 100)
$download_icon.removeClass("active").addClass("ok");
};
var reset = function() {
$bar.css("width", 0);
};
var setMessage = function (text, category, state) {
var $category_icon = $("#" + category + "_icon");
$message.text(text);
$category_icon[0].classList.remove("ok", "active", "error");
$category_icon.addClass(state);
};
return {
"show": show,
"hide": hide,
"setSize": setSize,
"setProgress": setProgress,
"setMessage": setMessage
};
};

View file

@ -0,0 +1,166 @@
PDFJS.reader.ReaderController = function() {
var $main = $("#main"),
$viewer = $("#viewer"),
$divider = $("#divider"),
$loader = $("#loader"),
$next = $("#next"),
$prev = $("#prev"),
$sidebarReflow = $('#sidebarReflow'),
$metainfo = $("#metainfo"),
$use_custom_colors = $("#use_custom_colors"),
$container = $("#container"),
$fullscreen = $("#fullscreen"),
$bookmark = $("#bookmark"),
$note = $("#note"),
$nightmode = $("#nightmode"),
$rotate_left = $("#rotate_left"),
$rotate_right = $("#rotate_right"),
$clear_search = $("#clear_search");
var reader = this,
book = this.book,
settings = reader.settings;
var slideIn = function() {
if (reader.viewerResized) {
var currentPosition = settings.currentPage;
reader.viewerResized = false;
}
};
var slideOut = function() {
var currentPosition = settings.currentPage;
reader.viewerResized = true;
};
var showLoader = function() {
$loader.show();
hideDivider();
};
var hideLoader = function() {
$loader.hide();
};
var showDivider = function() {
$divider.addClass("show");
};
var hideDivider = function() {
$divider.removeClass("show");
};
var keylock = false;
var showActive = function (obj) {
keylock = true;
obj.addClass("active");
setTimeout(function () {
keylock = false;
obj.removeClass("active");
}, 100);
};
var keyCommands = function(e) {
var page_no = false;
e.preventDefault();
switch (settings.keyboard[e.keyCode]) {
case 'previous':
$prev.click();
break;
case 'next':
$next.click();
break;
case 'first':
page_no = 1;
break;
case 'last':
page_no = reader.settings.numPages;
break;
case 'annotate':
$note.click();
break;
case 'bookmark':
$bookmark.click();
break;
case 'toggleTitlebar':
reader.ControlsController.toggle();
break;
case 'toggleSidebar':
reader.SidebarController.toggle();
break;
case 'closeSidebar':
reader.SidebarController.hide();
break;
case 'toggleFullscreen':
$fullscreen.click();
break;
case 'toggleNight':
$nightmode.click();
break;
case 'rotateLeft':
$rotate_left.click();
break;
case 'rotateRight':
$rotate_right.click();
break;
case 'cycleZoom':
reader.cycleZoom();
break;
case 'previousMatch':
reader.SearchController.nextMatch(true);
break;
case 'nextMatch':
if (e.shiftKey)
reader.SearchController.nextMatch(true);
else
reader.SearchController.nextMatch(false);
break;
case 'clearSearch':
$clear_search.click();
break;
case 'search':
if (e.shiftKey) {
reader.SidebarController.changePanelTo("Search");
reader.SearchController.show();
}
break;
default:
console.log("unsupported keyCode: " + e.keyCode);
}
if (page_no) {
reader.queuePage(page_no);
}
};
document.addEventListener('keydown', keyCommands, false);
$next.on("click", function(e){
reader.nextPage();
showActive($next);
e.preventDefault();
});
$prev.on("click", function(e){
reader.prevPage();
showActive($prev);
e.preventDefault();
});
return {
"slideOut" : slideOut,
"slideIn" : slideIn,
"showLoader" : showLoader,
"hideLoader" : hideLoader,
"showDivider" : showDivider,
"hideDivider" : hideDivider,
"keyCommands" : keyCommands
};
};

Some files were not shown because too many files have changed in this diff Show more