From d7eed01e8071785303a282c3c8bfa3ccb4dc7cec Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Thu, 27 Jun 2019 23:22:08 -0400 Subject: [PATCH] initial commit with overhauled / rebranded project --- .github/FUNDING.yml | 1 + .gitignore | 7 + LICENSE | 19 + PDFJS_LICENSE | 177 +++++++ app/.gitignore | 1 + app/build.gradle | 62 +++ app/lint.xml | 16 + app/proguard-rules.pro | 3 + app/src/main/AndroidManifest.xml | 29 ++ app/src/main/assets/pdf.js | 1 + app/src/main/assets/pdf.worker.js | 1 + app/src/main/assets/viewer.css | 66 +++ app/src/main/assets/viewer.html | 14 + app/src/main/assets/viewer.js | 193 ++++++++ app/src/main/ic_launcher-web.png | Bin 0 -> 7794 bytes .../org/grapheneos/pdfviewer/PdfViewer.java | 442 ++++++++++++++++++ .../java/org/grapheneos/pdfviewer/Utils.java | 196 ++++++++ .../fragment/DocumentPropertiesFragment.java | 60 +++ .../fragment/JumpToPageFragment.java | 66 +++ .../loader/DocumentPropertiesLoader.java | 149 ++++++ .../ic_insert_drive_file_white_24dp.png | Bin 0 -> 153 bytes .../ic_navigate_before_white_24dp.png | Bin 0 -> 132 bytes .../ic_navigate_next_white_24dp.png | Bin 0 -> 133 bytes .../drawable-hdpi/ic_pageview_white_24dp.png | Bin 0 -> 360 bytes .../drawable-hdpi/ic_zoom_in_white_24dp.png | Bin 0 -> 422 bytes .../drawable-hdpi/ic_zoom_out_white_24dp.png | Bin 0 -> 412 bytes .../ic_insert_drive_file_white_24dp.png | Bin 0 -> 133 bytes .../ic_navigate_before_white_24dp.png | Bin 0 -> 116 bytes .../ic_navigate_next_white_24dp.png | Bin 0 -> 113 bytes .../drawable-mdpi/ic_pageview_white_24dp.png | Bin 0 -> 226 bytes .../drawable-mdpi/ic_zoom_in_white_24dp.png | Bin 0 -> 257 bytes .../drawable-mdpi/ic_zoom_out_white_24dp.png | Bin 0 -> 249 bytes .../ic_insert_drive_file_white_24dp.png | Bin 0 -> 206 bytes .../ic_navigate_before_white_24dp.png | Bin 0 -> 136 bytes .../ic_navigate_next_white_24dp.png | Bin 0 -> 144 bytes .../drawable-xhdpi/ic_pageview_white_24dp.png | Bin 0 -> 392 bytes .../drawable-xhdpi/ic_zoom_in_white_24dp.png | Bin 0 -> 486 bytes .../drawable-xhdpi/ic_zoom_out_white_24dp.png | Bin 0 -> 470 bytes .../ic_insert_drive_file_white_24dp.png | Bin 0 -> 283 bytes .../ic_navigate_before_white_24dp.png | Bin 0 -> 202 bytes .../ic_navigate_next_white_24dp.png | Bin 0 -> 213 bytes .../ic_pageview_white_24dp.png | Bin 0 -> 601 bytes .../drawable-xxhdpi/ic_zoom_in_white_24dp.png | Bin 0 -> 737 bytes .../ic_zoom_out_white_24dp.png | Bin 0 -> 731 bytes .../ic_insert_drive_file_white_24dp.png | Bin 0 -> 372 bytes .../ic_navigate_before_white_24dp.png | Bin 0 -> 197 bytes .../ic_navigate_next_white_24dp.png | Bin 0 -> 206 bytes .../ic_pageview_white_24dp.png | Bin 0 -> 770 bytes .../ic_zoom_in_white_24dp.png | Bin 0 -> 954 bytes .../ic_zoom_out_white_24dp.png | Bin 0 -> 925 bytes .../res/drawable/ic_launcher_foreground.xml | 16 + app/src/main/res/layout/webview.xml | 5 + app/src/main/res/menu/pdf_viewer.xml | 51 ++ .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 + app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 973 bytes .../res/mipmap-hdpi/ic_launcher_round.png | Bin 0 -> 2188 bytes app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 705 bytes .../res/mipmap-mdpi/ic_launcher_round.png | Bin 0 -> 1376 bytes app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 1264 bytes .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 0 -> 2848 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 1830 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 0 -> 4517 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 2568 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 0 -> 6450 bytes app/src/main/res/values/arrays.xml | 17 + .../res/values/ic_launcher_background.xml | 4 + app/src/main/res/values/strings.xml | 15 + app/src/main/res/values/styles.xml | 8 + build.gradle | 31 ++ gradle.properties | 2 + gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 55616 bytes gradle/wrapper/gradle-wrapper.properties | 5 + gradlew | 188 ++++++++ gradlew.bat | 100 ++++ settings.gradle | 1 + 76 files changed, 1956 insertions(+) create mode 100644 .github/FUNDING.yml create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 PDFJS_LICENSE create mode 100644 app/.gitignore create mode 100644 app/build.gradle create mode 100644 app/lint.xml create mode 100644 app/proguard-rules.pro create mode 100644 app/src/main/AndroidManifest.xml create mode 100644 app/src/main/assets/pdf.js create mode 100644 app/src/main/assets/pdf.worker.js create mode 100644 app/src/main/assets/viewer.css create mode 100644 app/src/main/assets/viewer.html create mode 100644 app/src/main/assets/viewer.js create mode 100644 app/src/main/ic_launcher-web.png create mode 100644 app/src/main/java/org/grapheneos/pdfviewer/PdfViewer.java create mode 100644 app/src/main/java/org/grapheneos/pdfviewer/Utils.java create mode 100644 app/src/main/java/org/grapheneos/pdfviewer/fragment/DocumentPropertiesFragment.java create mode 100644 app/src/main/java/org/grapheneos/pdfviewer/fragment/JumpToPageFragment.java create mode 100644 app/src/main/java/org/grapheneos/pdfviewer/loader/DocumentPropertiesLoader.java create mode 100644 app/src/main/res/drawable-hdpi/ic_insert_drive_file_white_24dp.png create mode 100644 app/src/main/res/drawable-hdpi/ic_navigate_before_white_24dp.png create mode 100644 app/src/main/res/drawable-hdpi/ic_navigate_next_white_24dp.png create mode 100644 app/src/main/res/drawable-hdpi/ic_pageview_white_24dp.png create mode 100644 app/src/main/res/drawable-hdpi/ic_zoom_in_white_24dp.png create mode 100644 app/src/main/res/drawable-hdpi/ic_zoom_out_white_24dp.png create mode 100644 app/src/main/res/drawable-mdpi/ic_insert_drive_file_white_24dp.png create mode 100644 app/src/main/res/drawable-mdpi/ic_navigate_before_white_24dp.png create mode 100644 app/src/main/res/drawable-mdpi/ic_navigate_next_white_24dp.png create mode 100644 app/src/main/res/drawable-mdpi/ic_pageview_white_24dp.png create mode 100644 app/src/main/res/drawable-mdpi/ic_zoom_in_white_24dp.png create mode 100644 app/src/main/res/drawable-mdpi/ic_zoom_out_white_24dp.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_insert_drive_file_white_24dp.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_navigate_before_white_24dp.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_navigate_next_white_24dp.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_pageview_white_24dp.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_zoom_in_white_24dp.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_zoom_out_white_24dp.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_insert_drive_file_white_24dp.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_navigate_before_white_24dp.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_navigate_next_white_24dp.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_pageview_white_24dp.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_zoom_in_white_24dp.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_zoom_out_white_24dp.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_insert_drive_file_white_24dp.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_navigate_before_white_24dp.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_navigate_next_white_24dp.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_pageview_white_24dp.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_zoom_in_white_24dp.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_zoom_out_white_24dp.png create mode 100644 app/src/main/res/drawable/ic_launcher_foreground.xml create mode 100644 app/src/main/res/layout/webview.xml create mode 100644 app/src/main/res/menu/pdf_viewer.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png create mode 100644 app/src/main/res/values/arrays.xml create mode 100644 app/src/main/res/values/ic_launcher_background.xml create mode 100644 app/src/main/res/values/strings.xml create mode 100644 app/src/main/res/values/styles.xml create mode 100644 build.gradle create mode 100644 gradle.properties create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 gradlew.bat create mode 100644 settings.gradle diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..c737277 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +custom: https://grapheneos.org/donate diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0fd942e --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +*.iml +.gradle +local.properties +build/ +signing.properties +*.jks +/.idea diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..21a6e0f --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2019 Daniel Micay + +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. diff --git a/PDFJS_LICENSE b/PDFJS_LICENSE new file mode 100644 index 0000000..f433b1a --- /dev/null +++ b/PDFJS_LICENSE @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..32be588 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,62 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 28 + buildToolsVersion "29.0.0" + defaultConfig { + applicationId "org.grapheneos.pdfviewer" + minSdkVersion 24 + targetSdkVersion 28 + versionCode 1 + versionName versionCode.toString() + resConfigs "en" + } + + signingConfigs { + release + } + buildTypes { + debug { + applicationIdSuffix ".debug" + } + release { + minifyEnabled true + shrinkResources true + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + signingConfig signingConfigs.release + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(include: ['*.jar'], dir: 'libs') + implementation 'androidx.appcompat:appcompat:1.0.2' +} + +def props = new Properties() +def propFile = new File('signing.properties') + +if (propFile.canRead()) { + props.load(new FileInputStream(propFile)) + + if (props != null && + props.containsKey('STORE_FILE') && + props.containsKey('STORE_PASSWORD') && + props.containsKey('KEY_ALIAS') && + props.containsKey('KEY_PASSWORD')) { + android.signingConfigs.release.storeFile = rootProject.file(props['STORE_FILE']) + android.signingConfigs.release.storePassword = props['STORE_PASSWORD'] + android.signingConfigs.release.keyAlias = props['KEY_ALIAS'] + android.signingConfigs.release.keyPassword = props['KEY_PASSWORD'] + } else { + println 'signing.properties found but some entries are missing' + android.buildTypes.release.signingConfig = null + } +} else { + println 'signing.properties not found' + android.buildTypes.release.signingConfig = null +} diff --git a/app/lint.xml b/app/lint.xml new file mode 100644 index 0000000..26fc1e1 --- /dev/null +++ b/app/lint.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..5e9f79b --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,3 @@ +-keepclassmembers class * { + @android.webkit.JavascriptInterface ; +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..dc055a6 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/assets/pdf.js b/app/src/main/assets/pdf.js new file mode 100644 index 0000000..61af55c --- /dev/null +++ b/app/src/main/assets/pdf.js @@ -0,0 +1 @@ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("pdfjs-dist/build/pdf",[],t):"object"==typeof exports?exports["pdfjs-dist/build/pdf"]=t():e["pdfjs-dist/build/pdf"]=e.pdfjsDistBuildPdf=t()}("undefined"!=typeof self?self:this,function(){return function(e){var t={};function r(n){if(t[n])return t[n].exports;var i=t[n]={i:n,l:!1,exports:{}};return e[n].call(i.exports,i,i.exports,r),i.l=!0,i.exports}return r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:n})},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=75)}([function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.unreachable=t.warn=t.utf8StringToString=t.stringToUTF8String=t.stringToPDFString=t.stringToBytes=t.string32=t.shadow=t.setVerbosityLevel=t.ReadableStream=t.removeNullCharacters=t.readUint32=t.readUint16=t.readInt8=t.log2=t.loadJpegStream=t.isEvalSupported=t.isLittleEndian=t.createValidAbsoluteUrl=t.isSameOrigin=t.isNodeJS=t.isSpace=t.isString=t.isNum=t.isEmptyObj=t.isBool=t.isArrayBuffer=t.info=t.getVerbosityLevel=t.getLookupTableFactory=t.deprecated=t.createObjectURL=t.createPromiseCapability=t.createBlob=t.bytesToString=t.assert=t.arraysToBytes=t.arrayByteLength=t.FormatError=t.XRefParseException=t.Util=t.UnknownErrorException=t.UnexpectedResponseException=t.TextRenderingMode=t.StreamType=t.StatTimer=t.PasswordResponses=t.PasswordException=t.PageViewport=t.NotImplementedException=t.NativeImageDecoding=t.MissingPDFException=t.MissingDataException=t.MessageHandler=t.InvalidPDFException=t.AbortException=t.CMapCompressionType=t.ImageKind=t.FontType=t.AnnotationType=t.AnnotationFlag=t.AnnotationFieldFlag=t.AnnotationBorderStyleType=t.UNSUPPORTED_FEATURES=t.VERBOSITY_LEVELS=t.OPS=t.IDENTITY_MATRIX=t.FONT_IDENTITY_MATRIX=void 0;var n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};r(76);var i=r(116),a={errors:0,warnings:1,infos:5},o=a.warnings;function s(e){o>=a.warnings&&console.log("Warning: "+e)}function l(e){throw new Error(e)}function u(e,t){e||l(t)}var c=function(){function e(e,t){this.name="PasswordException",this.message=e,this.code=t}return e.prototype=new Error,e.constructor=e,e}(),h=function(){function e(e,t){this.name="UnknownErrorException",this.message=e,this.details=t}return e.prototype=new Error,e.constructor=e,e}(),d=function(){function e(e){this.name="InvalidPDFException",this.message=e}return e.prototype=new Error,e.constructor=e,e}(),f=function(){function e(e){this.name="MissingPDFException",this.message=e}return e.prototype=new Error,e.constructor=e,e}(),p=function(){function e(e,t){this.name="UnexpectedResponseException",this.message=e,this.status=t}return e.prototype=new Error,e.constructor=e,e}(),m=function(){function e(e){this.message=e}return e.prototype=new Error,e.prototype.name="NotImplementedException",e.constructor=e,e}(),v=function(){function e(e,t){this.begin=e,this.end=t,this.message="Missing data ["+e+", "+t+")"}return e.prototype=new Error,e.prototype.name="MissingDataException",e.constructor=e,e}(),g=function(){function e(e){this.message=e}return e.prototype=new Error,e.prototype.name="XRefParseException",e.constructor=e,e}(),b=function(){function e(e){this.message=e}return e.prototype=new Error,e.prototype.name="FormatError",e.constructor=e,e}(),y=function(){function e(e){this.name="AbortException",this.message=e}return e.prototype=new Error,e.constructor=e,e}(),_=/\x00/g;function A(e){u("string"==typeof e,"Invalid argument for stringToBytes");for(var t=e.length,r=new Uint8Array(t),n=0;ne[2]&&(t[0]=e[2],t[2]=e[0]),e[1]>e[3]&&(t[1]=e[3],t[3]=e[1]),t},e.intersect=function(t,r){function n(e,t){return e-t}var i=[t[0],t[2],r[0],r[2]].sort(n),a=[t[1],t[3],r[1],r[3]].sort(n),o=[];return t=e.normalizeRect(t),r=e.normalizeRect(r),(i[0]===t[0]&&i[1]===r[0]||i[0]===r[0]&&i[1]===t[0])&&(o[0]=i[1],o[2]=i[2],(a[0]===t[1]&&a[1]===r[1]||a[0]===r[1]&&a[1]===t[1])&&(o[1]=a[1],o[3]=a[2],o))};var r=["","C","CC","CCC","CD","D","DC","DCC","DCCC","CM","","X","XX","XXX","XL","L","LX","LXX","LXXX","XC","","I","II","III","IV","V","VI","VII","VIII","IX"];return e.toRoman=function(e,t){u(Number.isInteger(e)&&e>0,"The number should be a positive integer.");for(var n,i=[];e>=1e3;)e-=1e3,i.push("M");n=e/100|0,e%=100,i.push(r[n]),n=e/10|0,e%=10,i.push(r[10+n]),i.push(r[20+e]);var a=i.join("");return t?a.toLowerCase():a},e.appendToArray=function(e,t){Array.prototype.push.apply(e,t)},e.prependToArray=function(e,t){Array.prototype.unshift.apply(e,t)},e.extendObj=function(e,t){for(var r in t)e[r]=t[r]},e.getInheritableProperty=function(e,t,r){for(;e&&!e.has(t);)e=e.get("Parent");return e?r?e.getArray(t):e.get(t):null},e.inherit=function(e,t,r){for(var n in e.prototype=Object.create(t.prototype),e.prototype.constructor=e,r)e.prototype[n]=r[n]},e.loadScript=function(e,t){var r=document.createElement("script"),n=!1;r.setAttribute("src",e),t&&(r.onload=function(){n||t(),n=!0}),document.getElementsByTagName("head")[0].appendChild(r)},e}(),P=function(){function e(e,t,r,n,i,a){this.viewBox=e,this.scale=t,this.rotation=r,this.offsetX=n,this.offsetY=i;var o,s,l,u,c,h,d,f,p=(e[2]+e[0])/2,m=(e[3]+e[1])/2;switch(r=(r%=360)<0?r+360:r){case 180:o=-1,s=0,l=0,u=1;break;case 90:o=0,s=1,l=1,u=0;break;case 270:o=0,s=-1,l=-1,u=0;break;default:o=1,s=0,l=0,u=-1}a&&(l=-l,u=-u),0===o?(c=Math.abs(m-e[1])*t+n,h=Math.abs(p-e[0])*t+i,d=Math.abs(e[3]-e[1])*t,f=Math.abs(e[2]-e[0])*t):(c=Math.abs(p-e[0])*t+n,h=Math.abs(m-e[1])*t+i,d=Math.abs(e[2]-e[0])*t,f=Math.abs(e[3]-e[1])*t),this.transform=[o*t,s*t,l*t,u*t,c-o*t*p-l*t*m,h-s*t*p-u*t*m],this.width=d,this.height=f,this.fontScale=t}return e.prototype={clone:function(t){var r="scale"in(t=t||{})?t.scale:this.scale,n="rotation"in t?t.rotation:this.rotation;return new e(this.viewBox.slice(),r,n,this.offsetX,this.offsetY,t.dontFlip)},convertToViewportPoint:function(e,t){return w.applyTransform([e,t],this.transform)},convertToViewportRectangle:function(e){var t=w.applyTransform([e[0],e[1]],this.transform),r=w.applyTransform([e[2],e[3]],this.transform);return[t[0],t[1],r[0],r[1]]},convertToPdfPoint:function(e,t){return w.applyInverseTransform([e,t],this.transform)}},e}(),k=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,728,711,710,729,733,731,730,732,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8226,8224,8225,8230,8212,8211,402,8260,8249,8250,8722,8240,8222,8220,8221,8216,8217,8218,8482,64257,64258,321,338,352,376,381,305,322,339,353,382,0,8364];function C(){var e={};return e.promise=new Promise(function(t,r){e.resolve=t,e.reject=r}),e}var R,x=function(){function e(e,t,r){for(;e.lengtha&&(a=o.length)}for(t=0,r=n.length;t2&&void 0!==arguments[2]&&arguments[2])&&URL.createObjectURL){var r=T(e,t);return URL.createObjectURL(r)}for(var n="data:"+t+";base64,",i=0,a=e.length;i>2]+R[(3&o)<<4|s>>4]+R[i+1>6:64]+R[i+22&&void 0!==arguments[2]?arguments[2]:null;return e?new Promise(function(n,i){n(e.apply(r,t))}):Promise.resolve(void 0)}function L(e){if("object"!==(void 0===e?"undefined":n(e)))return e;switch(e.name){case"AbortException":return new y(e.message);case"MissingPDFException":return new f(e.message);case"UnexpectedResponseException":return new p(e.message,e.status);default:return new h(e.message,e.details)}}function I(e,t,r){t?e.resolve():e.reject(r)}function F(e,t,r){var n=this;this.sourceName=e,this.targetName=t,this.comObj=r,this.callbackId=1,this.streamId=1,this.postMessageTransfers=!0,this.streamSinks=Object.create(null),this.streamControllers=Object.create(null);var i=this.callbacksCapabilities=Object.create(null),a=this.actionHandler=Object.create(null);this._onComObjOnMessage=function(e){var t=e.data;if(t.targetName===n.sourceName)if(t.stream)n._processStreamMessage(t);else if(t.isReply){var o=t.callbackId;if(!(t.callbackId in i))throw new Error("Cannot resolve callback "+o);var s=i[o];delete i[o],"error"in t?s.reject(L(t.error)):s.resolve(t.data)}else{if(!(t.action in a))throw new Error("Unknown action from worker: "+t.action);var l=a[t.action];if(t.callbackId){var u=n.sourceName,c=t.sourceName;Promise.resolve().then(function(){return l[0].call(l[1],t.data)}).then(function(e){r.postMessage({sourceName:u,targetName:c,isReply:!0,callbackId:t.callbackId,data:e})},function(e){r.postMessage({sourceName:u,targetName:c,isReply:!0,callbackId:t.callbackId,error:function(e){return!(e instanceof Error)||e instanceof y||e instanceof f||e instanceof p||e instanceof h?e:new h(e.message,e.toString())}(e)})})}else t.streamId?n._createStreamSink(t):l[0].call(l[1],t.data)}},r.addEventListener("message",this._onComObjOnMessage)}F.prototype={on:function(e,t,r){var n=this.actionHandler;if(n[e])throw new Error('There is already an actionName called "'+e+'"');n[e]=[t,r]},send:function(e,t,r){var n={sourceName:this.sourceName,targetName:this.targetName,action:e,data:t};this.postMessage(n,r)},sendWithPromise:function(e,t,r){var n=this.callbackId++,i={sourceName:this.sourceName,targetName:this.targetName,action:e,data:t,callbackId:n},a=C();this.callbacksCapabilities[n]=a;try{this.postMessage(i,r)}catch(e){a.reject(e)}return a.promise},sendWithStream:function(e,t,r,n){var a=this,o=this.streamId++,s=this.sourceName,l=this.targetName;return new i.ReadableStream({start:function(r){var n=C();return a.streamControllers[o]={controller:r,startCall:n,isClosed:!1},a.postMessage({sourceName:s,targetName:l,action:e,streamId:o,data:t,desiredSize:r.desiredSize}),n.promise},pull:function(e){var t=C();return a.streamControllers[o].pullCall=t,a.postMessage({sourceName:s,targetName:l,stream:"pull",streamId:o,desiredSize:e.desiredSize}),t.promise},cancel:function(e){var t=C();return a.streamControllers[o].cancelCall=t,a.streamControllers[o].isClosed=!0,a.postMessage({sourceName:s,targetName:l,stream:"cancel",reason:e,streamId:o}),t.promise}},r)},_createStreamSink:function(e){var t=this,r=this,n=this.actionHandler[e.action],i=e.streamId,a=e.desiredSize,o=this.sourceName,s=e.sourceName,l=function(e){var r=e.stream,n=e.chunk,a=e.transfers,l=e.success,u=e.reason;t.postMessage({sourceName:o,targetName:s,stream:r,streamId:i,chunk:n,success:l,reason:u},a)},u={enqueue:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1,r=arguments[2];if(!this.isCancelled){var n=this.desiredSize;this.desiredSize-=t,n>0&&this.desiredSize<=0&&(this.sinkCapability=C(),this.ready=this.sinkCapability.promise),l({stream:"enqueue",chunk:e,transfers:r})}},close:function(){this.isCancelled||(this.isCancelled=!0,l({stream:"close"}),delete r.streamSinks[i])},error:function(e){this.isCancelled||(this.isCancelled=!0,l({stream:"error",reason:e}))},sinkCapability:C(),onPull:null,onCancel:null,isCancelled:!1,desiredSize:a,ready:null};u.sinkCapability.resolve(),u.ready=u.sinkCapability.promise,this.streamSinks[i]=u,O(n[0],[e.data,u],n[1]).then(function(){l({stream:"start_complete",success:!0})},function(e){l({stream:"start_complete",success:!1,reason:e})})},_processStreamMessage:function(e){var t=this,r=this.sourceName,n=e.sourceName,i=e.streamId,a=function(e){var a=e.stream,o=e.success,s=e.reason;t.comObj.postMessage({sourceName:r,targetName:n,stream:a,success:o,streamId:i,reason:s})},o=function(){Promise.all([t.streamControllers[e.streamId].startCall,t.streamControllers[e.streamId].pullCall,t.streamControllers[e.streamId].cancelCall].map(function(e){return e&&(t=e.promise,Promise.resolve(t).catch(function(){}));var t})).then(function(){delete t.streamControllers[e.streamId]})};switch(e.stream){case"start_complete":I(this.streamControllers[e.streamId].startCall,e.success,L(e.reason));break;case"pull_complete":I(this.streamControllers[e.streamId].pullCall,e.success,L(e.reason));break;case"pull":if(!this.streamSinks[e.streamId]){a({stream:"pull_complete",success:!0});break}this.streamSinks[e.streamId].desiredSize<=0&&e.desiredSize>0&&this.streamSinks[e.streamId].sinkCapability.resolve(),this.streamSinks[e.streamId].desiredSize=e.desiredSize,O(this.streamSinks[e.streamId].onPull).then(function(){a({stream:"pull_complete",success:!0})},function(e){a({stream:"pull_complete",success:!1,reason:e})});break;case"enqueue":u(this.streamControllers[e.streamId],"enqueue should have stream controller"),this.streamControllers[e.streamId].isClosed||this.streamControllers[e.streamId].controller.enqueue(e.chunk);break;case"close":if(u(this.streamControllers[e.streamId],"close should have stream controller"),this.streamControllers[e.streamId].isClosed)break;this.streamControllers[e.streamId].isClosed=!0,this.streamControllers[e.streamId].controller.close(),o();break;case"error":u(this.streamControllers[e.streamId],"error should have stream controller"),this.streamControllers[e.streamId].controller.error(L(e.reason)),o();break;case"cancel_complete":I(this.streamControllers[e.streamId].cancelCall,e.success,L(e.reason)),o();break;case"cancel":if(!this.streamSinks[e.streamId])break;O(this.streamSinks[e.streamId].onCancel,[L(e.reason)]).then(function(){a({stream:"cancel_complete",success:!0})},function(e){a({stream:"cancel_complete",success:!1,reason:e})}),this.streamSinks[e.streamId].sinkCapability.reject(L(e.reason)),this.streamSinks[e.streamId].isCancelled=!0,delete this.streamSinks[e.streamId];break;default:throw new Error("Unexpected stream case")}},postMessage:function(e,t){t&&this.postMessageTransfers?this.comObj.postMessage(e,t):this.comObj.postMessage(e)},destroy:function(){this.comObj.removeEventListener("message",this._onComObjOnMessage)}},t.FONT_IDENTITY_MATRIX=[.001,0,0,.001,0,0],t.IDENTITY_MATRIX=[1,0,0,1,0,0],t.OPS={dependency:1,setLineWidth:2,setLineCap:3,setLineJoin:4,setMiterLimit:5,setDash:6,setRenderingIntent:7,setFlatness:8,setGState:9,save:10,restore:11,transform:12,moveTo:13,lineTo:14,curveTo:15,curveTo2:16,curveTo3:17,closePath:18,rectangle:19,stroke:20,closeStroke:21,fill:22,eoFill:23,fillStroke:24,eoFillStroke:25,closeFillStroke:26,closeEOFillStroke:27,endPath:28,clip:29,eoClip:30,beginText:31,endText:32,setCharSpacing:33,setWordSpacing:34,setHScale:35,setLeading:36,setFont:37,setTextRenderingMode:38,setTextRise:39,moveText:40,setLeadingMoveText:41,setTextMatrix:42,nextLine:43,showText:44,showSpacedText:45,nextLineShowText:46,nextLineSetSpacingShowText:47,setCharWidth:48,setCharWidthAndBounds:49,setStrokeColorSpace:50,setFillColorSpace:51,setStrokeColor:52,setStrokeColorN:53,setFillColor:54,setFillColorN:55,setStrokeGray:56,setFillGray:57,setStrokeRGBColor:58,setFillRGBColor:59,setStrokeCMYKColor:60,setFillCMYKColor:61,shadingFill:62,beginInlineImage:63,beginImageData:64,endInlineImage:65,paintXObject:66,markPoint:67,markPointProps:68,beginMarkedContent:69,beginMarkedContentProps:70,endMarkedContent:71,beginCompat:72,endCompat:73,paintFormXObjectBegin:74,paintFormXObjectEnd:75,beginGroup:76,endGroup:77,beginAnnotations:78,endAnnotations:79,beginAnnotation:80,endAnnotation:81,paintJpegXObject:82,paintImageMaskXObject:83,paintImageMaskXObjectGroup:84,paintImageXObject:85,paintInlineImageXObject:86,paintInlineImageXObjectGroup:87,paintImageXObjectRepeat:88,paintImageMaskXObjectRepeat:89,paintSolidColorImageMask:90,constructPath:91},t.VERBOSITY_LEVELS=a,t.UNSUPPORTED_FEATURES={unknown:"unknown",forms:"forms",javaScript:"javaScript",smask:"smask",shadingPattern:"shadingPattern",font:"font"},t.AnnotationBorderStyleType={SOLID:1,DASHED:2,BEVELED:3,INSET:4,UNDERLINE:5},t.AnnotationFieldFlag={READONLY:1,REQUIRED:2,NOEXPORT:4,MULTILINE:4096,PASSWORD:8192,NOTOGGLETOOFF:16384,RADIO:32768,PUSHBUTTON:65536,COMBO:131072,EDIT:262144,SORT:524288,FILESELECT:1048576,MULTISELECT:2097152,DONOTSPELLCHECK:4194304,DONOTSCROLL:8388608,COMB:16777216,RICHTEXT:33554432,RADIOSINUNISON:33554432,COMMITONSELCHANGE:67108864},t.AnnotationFlag={INVISIBLE:1,HIDDEN:2,PRINT:4,NOZOOM:8,NOROTATE:16,NOVIEW:32,READONLY:64,LOCKED:128,TOGGLENOVIEW:256,LOCKEDCONTENTS:512},t.AnnotationType={TEXT:1,LINK:2,FREETEXT:3,LINE:4,SQUARE:5,CIRCLE:6,POLYGON:7,POLYLINE:8,HIGHLIGHT:9,UNDERLINE:10,SQUIGGLY:11,STRIKEOUT:12,STAMP:13,CARET:14,INK:15,POPUP:16,FILEATTACHMENT:17,SOUND:18,MOVIE:19,WIDGET:20,SCREEN:21,PRINTERMARK:22,TRAPNET:23,WATERMARK:24,THREED:25,REDACT:26},t.FontType={UNKNOWN:0,TYPE1:1,TYPE1C:2,CIDFONTTYPE0:3,CIDFONTTYPE0C:4,TRUETYPE:5,CIDFONTTYPE2:6,TYPE3:7,OPENTYPE:8,TYPE0:9,MMTYPE1:10},t.ImageKind={GRAYSCALE_1BPP:1,RGB_24BPP:2,RGBA_32BPP:3},t.CMapCompressionType={NONE:0,BINARY:1,STREAM:2},t.AbortException=y,t.InvalidPDFException=d,t.MessageHandler=F,t.MissingDataException=v,t.MissingPDFException=f,t.NativeImageDecoding={NONE:"none",DECODE:"decode",DISPLAY:"display"},t.NotImplementedException=m,t.PageViewport=P,t.PasswordException=c,t.PasswordResponses={NEED_PASSWORD:1,INCORRECT_PASSWORD:2},t.StatTimer=x,t.StreamType={UNKNOWN:0,FLATE:1,LZW:2,DCT:3,JPX:4,JBIG:5,A85:6,AHX:7,CCF:8,RL:9},t.TextRenderingMode={FILL:0,STROKE:1,FILL_STROKE:2,INVISIBLE:3,FILL_ADD_TO_PATH:4,STROKE_ADD_TO_PATH:5,FILL_STROKE_ADD_TO_PATH:6,ADD_TO_PATH:7,FILL_STROKE_MASK:3,ADD_TO_PATH_FLAG:4},t.UnexpectedResponseException=p,t.UnknownErrorException=h,t.Util=w,t.XRefParseException=g,t.FormatError=b,t.arrayByteLength=S,t.arraysToBytes=function(e){if(1===e.length&&e[0]instanceof Uint8Array)return e[0];var t,r,n,i=0,a=e.length;for(t=0;t=a.infos&&console.log("Info: "+e)},t.isArrayBuffer=function(e){return"object"===(void 0===e?"undefined":n(e))&&null!==e&&void 0!==e.byteLength},t.isBool=function(e){return"boolean"==typeof e},t.isEmptyObj=function(e){for(var t in e)return!1;return!0},t.isNum=function(e){return"number"==typeof e},t.isString=function(e){return"string"==typeof e},t.isSpace=function(e){return 32===e||9===e||13===e||10===e},t.isNodeJS=function(){return"object"===("undefined"==typeof process?"undefined":n(process))&&process+""=="[object process]"},t.isSameOrigin=function(e,t){try{var r=new URL(e);if(!r.origin||"null"===r.origin)return!1}catch(e){return!1}var n=new URL(t,r);return r.origin===n.origin},t.createValidAbsoluteUrl=function(e,t){if(!e)return null;try{var r=t?new URL(e,t):new URL(e);if(function(e){if(!e)return!1;switch(e.protocol){case"http:":case"https:":case"ftp:":case"mailto:":case"tel:":return!0;default:return!1}}(r))return r}catch(e){}return null},t.isLittleEndian=function(){var e=new Uint8Array(4);return e[0]=1,1===new Uint32Array(e.buffer,0,1)[0]},t.isEvalSupported=function(){try{return new Function(""),!0}catch(e){return!1}},t.loadJpegStream=function(e,t,r){var n=new Image;n.onload=function(){r.resolve(e,n)},n.onerror=function(){r.resolve(e,null),s("Error during JPEG image loading")},n.src=t},t.log2=function(e){for(var t=1,r=0;e>t;)t<<=1,r++;return r},t.readInt8=function(e,t){return e[t]<<24>>24},t.readUint16=function(e,t){return e[t]<<8|e[t+1]},t.readUint32=function(e,t){return(e[t]<<24|e[t+1]<<16|e[t+2]<<8|e[t+3])>>>0},t.removeNullCharacters=function(e){return"string"!=typeof e?(s("The argument for removeNullCharacters must be a string."),e):e.replace(_,"")},t.ReadableStream=i.ReadableStream,t.setVerbosityLevel=function(e){o=e},t.shadow=function(e,t,r){return Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!1}),r},t.string32=function(e){return String.fromCharCode(e>>24&255,e>>16&255,e>>8&255,255&e)},t.stringToBytes=A,t.stringToPDFString=function(e){var t,r=e.length,n=[];if("þ"===e[0]&&"ÿ"===e[1])for(t=2;t0?i(n(e),9007199254740991):0}},function(e,t,r){"use strict";var n=r(7),i=r(45),a=r(33),o=Object.defineProperty;t.f=r(8)?Object.defineProperty:function(e,t,r){if(n(e),t=a(t,!0),n(r),i)try{return o(e,t,r)}catch(e){}if("get"in r||"set"in r)throw TypeError("Accessors not supported!");return"value"in r&&(e[t]=r.value),e}},function(e,t,r){"use strict";var n=r(1),i=r(6),a=r(10),o=r(16)("src"),s=Function.toString,l=(""+s).split("toString");r(4).inspectSource=function(e){return s.call(e)},(e.exports=function(e,t,r,s){var u="function"==typeof r;u&&(a(r,"name")||i(r,"name",t)),e[t]!==r&&(u&&(a(r,o)||i(r,o,e[t]?""+e[t]:l.join(String(t)))),e===n?e[t]=r:s?e[t]?e[t]=r:i(e,t,r):(delete e[t],i(e,t,r)))})(Function.prototype,"toString",function(){return"function"==typeof this&&this[o]||s.call(this)})},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.DOMSVGFactory=t.DOMCMapReaderFactory=t.DOMCanvasFactory=t.DEFAULT_LINK_REL=t.getDefaultSetting=t.LinkTarget=t.getFilenameFromUrl=t.isValidUrl=t.isExternalLinkTargetSet=t.addLinkAttributes=t.RenderingCancelledException=t.CustomStyle=void 0;var n,i=function(){function e(e,t){for(var r=0;r0&&t>0,"Invalid SVG dimensions");var r=document.createElementNS(c,"svg:svg");return r.setAttribute("version","1.1"),r.setAttribute("width",e+"px"),r.setAttribute("height",t+"px"),r.setAttribute("preserveAspectRatio","none"),r.setAttribute("viewBox","0 0 "+e+" "+t),r}},{key:"createElement",value:function(e){return(0,a.assert)("string"==typeof e,"Invalid SVG element type"),document.createElementNS(c,e)}}]),e}(),p=function(){var e=["ms","Moz","Webkit","O"],t=Object.create(null);function r(){}return r.getProp=function(r,n){if(1===arguments.length&&"string"==typeof t[r])return t[r];var i,a,o=(n=n||document.documentElement).style;if("string"==typeof o[r])return t[r]=r;a=r.charAt(0).toUpperCase()+r.slice(1);for(var s=0,l=e.length;s0?t:e.length,r>0?r:e.length);return e.substring(e.lastIndexOf("/",n)+1,n)},t.LinkTarget=v,t.getDefaultSetting=b,t.DEFAULT_LINK_REL=u,t.DOMCanvasFactory=h,t.DOMCMapReaderFactory=d,t.DOMSVGFactory=f},function(e,t,r){"use strict";var n=0,i=Math.random();e.exports=function(e){return"Symbol(".concat(void 0===e?"":e,")_",(++n+i).toString(36))}},function(e,t,r){"use strict";var n=Math.ceil,i=Math.floor;e.exports=function(e){return isNaN(e=+e)?0:(e>0?i:n)(e)}},function(e,t,r){"use strict";var n=r(35);e.exports=function(e){return Object(n(e))}},function(e,t,r){"use strict";e.exports={}},function(e,t,r){"use strict";e.exports="undefined"!=typeof window&&window.Math===Math?window:"undefined"!=typeof global&&global.Math===Math?global:"undefined"!=typeof self&&self.Math===Math?self:{}},function(e,t,r){"use strict";e.exports=!1},function(e,t,r){"use strict";e.exports=function(e){if("function"!=typeof e)throw TypeError(e+" is not a function!");return e}},function(e,t,r){"use strict";var n=r(14);e.exports=function(e,t,r){for(var i in t)n(e,i,t[i],r);return e}},function(e,t,r){"use strict";e.exports=function(e,t,r,n){if(!(e instanceof t)||void 0!==n&&n in e)throw TypeError(r+": incorrect invocation!");return e}},function(e,t,r){"use strict";var n={}.toString;e.exports=function(e){return n.call(e).slice(8,-1)}},function(e,t,r){"use strict";var n=r(13).f,i=r(10),a=r(3)("toStringTag");e.exports=function(e,t,r){e&&!i(e=r?e:e.prototype,a)&&n(e,a,{configurable:!0,value:t})}},function(e,t,r){"use strict";e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},function(e,t,r){"use strict";var n=r(34),i=r(35);e.exports=function(e){return n(i(e))}},function(e,t,r){"use strict";var n=r(17),i=Math.max,a=Math.min;e.exports=function(e,t){return(e=n(e))<0?i(e+t,0):a(e,t)}},function(e,t,r){"use strict";var n=r(25),i=r(3)("toStringTag"),a="Arguments"==n(function(){return arguments}());e.exports=function(e){var t,r,o;return void 0===e?"Undefined":null===e?"Null":"string"==typeof(r=function(e,t){try{return e[t]}catch(e){}}(t=Object(e),i))?r:a?n(t):"Object"==(o=n(t))&&"function"==typeof t.callee?"Arguments":o}},function(e,t,r){"use strict";var n=r(11),i=r(98),a=r(53),o=r(7),s=r(12),l=r(57),u={},c={},h=e.exports=function(e,t,r,h,d){var f,p,m,v,g=d?function(){return e}:l(e),b=n(r,h,t?2:1),y=0;if("function"!=typeof g)throw TypeError(e+" is not iterable!");if(a(g)){for(f=s(e.length);f>y;y++)if((v=t?b(o(p=e[y])[0],p[1]):b(e[y]))===u||v===c)return v}else for(m=g.call(e);!(p=m.next()).done;)if((v=i(m,b,p.value,t))===u||v===c)return v};h.BREAK=u,h.RETURN=c},function(e,t,r){"use strict";var n=r(2),i=r(1).document,a=n(i)&&n(i.createElement);e.exports=function(e){return a?i.createElement(e):{}}},function(e,t,r){"use strict";var n=r(2);e.exports=function(e,t){if(!n(e))return e;var r,i;if(t&&"function"==typeof(r=e.toString)&&!n(i=r.call(e)))return i;if("function"==typeof(r=e.valueOf)&&!n(i=r.call(e)))return i;if(!t&&"function"==typeof(r=e.toString)&&!n(i=r.call(e)))return i;throw TypeError("Can't convert object to primitive value")}},function(e,t,r){"use strict";var n=r(25);e.exports=Object("z").propertyIsEnumerable(0)?Object:function(e){return"String"==n(e)?e.split(""):Object(e)}},function(e,t,r){"use strict";e.exports=function(e){if(void 0==e)throw TypeError("Can't call method on "+e);return e}},function(e,t,r){"use strict";var n=r(51)("keys"),i=r(16);e.exports=function(e){return n[e]||(n[e]=i(e))}},function(e,t,r){"use strict";e.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},function(e,t,r){"use strict";var n=r(49),i=r(37);e.exports=Object.keys||function(e){return n(e,i)}},function(e,t,r){"use strict";var n=r(11),i=r(34),a=r(18),o=r(12),s=r(82);e.exports=function(e,t){var r=1==e,l=2==e,u=3==e,c=4==e,h=6==e,d=5==e||h,f=t||s;return function(t,s,p){for(var m,v,g=a(t),b=i(g),y=n(s,p,3),_=o(b.length),A=0,S=r?f(t,_):l?f(t,0):void 0;_>A;A++)if((d||A in b)&&(v=y(m=b[A],A,g),e))if(r)S[A]=v;else if(v)switch(e){case 3:return!0;case 5:return m;case 6:return A;case 2:S.push(m)}else if(c)return!1;return h?-1:u||c?c:S}}},function(e,t,r){"use strict";var n=r(7),i=r(22),a=r(3)("species");e.exports=function(e,t){var r,o=n(e).constructor;return void 0===o||void 0==(r=n(o)[a])?t:i(r)}},function(e,t,r){"use strict";var n=r(3)("iterator"),i=!1;try{var a=[7][n]();a.return=function(){i=!0},Array.from(a,function(){throw 2})}catch(e){}e.exports=function(e,t){if(!t&&!i)return!1;var r=!1;try{var a=[7],o=a[n]();o.next=function(){return{done:r=!0}},a[n]=function(){return o},e(a)}catch(e){}return r}},function(e,t,r){"use strict";var n=r(22);e.exports.f=function(e){return new function(e){var t,r;this.promise=new e(function(e,n){if(void 0!==t||void 0!==r)throw TypeError("Bad Promise constructor");t=e,r=n}),this.resolve=n(t),this.reject=n(r)}(e)}},function(e,t,r){"use strict";var n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},i=r(16)("meta"),a=r(2),o=r(10),s=r(13).f,l=0,u=Object.isExtensible||function(){return!0},c=!r(9)(function(){return u(Object.preventExtensions({}))}),h=function(e){s(e,i,{value:{i:"O"+ ++l,w:{}}})},d=e.exports={KEY:i,NEED:!1,fastKey:function(e,t){if(!a(e))return"symbol"==(void 0===e?"undefined":n(e))?e:("string"==typeof e?"S":"P")+e;if(!o(e,i)){if(!u(e))return"F";if(!t)return"E";h(e)}return e[i].i},getWeak:function(e,t){if(!o(e,i)){if(!u(e))return!0;if(!t)return!1;h(e)}return e[i].w},onFreeze:function(e){return c&&d.NEED&&u(e)&&!o(e,i)&&h(e),e}}},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.validateResponseStatus=t.validateRangeRequestCapabilities=t.createResponseStatusError=void 0;var n=r(0);t.createResponseStatusError=function(e,t){return 404===e||0===e&&/^file:/.test(t)?new n.MissingPDFException('Missing PDF "'+t+'".'):new n.UnexpectedResponseException("Unexpected server response ("+e+') while retrieving PDF "'+t+'".',e)},t.validateRangeRequestCapabilities=function(e){var t=e.getResponseHeader,r=e.isHttp,i=e.rangeChunkSize,a=e.disableRange;(0,n.assert)(i>0);var o={allowRangeRequests:!1,suggestedLength:void 0};if(a||!r)return o;if("bytes"!==t("Accept-Ranges"))return o;if("identity"!==(t("Content-Encoding")||"identity"))return o;var s=parseInt(t("Content-Length"),10);return Number.isInteger(s)?(o.suggestedLength=s,s<=2*i?o:(o.allowRangeRequests=!0,o)):o},t.validateResponseStatus=function(e){return 200===e||206===e}},function(e,t,r){"use strict";e.exports=!r(8)&&!r(9)(function(){return 7!=Object.defineProperty(r(32)("div"),"a",{get:function(){return 7}}).a})},function(e,t,r){"use strict";for(var n,i=r(1),a=r(6),o=r(16),s=o("typed_array"),l=o("view"),u=!(!i.ArrayBuffer||!i.DataView),c=u,h=0,d="Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array".split(",");h<9;)(n=i[d[h++]])?(a(n.prototype,s,!0),a(n.prototype,l,!0)):c=!1;e.exports={ABV:u,CONSTR:c,TYPED:s,VIEW:l}},function(e,t,r){"use strict";var n=r(17),i=r(12);e.exports=function(e){if(void 0===e)return 0;var t=n(e),r=i(t);if(t!==r)throw RangeError("Wrong length!");return r}},function(e,t,r){"use strict";var n=r(49),i=r(37).concat("length","prototype");t.f=Object.getOwnPropertyNames||function(e){return n(e,i)}},function(e,t,r){"use strict";var n=r(10),i=r(28),a=r(50)(!1),o=r(36)("IE_PROTO");e.exports=function(e,t){var r,s=i(e),l=0,u=[];for(r in s)r!=o&&n(s,r)&&u.push(r);for(;t.length>l;)n(s,r=t[l++])&&(~a(u,r)||u.push(r));return u}},function(e,t,r){"use strict";var n=r(28),i=r(12),a=r(29);e.exports=function(e){return function(t,r,o){var s,l=n(t),u=i(l.length),c=a(o,u);if(e&&r!=r){for(;u>c;)if((s=l[c++])!=s)return!0}else for(;u>c;c++)if((e||c in l)&&l[c]===r)return e||c||0;return!e&&-1}}},function(e,t,r){"use strict";var n=r(4),i=r(1),a=i["__core-js_shared__"]||(i["__core-js_shared__"]={});(e.exports=function(e,t){return a[e]||(a[e]=void 0!==t?t:{})})("versions",[]).push({version:n.version,mode:r(21)?"pure":"global",copyright:"© 2018 Denis Pushkarev (zloirock.ru)"})},function(e,t,r){"use strict";var n=r(18),i=r(29),a=r(12);e.exports=function(e){for(var t=n(this),r=a(t.length),o=arguments.length,s=i(o>1?arguments[1]:void 0,r),l=o>2?arguments[2]:void 0,u=void 0===l?r:i(l,r);u>s;)t[s++]=e;return t}},function(e,t,r){"use strict";var n=r(19),i=r(3)("iterator"),a=Array.prototype;e.exports=function(e){return void 0!==e&&(n.Array===e||a[i]===e)}},function(e,t,r){"use strict";var n=r(7),i=r(81),a=r(37),o=r(36)("IE_PROTO"),s=function(){},l=function(){var e,t=r(32)("iframe"),n=a.length;for(t.style.display="none",r(55).appendChild(t),t.src="javascript:",(e=t.contentWindow.document).open(),e.write(" + + + +
+ + + diff --git a/app/src/main/assets/viewer.js b/app/src/main/assets/viewer.js new file mode 100644 index 0000000..d055081 --- /dev/null +++ b/app/src/main/assets/viewer.js @@ -0,0 +1,193 @@ +"use strict"; + +let pdfDoc = null; +let pageRendering = false; +let renderPending = false; +let renderPendingLazy = false; +const canvas = document.getElementById('content'); +let zoomLevel = 100; +let textLayerDiv = document.getElementById("text"); +const zoomLevels = [50, 75, 100, 125, 150]; +let task = null; + +let newPageNumber = 0; +let newZoomLevel = 0; +let useRender; + +const cache = []; +const maxCached = 6; + +function maybeRenderNextPage() { + if (renderPending) { + pageRendering = false; + renderPending = false; + renderPage(channel.getPage(), renderPendingLazy, false); + return true; + } + return false; +} + +function handleRenderingError(error) { + console.log("rendering error: " + error); + + pageRendering = false; + maybeRenderNextPage(); +} + +function doPrerender(pageNumber, prerenderTrigger) { + if (useRender) { + if (pageNumber + 1 <= pdfDoc.numPages) { + renderPage(pageNumber + 1, false, true, pageNumber); + } else if (pageNumber - 1 > 0) { + renderPage(pageNumber - 1, false, true, pageNumber); + } + } else if (pageNumber == prerenderTrigger + 1) { + if (prerenderTrigger - 1 > 0) { + renderPage(prerenderTrigger - 1, false, true, prerenderTrigger); + } + } +} + +function display(newCanvas) { + canvas.height = newCanvas.height; + canvas.width = newCanvas.width; + canvas.style.height = newCanvas.style.height; + canvas.style.width = newCanvas.style.width; + canvas.getContext("2d", { alpha: false }).drawImage(newCanvas, 0, 0); + scrollTo(0, 0); +} + +function renderPage(pageNumber, lazy, prerender, prerenderTrigger=0) { + pageRendering = true; + useRender = !prerender; + + newPageNumber = pageNumber; + newZoomLevel = zoomLevels[channel.getZoomLevel()]; + console.log("page: " + pageNumber + ", zoom: " + newZoomLevel + ", prerender: " + prerender); + for (let i = 0; i < cache.length; i++) { + const cached = cache[i]; + if (cached.pageNumber === pageNumber && cached.zoomLevel === newZoomLevel) { + if (useRender) { + cache.splice(i, 1); + cache.push(cached); + + display(cached.canvas); + + textLayerDiv.replaceWith(cached.textLayerDiv); + textLayerDiv = cached.textLayerDiv; + } + + pageRendering = false; + doPrerender(pageNumber, prerenderTrigger); + return; + } + } + + pdfDoc.getPage(pageNumber).then(function(page) { + if (maybeRenderNextPage()) { + return; + } + + const newCanvas = document.createElement("canvas"); + const viewport = page.getViewport(newZoomLevel / 100) + const ratio = window.devicePixelRatio; + newCanvas.height = viewport.height * ratio; + newCanvas.width = viewport.width * ratio; + newCanvas.style.height = viewport.height + "px"; + newCanvas.style.width = viewport.width + "px"; + const newContext = newCanvas.getContext("2d", { alpha: false }); + newContext.scale(ratio, ratio); + + if (useRender) { + if (newZoomLevel != zoomLevel) { + canvas.style.height = viewport.height + "px"; + canvas.style.width = viewport.width + "px"; + } + zoomLevel = newZoomLevel; + } + + task = page.render({ + canvasContext: newContext, + viewport: viewport + }); + + task.then(function() { + task = null; + + let rendered = false; + function render() { + if (!useRender || rendered) { + return; + } + display(newCanvas); + rendered = true; + } + render(); + + const textLayerFrag = document.createDocumentFragment(); + task = PDFJS.renderTextLayer({ + textContentStream: page.streamTextContent(), + container: textLayerFrag, + viewport: viewport + }); + task.promise.then(function() { + task = null; + + render(); + + const newTextLayerDiv = textLayerDiv.cloneNode(); + newTextLayerDiv.style.height = newCanvas.style.height; + newTextLayerDiv.style.width = newCanvas.style.width; + if (useRender) { + textLayerDiv.replaceWith(newTextLayerDiv); + textLayerDiv = newTextLayerDiv; + } + newTextLayerDiv.appendChild(textLayerFrag); + + if (cache.length === maxCached) { + cache.shift() + } + cache.push({ + pageNumber: pageNumber, + zoomLevel: newZoomLevel, + canvas: newCanvas, + textLayerDiv: newTextLayerDiv + }); + + pageRendering = false; + doPrerender(pageNumber, prerenderTrigger); + }).catch(handleRenderingError); + }).catch(handleRenderingError); + }); +} + +function onRenderPage(lazy) { + if (pageRendering) { + if (newPageNumber === channel.getPage() && newZoomLevel === zoomLevels[channel.getZoomLevel()]) { + useRender = true; + return; + } + + renderPending = true; + renderPendingLazy = lazy; + if (task !== null) { + task.cancel(); + task = null; + } + } else { + renderPage(channel.getPage(), lazy, false); + } +} + +PDFJS.getDocument("https://localhost/placeholder.pdf").then(function(newDoc) { + pdfDoc = newDoc; + channel.setNumPages(pdfDoc.numPages); + pdfDoc.getMetadata().then(function(data) { + channel.setDocumentProperties(JSON.stringify(data.info)); + }).catch(function(error) { + console.log("getMetadata error: " + error); + }); + renderPage(channel.getPage(), false, false); +}).catch(function(error) { + console.log("getDocument error: " + error); +}); diff --git a/app/src/main/ic_launcher-web.png b/app/src/main/ic_launcher-web.png new file mode 100644 index 0000000000000000000000000000000000000000..a407aa1e9fda6b2dcf399d962a50860fc290ec4d GIT binary patch literal 7794 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 Pep@!~_&vkg`P_d2iebWn literal 0 HcmV?d00001 diff --git a/app/src/main/java/org/grapheneos/pdfviewer/PdfViewer.java b/app/src/main/java/org/grapheneos/pdfviewer/PdfViewer.java new file mode 100644 index 0000000..3127fb3 --- /dev/null +++ b/app/src/main/java/org/grapheneos/pdfviewer/PdfViewer.java @@ -0,0 +1,442 @@ +package org.grapheneos.pdfviewer; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.content.Intent; +import android.content.res.ColorStateList; +import android.graphics.Color; +import android.net.Uri; +import android.os.Bundle; +import android.util.Log; +import android.view.Gravity; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.webkit.CookieManager; +import android.webkit.JavascriptInterface; +import android.webkit.WebResourceRequest; +import android.webkit.WebResourceResponse; +import android.webkit.WebSettings; +import android.webkit.WebView; +import android.webkit.WebViewClient; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.loader.app.LoaderManager; +import androidx.loader.content.Loader; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import org.grapheneos.pdfviewer.fragment.DocumentPropertiesFragment; +import org.grapheneos.pdfviewer.fragment.JumpToPageFragment; +import org.grapheneos.pdfviewer.loader.DocumentPropertiesLoader; + +public class PdfViewer extends AppCompatActivity implements LoaderManager.LoaderCallbacks> { + public static final String TAG = "PdfViewer"; + + private static final String STATE_URI = "uri"; + private static final String STATE_PAGE = "page"; + private static final String STATE_ZOOM_LEVEL = "zoomLevel"; + private static final String KEY_PROPERTIES = "properties"; + + private static final String CONTENT_SECURITY_POLICY = + "default-src 'none'; " + + "form-action 'none'; " + + "connect-src https://localhost/placeholder.pdf; " + + "img-src blob: 'self'; " + + "script-src 'self'; " + + "style-src 'self'; " + + "frame-ancestors 'none'; " + + "base-uri 'none'"; + + private static final String FEATURE_POLICY = + "accelerometer 'none'; " + + "ambient-light-sensor 'none'; " + + "autoplay 'none'; " + + "camera 'none'; " + + "encrypted-media 'none'; " + + "fullscreen 'none'; " + + "geolocation 'none'; " + + "gyroscope 'none'; " + + "magnetometer 'none'; " + + "microphone 'none'; " + + "midi 'none'; " + + "payment 'none'; " + + "picture-in-picture 'none'; " + + "speaker 'none'; " + + "sync-xhr 'none'; " + + "usb 'none'; " + + "vr 'none'"; + + private static final int MIN_ZOOM_LEVEL = 0; + private static final int MAX_ZOOM_LEVEL = 4; + private static final int ALPHA_LOW = 130; + private static final int ALPHA_HIGH = 255; + private static final int ACTION_OPEN_DOCUMENT_REQUEST_CODE = 1; + private static final int STATE_LOADED = 1; + private static final int STATE_END = 2; + private static final int PADDING = 10; + + private Uri mUri; + public int mPage; + public int mNumPages; + private int mZoomLevel = 2; + private int mDocumentState; + private List mDocumentProperties; + private InputStream mInputStream; + + private WebView mWebView; + private TextView mTextView; + private Toast mToast; + + private class Channel { + @JavascriptInterface + public int getPage() { + return mPage; + } + + @JavascriptInterface + public int getZoomLevel() { + return mZoomLevel; + } + + @JavascriptInterface + public void setNumPages(int numPages) { + mNumPages = numPages; + } + + @JavascriptInterface + public void setDocumentProperties(final String properties) { + if (mDocumentProperties != null) { + throw new SecurityException("mDocumentProperties not null"); + } + + final Bundle args = new Bundle(); + args.putString(KEY_PROPERTIES, properties); + runOnUiThread(() -> { + LoaderManager.getInstance(PdfViewer.this).restartLoader(DocumentPropertiesLoader.ID, args, PdfViewer.this); + }); + } + } + + // Can be removed once minSdkVersion >= 26 + @SuppressWarnings("deprecation") + private void disableSaveFormData(final WebSettings settings) { + settings.setSaveFormData(false); + } + + @Override + @SuppressLint("SetJavaScriptEnabled") + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.webview); + + mWebView = findViewById(R.id.webview); + final WebSettings settings = mWebView.getSettings(); + settings.setAllowContentAccess(false); + settings.setAllowFileAccess(false); + settings.setCacheMode(WebSettings.LOAD_NO_CACHE); + settings.setJavaScriptEnabled(true); + disableSaveFormData(settings); + + CookieManager.getInstance().setAcceptCookie(false); + + mWebView.addJavascriptInterface(new Channel(), "channel"); + + mWebView.setWebViewClient(new WebViewClient() { + private WebResourceResponse fromAsset(final String mime, final String path) { + try { + InputStream inputStream = getAssets().open(path.substring(1)); + return new WebResourceResponse(mime, null, inputStream); + } catch (IOException e) { + return null; + } + } + + @Override + public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { + if (!"GET".equals(request.getMethod())) { + return null; + } + + final Uri url = request.getUrl(); + if (!"localhost".equals(url.getHost())) { + return null; + } + + final String path = url.getPath(); + Log.d(TAG, "path " + path); + + if ("/placeholder.pdf".equals(path)) { + return new WebResourceResponse("application/pdf", null, mInputStream); + } + + if ("/viewer.html".equals(path)) { + final WebResourceResponse response = fromAsset("text/html", path); + HashMap headers = new HashMap(); + headers.put("Content-Security-Policy", CONTENT_SECURITY_POLICY); + headers.put("Feature-Policy", FEATURE_POLICY); + response.setResponseHeaders(headers); + return response; + } + + if ("/viewer.css".equals(path)) { + return fromAsset("text/css", path); + } + + if ("/viewer.js".equals(path)) { + return fromAsset("application/javascript", path); + } + + if ("/pdf.js".equals(path)) { + return fromAsset("application/javascript", path); + } + + if ("/pdf.worker.js".equals(path)) { + return fromAsset("application/javascript", path); + } + + return null; + } + + @Override + public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { + return true; + } + + @Override + public void onPageFinished(WebView view, String url) { + mDocumentState = STATE_LOADED; + invalidateOptionsMenu(); + } + }); + + mTextView = new TextView(this); + mTextView.setBackgroundColor(Color.DKGRAY); + mTextView.setTextColor(ColorStateList.valueOf(Color.WHITE)); + mTextView.setTextSize(18); + mTextView.setPadding(PADDING, 0, PADDING, 0); + + // If loaders are not being initialized in onCreate(), the result will not be delivered + // after orientation change (See FragmentHostCallback), thus initialize the + // loader manager impl so that the result will be delivered. + LoaderManager.getInstance(this); + + final Intent intent = getIntent(); + if (Intent.ACTION_VIEW.equals(intent.getAction())) { + if (!"application/pdf".equals(intent.getType())) { + Log.e(TAG, "invalid mime type"); + finish(); + return; + } + mUri = intent.getData(); + mPage = 1; + } + + if (savedInstanceState != null) { + mUri = savedInstanceState.getParcelable(STATE_URI); + mPage = savedInstanceState.getInt(STATE_PAGE); + mZoomLevel = savedInstanceState.getInt(STATE_ZOOM_LEVEL); + } + + if (mUri != null) { + loadPdf(); + } + } + + @Override + public Loader> onCreateLoader(int id, Bundle args) { + return new DocumentPropertiesLoader(this, args.getString(KEY_PROPERTIES), mNumPages, mUri); + } + + @Override + public void onLoadFinished(Loader> loader, List data) { + mDocumentProperties = data; + LoaderManager.getInstance(this).destroyLoader(DocumentPropertiesLoader.ID); + } + + @Override + public void onLoaderReset(Loader> loader) { + mDocumentProperties = null; + } + + private void loadPdf() { + try { + if (mInputStream != null) { + mInputStream.close(); + } + mInputStream = getContentResolver().openInputStream(mUri); + } catch (IOException e) { + return; + } + mWebView.loadUrl("https://localhost/viewer.html"); + } + + private void renderPage(final boolean lazy) { + mWebView.evaluateJavascript(lazy ? "onRenderPage(true)" : "onRenderPage(false)", null); + } + + private void openDocument() { + Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); + intent.addCategory(Intent.CATEGORY_OPENABLE); + intent.setType("application/pdf"); + startActivityForResult(intent, ACTION_OPEN_DOCUMENT_REQUEST_CODE); + } + + private static void enableDisableMenuItem(MenuItem item, boolean enable) { + if (enable) { + if (!item.isEnabled()) { + item.setEnabled(true); + item.getIcon().setAlpha(ALPHA_HIGH); + } + } else if (item.isEnabled()) { + item.setEnabled(false); + item.getIcon().setAlpha(ALPHA_LOW); + } + } + + public void onJumpToPageInDocument(int selected_page) { + if (selected_page >= 1 && selected_page <= mNumPages) { + mPage = selected_page; + renderPage(false); + showPageNumber(); + } + } + + @Override + public void onSaveInstanceState(Bundle savedInstanceState) { + super.onSaveInstanceState(savedInstanceState); + savedInstanceState.putParcelable(STATE_URI, mUri); + savedInstanceState.putInt(STATE_PAGE, mPage); + savedInstanceState.putInt(STATE_ZOOM_LEVEL, mZoomLevel); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent resultData) { + if (requestCode == ACTION_OPEN_DOCUMENT_REQUEST_CODE && resultCode == Activity.RESULT_OK) { + if (resultData != null) { + mUri = resultData.getData(); + mPage = 1; + mDocumentProperties = null; + loadPdf(); + invalidateOptionsMenu(); + } + } + } + + private void showPageNumber() { + if (mToast != null) { + mToast.cancel(); + } + mTextView.setText(String.format("%s/%s", mPage, mNumPages)); + mToast = new Toast(getApplicationContext()); + mToast.setGravity(Gravity.BOTTOM | Gravity.END, PADDING, PADDING); + mToast.setDuration(Toast.LENGTH_SHORT); + mToast.setView(mTextView); + mToast.show(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + super.onCreateOptionsMenu(menu); + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.pdf_viewer, menu); + return true; + } + + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + final int ids[] = { R.id.action_zoom_in, R.id.action_zoom_out, R.id.action_jump_to_page, + R.id.action_next, R.id.action_previous, R.id.action_view_document_properties }; + if (mDocumentState < STATE_LOADED) { + for (final int id : ids) { + final MenuItem item = menu.findItem(id); + if (item.isVisible()) { + item.setVisible(false); + } + } + } else if (mDocumentState == STATE_LOADED) { + for (final int id : ids) { + final MenuItem item = menu.findItem(id); + if (!item.isVisible()) { + item.setVisible(true); + } + } + mDocumentState = STATE_END; + } + + switch (mZoomLevel) { + case MAX_ZOOM_LEVEL: + enableDisableMenuItem(menu.findItem(R.id.action_zoom_in), false); + return true; + case MIN_ZOOM_LEVEL: + enableDisableMenuItem(menu.findItem(R.id.action_zoom_out), false); + return true; + default: + enableDisableMenuItem(menu.findItem(R.id.action_zoom_in), true); + enableDisableMenuItem(menu.findItem(R.id.action_zoom_out), true); + return true; + } + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.action_previous: + if (mPage > 1) { + mPage--; + renderPage(false); + showPageNumber(); + } + return true; + + case R.id.action_next: + if (mPage < mNumPages) { + mPage++; + renderPage(false); + showPageNumber(); + } + return true; + + case R.id.action_open: + openDocument(); + return super.onOptionsItemSelected(item); + + case R.id.action_zoom_out: + if (mZoomLevel > 0) { + mZoomLevel--; + renderPage(true); + invalidateOptionsMenu(); + } + return true; + + case R.id.action_zoom_in: + if (mZoomLevel < MAX_ZOOM_LEVEL) { + mZoomLevel++; + renderPage(true); + invalidateOptionsMenu(); + } + return true; + + case R.id.action_view_document_properties: + DocumentPropertiesFragment + .getInstance((ArrayList) mDocumentProperties) + .show(getSupportFragmentManager(), DocumentPropertiesFragment.TAG); + return true; + + case R.id.action_jump_to_page: + new JumpToPageFragment() + .show(getSupportFragmentManager(), JumpToPageFragment.TAG); + return true; + + default: + return super.onOptionsItemSelected(item); + } + } +} diff --git a/app/src/main/java/org/grapheneos/pdfviewer/Utils.java b/app/src/main/java/org/grapheneos/pdfviewer/Utils.java new file mode 100644 index 0000000..9cb0183 --- /dev/null +++ b/app/src/main/java/org/grapheneos/pdfviewer/Utils.java @@ -0,0 +1,196 @@ +package org.grapheneos.pdfviewer; + +import android.text.TextUtils; + +import java.math.RoundingMode; +import java.text.DateFormat; +import java.text.DecimalFormat; +import java.text.ParseException; +import java.util.Calendar; + +public class Utils { + public static String parseFileSize(long fileSize) { + final double kb = fileSize / 1000; + + if (kb == 0) { + return fileSize + " Bytes"; + } + + final DecimalFormat format = new DecimalFormat("#.##"); + format.setRoundingMode(RoundingMode.CEILING); + + if (kb < 1000) { + return format.format(kb) + " kB (" + fileSize + " Bytes)"; + } + return format.format(kb / 1000) + " MB (" + fileSize + " Bytes)"; + } + + // Parse date as per PDF spec (complies with PDF v1.4 to v1.7) + public static String parseDate(String date) throws ParseException { + int position = 0; + + // D: prefix is optional for PDF < v1.7; required for PDF v1.7 + if (!date.startsWith("D:")) { + date = "D:" + date; + } + if (date.length() < 6 || date.length() > 23) { + throw new ParseException("Invalid datetime length", position); + } + + final Calendar calendar = Calendar.getInstance(); + final int currentYear = calendar.get(Calendar.YEAR); + int year; + + // Year is required + String field = date.substring(position += 2, 6); + if (!TextUtils.isDigitsOnly(field)) { + throw new ParseException("Invalid year", position); + } + year = Integer.valueOf(field); + if (year > currentYear) { + year = currentYear; + } + + position += 4; + + // Default value for month and day shall be 1 (calendar month starts at 0 in Java 7), + // all others default to 0 + int month = 0; + int day = 1; + int hours = 0; + int minutes = 0; + int seconds = 0; + + // All succeeding fields are optional, but each preceding field must be present + if (date.length() > 8) { + field = date.substring(position, 8); + if (!TextUtils.isDigitsOnly(field)) { + throw new ParseException("Invalid month", position); + } + month = Integer.valueOf(field) - 1; + if (month > 11) { + throw new ParseException("Invalid month", position); + } + position += 2; + } + if (date.length() > 10) { + field = date.substring(8, 10); + if (!TextUtils.isDigitsOnly(field)) { + throw new ParseException("Invalid day", position); + } + day = Integer.valueOf(field); + if (day > 31) { + throw new ParseException("Invalid day", position); + } + position += 2; + } + if (date.length() > 12) { + field = date.substring(10, 12); + if (!TextUtils.isDigitsOnly(field)) { + throw new ParseException("Invalid hours", position); + } + hours = Integer.valueOf(field); + if (hours > 23) { + throw new ParseException("Invalid hours", position); + } + position += 2; + } + if (date.length() > 14) { + field = date.substring(12, 14); + if (!TextUtils.isDigitsOnly(field)) { + throw new ParseException("Invalid minutes", position); + } + minutes = Integer.valueOf(field); + if (minutes > 59) { + throw new ParseException("Invalid minutes", position); + } + position += 2; + } + if (date.length() > 16) { + field = date.substring(14, 16); + if (!TextUtils.isDigitsOnly(field)) { + throw new ParseException("Invalid seconds", position); + } + seconds = Integer.valueOf(field); + if (seconds > 59) { + throw new ParseException("Invalid seconds", position); + } + position += 2; + } + + + if (date.length() > position) { + int offsetHours = 0; + int offsetMinutes = 0; + + final char utRel = date.charAt(position); + if (utRel != '\u002D' && utRel != '\u002B' && utRel != '\u005A') { + throw new ParseException("Invalid UT relation", position); + } + + position++; + + if (date.length() > position + 2) { + field = date.substring(position, position + 2); + if (!TextUtils.isDigitsOnly(field)) { + throw new ParseException("Invalid UTC offset hours", position); + } + offsetHours = Integer.parseInt(field); + final int offsetHoursMinutes = offsetHours * 100 + offsetMinutes; + + // Validate UTC offset (UTC-12:00 to UTC+14:00) + if ((utRel == '\u002D' && offsetHoursMinutes > 1200) || + (utRel == '\u002B' && offsetHoursMinutes > 1400)) { + throw new ParseException("Invalid UTC offset hours", position); + } + + position += 2; + + // Apostrophe shall succeed HH and precede mm + if (date.charAt(position) != '\'') { + throw new ParseException("Expected apostrophe", position); + } + + position++; + + if (date.length() > position + 2) { + field = date.substring(position, position + 2); + if (!TextUtils.isDigitsOnly(field)) { + throw new ParseException("Invalid UTC offset minutes", position); + } + offsetMinutes = Integer.parseInt(field); + if (offsetMinutes > 59) { + throw new ParseException("Invalid UTC offset minutes", position); + } + position += 2; + } + + // Apostrophe shall succeed mm + if (date.charAt(position) != '\'') { + throw new ParseException("Expected apostrophe", position); + } + } + + + switch (utRel) { + case '\u002D': + hours -= offsetHours; + minutes -= offsetMinutes; + break; + case '\u002B': + hours += offsetHours; + minutes += offsetMinutes; + break; + default: + // "Z" means equal to UTC + break; + } + } + + calendar.set(year, month, day, hours, minutes, seconds); + + return DateFormat + .getDateTimeInstance(DateFormat.DEFAULT, DateFormat.LONG) + .format(calendar.getTime()); + } +} diff --git a/app/src/main/java/org/grapheneos/pdfviewer/fragment/DocumentPropertiesFragment.java b/app/src/main/java/org/grapheneos/pdfviewer/fragment/DocumentPropertiesFragment.java new file mode 100644 index 0000000..0f50198 --- /dev/null +++ b/app/src/main/java/org/grapheneos/pdfviewer/fragment/DocumentPropertiesFragment.java @@ -0,0 +1,60 @@ +package org.grapheneos.pdfviewer.fragment; + +import android.app.Activity; +import android.app.Dialog; +import android.os.Bundle; +import android.widget.ArrayAdapter; + +import androidx.appcompat.app.AlertDialog; +import androidx.fragment.app.DialogFragment; + +import java.util.ArrayList; +import java.util.List; + +import org.grapheneos.pdfviewer.R; + +public class DocumentPropertiesFragment extends DialogFragment { + public static final String TAG = "DocumentPropertiesFragment"; + + private static final String KEY_DOCUMENT_PROPERTIES = "key_document_properties"; + + private static DocumentPropertiesFragment sDocumentPropertiesFragment; + + private List mDocumentProperties; + + public static DocumentPropertiesFragment getInstance(final ArrayList metaData) { + if (sDocumentPropertiesFragment == null) { + sDocumentPropertiesFragment = new DocumentPropertiesFragment(); + final Bundle args = new Bundle(); + args.putCharSequenceArrayList(KEY_DOCUMENT_PROPERTIES, metaData); + sDocumentPropertiesFragment.setArguments(args); + } else { + final Bundle args = sDocumentPropertiesFragment.getArguments(); + args.clear(); + args.putCharSequenceArrayList(KEY_DOCUMENT_PROPERTIES, metaData); + } + return sDocumentPropertiesFragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mDocumentProperties = getArguments().getStringArrayList(KEY_DOCUMENT_PROPERTIES); + } + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + final Activity activity = getActivity(); + final AlertDialog.Builder dialog = new AlertDialog.Builder(activity) + .setPositiveButton(android.R.string.ok, null); + + if (mDocumentProperties != null) { + dialog.setTitle(getString(R.string.action_view_document_properties)); + dialog.setAdapter(new ArrayAdapter<>(activity, android.R.layout.simple_list_item_1, + mDocumentProperties), null); + } else { + dialog.setTitle(R.string.document_properties_retrieval_failed); + } + return dialog.create(); + } +} diff --git a/app/src/main/java/org/grapheneos/pdfviewer/fragment/JumpToPageFragment.java b/app/src/main/java/org/grapheneos/pdfviewer/fragment/JumpToPageFragment.java new file mode 100644 index 0000000..53c236f --- /dev/null +++ b/app/src/main/java/org/grapheneos/pdfviewer/fragment/JumpToPageFragment.java @@ -0,0 +1,66 @@ +package org.grapheneos.pdfviewer.fragment; + +import android.app.Dialog; +import android.content.DialogInterface; +import android.os.Bundle; +import android.view.Gravity; +import android.widget.FrameLayout; +import android.widget.NumberPicker; + +import androidx.appcompat.app.AlertDialog; +import androidx.fragment.app.DialogFragment; + +import org.grapheneos.pdfviewer.PdfViewer; + +public class JumpToPageFragment extends DialogFragment { + public static final String TAG = "JumpToPageFragment"; + + private final static String STATE_PICKER_CUR = "picker_cur"; + private final static String STATE_PICKER_MIN = "picker_min"; + private final static String STATE_PICKER_MAX = "picker_max"; + + private NumberPicker mPicker; + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + if (savedInstanceState != null) { + mPicker.setMinValue(savedInstanceState.getInt(STATE_PICKER_MIN)); + mPicker.setMaxValue(savedInstanceState.getInt(STATE_PICKER_MAX)); + mPicker.setValue(savedInstanceState.getInt(STATE_PICKER_CUR)); + } + } + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + mPicker = new NumberPicker(getActivity()); + mPicker.setMinValue(1); + mPicker.setMaxValue(((PdfViewer)getActivity()).mNumPages); + mPicker.setValue(((PdfViewer)getActivity()).mPage); + + final FrameLayout layout = new FrameLayout(getActivity()); + layout.addView(mPicker, new FrameLayout.LayoutParams( + FrameLayout.LayoutParams.WRAP_CONTENT, + FrameLayout.LayoutParams.WRAP_CONTENT, + Gravity.CENTER)); + + return new AlertDialog.Builder(getActivity()) + .setView(layout) + .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + mPicker.clearFocus(); + ((PdfViewer)getActivity()).onJumpToPageInDocument(mPicker.getValue()); + } + }) + .setNegativeButton(android.R.string.cancel, null) + .create(); + } + + @Override + public void onSaveInstanceState(Bundle outState) { + outState.putInt(STATE_PICKER_MIN, mPicker.getMinValue()); + outState.putInt(STATE_PICKER_MAX, mPicker.getMaxValue()); + outState.putInt(STATE_PICKER_CUR, mPicker.getValue()); + } +} diff --git a/app/src/main/java/org/grapheneos/pdfviewer/loader/DocumentPropertiesLoader.java b/app/src/main/java/org/grapheneos/pdfviewer/loader/DocumentPropertiesLoader.java new file mode 100644 index 0000000..f271c05 --- /dev/null +++ b/app/src/main/java/org/grapheneos/pdfviewer/loader/DocumentPropertiesLoader.java @@ -0,0 +1,149 @@ +package org.grapheneos.pdfviewer.loader; + +import android.content.Context; +import android.database.Cursor; +import android.graphics.Typeface; +import android.net.Uri; +import android.provider.OpenableColumns; +import android.text.SpannableStringBuilder; +import android.text.Spanned; +import android.text.style.StyleSpan; +import android.util.Log; + +import androidx.loader.content.AsyncTaskLoader; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; + +import org.grapheneos.pdfviewer.R; +import org.grapheneos.pdfviewer.Utils; + +public class DocumentPropertiesLoader extends AsyncTaskLoader> { + public static final String TAG = "DocumentPropertiesLoader"; + + public static final int ID = 1; + + private final String mProperties; + private final int mNumPages; + private final Uri mUri; + + private Cursor mCursor; + + public DocumentPropertiesLoader(Context context, String properties, int numPages, Uri uri) { + super(context); + + mProperties = properties; + mNumPages = numPages; + mUri = uri; + } + + @Override + public List loadInBackground() { + final Context context = getContext(); + + final String[] names = context.getResources().getStringArray(R.array.property_names); + final List properties = new ArrayList<>(names.length); + + mCursor = context.getContentResolver().query(mUri, null, null, null, null); + if (mCursor != null) { + mCursor.moveToFirst(); + + final int indexName = mCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); + if (indexName >= 0) { + properties.add(getProperty(null, names[0], mCursor.getString(indexName))); + } + + final int indexSize = mCursor.getColumnIndex(OpenableColumns.SIZE); + if (indexSize >= 0) { + final long fileSize = Long.valueOf(mCursor.getString(indexSize)); + properties.add(getProperty(null, names[1], Utils.parseFileSize(fileSize))); + } + + mCursor.close(); + } + + try { + final JSONObject json = new JSONObject(mProperties); + + properties.add(getProperty(json, names[2], "Title")); + properties.add(getProperty(json, names[3], "Author")); + properties.add(getProperty(json, names[4], "Subject")); + properties.add(getProperty(json, names[5], "Keywords")); + properties.add(getProperty(json, names[6], "CreationDate")); + properties.add(getProperty(json, names[7], "ModDate")); + properties.add(getProperty(json, names[8], "Producer")); + properties.add(getProperty(json, names[9], "Creator")); + properties.add(getProperty(json, names[10], "PDFFormatVersion")); + properties.add(getProperty(null, names[11], String.valueOf(mNumPages))); + + return properties; + } catch (JSONException e) { + e.printStackTrace(); + } + return null; + } + + @Override + public void deliverResult(List properties) { + if (isReset()) { + onReleaseResources(); + } else if (isStarted()) { + super.deliverResult(properties); + } + } + + @Override + protected void onStartLoading() { + forceLoad(); + } + + @Override + protected void onStopLoading() { + cancelLoad(); + } + + @Override + public void onCanceled(List properties) { + super.onCanceled(properties); + + onReleaseResources(); + } + + @Override + protected void onReset() { + super.onReset(); + + onStopLoading(); + onReleaseResources(); + } + + private void onReleaseResources() { + if (mCursor != null) { + mCursor.close(); + mCursor = null; + } + } + + private CharSequence getProperty(final JSONObject json, String name, String specName) { + final SpannableStringBuilder property = new SpannableStringBuilder(name).append(":\n"); + final String value = json != null ? json.optString(specName, "-") : specName; + + if (specName.endsWith("Date")) { + final Context context = getContext(); + try { + property.append(value.equals("-") ? value : Utils.parseDate(value)); + } catch (ParseException e) { + Log.w(TAG, e.getMessage() + " for " + value + " at offset: " + e.getErrorOffset()); + property.append(context.getString(R.string.document_properties_invalid_date)); + } + } else { + property.append(value); + } + property.setSpan(new StyleSpan(Typeface.BOLD), 0, name.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + return property; + } +} diff --git a/app/src/main/res/drawable-hdpi/ic_insert_drive_file_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_insert_drive_file_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..84755e48817d86d61d09e70489b6c94b5c1f4d38 GIT binary patch literal 153 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k0wldT1B8K8f~SjPh{y4_XAbf<81OJ3(CJ7} zndX``b76v-N7DYNg?AXzx0$@j_%O$-MDb9#M4)m=#h>FoD;{~Q*wnG^Q^%Sa9jkV9 zthk}E_JdQ<#r;ZwuA-qP*1MK2|9P?TocWEMO!)@USli?GV)cP`F?hQAxvX|k0wldT1B5}8r;B5V$MLsUPI59R2sj5iURcJu zTy^?CB{^H^0>%9e|k0wldT1B8K;kEe@ch{y4_7awvqC@`=lDjqy` zt?bgBcUl?E^Co`GYj}UY^}!vTz!O|)k6&pXbz#4y#ia^1mT=&a`ZL03BHPQ%B6EUgq9P} zZ}jjif1&8PgCOwt4B?mK1A%z%|86_VL?l?ZAfkl(I)@w)c^8FHLf$1IRA9e>R*dP> zVZf{iG~^Jc=eZ)z2R-7#typH5iXpq2hp7kp?LQIYa&gT~UT2&3yt zJF`K3X|15e(spf7M_M~*sk9v%G>}#g+C*B-2F>s|JR{I8IhE(`Z4g{at_r!kZa!Q5tM<9G1lvl#Np6PVfYXTMr9oR$7- zJ+I)+m7cE3mSYcqne|dAIk1q=42;!fP_k_T0N}-$b--Po%Ifx9y0_4n8#`TI@fdKc z4xpeqS!x9+soeo?)FBj5w|OdAo%*2;ppd!&^kXQdf)kZf{Z;QMs1GQvUxpAwAFi^H QT>t<807*qoM6N<$f(6mHd;kCd literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/ic_zoom_out_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_zoom_out_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..7772ceea714619719877d3bab5fb286a9e0979bb GIT binary patch literal 412 zcmV;N0b~A&P)I|w$@3Bq7y zv4zOu7Z|26$(1wN+VeM;!_UX%!X13hqGQFL6Jv+AWCn3k%N>%*!0ksx1-Of$6L8j^zd3!Mb~ggE7#f4JJ)Z&q?JfiJ7&-)#kBZho6GL0z z!BV>D08C>j^91&j#mqf8ilKoLG*%PEAK=+nG31L!P}}_THXXxp-@jIP0k19;Ml$OT z+yiRMG1SGbne^0PDi5J98!CU#vt!GEn>3ZwZ98{oX09=H)IISOa4ip@Aj2e;fa2tC z09W!53aIN86+i*?QyxMAbp;s5P)zl|Q9z9seWM_sP@LbDcsnH${Es030000~5;q+UmdnXs1e(j>>FVdQ&MBb@07N}3VE_OC literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_navigate_before_white_24dp.png b/app/src/main/res/drawable-mdpi/ic_navigate_before_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..4d7869d26f59e9104ff46a6b9778da2660594811 GIT binary patch literal 116 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1Yfl%)5R22v2@TxU(&b&bP0l+XkK{KX?Y literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_pageview_white_24dp.png b/app/src/main/res/drawable-mdpi/ic_pageview_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..2e1a81034d524a37eba09ad31e4a50c91dcc4ab2 GIT binary patch literal 226 zcmV<803H8{P)FvRP8B8@jA5U#>fvker_#<P5m;(KmJQz6%=1_t5L(apg^c+bF8I0E*=RAS~=%?aYO32C9{4XQ^a6R2vWOJ=t20NV;_SBDDuJ^1&FK{a)Mp)WBMib@I|c c=lxOe3D?Zy(M=wjng9R*07*qoM6N<$fP#jd(6VUXdS7krMY%m884WHAk4%peJ{CfmfjuxI(qY* z|C!miR-0v*4NhJZ6P1+~b%t2twOExuG4=E>f{ z*|(j?#1}qQ8B668jgqlc8Z=7AQfcs^WGqGFL&1nK00z(x^&Ee&XK3jnD0nN2y@!K)v3ewzpR#T-|!dGh9lY1-Lgkp@eAr=1H*8jNvDI}Z#JPl+LZ(#{1{ z8oc0~cDDFPgHLSI&I~tidGhX#NxE3!W@&8b#iu*I(#^<9(-)4abTjqsmdKI;Vst E0NwCNssI20 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_navigate_before_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_navigate_before_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..62f3590eef334980b01a178f9479afb3a389d383 GIT binary patch literal 136 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}a}te@_?3kch)?&mQD$FyLW1_?jz7 zLP);Fn@?2YlA~SwlZ@pJv78L2PM!GhtR09h&wjsiqPqXSV-MaR-FzY`KIvk_86Ccp jJ9j+!teeN^AgRCaAJ3g9ySr}zjb`w4^>bP0l+XkKZbLLy literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_navigate_next_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_navigate_next_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..93dec392d64168f33fada4a4aa7bd9905e3eb6c1 GIT binary patch literal 144 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}b0Da8DPcwfvt z*@J~!)tS+m>1CQ*RAwCGyfdMbOnCUBivF>5sNVRQBIFaJ<}>4m)>(;ITTCJ zEwqsDOv3r#{=ywyFP=1M(hxFWk2Xg}gm{>-AB601l^vl32Dr>n0()HMAOY9;Tfl`e z4GQ>VDbi%(7TEBBmzXkO!4k(yzEt;ii0v+I+?kt*vLsdlT?=K+$w7(Jb6tQPXsF(Ns;- z)&UdSc8RBB_j4TpW!u+Sa=Olfs@;`93q<7czMKp_Eda9{#G4j?h>AG4M8*=Y3czMc zi+~(H0d3|$PY^0VBtg752L!Qo3J9VD4go@P)DsU(V<-p+}yyASTR^cTolit=r#Oy)H?{uUPBaF?GfD_%%#Bt=$ye8=Gow- zC>p1&eM>6q=N}f-4{Ca(sVQyDb3%t6B_%y_j+sMjt3O)h4}*GO_YXeTuE|6M4cZGIj13GAHL0|*z#s>7zCWF8<+KUY+ z(T4oRl|0l!dy4~x{~LIZd!nh}6V0H#+JGEwJqT=~3L?J@{lqqS|o9Ik~=fu-0# zn(%;DFpAV{jAyhv#0sq7x~(C`=%DraX$ORJTm_3CPM3Jbb&A9Q8C`r=Y%ooW7Bg&e zjjv=P4iLua5~@Tyi~)pKE50nE(I)07*qoM6N<$f=v0>=Kufz literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_zoom_out_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_zoom_out_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..8c6ccea7b868ef0e31882985e38a4b3d7ae6bd64 GIT binary patch literal 470 zcmV;{0V)28P)@ECRS1d$?5Z6Jtjf0}N2MKW-LS$%#nZ{n4xBz+$j-($m{mq*< zk)tQ?nRyqJ^m(L#fvA|{m?j-kQaUs^VpjhOYy2R~1FQO5jBrjrXOvYO-*_ZXi*Xgh z2#+{jE?8%hA%>Y^gG;;?Wfj3W&J*+cgaz6-rwYd!&UZ$YfeN=cD+R(`88cNc)+x& z=nIVTjJZ=NR&j2rC<9|OF6j7})P zi3R_eVwcPdw#%5()K(Lq&bsyI0x4_Bbf>AG4m-Kby09c-#l^%UGs{zXGMryqJkPLY Y&k!-k0jdOFS95FODHr{Oil1=oPcW94JZ4uC&44$rj JF6*2UngBYURH*;} literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_pageview_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_pageview_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..d292effbda904a3f7969c9b39b4a682d51e7b4d5 GIT binary patch literal 601 zcmV-f0;c_mP)I0+nmFo6rIXcu*T?Hczpm!Q-U)>NGfGwocApVs5R*;aCro-mc9cQYl6erIiZ;}pq)@2eM zL_&wWJ0j6RbwaePgLVkfo({SoL<1cZsJuWC)Mu3$DwHTtqQWd|oQDD(vp|Z=T*@LR z`GeLO$EjDQl_%(ix41vv3O9LyR8EGJ3uqnp*VnQK9V6dPk$JZ1b4{Nu<|vAX3rB`(O#0@s{)G)x2HR5>)Y) z+vsh2yT_KGlDF)m*YkGch9L1auF<>lc6a`@?@%ePH?)P`hPQiU37YkmbLdsQUCk1- z<}HhKl+}TFYo9Ga=cL|tnjYD{@<9BKU08x(QLLvpM0OxJj(1=SI-xA~1!`>4| zR4E`o3!GVl;1li^_nM(K2pYE{y<%wpnR;b(k_8B$#RNK`h!gjcp*09jSz?SVrp$ZJ zc&3xAKmb4ZNR21lBjGMjc|)6@01Psu7hD>H^c2!_E{#A2BzurTY6k)-q$Y#~Nm3KS zf+VR4qkx7+r1q$P^xP*zyE>>ri0V2hrAyv@A^H73UygF-+{dAVaHK4=#{laF>{2Je n>7d{jK@k)|5fniYG{XG?nsW>4=RKEC00000NkvXXu0mjf_2v&I literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_zoom_in_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_zoom_in_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..30b84706716908a6fc75537b9a91414016700494 GIT binary patch literal 737 zcmV<70v`Q|P)ED4j(_l$%%=Iii(Q*hv*{DA|)<)rp_}JN-U70 z6QecWj}Ea-4fkqnG5D6CehzrOAN0Ki=p6;TX0b$~xu6V3_^V91d7w{R;lB#m=72IT zoI48S$kIxTRJLdNn}@NW97slD&OB&=B@kd@L+tZ$JyQjdbODcK~qt`~x>g8#~U+;}c|9MVi+Dm5_1)K%+=I8lX$0YyeOX(uD@- z8L71a;hF>2hV-NXsw2e$fMQ5>!vBUyBE4vUD*xLZDk0?qfX0w^H9!kU%K<=ZNOKyX z9MXM&m--QDL<7`G4QawBXbP!Hy9UUxg>+5Q2dJG}q)m(tXb^kfeJotZ-WM&9;V1T{ zJ+7O<-X2B|)Q5#+c_PhVA=UY;2{L@cS<&?_$=zAU*(^pEl%R~W8zxD(o}A(qXNSbK zL54IHoWTRDjM76JF_QE!#u|?_R-{EAWXK9BQ0HWHL54JC{B=kX>5Pmn$dF(O3vbn# zB~A_4fY!&~cJT>w#nj*r1AgRW=>3@_BHQ!OwIs%se|>@I;*#F4$#` zk%qs}kHJZX=1hh&oSl$X1}TtI;edp6>Yro?ffOFdkZvFylL`kUq>~0xw*p9;6eh@! z@=h{@Mfyc|I3OV%tAO-L!U-E>=;l~BA%lb@oKQhR5>ChWf5+zFT&`y>)@|;qnM3Dk{ zX35aj2$@%Ga7X3bvCcp}WnS=!f9C^z^^keQ0)BJPJc-)sbn_Xv?9o*_ooAfko&xDw ztxmblHx|f{rkNPcq{*_#Wd)^9eVxZ;n{~!0@d`8JjB#GJaoT68>?pq_S!H&L70>*6 z?Tc>To=G1}j(dyg)fBS(&ZJK&XHh$vUD?_!2h!fSel4L5>nJB3$R}I~c2!5G-FmY| z9qDnw-qNZel(qU!+>uUjCHO%Np*c}-AppN5_!$kMyeOCnzz++4Q$y%f6b$ex(Ifa1 z4WXha*eu4YM$Ai!;cE?{k|-DpAQThBr7)~eN(|p<2o=J1hU6{F2H-~ozoj8GD+(?K z;FkqIts#^V1up}1>hFRd(hzF1-m)=Adcu0kT8u_m7e&uWIgl-U73`YP2?N%Re&;~G zx5$@9D}1yH=X_GHEo$57g+9;sEHO+ENn)hvVT5I?@BCTMCZiwH6_i|ZOt=0j?Kw*9 zT0e!3^pz6KTeqiLN=y-_$r?LUS2BiPc6{h;|GMa&@xz+@V?;lz-2O%7mNnUxIj)P6 zF|;zs44a&AO^F*$*kYO??-R+MxXFXli2*NgVS zce*$hNuLo@ada)wwkl-hV=5FsC)E4*jDt)D|B?8wr!IWgTTscqYIn4V0dUAW1Y}9z7KOhqi^sPPIw7!dLw*NrLf;=eP`^JY9k?(#X=nCd zcgzlKvHty0=g_lyrE}%$KcD@NJa^2A$V!HX=v7zCg9d&s2ko((e7)78&qol`;+ E02^zJCIA2c literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/ic_navigate_before_white_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_navigate_before_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..a68bc5fb5f3f79165ed908b0443fb85cf623faa4 GIT binary patch literal 197 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD0wg^q?%xcgdOTemLn>~)J-?Cnkb?;8!FYx* z8NV2c_cE5sZgVNvq$8-%#BMD5CX5lN_Q3V8*P_e*txA2qT#x5xC->|>TUzJ-xvFXX z{~G_Nr>Cdu$M38831<9X&#n`(;X~TPyn{`x*AHE6V&(2`XXO^FOHEwm6=xAX?d+kY ppLn=Ce;z&*vvXQ&HrVvz^WNAq$9(*;8V^t@!wntd&6WQwJ+p+1PTqbq@BWMl+0$kT6`h(j zujNhAWCh127EU1*j|pH#z0`*FdpZ4?r19|VC$)7R5|L5HPQl0ue y$thvy<2^HG@At@<^MB$6tN&9k*vJE|X^`?i5X2&#ENa&Vvenbo&t;ucLK6T|$WlN6 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/ic_pageview_white_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_pageview_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..9df7fddd5e5711f7591a6aebff2e2689263307b4 GIT binary patch literal 770 zcmV+d1O5DoP);IO1!MUKu{V}K??trq6jM7+$)GzilFF4ffPcRnFZY| zT26)v>b*ZEW8d!IbJ%&?g!2gJ``kXy#RuLqZ&bc;KA+F$^Z9%}pN|v)JCt!iot#JkoRUJ-F+H5i0F0vQoG}T2Wt3qOjIczBOD-v~$PfwR-im8L z#rVVdj6=d5FlgB9qT&`Xqus_R0OoSUwEa1^0R69Sfm-FX{XUm~KZcLT)_`_XbO*?5 zPxla8`@}<6fjdAZbT>kjvZ1T2J3umYw?vc{LRV>bfVR+Gi74%bt~#6nw6FP+D3!IB zbIk$G*XJmN*7G#|Q3%J~@`s_Sal9biIxjtAH(X)kBe9bi|x9K=?C=%R@O zcL31>Fw;TixZ^fW-Y#fEDDoHN!C;fHGg zzzSU`%RFS7J4V8~djM3JqYq`ACZ6ySfZs;KP1fB2^oj&zNz*}sX4*+I%q05&P?PZ8 zIl!KUuqGd1CrAfa2sij99$+E7lMJvE-hfj(yV<3Zdbq)4r$c^k8ejnCpjGa zaG0aB-2rj_Ac(hE?F@L%2ZE}SZCAi|ToHyE-?k&*xyQ#pVV+@+ zJi$Tr56Kn}9haya(k24#ap>~#AGExU<&sb|5ip4A6G>kiWvHR**B?+s_1gDVBdGRt z2RuTx;&C+q;Bmzos)u?5W{}mnA1EM>jcihHzy-1eM4$k{60$R$0SQ!30|)e?vh)Rv zB0E6@4iJ=(z0nttM>Zck!2Pf43fMw697@1TWb66@%E*$T1f-Fb^aWIqbs?l_jvCaB z?7hB#Yh)dv1jLYizUu+@UH=MwG+HyK`0pv=wc44DoP^id;x`bm zVF=U&a{+=FvpD!+GeHc2pwVx-1LVn2q*c5Bdu$PIg1=?`?9r?p<;>&mR}%s9JY7>3Mim} c0tyJ;AK9!R=?G29w*UYD07*qoM6N<$g1^0>_y7O^ literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/ic_zoom_out_white_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_zoom_out_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..d85e242b97041c9907ee8e2c94417645c034edbd GIT binary patch literal 925 zcmV;O17iG%P)KhH-uTH!aML{-J?H`c7zwK5;MQKT|Me!dHL3}|J zrHG>2rCTGSAXQR9T#9YNcNB@0)2v7A(pEqx3sh-Em5X$0bCKqE z!gxlY&BK1)6V@s@Z4Q27jdm#WqoT)t)~M$>^Bkd|(cwG(z~ve{^bG`D$K@$0MTG@wedL51#4nVobwSZ!4^?b$=v5QQ zvVyHjR{pV#$JpNRy_!V83brNr$02MV=~WBpr;P1@d}9gQ3AKnJY!BoYJF#6;2;9Kd zBcC{rX@eaKfix9NXXF#FFVa%`9cBHyxM>Q zrg{0o9ZW~m1{}k5Q@&8d)T=fii)mTDP{PzD0}YaaZcOjw3+tFVWS~JZkizsyzOas| zLk1co11U@u`9cX(mkcyW2D&kQkS`Q5^{EZ$$5fOr+{ScNZNPC%cjXHOObcoQ7BMZ# z7ltwYsWza9X-K}1#{RpwVUh*PXl>$IXmC(m%X!4LWdGTg%D2`NQ~fK^;7Twy?UkmD*dhE#RXHijVUge#BEe@!6a@YiVG%i8&O;^fm>d2!8mSt#RX%y + + + + + diff --git a/app/src/main/res/layout/webview.xml b/app/src/main/res/layout/webview.xml new file mode 100644 index 0000000..36674fc --- /dev/null +++ b/app/src/main/res/layout/webview.xml @@ -0,0 +1,5 @@ + + diff --git a/app/src/main/res/menu/pdf_viewer.xml b/app/src/main/res/menu/pdf_viewer.xml new file mode 100644 index 0000000..516fb98 --- /dev/null +++ b/app/src/main/res/menu/pdf_viewer.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..7353dbd --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..7353dbd --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..e2c7ff3aebad0510338c162c3a456d1c81ca303b GIT binary patch literal 973 zcmV;;12X)HP)Hs9@0O+OOJXgn9`h@dguem$ri+` zVoFb<7;HTV3VQH?AcjN~A5p%}gxMvoiOD8gn%Vt6_z~Ff?acSfWM+3@R}e5TFfcH< z4->(nGfY~^5q12-i&~!G6=9n2o-jiQbH)to`!uViVo6eB3n5Mboe^iXl_e?n|M`=h zFrzbQO}}#FsG5^3>@$!fM{grYswt?bxnx1q=sN=lisY=)ssz!Y_t5}?KC@a?3!+2~ zAm~d@y{ZL$GJv43l?a+OfS_+E2nC@a6oi6M5DG#;Cb2M6=!4Gj%JTU#4gES5)k9*+kCfk56oB|SYo|6h>JW`o_` zUAVcq$;;K%6&xHKz}VOrh@vRxb#`{b$;ru+d24HH;P?98~p_V@RpqoYG^FBlAFIL;|+9w&42uT0VYub_T7jtpx?q9Lmnl4rDSJ`S|AMW7Cn1?k%ExbS zZ^7kqX)1_L;}Hh00&LP3TWgwJZ=2&!xZeK3Ha z*-8YxHh`cvtkxPeg6JcPW`diL5cK;{?{9*a)vEeM12oA=@Us)?Z3O)xyks?6gfhcQ z@DRF0QG822V}u`sdBS(jm}h;Dv0A!VZ8o8Tpu^5ia1mY*+6g|+X=k-OCpZL+-r-Th vh9Z4a!86WjVYSo<{~$~{0RsaAgNyhJK<7^IGM?uV00000NkvXXu0mjfddk8M literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..8b1922dd3d218615fed282cf998950e006751a08 GIT binary patch literal 2188 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..9223cf6f4560259a8be0da958858f786573cfd0f GIT binary patch literal 1376 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..1427b071ee5e9f105c7000adcb6c0ca04628fb00 GIT binary patch literal 4517 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 DFZ!%Y literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..85eed3265c871171dcf442eb55ead4b797c13ea4 GIT binary patch literal 2568 zcmc&$dpOg58~^RsvSoP;*`7*TC=(;+T4EOEP>408(TO>gLMX}{a_B^F8aYmRl+yHM zge|0l!(^h2IhLk_!&q3N_WZiu_xKD0|+%uoBj30mf?&>0#p5wht@R zi9>nXGKm5vSzVETqj7Oz@k|GvSUD#vEgP>N)THWUB?^meK3}NJxnIe6JU6V-TXb|I zxvUvJB(Uka`j)$yp;1` zSiEd9*Mn=TL}YE?8-OGS(BZK~kZ=u6m9=l&p#FZ;ebDz@D=U1t`yK;ia$XzOF; z{I=^G1|+qBajx8+iCn;h6{Za&8#H2|mq4@e*9*ExU;}E)JzB^qdq$07=KT+jmE@Bji5P*)vE6;)9^;b{x--Za1s1`~0@jI-f^I{^{^2jHZCGKfN_ z|4#lb`!ALMf!!s-ME(7HU0q#UBcr49Zs>dFGMN~)OD~u^3S+EJ)Ya9snUr>PbhJy& z&CIf9S65Y6GySbz;EG^i^1<_ZU!Fftu8ozQXdS4HXdb9J_3Yr2vu`!5<9b5}YF?MP zm)&aCkqc&LBfVcnj`t8u&CUG{eR+W|o16C%3oPd5=Ik?qLPN_9M)edHR-#!Ts9|${ zfOq~!-9)=UkT))@$Rqevui9Uyu20Qblu1%eN_AZebJTQQa_Z~rZv~V+iIt_86vnmC z8Gs6=aa7FD9{cqAc4=AJ=PRg@Q<9+_rY0td01{mfG&MCP)}DMvwpFE&fiR2S>f>uc zT;t5e^3K}YZ4sY3H_+i|O{ILVZv62OjZYIZ*pj+cVaPR!5mW)%xjE zpf`N$=`WNHWA$hE_TNW0n#1NN`?J4Bw-S`Y$c%%dj+?HJL0G9{M_R6F4=7y(kc_`s zDp*qCH)6!t9x9v0rA|w(>2gX~Z}E+<@+>3H@3M`W8u0EKy^Tb_)_)2C(r&fra|K+L z6gQ7_O9Cf`8yZ4oAmqE93nNas7zYKR3Xr}`iql^QL$iXHXEtkn9aOvmAl=@Adt6)$ z7Y^{D zfYA36luB;FMe1Nnb8Jqzei=J*k^-m~?k{ zFVE0hFWso-;o)%;d+JI?MqVV5HapqZ)Z6RzR6drl41vaN29e?8;ZW_`a;mB>SZkg+ zO!f5ie0sEPH=RxoSYQ(Qm8-(9m3PKhX8Al-8Bsz4<}eTdaR7wL|BXGA0x%%hk#Ppj zIH1PzM$D!AE5L9%umHkss4qfo&t1DAcmeyX2`}|a_o}n{)M4+L3hE=y%mytWc>~D+ z!#ysac+EBsmgS>yL5^hr9qQ`2FvE~$chR;x@Ic|yAH9~-_EgQRmRl!&h(8tuHB)PJ zNP7_4-Cg}mYrbFPbcI)fn^pyd(a>)r3~m;2B04nSy0feg>-fQZx_7A&Lp-&}7uX0- zoDLSMvRB~fiNwgvAim_B$M33*;cX3gaYpkfmg8~1>gZm>6(crkItblCrukW?S*Jsr zM{@whzK^n~*kqgF?4D1nSy@qpsa#;LeiT?e;c4JkncuC~9%ex@yj-z_ofNExgaRKQ zs0x`OroJCm`bVWLjcMd#eYc`Q-sy6<;UVg41_KGmQ!(!GfhPJ7#08M z6{t^m!aUC>dZYQmN%9Y;QZqh{ug%Z@AwiwZK)lgJRWGaHpt{mSseaZ_>Q2%YRNKYVFm5Md|Oi*Jc&8idMteFHHXm3xB%=oUAM|53K2)kbaAjO(f0M@ zY`ka)O;WnV(pd2MGF9FK zddl}%3bn!I_TjH)K!NOu}>j$$QE>req zn&T4T#x1ErNrEiTa`e}U3SQ!G*x+r+fw~EW2&ft-f+Qig)Q3BLHR|?GZdduB zquqn0+JK~#I{6OE&QcE_?ojWC*D&*h_=3kFSl%68E=Ru=kF|kDkX;U6%E}cAhSr=e zE}oz6iBF2sTHX78cl}bWUD{$YFdcpC%SFGmRc`%%H#cQ=eO)hf_;e&b=CnUF;Q@~J LE_Q74p~SxccjHQ& literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..3526c51c85cb60b3990a945ed0fe229da0bc8a2c GIT binary patch literal 6450 zcmV-28O`R2P)INklLN;f5Q7jDjPep@=I`D!-*FCy|K7R(ef*Dm_gU*( zm&d*TMT!(DQc^5=ga{!YC~yh&y9ll&MM|Ja z&ZLcMq)m5G_lar(5phWItw&FUBHV%A_+T7js-CB^|p26w62k;IzSC@j0*HB(CD9z+wr9t1 zvqMjrt)w4L4CctT8Ff@@gi~ci2(hVCNw|*iONZXRH>BoGI?beBhf#s+YB`}wOr!8Q zx2lwZ_^&wh_PI>@cw#W?<`vXonK2@Wvm8J>KTi|FmkB$B_-PXY*X5UtIu`#RfW1EF z(>&!c#0&A0H;?qXdkS?dqd@?QPW%>YaQ5?Kt+7rDiPHwXEoyK@Ixc2(aB3qd88UgkNZ2dpPGHQU zy=W6Li85sJs9uHR(szov6Iiq8yV~4AzL-SmHF-FJ>sQk22Yxi*NwjmtBucNzvyAYO z^!lMludvZpUlEfib@KDn`)$(ehjujhmNo*22walCmhgxXjH?t;O`aEHxh#;}at*L}J#NN-kC=pMbO_xct_+idJBK#f|c0vf0HBfEIZF{kV zNlzue$}zu;a9GHn^&;RlUZ4dz@^ZcB=TF|#=9ol!awbB=ZT$s<13BsN@{3<8{8I?~g#0-#0^XHkX0C`pkMr*qhgTe9d~(>k zBirW*RH&1;{QiZIUtnZdE%Nh_m_33R=Fp=W`LkvV7JVmyZ)nrxGQ%q{ zw{he@|BJzytZ{l5Tc_rUNW%;47@Sz1El#l_|ECBaSd!H#NGyx=4}@7^7lE?ncx%Gv z#qJll^aptLU#%6=O}O$j+$rQ2Bq@Ts4K9VIMDf615W8QHqCapgxD*YO>BA4q$9(RQ z-d~X7DDXRL@DPts_yc)b4EMi;{DL%z;6cp~2(&4rqCQs|Fd%XVJ_;z) zr;+e$>HP(19tAjeY*dg%piU6^mc;u78JZvXuH}5#VPH(38P?FUMv3|e(j65#Vhye# z2~<=_#b_f)W)jm!kV#YMDXqiJ3zF%xP#j-@M-K5dK{18Ys{RtfHtGEZ9*qLLXaHTb&G_;IERo({;PEK10^BR~yZ0}*23PY)51*nS$S`Z00aRM056)E;6+5J z04iH1&aWU~&hRR5Gh@zhL{r$4;`|B%<_vE^N=_tG=@F{;=QF(iAkMEKV9qdavwtBt znh`Td4KIHuU-cb*p{(<(Jz6HLOK;B3mdL3!GR*81W6`XK#y50X3Pk@06zNYBYXAg)d`zzSu6m>P2QlP zJRPYK1wgwW_P^f(U~JsDaUl8Hr3T&xW*{kbFnb~u+W zUmkb?Fdlm7p@gDCSuB8l%@q0~xLcTt{jVN+w^}H94<`80cQKD z$nyEPqhti|?6c1fqzS~r(xpoWV*GBdxq0*EfoDm#0OCC-PsBa&zyq$X_wKvz+UK8t ze%b}FcJ11@&zcOny1FvGO!6z>aEV(-SP6jfSAMSjO-2Ar#CX>nIdY`EW5*6x*W9vY zi(Ow|pLPMnyBU#V3?He}BG8q9dVMDl9cnvt5lmL`+Zu2w$Uj!fmNWl#H zcW}5U83C{lP)7J~KUaW>07L*OIKn>yhh5JFs8mwUr+8XM01-e)M}TLsL^A4jov_LP zts?wf1Rw$ksQ`8o8nhW0URYvv0cT zri^5RiU2Yyfa8SEfXgLr1Woo@}Ez>)I;m^pK%2q1g{;GLuAfy$!6!I+CQ8_CBcK&!P#Z0XU76D{b0BpWr0xp-h5kLuk zbWW~2!P~cQw;LK7L;&G+f-Mi`DU&OVE69b_QHh=J=q&n z1dveyyo1SH*8(WQk6H<@-Xz#o4zJY@%%F4<-Js%(}0!XAzO#~nn;w8cv;Bui` z0kG3BB8&@Scqcbb-in8nD_7cAUU{W`;e{8bbl60$2w?sC^~2VwiPF;2AS{Tf2bZIX z3P5d%UJe1Q&$e{vOhMA21D6i{I5=Exx!5W_Pumf$j_^$pfCwO@0{9PbxWcUf^0Ah( zR@)f2Uj!fm2-&tMUk8V)z-d^WCk zgU8SNb~bRf3m`08BZf!-ilZMAJ_in$yA^;+hp572*c&2%a0nn%o8yL10PkQuaFvz@ zk?`I?YBG%dfM&uLzc$Ab0R&@v^biR^ar762(co~xlVG|4)V@HC*kVouki!RLgirt* zz}+f0lVIj#SQR!FT4kMnB)teAhmJ@Ji2!tdt_63i+)RQw%?0p8!exG~3=;ta3E;Qb(4p4tB$ycrEkPKG6N-N9haVsU z2*yF#ArU~YmIKrZ?v}a%iRtE6J1Ml_Ok?a8iplAK+PHTuDiZy<)`*SC}_%o-d8S z_jUWM!(rL7WdkeKIKop?Q)3qv7ACYwS3Godbhv(w_V)HLB*3Zoe+x!{;$$3P(-AI& zH{E0n?zH=RKi3Bc1aW%*gP5~wg6~?GtOIQN0p(EC7{dShl@=io#0!6t0JhQRIB>N* z75m@x14?jF_5=Rjue1n(V3_ddH^I?*aJC?o-e30v)Ox+5 zc;QfG2K5kji2wuv>HT^8&Ka8dQ=BgI$25Z~a1%CzzAXX}1Y`vGPjIpY98H_~<75Uk zz|-clmp%{?2z>7SdGY%d;ACUE%^#;|P&JgsCvg9dHFOq}G>X7WoP+?L1{Yhv&7yRh zKTeZkO_&tBTAL7)Q9$5z@6Vsh!NuluO@1XZDaOw5NWuidR+$+V_%!qTbNcK67wghB z`ISg+Pz6?rwGsYYLZSj6dVd?qnQah2MLKeS+&IG{;CQeCx5+3V@VNJXkv==M)Q8ec z_Wn-Ja20Mo4t7|-mub?1oXz`T^7H3vaBnoYm@(%!mNTqQkl_d5V`w(ZC?N2t_ur1* ze>6B)mPzL~-pp_{>@N;O{fXuCsq%uHu>C)V-`Nfeq&gEbzsalk^epVTmY`=y?=q1MSu1NAXtbw_CDcMv%Gv zekMWy>g=yVuX}$dU!V%}0{mcny8H{0A|Xg~$^)NQJrx`q3C?+L`#X&SDk4;;jRMzN zgBz5JDI`dT>BC&Q9^7gJ*UJ2`{fC2sVu zuLGCHgIg-+ClI~AQ>JJ&Qd2oow3CJ}edU-$g#-ziKAh}E+_?)gz7xQy>P%;RrqdyA z#e?(V8b1+JNRULT^JH*nOpqMkL>yw?LZwkNg)SoO5fKOyB>(T|^Ad2U9bBpmlH(iC zA=XWy7KE!g@)S5SXbBOn$<{;0SYNtQPeNyy+7!Sx!xm zwPP}a9h*%O84~D|T}1x>vj$HgGAF!zNp?%8Da4Z&HM&0#jYenE=kwwei_;78?<^=N zm}S`gHO7Qjs05&kKxK^T{=ixE!W5>~ z!RhS+CmO(!;xL3f-I_vbexM2y8)GyPd`T05m_ylb_UxxNzgi>z7|rR`8}zZ z&CXEgZ(#FJ0>**^p^x~a8Xj#^m4fKd^Je7b#xX&~SL0h5WHapd8~d zm>5waxSlHXZSf02WAFc#+H9pp{!VM?5Q`cie|*PSg-BbG7c!YDax&SF7qcyC46`yC z1gqC)Y|GEjzl7V&8cc5MKwGL%r;7Fn`QwN{O_r%0CI*}*s?;9pS=Lb{AJKXp84djH z^;L-T2(``kVeczvcRbp#5p9|iq0V$omT`q~UI_02*{&i)ECT9bmQaPiY)r4qXy9$H ze^Tr9U!^wrGj1CYzsnlhy}4eS;T7_`NSok%5KfBXJs{O_OlQF)>LyI59_L=oL6%i! z9Jwj9sTT+=sXKSOuG+s-}8HR?FEJ8>R@q4vi ze;?KL9XtYSz5dyn$*S>AH+XQ zc$D+Cv|fKQ+F-0^@>FW}zC?O5;1`r5mfVC0Lp$uw9*hQ4sFD7Z8fy!76_ybpwI2Tj z;TfvaWn8!D^?Oj~?P!B0v`M+x``(yDDpabE25J|&ZY2bsjG@N+8R4V|!8P$u5}uGoM-=Je~49iDIm z@uwQ*&Y9NG@kEVAuP-4^A4dbWJL?dAXvNUniP2y(8gU9DMvvjFsklVQ@)-VU!lycU zpYS;1`BOCF_nq_bM{S|>3E>)4DdJN5DFcW!}gAgvK9`1Y8;JXOs2+*5_ zV(2$b9FV@3@N24zf8#nah~JI68;`m?19ht+JZ5-P$nW!LV46h@ntw1}n?&nTLf{;A zYW%+?5cm&MI}#m|Ii+sHGugzMh^Z_H>P@fZUX}0zo+M&Nk|Rq-VqQkT_rSgQp3m?zpod?~&&FvX zI^kj0D-)+v>+O}9(}cRHLfr`Qvs?(uSytgweN-4_h~Z4lOwxUZ9<67cM#MWGX4CbA zTX@X^{e1&QjORFY8@=<}gm*ZfhHwBxeh+`%hyQyU-`$DdK26tpkgv%;3g3gx8M@~M z8ri34&()2bd}ZF8X^?)D(c7zVrgCnD_&Fei{1~G`E$rWBZDbe+$8g|~50I)GqA)SV zz*LZQI*Wu?wGnwQB`oAEA$c<};Pd#mOZhweT_l@L)9m&s4rEu6n;vUumR21uF&@vZ zdirL(TWyTqK3|BRdr>2OR48%~Lp@A{Ghip{f>0v_n@n9GAY&Sc+v7ymB%rP_jjyfU zr^_1JQF)?4_|bUgCcJ}5`XZyZm#B`63ZIM$x){n}B2>dpR)T1ODbb2p`8b#u6F|le z5VI3Kau;lH9X$rj|5rOHbmCeaxb_6xYaH&~if3uj2w#V1uEaZ-q?g`aO2T3&)O-dd z2sJ{CfLYN56XOh!aWsfI1|)6MM4~X>fc}5u@SCx?Mk}s43ioKnJsa>0s)tvES2lg2 zkX}lvVsH|K8X-zyR#bq1)o?89K+JlOv=M|=LQ!Y|^nX*|Ys7EsajiOByBhbZz`aYg z9^Q%YLV77_5rZiRCs7oGj3wHLQLc%kQX4^>p#Hx?`(2qv@)F#`iR?~<7t%}dOcbUt zlsKZAND4KvI6?o8{@a2WL>ID437jBei6at2EKa13#38v5K8@x70Z)< + + + File name + File size + Title + Author + Subject + Keywords + Creation date + Modify date + Producer + Creator + PDF version + Pages + + diff --git a/app/src/main/res/values/ic_launcher_background.xml b/app/src/main/res/values/ic_launcher_background.xml new file mode 100644 index 0000000..beab31f --- /dev/null +++ b/app/src/main/res/values/ic_launcher_background.xml @@ -0,0 +1,4 @@ + + + #000000 + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..9fd3196 --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,15 @@ + + + PDF Viewer + + Previous page + Next page + Open document + Zoom out + Zoom in + Jump to page + Properties + + Invalid date + Failed to obtain document metadata + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..766ab99 --- /dev/null +++ b/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + + + diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..33d9a98 --- /dev/null +++ b/build.gradle @@ -0,0 +1,31 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + repositories { + google() + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:3.4.1' + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + google() + jcenter() + } + + gradle.projectsEvaluated { + tasks.withType(JavaCompile) { + options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" + } + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..dbb7bf7 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,2 @@ +android.enableJetifier=true +android.useAndroidX=true diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..5c2d1cf016b3885f6930543d57b744ea8c220a1a GIT binary patch literal 55616 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 \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..15e1ee3 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,100 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem http://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..e7b4def --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +include ':app'