├── .dockerignore ├── .env.example ├── .gitattributes ├── .github └── workflows │ └── docker-image.yml ├── .gitignore ├── .stylelintrc.json ├── Dockerfile ├── LICENSE ├── README.md ├── app ├── __init__.py ├── api.py ├── service │ ├── __init__.py │ ├── file.py │ └── mail.py ├── static │ ├── css │ │ ├── filepond.css │ │ └── index.css │ ├── fonts │ │ └── Mukta │ │ │ ├── Mukta-Bold.ttf │ │ │ └── Mukta-Regular.ttf │ ├── images │ │ └── icons │ │ │ └── favicon.png │ └── js │ │ ├── filepond-plugin-file-validate-size.js │ │ ├── filepond-plugin-file-validate-type.js │ │ ├── filepond.jquery.js │ │ ├── filepond.min.js │ │ └── jquery.js ├── templates │ ├── banner.html │ └── index.html └── utils.py ├── config.py ├── docker-compose.yml ├── manager.py ├── requirements.txt └── uwsgi.ini /.dockerignore: -------------------------------------------------------------------------------- 1 | .idea 2 | logs 3 | .DS_Store 4 | .vscode 5 | *.log 6 | __pycache__ 7 | *.pyc 8 | 9 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | FLASK_APP=manager.py 2 | FLASK_ENV=production 3 | FLASK_DEBUG=0 4 | PRODUCTION_HOST=https://tokindle.top 5 | UPLOAD_FOLDER=/tmp/push-to-kindle 6 | MG_API_KEY= 7 | MG_EMAIL_TO_FOR_TEST= 8 | LANG=en_US.UTF-8 9 | LC_ALL=en_US.UTF-8 -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.github/workflows/docker-image.yml: -------------------------------------------------------------------------------- 1 | name: Publish Docker image 2 | on: 3 | push: 4 | branches: [master] 5 | pull_request: 6 | branches: [master] 7 | jobs: 8 | push_to_docker_hub: 9 | name: Push Docker image to Docker Hub 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Check out the repo 13 | uses: actions/checkout@v2 14 | - name: Push to Docker Hub 15 | uses: docker/build-push-action@v2 16 | with: 17 | username: ${{ secrets.DOCKER_USER }} 18 | password: ${{ secrets.DOCKER_PASSWORD }} 19 | repository: aneureka/push-to-kindle 20 | tag_with_ref: true 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # IDE 2 | .idea 3 | logs 4 | .DS_Store 5 | .vscode 6 | *.log 7 | __pycache__ 8 | *.pyc 9 | 10 | # virtual environment 11 | venv 12 | logs 13 | 14 | # script & configuration 15 | *.sh 16 | .tmp 17 | .env -------------------------------------------------------------------------------- /.stylelintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "stylelint-config-standard" 3 | } 4 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.7 2 | WORKDIR /app 3 | RUN apt-get install gcc 4 | COPY . . 5 | RUN pip install --no-cache-dir -r requirements.txt 6 | CMD [ "sh", "-c", "uwsgi uwsgi.ini" ] 7 | EXPOSE 8001 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PUSH TO KINDLE! 2 | 3 | ![Author](https://img.shields.io/badge/author-aneureka-orange.svg) [![LICENSE](https://img.shields.io/badge/license-Anti%20996-blue.svg)](https://github.com/996icu/996.ICU/blob/master/LICENSE) 4 | 5 | `PUSH TO KINDLE!` 是一个简洁优雅的 Kindle 文档推送工具,快来拯救你的泡面板! 6 | 7 | ## 开始 8 | 9 | 访问: 10 | 11 | 现在就推送文档到你心爱的 Kindle 上吧~ 12 | 13 | ## 为什么我需要这个东西 14 | 15 | 其实通过官方的方法用邮箱发送文档没什么问题,但因为懒,想去掉重复无谓的操作 16 | 17 | 如果你觉得有哪些需要改进或新增的功能或点子,欢迎联系我哦 18 | 19 | ## 技术栈 20 | 21 | - JQuery(前端就是一把梭) 22 | - Flask 23 | - Docker 24 | 25 | ## 部署 26 | 27 | 如果你想学习或重新运行本项目,也可以将 `PUSH TO KINDLE!` 部署到你的服务器上,只需要重新填写配置信息: 28 | 29 | - 前提条件:了解 Docker 及其部署方式 30 | - 将 `.env.example` 重命名为 `.env`,并修改为自己的配置 31 | - 运行 `docker-compose up` 32 | 33 | ## 计划 34 | 35 | - 支持中文文档名 ✅ 36 | - 文档分享(还没做) 37 | 38 | ## 特别感谢 39 | 40 | - [filepond](https://github.com/pqina/filepond),一个超好用又好看的 JS 文件上传工具 41 | - [eruda](https://github.com/liriliri/eruda),一个移动端网页控制台,用它调试解决了关键的问题 42 | 43 | ## 捐赠 44 | 45 | 觉得 `PUSH TO KINDLE!` 刚好解决了你的问题,可以考虑 `某宝` 请我喝杯一点点哟~ 46 | 47 | 48 | 49 | ❤️ 感谢以下同学(如果需要匿名请联系我或备注一下哦) 50 | 51 | | 昵称 | 金额 | 日期 | 备注 | 52 | | ------ | ------- | ---------- | -------------------------- | 53 | | \*逸涵 | ¥ 5.00 | 2019-08-13 | 肥肠感谢你的大白兔奶糖 www | 54 | | \*\*跃 | ¥ 10.00 | 2021-05-26 | 感谢投喂~ | 55 | -------------------------------------------------------------------------------- /app/__init__.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | from flask import Flask 4 | from flask_cors import CORS 5 | 6 | from config import config 7 | 8 | 9 | def create_app(config_name="default"): 10 | app = Flask(__name__) 11 | CORS(app) 12 | 13 | app.config.from_object(config[config_name]) 14 | app.logger.setLevel(logging.DEBUG) 15 | 16 | config[config_name].init_app(app) 17 | 18 | # blueprint 19 | from app.api import api 20 | 21 | app.register_blueprint(api) 22 | 23 | return app 24 | -------------------------------------------------------------------------------- /app/api.py: -------------------------------------------------------------------------------- 1 | import json 2 | from smtplib import SMTPDataError 3 | 4 | import requests 5 | from flask import current_app, render_template, request, Blueprint 6 | 7 | 8 | from app.service.file import create_file, read_file, remove_file 9 | from app.service.mail import send_mail 10 | from app.utils import convert_file_size_to_mb 11 | 12 | api = Blueprint("api", __name__) 13 | 14 | 15 | @api.route("/ping", methods=["GET"]) 16 | def ping(): 17 | return render_template("banner.html") 18 | 19 | 20 | @api.route("/", methods=["GET"]) 21 | def index(): 22 | return render_template( 23 | "index.html", 24 | title=current_app.config["APP_NAME"], 25 | from_user=current_app.config["MG_EMAIL_FROM"], 26 | host=current_app.config["HOST"], 27 | ) 28 | 29 | 30 | @api.route("/files", methods=["POST", "DELETE"]) 31 | def handle_files(): 32 | if request.method == "POST": 33 | file = request.files["file"] 34 | # validate file type 35 | if file is None: 36 | return json.dumps({"code": -2, "msg": "Missing uploaded file."}) 37 | try: 38 | file_id = create_file(file) 39 | return json.dumps({"code": 0, "data": file_id}) 40 | except ValueError as e: 41 | print(str(e)) 42 | return json.dumps({"code": -1, "msg": str(e)}) 43 | else: 44 | file_id = request.data.decode("utf-8") 45 | if file_id is None or file_id == "": 46 | return json.dumps({"code": -1, "msg": "Missing file id."}) 47 | remove_file(file_id) 48 | return json.dumps({"code": 0, "data": file_id}) 49 | 50 | 51 | @api.route("/push", methods=["POST"]) 52 | def push(): 53 | data = request.json 54 | to_email = data.get("email") 55 | file_ids = data.get("fileIds") 56 | if to_email is None or file_ids is None: 57 | return json.dumps({"code": -1, "msg": "Email and File ids are required."}) 58 | # send emails 59 | files = [read_file(file_id) for file_id in file_ids] 60 | try: 61 | for file in files: 62 | file = [file] 63 | send_mail( 64 | to_email, 65 | current_app.config["MG_EMAIL_FROM"], 66 | current_app.config["MG_EMAIL_SUBJECT"], 67 | current_app.config["MG_EMAIL_TEXT"], 68 | file, 69 | current_app.config["MG_DOMAIN_NAME"], 70 | current_app.config["MG_API_KEY"], 71 | ) 72 | return json.dumps({"code": 0}) 73 | except requests.exceptions.RequestException as e: 74 | print(str(e)) 75 | return json.dumps( 76 | {"code": -1, "msg": "Failed to send emails. Please try again."} 77 | ) 78 | except SMTPDataError as e1: 79 | print(str(e1)) 80 | return json.dumps({"code": -2, "msg": "File too large."}) 81 | -------------------------------------------------------------------------------- /app/service/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aneureka/push-to-kindle/791dbc70827ee0da6ba8490bceb6e236f7be1064/app/service/__init__.py -------------------------------------------------------------------------------- /app/service/file.py: -------------------------------------------------------------------------------- 1 | import glob 2 | import os 3 | import uuid 4 | 5 | from flask import current_app 6 | 7 | 8 | def create_file(file): 9 | origin_filename = file.filename.encode("ascii", "replace").decode("utf-8") 10 | origin_filename = file.filename 11 | core_filename, file_type = os.path.splitext(origin_filename) 12 | if file_type not in current_app.config["ACCEPTED_FILE_TYPES"]: 13 | raise ValueError("Not supported file type.") 14 | if file_type in current_app.config["TRANSFER_FILE_TYPES"]: 15 | file_type = ".html" 16 | file_id = str(uuid.uuid4()) 17 | filename = os.path.join( 18 | current_app.config["UPLOAD_FOLDER"], 19 | "%s%s.%s" % (core_filename, file_type, file_id), 20 | ) 21 | if not os.path.exists(filename): 22 | file.save(filename) 23 | return file_id 24 | 25 | 26 | def remove_file(file_id): 27 | filename = _get_filename(file_id) 28 | if filename: 29 | os.remove(filename) 30 | 31 | 32 | def read_file(file_id): 33 | filename = _get_filename(file_id) 34 | origin_filename = os.path.splitext(filename)[0] 35 | origin_filename = origin_filename.split("/")[-1] 36 | if filename: 37 | with open(filename, "rb") as f: 38 | return origin_filename, f.read() 39 | return None 40 | 41 | 42 | def _get_filename(file_id): 43 | filenames = glob.glob( 44 | os.path.join(current_app.config["UPLOAD_FOLDER"], "*.%s" % file_id) 45 | ) 46 | if filenames: 47 | return filenames[0] 48 | else: 49 | return "" 50 | -------------------------------------------------------------------------------- /app/service/mail.py: -------------------------------------------------------------------------------- 1 | import smtplib 2 | from email.mime.application import MIMEApplication 3 | from email.mime.multipart import MIMEMultipart 4 | from email.mime.text import MIMEText 5 | from smtplib import SMTPDataError 6 | 7 | import requests 8 | 9 | 10 | def send_mail(to_email, from_email, subject, text, files, domain_name, password): 11 | msg = MIMEMultipart() 12 | msg["Subject"] = subject 13 | msg["From"] = from_email 14 | msg["To"] = to_email 15 | msg.attach(MIMEText(text, _charset="utf-8")) 16 | for file in files: 17 | file_name, file_content = file 18 | print(file_name) 19 | part = MIMEApplication(file_content) 20 | part.add_header( 21 | "Content-Disposition", "attachment", filename=("gb18030", "", file_name) 22 | ) 23 | msg.attach(part) 24 | s = smtplib.SMTP("smtp.mailgun.org", 587) 25 | s.login("postmaster@%s" % domain_name, password) 26 | try: 27 | s.sendmail(msg["From"], msg["To"], msg.as_string()) 28 | except SMTPDataError as e: 29 | raise e 30 | finally: 31 | s.close() 32 | 33 | 34 | def send_mail_via_api( 35 | to_email, from_email, subject, text, files, domain_name, auth_api 36 | ): 37 | # send mail with mailgun 38 | try: 39 | response = requests.post( 40 | "https://api.mailgun.net/v3/%s/messages" % domain_name, 41 | auth=("api", auth_api), 42 | data={"from": from_email, "to": to_email, "subject": subject, "text": text}, 43 | files=[("attachment", f) for f in files], 44 | ) 45 | response.raise_for_status() 46 | except requests.exceptions.HTTPError as e1: 47 | raise e1 48 | except requests.exceptions.RequestException as e2: 49 | raise e2 50 | except Exception as e: 51 | raise e 52 | -------------------------------------------------------------------------------- /app/static/css/filepond.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * FilePond 4.29.1 3 | * Licensed under MIT, https://opensource.org/licenses/MIT/ 4 | * Please visit https://pqina.nl/filepond/ for details. 5 | */ 6 | 7 | /* eslint-disable */ 8 | .filepond--assistant { 9 | position: absolute; 10 | overflow: hidden; 11 | height: 1px; 12 | width: 1px; 13 | padding: 0; 14 | border: 0; 15 | clip: rect(1px, 1px, 1px, 1px); 16 | -webkit-clip-path: inset(50%); 17 | clip-path: inset(50%); 18 | white-space: nowrap; 19 | } 20 | /* Hard to override styles */ 21 | .filepond--browser.filepond--browser { 22 | /* is positioned absolute so it is focusable for form validation errors */ 23 | position: absolute; 24 | margin: 0; 25 | padding: 0; 26 | 27 | /* is positioned ~behind drop label */ 28 | left: 1em; 29 | top: 1.75em; 30 | width: calc(100% - 2em); 31 | 32 | /* hide visually */ 33 | opacity: 0; 34 | font-size: 0; /* removes text cursor in Internet Explorer 11 */ 35 | } 36 | .filepond--data { 37 | position: absolute; 38 | width: 0; 39 | height: 0; 40 | padding: 0; 41 | margin: 0; 42 | border: none; 43 | visibility: hidden; 44 | pointer-events: none; 45 | contain: strict; 46 | } 47 | .filepond--drip { 48 | position: absolute; 49 | top: 0; 50 | left: 0; 51 | right: 0; 52 | bottom: 0; 53 | overflow: hidden; 54 | opacity: 0.1; 55 | 56 | /* can't interact with this element */ 57 | pointer-events: none; 58 | 59 | /* inherit border radius from parent (needed for drip-blob cut of) */ 60 | border-radius: 0.5em; 61 | 62 | /* this seems to prevent Chrome from redrawing this layer constantly */ 63 | background: rgba(0, 0, 0, 0.01); 64 | } 65 | .filepond--drip-blob { 66 | position: absolute; 67 | -webkit-transform-origin: center center; 68 | transform-origin: center center; 69 | top: 0; 70 | left: 0; 71 | width: 8em; 72 | height: 8em; 73 | margin-left: -4em; 74 | margin-top: -4em; 75 | background: #292625; 76 | border-radius: 50%; 77 | 78 | /* will be animated */ 79 | will-change: transform, opacity; 80 | } 81 | .filepond--drop-label { 82 | position: absolute; 83 | left: 0; 84 | right: 0; 85 | top: 0; 86 | margin: 0; 87 | color: #4f4f4f; 88 | 89 | /* center contents */ 90 | display: flex; 91 | justify-content: center; 92 | align-items: center; 93 | 94 | /* fixes IE11 centering problems (is overruled by label min-height) */ 95 | height: 0px; 96 | 97 | /* dont allow selection */ 98 | -webkit-user-select: none; 99 | -moz-user-select: none; 100 | -ms-user-select: none; 101 | user-select: none; 102 | 103 | /* will be animated */ 104 | will-change: transform, opacity; 105 | } 106 | /* Hard to override styles on purpose */ 107 | .filepond--drop-label.filepond--drop-label label { 108 | display: block; 109 | margin: 0; 110 | padding: 0.5em; /* use padding instead of margin so click area is not impacted */ 111 | } 112 | .filepond--drop-label label { 113 | cursor: default; 114 | font-size: 0.875em; 115 | font-weight: normal; 116 | text-align: center; 117 | line-height: 1.5; 118 | } 119 | .filepond--label-action { 120 | text-decoration: underline; 121 | -webkit-text-decoration-skip: ink; 122 | text-decoration-skip-ink: auto; 123 | -webkit-text-decoration-color: #a7a4a4; 124 | text-decoration-color: #a7a4a4; 125 | cursor: pointer; 126 | } 127 | .filepond--root[data-disabled] .filepond--drop-label label { 128 | opacity: 0.5; 129 | } 130 | /* Hard to override styles */ 131 | .filepond--file-action-button.filepond--file-action-button { 132 | font-size: 1em; 133 | width: 1.625em; 134 | height: 1.625em; 135 | 136 | font-family: inherit; 137 | line-height: inherit; 138 | 139 | margin: 0; 140 | padding: 0; 141 | border: none; 142 | outline: none; 143 | 144 | will-change: transform, opacity; 145 | 146 | /* hidden label */ 147 | } 148 | .filepond--file-action-button.filepond--file-action-button span { 149 | position: absolute; 150 | overflow: hidden; 151 | height: 1px; 152 | width: 1px; 153 | padding: 0; 154 | border: 0; 155 | clip: rect(1px, 1px, 1px, 1px); 156 | -webkit-clip-path: inset(50%); 157 | clip-path: inset(50%); 158 | white-space: nowrap; 159 | } 160 | .filepond--file-action-button.filepond--file-action-button { 161 | /* scale SVG to fill button */ 162 | } 163 | .filepond--file-action-button.filepond--file-action-button svg { 164 | width: 100%; 165 | height: 100%; 166 | } 167 | .filepond--file-action-button.filepond--file-action-button { 168 | /* bigger touch area */ 169 | } 170 | .filepond--file-action-button.filepond--file-action-button::after { 171 | position: absolute; 172 | left: -0.75em; 173 | right: -0.75em; 174 | top: -0.75em; 175 | bottom: -0.75em; 176 | content: ''; 177 | } 178 | /* Soft styles */ 179 | .filepond--file-action-button { 180 | /* use default arrow cursor */ 181 | cursor: auto; 182 | 183 | /* reset default button styles */ 184 | color: #fff; 185 | 186 | /* set default look n feel */ 187 | border-radius: 50%; 188 | background-color: rgba(0, 0, 0, 0.5); 189 | background-image: none; 190 | 191 | /* we animate box shadow on focus */ 192 | /* it's only slightly slower than animating */ 193 | /* a pseudo-element with transforms and renders */ 194 | /* a lot better on chrome */ 195 | box-shadow: 0 0 0 0 rgba(255, 255, 255, 0); 196 | transition: box-shadow 0.25s ease-in; 197 | } 198 | .filepond--file-action-button:hover, 199 | .filepond--file-action-button:focus { 200 | box-shadow: 0 0 0 0.125em rgba(255, 255, 255, 0.9); 201 | } 202 | .filepond--file-action-button[disabled] { 203 | color: rgba(255, 255, 255, 0.5); 204 | background-color: rgba(0, 0, 0, 0.25); 205 | } 206 | .filepond--file-action-button[hidden] { 207 | display: none; 208 | } 209 | /* edit button */ 210 | .filepond--action-edit-item.filepond--action-edit-item { 211 | width: 2em; 212 | height: 2em; 213 | padding: 0.1875em; 214 | } 215 | .filepond--action-edit-item.filepond--action-edit-item[data-align*='center'] { 216 | margin-left: -0.1875em; 217 | } 218 | .filepond--action-edit-item.filepond--action-edit-item[data-align*='bottom'] { 219 | margin-bottom: -0.1875em; 220 | } 221 | .filepond--action-edit-item-alt { 222 | border: none; 223 | line-height: inherit; 224 | background: transparent; 225 | font-family: inherit; 226 | color: inherit; 227 | outline: none; 228 | padding: 0; 229 | margin: 0 0 0 0.25em; 230 | pointer-events: all; 231 | position: absolute; 232 | } 233 | .filepond--action-edit-item-alt svg { 234 | width: 1.3125em; 235 | height: 1.3125em; 236 | } 237 | .filepond--action-edit-item-alt span { 238 | font-size: 0; 239 | opacity: 0; 240 | } 241 | .filepond--file-info { 242 | position: static; 243 | display: flex; 244 | flex-direction: column; 245 | align-items: flex-start; 246 | flex: 1; 247 | margin: 0 0.5em 0 0; 248 | min-width: 0; 249 | 250 | /* will be animated */ 251 | will-change: transform, opacity; 252 | 253 | /* can't do anything with this info */ 254 | pointer-events: none; 255 | -webkit-user-select: none; 256 | -moz-user-select: none; 257 | -ms-user-select: none; 258 | user-select: none; 259 | 260 | /* no margins on children */ 261 | } 262 | .filepond--file-info * { 263 | margin: 0; 264 | } 265 | .filepond--file-info { 266 | /* we don't want to have these overrules so these selectors are a bit more specific */ 267 | } 268 | .filepond--file-info .filepond--file-info-main { 269 | font-size: 0.75em; 270 | line-height: 1.2; 271 | 272 | /* we want ellipsis if this bar gets too wide */ 273 | text-overflow: ellipsis; 274 | overflow: hidden; 275 | white-space: nowrap; 276 | width: 100%; 277 | } 278 | .filepond--file-info .filepond--file-info-sub { 279 | font-size: 0.625em; 280 | opacity: 0.5; 281 | transition: opacity 0.25s ease-in-out; 282 | white-space: nowrap; 283 | } 284 | .filepond--file-info .filepond--file-info-sub:empty { 285 | display: none; 286 | } 287 | .filepond--file-status { 288 | position: static; 289 | display: flex; 290 | flex-direction: column; 291 | align-items: flex-end; 292 | flex-grow: 0; 293 | flex-shrink: 0; 294 | 295 | margin: 0; 296 | min-width: 2.25em; 297 | text-align: right; 298 | 299 | /* will be animated */ 300 | will-change: transform, opacity; 301 | 302 | /* can't do anything with this info */ 303 | pointer-events: none; 304 | -webkit-user-select: none; 305 | -moz-user-select: none; 306 | -ms-user-select: none; 307 | user-select: none; 308 | 309 | /* no margins on children */ 310 | } 311 | .filepond--file-status * { 312 | margin: 0; 313 | white-space: nowrap; 314 | } 315 | .filepond--file-status { 316 | /* font sizes */ 317 | } 318 | .filepond--file-status .filepond--file-status-main { 319 | font-size: 0.75em; 320 | line-height: 1.2; 321 | } 322 | .filepond--file-status .filepond--file-status-sub { 323 | font-size: 0.625em; 324 | opacity: 0.5; 325 | transition: opacity 0.25s ease-in-out; 326 | } 327 | /* Hard to override styles */ 328 | .filepond--file-wrapper.filepond--file-wrapper { 329 | border: none; 330 | margin: 0; 331 | padding: 0; 332 | min-width: 0; 333 | height: 100%; 334 | 335 | /* hide legend for visual users */ 336 | } 337 | .filepond--file-wrapper.filepond--file-wrapper > legend { 338 | position: absolute; 339 | overflow: hidden; 340 | height: 1px; 341 | width: 1px; 342 | padding: 0; 343 | border: 0; 344 | clip: rect(1px, 1px, 1px, 1px); 345 | -webkit-clip-path: inset(50%); 346 | clip-path: inset(50%); 347 | white-space: nowrap; 348 | } 349 | .filepond--file { 350 | position: static; 351 | display: flex; 352 | height: 100%; 353 | align-items: flex-start; 354 | 355 | padding: 0.5625em 0.5625em; 356 | 357 | color: #fff; 358 | border-radius: 0.5em; 359 | 360 | /* control positions */ 361 | } 362 | .filepond--file .filepond--file-status { 363 | margin-left: auto; 364 | margin-right: 2.25em; 365 | } 366 | .filepond--file .filepond--processing-complete-indicator { 367 | pointer-events: none; 368 | -webkit-user-select: none; 369 | -moz-user-select: none; 370 | -ms-user-select: none; 371 | user-select: none; 372 | z-index: 3; 373 | } 374 | .filepond--file .filepond--processing-complete-indicator, 375 | .filepond--file .filepond--progress-indicator, 376 | .filepond--file .filepond--file-action-button { 377 | position: absolute; 378 | } 379 | .filepond--file { 380 | /* .filepond--file-action-button */ 381 | } 382 | .filepond--file [data-align*='left'] { 383 | left: 0.5625em; 384 | } 385 | .filepond--file [data-align*='right'] { 386 | right: 0.5625em; 387 | } 388 | .filepond--file [data-align*='center'] { 389 | left: calc(50% - 0.8125em); /* .8125 is half of button width */ 390 | } 391 | .filepond--file [data-align*='bottom'] { 392 | bottom: 1.125em; 393 | } 394 | .filepond--file [data-align='center'] { 395 | top: calc(50% - 0.8125em); 396 | } 397 | .filepond--file .filepond--progress-indicator { 398 | margin-top: 0.1875em; 399 | } 400 | .filepond--file .filepond--progress-indicator[data-align*='right'] { 401 | margin-right: 0.1875em; 402 | } 403 | .filepond--file .filepond--progress-indicator[data-align*='left'] { 404 | margin-left: 0.1875em; 405 | } 406 | /* make sure text does not overlap */ 407 | [data-filepond-item-state='cancelled'] .filepond--file-info, 408 | [data-filepond-item-state*='invalid'] .filepond--file-info, 409 | [data-filepond-item-state*='error'] .filepond--file-info { 410 | margin-right: 2.25em; 411 | } 412 | [data-filepond-item-state~='processing'] .filepond--file-status-sub { 413 | opacity: 0; 414 | } 415 | [data-filepond-item-state~='processing'] 416 | .filepond--action-abort-item-processing 417 | ~ .filepond--file-status 418 | .filepond--file-status-sub { 419 | opacity: 0.5; 420 | } 421 | [data-filepond-item-state='processing-error'] .filepond--file-status-sub { 422 | opacity: 0; 423 | } 424 | [data-filepond-item-state='processing-error'] 425 | .filepond--action-retry-item-processing 426 | ~ .filepond--file-status 427 | .filepond--file-status-sub { 428 | opacity: 0.5; 429 | } 430 | [data-filepond-item-state='processing-complete'] { 431 | /* busy state */ 432 | } 433 | [data-filepond-item-state='processing-complete'] .filepond--action-revert-item-processing svg { 434 | -webkit-animation: fall 0.5s 0.125s linear both; 435 | animation: fall 0.5s 0.125s linear both; 436 | } 437 | [data-filepond-item-state='processing-complete'] { 438 | /* hide details by default, only show when can revert */ 439 | } 440 | [data-filepond-item-state='processing-complete'] .filepond--file-status-sub { 441 | opacity: 0.5; 442 | } 443 | [data-filepond-item-state='processing-complete'] 444 | .filepond--processing-complete-indicator:not([style*='hidden']) 445 | ~ .filepond--file-status 446 | .filepond--file-status-sub { 447 | opacity: 0; 448 | } 449 | [data-filepond-item-state='processing-complete'] .filepond--file-info-sub { 450 | opacity: 0; 451 | } 452 | [data-filepond-item-state='processing-complete'] 453 | .filepond--action-revert-item-processing 454 | ~ .filepond--file-info 455 | .filepond--file-info-sub { 456 | opacity: 0.5; 457 | } 458 | /* file state can be invalid or error, both are visually similar but */ 459 | /* having them as separate states might be useful */ 460 | [data-filepond-item-state*='invalid'] .filepond--panel, 461 | [data-filepond-item-state*='invalid'] .filepond--file-wrapper, 462 | [data-filepond-item-state*='error'] .filepond--panel, 463 | [data-filepond-item-state*='error'] .filepond--file-wrapper { 464 | -webkit-animation: shake 0.65s linear both; 465 | animation: shake 0.65s linear both; 466 | } 467 | /* spins progress indicator when file is marked as busy */ 468 | [data-filepond-item-state*='busy'] .filepond--progress-indicator svg { 469 | -webkit-animation: spin 1s linear infinite; 470 | animation: spin 1s linear infinite; 471 | } 472 | /** 473 | * States 474 | */ 475 | @-webkit-keyframes spin { 476 | 0% { 477 | -webkit-transform: rotateZ(0deg); 478 | transform: rotateZ(0deg); 479 | } 480 | 481 | 100% { 482 | -webkit-transform: rotateZ(360deg); 483 | transform: rotateZ(360deg); 484 | } 485 | } 486 | @keyframes spin { 487 | 0% { 488 | -webkit-transform: rotateZ(0deg); 489 | transform: rotateZ(0deg); 490 | } 491 | 492 | 100% { 493 | -webkit-transform: rotateZ(360deg); 494 | transform: rotateZ(360deg); 495 | } 496 | } 497 | @-webkit-keyframes shake { 498 | 10%, 499 | 90% { 500 | -webkit-transform: translateX(-0.0625em); 501 | transform: translateX(-0.0625em); 502 | } 503 | 504 | 20%, 505 | 80% { 506 | -webkit-transform: translateX(0.125em); 507 | transform: translateX(0.125em); 508 | } 509 | 510 | 30%, 511 | 50%, 512 | 70% { 513 | -webkit-transform: translateX(-0.25em); 514 | transform: translateX(-0.25em); 515 | } 516 | 517 | 40%, 518 | 60% { 519 | -webkit-transform: translateX(0.25em); 520 | transform: translateX(0.25em); 521 | } 522 | } 523 | @keyframes shake { 524 | 10%, 525 | 90% { 526 | -webkit-transform: translateX(-0.0625em); 527 | transform: translateX(-0.0625em); 528 | } 529 | 530 | 20%, 531 | 80% { 532 | -webkit-transform: translateX(0.125em); 533 | transform: translateX(0.125em); 534 | } 535 | 536 | 30%, 537 | 50%, 538 | 70% { 539 | -webkit-transform: translateX(-0.25em); 540 | transform: translateX(-0.25em); 541 | } 542 | 543 | 40%, 544 | 60% { 545 | -webkit-transform: translateX(0.25em); 546 | transform: translateX(0.25em); 547 | } 548 | } 549 | @-webkit-keyframes fall { 550 | 0% { 551 | opacity: 0; 552 | -webkit-transform: scale(0.5); 553 | transform: scale(0.5); 554 | -webkit-animation-timing-function: ease-out; 555 | animation-timing-function: ease-out; 556 | } 557 | 558 | 70% { 559 | opacity: 1; 560 | -webkit-transform: scale(1.1); 561 | transform: scale(1.1); 562 | -webkit-animation-timing-function: ease-in-out; 563 | animation-timing-function: ease-in-out; 564 | } 565 | 566 | 100% { 567 | -webkit-transform: scale(1); 568 | transform: scale(1); 569 | -webkit-animation-timing-function: ease-out; 570 | animation-timing-function: ease-out; 571 | } 572 | } 573 | @keyframes fall { 574 | 0% { 575 | opacity: 0; 576 | -webkit-transform: scale(0.5); 577 | transform: scale(0.5); 578 | -webkit-animation-timing-function: ease-out; 579 | animation-timing-function: ease-out; 580 | } 581 | 582 | 70% { 583 | opacity: 1; 584 | -webkit-transform: scale(1.1); 585 | transform: scale(1.1); 586 | -webkit-animation-timing-function: ease-in-out; 587 | animation-timing-function: ease-in-out; 588 | } 589 | 590 | 100% { 591 | -webkit-transform: scale(1); 592 | transform: scale(1); 593 | -webkit-animation-timing-function: ease-out; 594 | animation-timing-function: ease-out; 595 | } 596 | } 597 | /* ignore all other interaction elements while dragging a file */ 598 | .filepond--hopper[data-hopper-state='drag-over'] > * { 599 | pointer-events: none; 600 | } 601 | /* capture all hit tests using a hidden layer, this speeds up the event flow */ 602 | .filepond--hopper[data-hopper-state='drag-over']::after { 603 | content: ''; 604 | position: absolute; 605 | left: 0; 606 | top: 0; 607 | right: 0; 608 | bottom: 0; 609 | z-index: 100; 610 | } 611 | .filepond--progress-indicator { 612 | z-index: 103; 613 | } 614 | .filepond--file-action-button { 615 | z-index: 102; 616 | } 617 | .filepond--file-status { 618 | z-index: 101; 619 | } 620 | .filepond--file-info { 621 | z-index: 100; 622 | } 623 | .filepond--item { 624 | position: absolute; 625 | top: 0; 626 | left: 0; 627 | right: 0; 628 | z-index: 1; 629 | 630 | padding: 0; 631 | margin: 0.25em; 632 | 633 | will-change: transform, opacity; 634 | 635 | /* item children order */ 636 | } 637 | .filepond--item > .filepond--panel { 638 | z-index: -1; 639 | } 640 | /* has a slight shadow */ 641 | .filepond--item > .filepond--panel .filepond--panel-bottom { 642 | box-shadow: 0 0.0625em 0.125em -0.0625em rgba(0, 0, 0, 0.25); 643 | } 644 | .filepond--item { 645 | /* drag related */ 646 | } 647 | .filepond--item > .filepond--file-wrapper, 648 | .filepond--item > .filepond--panel { 649 | transition: opacity 0.15s ease-out; 650 | } 651 | .filepond--item[data-drag-state] { 652 | cursor: -webkit-grab; 653 | cursor: grab; 654 | } 655 | .filepond--item[data-drag-state] > .filepond--panel { 656 | transition: box-shadow 0.125s ease-in-out; 657 | box-shadow: 0 0 0 rgba(0, 0, 0, 0); 658 | } 659 | .filepond--item[data-drag-state='drag'] { 660 | cursor: -webkit-grabbing; 661 | cursor: grabbing; 662 | } 663 | .filepond--item[data-drag-state='drag'] > .filepond--panel { 664 | box-shadow: 0 0.125em 0.3125em rgba(0, 0, 0, 0.325); 665 | } 666 | .filepond--item[data-drag-state]:not([data-drag-state='idle']) { 667 | z-index: 2; 668 | } 669 | /* states */ 670 | .filepond--item-panel { 671 | background-color: #64605e; 672 | } 673 | [data-filepond-item-state='processing-complete'] .filepond--item-panel { 674 | background-color: #369763; 675 | } 676 | [data-filepond-item-state*='invalid'] .filepond--item-panel, 677 | [data-filepond-item-state*='error'] .filepond--item-panel { 678 | background-color: #c44e47; 679 | } 680 | /* style of item panel */ 681 | .filepond--item-panel { 682 | border-radius: 0.5em; 683 | transition: background-color 0.25s; 684 | } 685 | /* normal mode */ 686 | .filepond--list-scroller { 687 | position: absolute; 688 | top: 0; 689 | left: 0; 690 | right: 0; 691 | margin: 0; 692 | will-change: transform; 693 | } 694 | /* scroll mode */ 695 | .filepond--list-scroller[data-state='overflow'] .filepond--list { 696 | bottom: 0; 697 | right: 0; 698 | } 699 | .filepond--list-scroller[data-state='overflow'] { 700 | overflow-y: scroll; 701 | overflow-x: hidden; 702 | -webkit-overflow-scrolling: touch; 703 | -webkit-mask: linear-gradient(to bottom, #000 calc(100% - 0.5em), transparent 100%); 704 | mask: linear-gradient(to bottom, #000 calc(100% - 0.5em), transparent 100%); 705 | } 706 | /* style scrollbar */ 707 | .filepond--list-scroller::-webkit-scrollbar { 708 | background: transparent; 709 | } 710 | .filepond--list-scroller::-webkit-scrollbar:vertical { 711 | width: 1em; 712 | } 713 | .filepond--list-scroller::-webkit-scrollbar:horizontal { 714 | height: 0; 715 | } 716 | .filepond--list-scroller::-webkit-scrollbar-thumb { 717 | background-color: rgba(0, 0, 0, 0.3); 718 | border-radius: 99999px; 719 | border: 0.3125em solid transparent; 720 | background-clip: content-box; 721 | } 722 | /* hard to overide styles on purpose */ 723 | .filepond--list.filepond--list { 724 | position: absolute; 725 | top: 0; 726 | margin: 0; 727 | padding: 0; 728 | list-style-type: none; 729 | 730 | /* prevents endless paint calls on filepond--list-scroller */ 731 | will-change: transform; 732 | } 733 | /* used for padding so allowed to be restyled */ 734 | .filepond--list { 735 | left: 0.75em; 736 | right: 0.75em; 737 | } 738 | .filepond--root[data-style-panel-layout~='integrated'] { 739 | width: 100%; 740 | height: 100%; 741 | max-width: none; 742 | margin: 0; 743 | } 744 | .filepond--root[data-style-panel-layout~='circle'] .filepond--panel-root, 745 | .filepond--root[data-style-panel-layout~='integrated'] .filepond--panel-root { 746 | border-radius: 0; 747 | } 748 | .filepond--root[data-style-panel-layout~='circle'] .filepond--panel-root > *, 749 | .filepond--root[data-style-panel-layout~='integrated'] .filepond--panel-root > * { 750 | display: none; 751 | } 752 | .filepond--root[data-style-panel-layout~='circle'] .filepond--drop-label, 753 | .filepond--root[data-style-panel-layout~='integrated'] .filepond--drop-label { 754 | bottom: 0; 755 | height: auto; 756 | display: flex; 757 | justify-content: center; 758 | align-items: center; 759 | z-index: 7; 760 | } 761 | .filepond--root[data-style-panel-layout~='circle'], 762 | .filepond--root[data-style-panel-layout~='integrated'] { 763 | /* we're only loading one item, this makes the intro animation a bit nicer */ 764 | } 765 | .filepond--root[data-style-panel-layout~='circle'] .filepond--item-panel, 766 | .filepond--root[data-style-panel-layout~='integrated'] .filepond--item-panel { 767 | display: none; 768 | } 769 | .filepond--root[data-style-panel-layout~='compact'] .filepond--list-scroller, 770 | .filepond--root[data-style-panel-layout~='integrated'] .filepond--list-scroller { 771 | overflow: hidden; 772 | height: 100%; 773 | margin-top: 0; 774 | margin-bottom: 0; 775 | } 776 | .filepond--root[data-style-panel-layout~='compact'] .filepond--list, 777 | .filepond--root[data-style-panel-layout~='integrated'] .filepond--list { 778 | left: 0; 779 | right: 0; 780 | height: 100%; 781 | } 782 | .filepond--root[data-style-panel-layout~='compact'] .filepond--item, 783 | .filepond--root[data-style-panel-layout~='integrated'] .filepond--item { 784 | margin: 0; 785 | } 786 | .filepond--root[data-style-panel-layout~='compact'] .filepond--file-wrapper, 787 | .filepond--root[data-style-panel-layout~='integrated'] .filepond--file-wrapper { 788 | height: 100%; 789 | } 790 | .filepond--root[data-style-panel-layout~='compact'] .filepond--drop-label, 791 | .filepond--root[data-style-panel-layout~='integrated'] .filepond--drop-label { 792 | z-index: 7; 793 | } 794 | .filepond--root[data-style-panel-layout~='circle'] { 795 | border-radius: 99999rem; 796 | overflow: hidden; 797 | } 798 | .filepond--root[data-style-panel-layout~='circle'] > .filepond--panel { 799 | border-radius: inherit; 800 | } 801 | .filepond--root[data-style-panel-layout~='circle'] > .filepond--panel > * { 802 | display: none; 803 | } 804 | .filepond--root[data-style-panel-layout~='circle'] { 805 | /* circle cuts of this info, so best to hide it */ 806 | } 807 | .filepond--root[data-style-panel-layout~='circle'] .filepond--file-info { 808 | display: none; 809 | } 810 | .filepond--root[data-style-panel-layout~='circle'] .filepond--file-status { 811 | display: none; 812 | } 813 | .filepond--root[data-style-panel-layout~='circle'] .filepond--action-edit-item { 814 | opacity: 1 !important; 815 | visibility: visible !important; 816 | } 817 | /* dirfty way to fix circular overflow issue on safari 11+ */ 818 | @media not all and (min-resolution: 0.001dpcm) { 819 | @supports (-webkit-appearance: none) and (stroke-color: transparent) { 820 | .filepond--root[data-style-panel-layout~='circle'] { 821 | will-change: transform; 822 | } 823 | } 824 | } 825 | .filepond--panel-root { 826 | border-radius: 0.5em; 827 | background-color: #f1f0ef; 828 | } 829 | .filepond--panel { 830 | position: absolute; 831 | left: 0; 832 | top: 0; 833 | right: 0; 834 | margin: 0; 835 | 836 | /* defaults to 100% height (fixed height mode) this fixes problem with panel height in IE11 */ 837 | height: 100% !important; 838 | 839 | /* no interaction possible with panel */ 840 | pointer-events: none; 841 | } 842 | .filepond-panel:not([data-scalable='false']) { 843 | height: auto !important; 844 | } 845 | .filepond--panel[data-scalable='false'] > div { 846 | display: none; 847 | } 848 | .filepond--panel[data-scalable='true'] { 849 | /* this seems to fix Chrome performance issues */ 850 | /* - when box-shadow is enabled */ 851 | /* - when multiple ponds are active on the same page */ 852 | -webkit-transform-style: preserve-3d; 853 | transform-style: preserve-3d; 854 | 855 | /* prevent borders and backgrounds */ 856 | background-color: transparent !important; 857 | border: none !important; 858 | } 859 | .filepond--panel-top, 860 | .filepond--panel-bottom, 861 | .filepond--panel-center { 862 | position: absolute; 863 | left: 0; 864 | top: 0; 865 | right: 0; 866 | margin: 0; 867 | padding: 0; 868 | } 869 | .filepond--panel-top, 870 | .filepond--panel-bottom { 871 | height: 0.5em; 872 | } 873 | .filepond--panel-top { 874 | border-bottom-left-radius: 0 !important; 875 | border-bottom-right-radius: 0 !important; 876 | border-bottom: none !important; 877 | 878 | /* fixes tiny transparant line between top and center panel */ 879 | } 880 | .filepond--panel-top::after { 881 | content: ''; 882 | position: absolute; 883 | height: 2px; 884 | left: 0; 885 | right: 0; 886 | bottom: -1px; 887 | background-color: inherit; 888 | } 889 | .filepond--panel-center, 890 | .filepond--panel-bottom { 891 | will-change: transform; 892 | -webkit-backface-visibility: hidden; 893 | backface-visibility: hidden; 894 | -webkit-transform-origin: left top; 895 | transform-origin: left top; 896 | -webkit-transform: translate3d(0, 0.5em, 0); 897 | transform: translate3d(0, 0.5em, 0); 898 | } 899 | .filepond--panel-bottom { 900 | border-top-left-radius: 0 !important; 901 | border-top-right-radius: 0 !important; 902 | border-top: none !important; 903 | 904 | /* fixes tiny transparant line between bottom and center of panel */ 905 | } 906 | .filepond--panel-bottom::before { 907 | content: ''; 908 | position: absolute; 909 | height: 2px; 910 | left: 0; 911 | right: 0; 912 | top: -1px; 913 | background-color: inherit; 914 | } 915 | .filepond--panel-center { 916 | /* the center panel is scaled using scale3d to fit the correct height */ 917 | /* we use 100px instead of 1px as scaling 1px to a huge height is really laggy on chrome */ 918 | height: 100px !important; 919 | border-top: none !important; 920 | border-bottom: none !important; 921 | border-radius: 0 !important; 922 | 923 | /* hide if not transformed, prevents a little flash when the panel is at 100px height while attached for first time */ 924 | } 925 | .filepond--panel-center:not([style]) { 926 | visibility: hidden; 927 | } 928 | .filepond--progress-indicator { 929 | position: static; 930 | width: 1.25em; 931 | height: 1.25em; 932 | 933 | color: #fff; 934 | 935 | /* can't have margins */ 936 | margin: 0; 937 | 938 | /* no interaction possible with progress indicator */ 939 | pointer-events: none; 940 | 941 | /* will be animated */ 942 | will-change: transform, opacity; 943 | } 944 | .filepond--progress-indicator svg { 945 | width: 100%; 946 | height: 100%; 947 | vertical-align: top; 948 | transform-box: fill-box; /* should center the animation correctly when zoomed in */ 949 | } 950 | .filepond--progress-indicator path { 951 | fill: none; 952 | stroke: currentColor; 953 | } 954 | .filepond--list-scroller { 955 | z-index: 6; 956 | } 957 | .filepond--drop-label { 958 | z-index: 5; 959 | } 960 | .filepond--drip { 961 | z-index: 3; 962 | } 963 | .filepond--root > .filepond--panel { 964 | z-index: 2; 965 | } 966 | .filepond--browser { 967 | z-index: 1; 968 | } 969 | .filepond--root { 970 | /* layout*/ 971 | box-sizing: border-box; 972 | position: relative; 973 | margin-bottom: 1em; 974 | 975 | /* base font size for whole component */ 976 | font-size: 1rem; 977 | 978 | /* base line height */ 979 | line-height: normal; 980 | 981 | /* up uses default system font family */ 982 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 983 | 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; 984 | 985 | /* will increase font weight a bit on Safari */ 986 | font-weight: 450; 987 | 988 | /* default text alignment */ 989 | text-align: left; 990 | 991 | /* better text rendering on Safari */ 992 | text-rendering: optimizeLegibility; 993 | 994 | /* text direction is ltr for now */ 995 | direction: ltr; 996 | 997 | /* optimize rendering */ 998 | /* https://developer.mozilla.org/en-US/docs/Web/CSS/contain */ 999 | contain: layout style size; 1000 | 1001 | /* correct box sizing, line-height and positioning on child elements */ 1002 | } 1003 | .filepond--root * { 1004 | box-sizing: inherit; 1005 | line-height: inherit; 1006 | } 1007 | .filepond--root *:not(text) { 1008 | font-size: inherit; 1009 | } 1010 | .filepond--root { 1011 | /* block everything */ 1012 | } 1013 | .filepond--root[data-disabled] { 1014 | pointer-events: none; 1015 | } 1016 | .filepond--root[data-disabled] .filepond--list-scroller { 1017 | pointer-events: all; 1018 | } 1019 | .filepond--root[data-disabled] .filepond--list { 1020 | pointer-events: none; 1021 | } 1022 | /** 1023 | * Root element children layout 1024 | */ 1025 | .filepond--root .filepond--drop-label { 1026 | min-height: 4.75em; 1027 | } 1028 | .filepond--root .filepond--list-scroller { 1029 | margin-top: 1em; 1030 | margin-bottom: 1em; 1031 | } 1032 | .filepond--root .filepond--credits { 1033 | position: absolute; 1034 | right: 0; 1035 | opacity: 0.175; 1036 | line-height: 0.85; 1037 | font-size: 11px; 1038 | color: inherit; 1039 | text-decoration: none; 1040 | z-index: 3; 1041 | bottom: -14px; 1042 | } 1043 | .filepond--root .filepond--credits[style] { 1044 | top: 0; 1045 | bottom: auto; 1046 | margin-top: 14px; 1047 | } -------------------------------------------------------------------------------- /app/static/css/index.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "Mukta"; 3 | src: url("../fonts/Mukta/Mukta-Regular.ttf"); 4 | } 5 | 6 | @font-face { 7 | font-family: "Mukta-Bold"; 8 | src: url("../fonts/Mukta/Mukta-Bold.ttf"); 9 | } 10 | 11 | html { 12 | background-color: #dff8fe; 13 | font-size: 16px; 14 | font-family: 15 | "Mukta", 16 | -apple-system, 17 | BlinkMacSystemFont, 18 | "Segoe UI", 19 | Roboto, 20 | Helvetica, 21 | Arial, 22 | sans-serif, 23 | "Apple Color Emoji", 24 | "Segoe UI Emoji", 25 | "Segoe UI Symbol"; 26 | min-height: 100%; 27 | height: auto; 28 | overflow: auto; 29 | } 30 | 31 | body { 32 | width: 100%; 33 | margin: 0; 34 | } 35 | 36 | a { 37 | text-decoration: none; 38 | color: #277999; 39 | } 40 | 41 | hr { 42 | display: block; 43 | height: 1px; 44 | margin-top: 2rem; 45 | padding: 0; 46 | border: 0; 47 | border-top: 1px solid #277999; 48 | width: 100%; 49 | color: #277999; 50 | } 51 | 52 | .main { 53 | margin: 0 auto; 54 | max-width: 60%; 55 | display: block; 56 | } 57 | 58 | .title { 59 | font-size: 3rem; 60 | font-family: 61 | "Mukta-Bold", 62 | "Mukta", 63 | -apple-system, 64 | BlinkMacSystemFont, 65 | "Segoe UI", 66 | Roboto, 67 | Helvetica, 68 | Arial, 69 | sans-serif, 70 | "Apple Color Emoji", 71 | "Segoe UI Emoji", 72 | "Segoe UI Symbol"; 73 | margin-top: 1rem; 74 | margin-bottom: 0.2rem; 75 | line-height: 1.2; 76 | } 77 | 78 | .logo { 79 | width: 2.5rem; 80 | height: 2.5rem; 81 | } 82 | 83 | .sentence { 84 | font-size: 1.2rem; 85 | line-height: 1.7; 86 | overflow: visible; 87 | display: block; 88 | } 89 | 90 | .desc { 91 | font-size: 1.2rem; 92 | margin-top: 0.5rem; 93 | } 94 | 95 | .footnote { 96 | font-size: 1rem; 97 | margin-top: 0.5rem; 98 | line-height: 1.5; 99 | } 100 | 101 | .click-to-copy { 102 | cursor: pointer; 103 | transition: transform ease-in 0.1s; 104 | } 105 | 106 | .click-to-copy:hover { 107 | transform: scale(0.98); 108 | } 109 | 110 | .step { 111 | margin-top: 2rem; 112 | font-size: 1.2rem; 113 | display: block; 114 | position: relative; 115 | } 116 | 117 | .number { 118 | font-size: 3rem; 119 | font-family: 120 | "Mukta-Bold", 121 | "Mukta", 122 | -apple-system, 123 | BlinkMacSystemFont, 124 | "Segoe UI", 125 | Roboto, 126 | Helvetica, 127 | Arial, 128 | sans-serif, 129 | "Apple Color Emoji", 130 | "Segoe UI Emoji", 131 | "Segoe UI Symbol"; 132 | line-height: 1; 133 | float: left; 134 | } 135 | 136 | .content { 137 | margin-left: 3rem; 138 | } 139 | 140 | .notification { 141 | font-size: 1rem; 142 | color: #3c7390; 143 | display: none; 144 | } 145 | 146 | .warning { 147 | color: coral; 148 | } 149 | 150 | .success { 151 | color: #529467; 152 | } 153 | 154 | .error { 155 | color: #dd685c; 156 | } 157 | 158 | .highlight { 159 | background-color: #3c7390; 160 | background-color: #d2ebf1; 161 | color: currentColor; 162 | -webkit-border-radius: 0.1rem; 163 | -moz-border-radius: 0.1rem; 164 | border-radius: 0.3em; 165 | padding-left: 0.3em; 166 | padding-right: 0.3em; 167 | } 168 | 169 | #email { 170 | -webkit-box-sizing: border-box; 171 | -moz-box-sizing: border-box; 172 | box-sizing: border-box; 173 | outline: none; 174 | font-size: 1.2rem; 175 | background: transparent; 176 | border: none; 177 | color: #41c7fb; 178 | font-family: 179 | "Mukta", 180 | -apple-system, 181 | BlinkMacSystemFont, 182 | "Segoe UI", 183 | Roboto, 184 | Helvetica, 185 | Arial, 186 | sans-serif, 187 | "Apple Color Emoji", 188 | "Segoe UI Emoji", 189 | "Segoe UI Symbol"; 190 | line-height: 1; 191 | width: 100%; 192 | } 193 | 194 | ::placeholder { 195 | color: #41c7fb; 196 | opacity: 0.5; 197 | } 198 | 199 | #push-button { 200 | margin-right: 0; 201 | background: #3f7896; 202 | font-size: 1.2rem; 203 | 204 | /* overflow: hidden; */ 205 | padding-top: 1rem; 206 | padding-bottom: 1rem; 207 | width: 100%; 208 | outline: none; 209 | border: none; 210 | border-radius: 0.5rem; 211 | cursor: pointer; 212 | transition: transform ease-in 0.1s, box-shadow ease-in 0.25s; 213 | font-family: 214 | "Mukta", 215 | -apple-system, 216 | BlinkMacSystemFont, 217 | "Segoe UI", 218 | Roboto, 219 | Helvetica, 220 | Arial, 221 | sans-serif, 222 | "Apple Color Emoji", 223 | "Segoe UI Emoji", 224 | "Segoe UI Symbol"; 225 | opacity: 1; 226 | } 227 | 228 | #push-button:active { 229 | opacity: 1; 230 | transform: scale(0.98); 231 | background: #3c7390; 232 | } 233 | 234 | #push-button:disabled { 235 | color: black; 236 | } 237 | 238 | /* filepond style */ 239 | .filepond--root { 240 | font-family: 241 | "Mukta", 242 | -apple-system, 243 | BlinkMacSystemFont, 244 | "Segoe UI", 245 | Roboto, 246 | Helvetica, 247 | Arial, 248 | sans-serif, 249 | "Apple Color Emoji", 250 | "Segoe UI Emoji", 251 | "Segoe UI Symbol"; 252 | font-size: 1.2rem; 253 | margin-bottom: 0; 254 | margin-right: 0; 255 | } 256 | 257 | .filepond--panel-root { 258 | background-color: #41c7fb; 259 | } 260 | 261 | .filepond--drop-label { 262 | color: black; 263 | } 264 | 265 | .filepond--item-panel { 266 | background-color: #277999; 267 | } 268 | 269 | .filepond--file-action-button { 270 | background-color: #3f7896; 271 | color: black; 272 | } 273 | 274 | .site-info { 275 | color: #277999; 276 | text-align: center; 277 | margin-top: 1.5rem; 278 | margin-bottom: 1.5rem; 279 | } 280 | 281 | @media screen and (max-width: 600px) { 282 | html { 283 | font-size: 14px; 284 | } 285 | 286 | .main { 287 | max-width: 90%; 288 | } 289 | 290 | .title { 291 | font-size: 2.5rem; 292 | } 293 | } 294 | 295 | @media screen and (max-width: 350px) { 296 | html { 297 | font-size: 14px; 298 | } 299 | 300 | .main { 301 | max-width: 90%; 302 | } 303 | 304 | .title { 305 | font-size: 2.2rem; 306 | } 307 | 308 | .sentence, 309 | #email, 310 | #push-button { 311 | font-size: 1.2rem; 312 | } 313 | 314 | .content { 315 | margin-left: 2rem; 316 | } 317 | } 318 | -------------------------------------------------------------------------------- /app/static/fonts/Mukta/Mukta-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aneureka/push-to-kindle/791dbc70827ee0da6ba8490bceb6e236f7be1064/app/static/fonts/Mukta/Mukta-Bold.ttf -------------------------------------------------------------------------------- /app/static/fonts/Mukta/Mukta-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aneureka/push-to-kindle/791dbc70827ee0da6ba8490bceb6e236f7be1064/app/static/fonts/Mukta/Mukta-Regular.ttf -------------------------------------------------------------------------------- /app/static/images/icons/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aneureka/push-to-kindle/791dbc70827ee0da6ba8490bceb6e236f7be1064/app/static/images/icons/favicon.png -------------------------------------------------------------------------------- /app/static/js/filepond-plugin-file-validate-size.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * FilePondPluginFileValidateSize 2.2.4 3 | * Licensed under MIT, https://opensource.org/licenses/MIT/ 4 | * Please visit https://pqina.nl/filepond/ for details. 5 | */ 6 | 7 | /* eslint-disable */ 8 | 9 | (function(global, factory) { 10 | typeof exports === 'object' && typeof module !== 'undefined' 11 | ? (module.exports = factory()) 12 | : typeof define === 'function' && define.amd 13 | ? define(factory) 14 | : ((global = global || self), (global.FilePondPluginFileValidateSize = factory())); 15 | })(this, function() { 16 | 'use strict'; 17 | 18 | var plugin = function plugin(_ref) { 19 | var addFilter = _ref.addFilter, 20 | utils = _ref.utils; 21 | // get quick reference to Type utils 22 | var Type = utils.Type, 23 | replaceInString = utils.replaceInString, 24 | toNaturalFileSize = utils.toNaturalFileSize; 25 | 26 | // filtering if an item is allowed in hopper 27 | addFilter('ALLOW_HOPPER_ITEM', function(file, _ref2) { 28 | var query = _ref2.query; 29 | if (!query('GET_ALLOW_FILE_SIZE_VALIDATION')) { 30 | return true; 31 | } 32 | 33 | var sizeMax = query('GET_MAX_FILE_SIZE'); 34 | if (sizeMax !== null && file.size >= sizeMax) { 35 | return false; 36 | } 37 | 38 | var sizeMin = query('GET_MIN_FILE_SIZE'); 39 | if (sizeMin !== null && file.size <= sizeMin) { 40 | return false; 41 | } 42 | 43 | return true; 44 | }); 45 | 46 | // called for each file that is loaded 47 | // right before it is set to the item state 48 | // should return a promise 49 | addFilter('LOAD_FILE', function(file, _ref3) { 50 | var query = _ref3.query; 51 | return new Promise(function(resolve, reject) { 52 | // if not allowed, all fine, exit 53 | if (!query('GET_ALLOW_FILE_SIZE_VALIDATION')) { 54 | return resolve(file); 55 | } 56 | 57 | // check if file should be filtered 58 | var fileFilter = query('GET_FILE_VALIDATE_SIZE_FILTER'); 59 | if (fileFilter && !fileFilter(file)) { 60 | return resolve(file); 61 | } 62 | 63 | // reject or resolve based on file size 64 | var sizeMax = query('GET_MAX_FILE_SIZE'); 65 | if (sizeMax !== null && file.size >= sizeMax) { 66 | reject({ 67 | status: { 68 | main: query('GET_LABEL_MAX_FILE_SIZE_EXCEEDED'), 69 | sub: replaceInString(query('GET_LABEL_MAX_FILE_SIZE'), { 70 | filesize: toNaturalFileSize( 71 | sizeMax, 72 | '.', 73 | query('GET_FILE_SIZE_BASE') 74 | ), 75 | }), 76 | }, 77 | }); 78 | 79 | return; 80 | } 81 | 82 | // reject or resolve based on file size 83 | var sizeMin = query('GET_MIN_FILE_SIZE'); 84 | if (sizeMin !== null && file.size <= sizeMin) { 85 | reject({ 86 | status: { 87 | main: query('GET_LABEL_MIN_FILE_SIZE_EXCEEDED'), 88 | sub: replaceInString(query('GET_LABEL_MIN_FILE_SIZE'), { 89 | filesize: toNaturalFileSize( 90 | sizeMin, 91 | '.', 92 | query('GET_FILE_SIZE_BASE') 93 | ), 94 | }), 95 | }, 96 | }); 97 | 98 | return; 99 | } 100 | 101 | // returns the current option value 102 | var totalSizeMax = query('GET_MAX_TOTAL_FILE_SIZE'); 103 | if (totalSizeMax !== null) { 104 | // get the current total file size 105 | var currentTotalSize = query('GET_ACTIVE_ITEMS').reduce(function(total, item) { 106 | return total + item.fileSize; 107 | }, 0); 108 | 109 | // get the size of the new file 110 | if (currentTotalSize > totalSizeMax) { 111 | reject({ 112 | status: { 113 | main: query('GET_LABEL_MAX_TOTAL_FILE_SIZE_EXCEEDED'), 114 | sub: replaceInString(query('GET_LABEL_MAX_TOTAL_FILE_SIZE'), { 115 | filesize: toNaturalFileSize(totalSizeMax), 116 | }), 117 | }, 118 | }); 119 | 120 | return; 121 | } 122 | } 123 | 124 | // file is fine, let's pass it back 125 | resolve(file); 126 | }); 127 | }); 128 | 129 | return { 130 | options: { 131 | // Enable or disable file type validation 132 | allowFileSizeValidation: [true, Type.BOOLEAN], 133 | 134 | // Max individual file size in bytes 135 | maxFileSize: [null, Type.INT], 136 | 137 | // Min individual file size in bytes 138 | minFileSize: [null, Type.INT], 139 | 140 | // Max total file size in bytes 141 | maxTotalFileSize: [null, Type.INT], 142 | 143 | // Filter the files that need to be validated for size 144 | fileValidateSizeFilter: [null, Type.FUNCTION], 145 | 146 | // error labels 147 | labelMinFileSizeExceeded: ['File is too small', Type.STRING], 148 | labelMinFileSize: ['Minimum file size is {filesize}', Type.STRING], 149 | 150 | labelMaxFileSizeExceeded: ['File is too large', Type.STRING], 151 | labelMaxFileSize: ['Maximum file size is {filesize}', Type.STRING], 152 | 153 | labelMaxTotalFileSizeExceeded: ['Maximum total size exceeded', Type.STRING], 154 | labelMaxTotalFileSize: ['Maximum total file size is {filesize}', Type.STRING], 155 | }, 156 | }; 157 | }; 158 | 159 | // fire pluginloaded event if running in browser, this allows registering the plugin when using async script tags 160 | var isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined'; 161 | if (isBrowser) { 162 | document.dispatchEvent(new CustomEvent('FilePond:pluginloaded', { detail: plugin })); 163 | } 164 | 165 | return plugin; 166 | }); -------------------------------------------------------------------------------- /app/static/js/filepond-plugin-file-validate-type.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * FilePondPluginFileValidateType 1.2.6 3 | * Licensed under MIT, https://opensource.org/licenses/MIT/ 4 | * Please visit https://pqina.nl/filepond/ for details. 5 | */ 6 | 7 | /* eslint-disable */ 8 | 9 | (function(global, factory) { 10 | typeof exports === 'object' && typeof module !== 'undefined' 11 | ? (module.exports = factory()) 12 | : typeof define === 'function' && define.amd 13 | ? define(factory) 14 | : ((global = global || self), 15 | (global.FilePondPluginFileValidateType = factory())); 16 | })(this, function() { 17 | 'use strict'; 18 | 19 | var plugin = function plugin(_ref) { 20 | var addFilter = _ref.addFilter, 21 | utils = _ref.utils; 22 | // get quick reference to Type utils 23 | var Type = utils.Type, 24 | isString = utils.isString, 25 | replaceInString = utils.replaceInString, 26 | guesstimateMimeType = utils.guesstimateMimeType, 27 | getExtensionFromFilename = utils.getExtensionFromFilename, 28 | getFilenameFromURL = utils.getFilenameFromURL; 29 | 30 | var mimeTypeMatchesWildCard = function mimeTypeMatchesWildCard( 31 | mimeType, 32 | wildcard 33 | ) { 34 | var mimeTypeGroup = (/^[^/]+/.exec(mimeType) || []).pop(); // image/png -> image 35 | var wildcardGroup = wildcard.slice(0, -2); // image/* -> image 36 | return mimeTypeGroup === wildcardGroup; 37 | }; 38 | 39 | var isValidMimeType = function isValidMimeType( 40 | acceptedTypes, 41 | userInputType 42 | ) { 43 | return acceptedTypes.some(function(acceptedType) { 44 | // accepted is wildcard mime type 45 | if (/\*$/.test(acceptedType)) { 46 | return mimeTypeMatchesWildCard(userInputType, acceptedType); 47 | } 48 | 49 | // is normal mime type 50 | return acceptedType === userInputType; 51 | }); 52 | }; 53 | 54 | var getItemType = function getItemType(item) { 55 | // if the item is a url we guess the mime type by the extension 56 | var type = ''; 57 | if (isString(item)) { 58 | var filename = getFilenameFromURL(item); 59 | var extension = getExtensionFromFilename(filename); 60 | if (extension) { 61 | type = guesstimateMimeType(extension); 62 | } 63 | } else { 64 | type = item.type; 65 | } 66 | 67 | return type; 68 | }; 69 | 70 | var validateFile = function validateFile( 71 | item, 72 | acceptedFileTypes, 73 | typeDetector 74 | ) { 75 | // no types defined, everything is allowed \o/ 76 | if (acceptedFileTypes.length === 0) { 77 | return true; 78 | } 79 | 80 | // gets the item type 81 | var type = getItemType(item); 82 | 83 | // no type detector, test now 84 | if (!typeDetector) { 85 | return isValidMimeType(acceptedFileTypes, type); 86 | } 87 | 88 | // use type detector 89 | return new Promise(function(resolve, reject) { 90 | typeDetector(item, type) 91 | .then(function(detectedType) { 92 | if (isValidMimeType(acceptedFileTypes, detectedType)) { 93 | resolve(); 94 | } else { 95 | reject(); 96 | } 97 | }) 98 | .catch(reject); 99 | }); 100 | }; 101 | 102 | var applyMimeTypeMap = function applyMimeTypeMap(map) { 103 | return function(acceptedFileType) { 104 | return map[acceptedFileType] === null 105 | ? false 106 | : map[acceptedFileType] || acceptedFileType; 107 | }; 108 | }; 109 | 110 | // setup attribute mapping for accept 111 | addFilter('SET_ATTRIBUTE_TO_OPTION_MAP', function(map) { 112 | return Object.assign(map, { 113 | accept: 'acceptedFileTypes' 114 | }); 115 | }); 116 | 117 | // filtering if an item is allowed in hopper 118 | addFilter('ALLOW_HOPPER_ITEM', function(file, _ref2) { 119 | var query = _ref2.query; 120 | // if we are not doing file type validation exit 121 | if (!query('GET_ALLOW_FILE_TYPE_VALIDATION')) { 122 | return true; 123 | } 124 | 125 | // we validate the file against the accepted file types 126 | return validateFile(file, query('GET_ACCEPTED_FILE_TYPES')); 127 | }); 128 | 129 | // called for each file that is loaded 130 | // right before it is set to the item state 131 | // should return a promise 132 | addFilter('LOAD_FILE', function(file, _ref3) { 133 | var query = _ref3.query; 134 | return new Promise(function(resolve, reject) { 135 | if (!query('GET_ALLOW_FILE_TYPE_VALIDATION')) { 136 | resolve(file); 137 | return; 138 | } 139 | 140 | var acceptedFileTypes = query('GET_ACCEPTED_FILE_TYPES'); 141 | 142 | // custom type detector method 143 | var typeDetector = query('GET_FILE_VALIDATE_TYPE_DETECT_TYPE'); 144 | 145 | // if invalid, exit here 146 | var validationResult = validateFile( 147 | file, 148 | acceptedFileTypes, 149 | typeDetector 150 | ); 151 | 152 | var handleRejection = function handleRejection() { 153 | var acceptedFileTypesMapped = acceptedFileTypes 154 | .map( 155 | applyMimeTypeMap( 156 | query('GET_FILE_VALIDATE_TYPE_LABEL_EXPECTED_TYPES_MAP') 157 | ) 158 | ) 159 | .filter(function(label) { 160 | return label !== false; 161 | }); 162 | 163 | reject({ 164 | status: { 165 | main: query('GET_LABEL_FILE_TYPE_NOT_ALLOWED'), 166 | sub: replaceInString( 167 | query('GET_FILE_VALIDATE_TYPE_LABEL_EXPECTED_TYPES'), 168 | { 169 | allTypes: acceptedFileTypesMapped.join(', '), 170 | allButLastType: acceptedFileTypesMapped 171 | .slice(0, -1) 172 | .join(', '), 173 | lastType: 174 | acceptedFileTypesMapped[acceptedFileTypesMapped.length - 1] 175 | } 176 | ) 177 | } 178 | }); 179 | }; 180 | 181 | // has returned new filename immidiately 182 | if (typeof validationResult === 'boolean') { 183 | if (!validationResult) { 184 | return handleRejection(); 185 | } 186 | return resolve(file); 187 | } 188 | 189 | // is promise 190 | validationResult 191 | .then(function() { 192 | resolve(file); 193 | }) 194 | .catch(handleRejection); 195 | }); 196 | }); 197 | 198 | // expose plugin 199 | return { 200 | // default options 201 | options: { 202 | // Enable or disable file type validation 203 | allowFileTypeValidation: [true, Type.BOOLEAN], 204 | 205 | // What file types to accept 206 | acceptedFileTypes: [[], Type.ARRAY], 207 | // - must be comma separated 208 | // - mime types: image/png, image/jpeg, image/gif 209 | // - extensions: .png, .jpg, .jpeg ( not enabled yet ) 210 | // - wildcards: image/* 211 | 212 | // label to show when a type is not allowed 213 | labelFileTypeNotAllowed: ['File is of invalid type', Type.STRING], 214 | 215 | // nicer label 216 | fileValidateTypeLabelExpectedTypes: [ 217 | 'Expects {allButLastType} or {lastType}', 218 | Type.STRING 219 | ], 220 | 221 | // map mime types to extensions 222 | fileValidateTypeLabelExpectedTypesMap: [{}, Type.OBJECT], 223 | 224 | // Custom function to detect type of file 225 | fileValidateTypeDetectType: [null, Type.FUNCTION] 226 | } 227 | }; 228 | }; 229 | 230 | // fire pluginloaded event if running in browser, this allows registering the plugin when using async script tags 231 | var isBrowser = 232 | typeof window !== 'undefined' && typeof window.document !== 'undefined'; 233 | if (isBrowser) { 234 | document.dispatchEvent( 235 | new CustomEvent('FilePond:pluginloaded', { detail: plugin }) 236 | ); 237 | } 238 | 239 | return plugin; 240 | }); -------------------------------------------------------------------------------- /app/static/js/filepond.jquery.js: -------------------------------------------------------------------------------- 1 | (function($, FilePond){ 2 | 'use strict'; 3 | 4 | // No jQuery No Go 5 | if (!$ || !FilePond) { 6 | return; 7 | } 8 | 9 | // Test if FilePond is supported 10 | if (!FilePond.supported()) { 11 | // add stub 12 | $.fn.filepond = function() {}; 13 | return; 14 | } 15 | 16 | // Helpers 17 | function argsToArray(args) { 18 | return Array.prototype.slice.call(args); 19 | } 20 | 21 | function isFactory(args) { 22 | return !args.length || typeof args[0] === 'object'; 23 | } 24 | 25 | function isGetter(obj, key) { 26 | var descriptor = Object.getOwnPropertyDescriptor(obj, key); 27 | return descriptor ? typeof descriptor.get !== 'undefined' : false; 28 | } 29 | 30 | function isSetter(obj, key) { 31 | var descriptor = Object.getOwnPropertyDescriptor(obj, key); 32 | return descriptor ? typeof descriptor.set !== 'undefined' : false; 33 | } 34 | 35 | function isMethod(obj, key) { 36 | return typeof obj[key] === 'function'; 37 | } 38 | 39 | // Setup plugin 40 | $.fn.filepond = function() { 41 | 42 | // get arguments as array 43 | var args = argsToArray(arguments); 44 | 45 | // method results array 46 | var results = []; 47 | 48 | // Execute for every item in the list 49 | var items = this.each(function() { 50 | 51 | // test if is create call 52 | if (isFactory(args)) { 53 | FilePond.create(this, args[0]) 54 | return; 55 | } 56 | 57 | // get a reference to the pond instance based on the element 58 | var pond = FilePond.find(this); 59 | 60 | // if no pond found, exit here 61 | if (!pond) { 62 | return; 63 | } 64 | 65 | // get property name or method name 66 | var key = args[0]; 67 | 68 | // get params to pass 69 | var params = args.concat().slice(1); 70 | 71 | // run method 72 | if (isMethod(pond, key)) { 73 | results.push(pond[key].apply(pond, params)); 74 | return; 75 | } 76 | 77 | // set setter 78 | if (isSetter(pond, key) && params.length) { 79 | pond[key] = params[0]; 80 | return; 81 | } 82 | 83 | // get getter 84 | if (isGetter(pond, key)) { 85 | results.push(pond[key]); 86 | return; 87 | } 88 | 89 | console.warn('$().filepond("' + key + '") is an unknown property or method.'); 90 | }); 91 | 92 | // returns a jQuery object if no results returned 93 | return results.length ? this.length === 1 ? results[0] : results : items; 94 | }; 95 | 96 | // Static API 97 | Object.keys(FilePond).forEach(function(key) { 98 | $.fn.filepond[key] = FilePond[key]; 99 | }); 100 | 101 | // Redirect setDefaults to setOptions 102 | $.fn.filepond.setDefaults = FilePond.setOptions; 103 | 104 | }(jQuery, FilePond)); -------------------------------------------------------------------------------- /app/static/js/filepond.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * FilePond 4.29.1 3 | * Licensed under MIT, https://opensource.org/licenses/MIT/ 4 | * Please visit https://pqina.nl/filepond/ for details. 5 | */ 6 | 7 | /* eslint-disable */ 8 | 9 | !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e=e||self).FilePond={})}(this,function(e){"use strict";var t=function(e,t){for(var n in e)e.hasOwnProperty(n)&&t(n,e[n])},n=function(e){var n={};return t(e,function(t){!function(e,t,n){"function"!=typeof n?Object.defineProperty(e,t,Object.assign({},n)):e[t]=n}(n,t,e[t])}),n},r=function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;if(null===n)return e.getAttribute(t)||e.hasAttribute(t);e.setAttribute(t,n)},o=["svg","path"],i=function(e){return o.includes(e)},a=function(e,n){var o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};"object"==typeof n&&(o=n,n=null);var a=i(e)?document.createElementNS("http://www.w3.org/2000/svg",e):document.createElement(e);return n&&(i(e)?r(a,"class",n):a.className=n),t(o,function(e,t){r(a,e,t)}),a},s=function(e,t){return function(e,n){return void 0!==n?t.splice(n,0,e):t.push(e),e}},u=function(e,t){return function(n){return t.splice(t.indexOf(n),1),n.element.parentNode&&e.removeChild(n.element),n}},l="undefined"!=typeof window&&void 0!==window.document,c=function(){return l},f="children"in(c()?a("svg"):{})?function(e){return e.children.length}:function(e){return e.childNodes.length},d=function(e,t,n,r){var o=n[0]||e.left,i=n[1]||e.top,a=o+e.width,s=i+e.height*(r[1]||1),u={element:Object.assign({},e),inner:{left:e.left,top:e.top,right:e.right,bottom:e.bottom},outer:{left:o,top:i,right:a,bottom:s}};return t.filter(function(e){return!e.isRectIgnored()}).map(function(e){return e.rect}).forEach(function(e){p(u.inner,Object.assign({},e.inner)),p(u.outer,Object.assign({},e.outer))}),E(u.inner),u.outer.bottom+=u.element.marginBottom,u.outer.right+=u.element.marginRight,E(u.outer),u},p=function(e,t){t.top+=e.top,t.right+=e.left,t.bottom+=e.top,t.left+=e.left,t.bottom>e.bottom&&(e.bottom=t.bottom),t.right>e.right&&(e.right=t.right)},E=function(e){e.width=e.right-e.left,e.height=e.bottom-e.top},_=function(e){return"number"==typeof e},T=function(e){return e<.5?2*e*e:(4-2*e)*e-1},I={spring:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.stiffness,r=void 0===t?.5:t,o=e.damping,i=void 0===o?.75:o,a=e.mass,s=void 0===a?10:a,u=null,l=null,c=0,f=!1,d=n({interpolate:function(e,t){if(!f){if(!_(u)||!_(l))return f=!0,void(c=0);(function(e,t,n){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:.001;return Math.abs(e-t)0&&void 0!==arguments[0]?arguments[0]:{},o=r.duration,i=void 0===o?500:o,a=r.easing,s=void 0===a?T:a,u=r.delay,l=void 0===u?0:u,c=null,f=!0,d=!1,p=null,E=n({interpolate:function(n,r){f||null===p||(null===c&&(c=n),n-c=i||r?(e=1,t=d?0:1,E.onupdate(t*p),E.oncomplete(t*p),f=!0):(t=e/i,E.onupdate((e>=0?s(d?1-t:t):0)*p))))},target:{get:function(){return d?0:p},set:function(e){if(null===p)return p=e,E.onupdate(e),void E.oncomplete(e);e3&&void 0!==arguments[3]&&arguments[3];(t=Array.isArray(t)?t:[t]).forEach(function(t){e.forEach(function(e){var o=e,i=function(){return n[e]},a=function(t){return n[e]=t};"object"==typeof e&&(o=e.key,i=e.getter||i,a=e.setter||a),t[o]&&!r||(t[o]={get:i,set:a})})})},h=function(e){return null!=e},g={opacity:1,scaleX:1,scaleY:1,translateX:0,translateY:0,rotateX:0,rotateY:0,rotateZ:0,originX:0,originY:0},R=function(e,t){if(Object.keys(e).length!==Object.keys(t).length)return!0;for(var n in t)if(t[n]!==e[n])return!0;return!1},O=function(e,t){var n=t.opacity,r=t.perspective,o=t.translateX,i=t.translateY,a=t.scaleX,s=t.scaleY,u=t.rotateX,l=t.rotateY,c=t.rotateZ,f=t.originX,d=t.originY,p=t.width,E=t.height,_="",T="";(h(f)||h(d))&&(T+="transform-origin: "+(f||0)+"px "+(d||0)+"px;"),h(r)&&(_+="perspective("+r+"px) "),(h(o)||h(i))&&(_+="translate3d("+(o||0)+"px, "+(i||0)+"px, 0) "),(h(a)||h(s))&&(_+="scale3d("+(h(a)?a:1)+", "+(h(s)?s:1)+", 1) "),h(c)&&(_+="rotateZ("+c+"rad) "),h(u)&&(_+="rotateX("+u+"rad) "),h(l)&&(_+="rotateY("+l+"rad) "),_.length&&(T+="transform:"+_+";"),h(n)&&(T+="opacity:"+n+";",0===n&&(T+="visibility:hidden;"),n<1&&(T+="pointer-events:none;")),h(E)&&(T+="height:"+E+"px;"),h(p)&&(T+="width:"+p+"px;");var I=e.elementCurrentStyle||"";T.length===I.length&&T===I||(e.style.cssText=T,e.elementCurrentStyle=T)},D={styles:function(e){var t=e.mixinConfig,n=e.viewProps,r=e.viewInternalAPI,o=e.viewExternalAPI,i=e.view,a=Object.assign({},n),s={};m(t,[r,o],n);var u=function(){return i.rect?d(i.rect,i.childViews,[n.translateX||0,n.translateY||0],[n.scaleX||0,n.scaleY||0]):null};return r.rect={get:u},o.rect={get:u},t.forEach(function(e){n[e]=void 0===a[e]?g[e]:a[e]}),{write:function(){if(R(s,n))return O(i.element,n),Object.assign(s,Object.assign({},n)),!0},destroy:function(){}}},listeners:function(e){e.mixinConfig,e.viewProps,e.viewInternalAPI;var t,n=e.viewExternalAPI,r=(e.viewState,e.view),o=[],i=(t=r.element,function(e,n){t.addEventListener(e,n)}),a=function(e){return function(t,n){e.removeEventListener(t,n)}}(r.element);return n.on=function(e,t){o.push({type:e,fn:t}),i(e,t)},n.off=function(e,t){o.splice(o.findIndex(function(n){return n.type===e&&n.fn===t}),1),a(e,t)},{write:function(){return!0},destroy:function(){o.forEach(function(e){a(e.type,e.fn)})}}},animations:function(e){var n=e.mixinConfig,r=e.viewProps,o=e.viewInternalAPI,i=e.viewExternalAPI,a=Object.assign({},r),s=[];return t(n,function(e,t){var n=v(t);n&&(n.onupdate=function(t){r[e]=t},n.target=a[e],m([{key:e,setter:function(e){n.target!==e&&(n.target=e)},getter:function(){return r[e]}}],[o,i],r,!0),s.push(n))}),{write:function(e){var t=document.hidden,n=!0;return s.forEach(function(r){r.resting||(n=!1),r.interpolate(e,t)}),n},destroy:function(){}}},apis:function(e){var t=e.mixinConfig,n=e.viewProps,r=e.viewExternalAPI;m(t,r,n)}},y=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return t.layoutCalculated||(e.paddingTop=parseInt(n.paddingTop,10)||0,e.marginTop=parseInt(n.marginTop,10)||0,e.marginRight=parseInt(n.marginRight,10)||0,e.marginBottom=parseInt(n.marginBottom,10)||0,e.marginLeft=parseInt(n.marginLeft,10)||0,t.layoutCalculated=!0),e.left=t.offsetLeft||0,e.top=t.offsetTop||0,e.width=t.offsetWidth||0,e.height=t.offsetHeight||0,e.right=e.left+e.width,e.bottom=e.top+e.height,e.scrollTop=t.scrollTop,e.hidden=null===t.offsetParent,e},S=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.tag,r=void 0===t?"div":t,o=e.name,i=void 0===o?null:o,l=e.attributes,c=void 0===l?{}:l,p=e.read,E=void 0===p?function(){}:p,_=e.write,T=void 0===_?function(){}:_,I=e.create,v=void 0===I?function(){}:I,m=e.destroy,h=void 0===m?function(){}:m,g=e.filterFrameActionsForChild,R=void 0===g?function(e,t){return t}:g,O=e.didCreateView,S=void 0===O?function(){}:O,A=e.didWriteView,L=void 0===A?function(){}:A,P=e.ignoreRect,b=void 0!==P&&P,M=e.ignoreRectUpdate,w=void 0!==M&&M,C=e.mixins,N=void 0===C?[]:C;return function(e){var t,o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},l=a(r,"filepond--"+i,c),p=window.getComputedStyle(l,null),_=y(),I=null,m=!1,g=[],O=[],A={},P={},M=[T],C=[E],G=[h],U=function(){return l},B=function(){return g.concat()},q=function(){return I||(I=d(_,g,[0,0],[1,1]))},F={element:{get:U},style:{get:function(){return p}},childViews:{get:B}},V=Object.assign({},F,{rect:{get:q},ref:{get:function(){return A}},is:function(e){return i===e},appendChild:(t=l,function(e,n){void 0!==n&&t.children[n]?t.insertBefore(e,t.children[n]):t.appendChild(e)}),createChildView:function(e){return function(t,n){return t(e,n)}}(e),linkView:function(e){return g.push(e),e},unlinkView:function(e){g.splice(g.indexOf(e),1)},appendChildView:s(0,g),removeChildView:u(l,g),registerWriter:function(e){return M.push(e)},registerReader:function(e){return C.push(e)},registerDestroyer:function(e){return G.push(e)},invalidateLayout:function(){return l.layoutCalculated=!1},dispatch:e.dispatch,query:e.query}),x={element:{get:U},childViews:{get:B},rect:{get:q},resting:{get:function(){return m}},isRectIgnored:function(){return b},_read:function(){I=null,g.forEach(function(e){return e._read()}),!(w&&_.width&&_.height)&&y(_,l,p);var e={root:k,props:o,rect:_};C.forEach(function(t){return t(e)})},_write:function(e,t,n){var r=0===t.length;return M.forEach(function(i){!1===i({props:o,root:k,actions:t,timestamp:e,shouldOptimize:n})&&(r=!1)}),O.forEach(function(t){!1===t.write(e)&&(r=!1)}),g.filter(function(e){return!!e.element.parentNode}).forEach(function(o){o._write(e,R(o,t),n)||(r=!1)}),g.forEach(function(o,i){o.element.parentNode||(k.appendChild(o.element,i),o._read(),o._write(e,R(o,t),n),r=!1)}),m=r,L({props:o,root:k,actions:t,timestamp:e}),r},_destroy:function(){O.forEach(function(e){return e.destroy()}),G.forEach(function(e){e({root:k,props:o})}),g.forEach(function(e){return e._destroy()})}},Y=Object.assign({},F,{rect:{get:function(){return _}}});Object.keys(N).sort(function(e,t){return"styles"===e?1:"styles"===t?-1:0}).forEach(function(e){var t=D[e]({mixinConfig:N[e],viewProps:o,viewState:P,viewInternalAPI:V,viewExternalAPI:x,view:n(Y)});t&&O.push(t)});var k=n(V);v({root:k,props:o});var j=f(l);return g.forEach(function(e,t){k.appendChild(e.element,j+t)}),S(k),n(x)}},A=function(e,t){return function(n){var r=n.root,o=n.props,i=n.actions,a=void 0===i?[]:i,s=n.timestamp,u=n.shouldOptimize;a.filter(function(t){return e[t.type]}).forEach(function(t){return e[t.type]({root:r,props:o,action:t.data,timestamp:s,shouldOptimize:u})}),t&&t({root:r,props:o,actions:a,timestamp:s,shouldOptimize:u})}},L=function(e,t){return t.parentNode.insertBefore(e,t)},P=function(e,t){return t.parentNode.insertBefore(e,t.nextSibling)},b=function(e){return Array.isArray(e)},M=function(e){return null==e},w=function(e){return e.trim()},C=function(e){return""+e},N=function(e){return"boolean"==typeof e},G=function(e){return N(e)?e:"true"===e},U=function(e){return"string"==typeof e},B=function(e){return _(e)?e:U(e)?C(e).replace(/[a-z]+/gi,""):0},q=function(e){return parseInt(B(e),10)},F=function(e){return parseFloat(B(e))},V=function(e){return _(e)&&isFinite(e)&&Math.floor(e)===e},x=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1e3;if(V(e))return e;var n=C(e).trim();return/MB$/i.test(n)?(n=n.replace(/MB$i/,"").trim(),q(n)*t*t):/KB/i.test(n)?(n=n.replace(/KB$i/,"").trim(),q(n)*t):q(n)},Y=function(e){return"function"==typeof e},k={process:"POST",patch:"PATCH",revert:"DELETE",fetch:"GET",restore:"GET",load:"GET"},j=function(e,t,n,r,o){if(null===t)return null;if("function"==typeof t)return t;var i={url:"GET"===n||"PATCH"===n?"?"+e+"=":"",method:n,headers:o,withCredentials:!1,timeout:r,onload:null,ondata:null,onerror:null};if(U(t))return i.url=t,i;if(Object.assign(i,t),U(i.headers)){var a=i.headers.split(/:(.+)/);i.headers={header:a[0],value:a[1]}}return i.withCredentials=G(i.withCredentials),i},H=function(e){return"object"==typeof e&&null!==e},X=function(e){return b(e)?"array":function(e){return null===e}(e)?"null":V(e)?"int":/^[0-9]+ ?(?:GB|MB|KB)$/gi.test(e)?"bytes":function(e){return H(e)&&U(e.url)&&H(e.process)&&H(e.revert)&&H(e.restore)&&H(e.fetch)}(e)?"api":typeof e},W={array:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:",";return M(e)?[]:b(e)?e:C(e).split(t).map(w).filter(function(e){return e.length})},boolean:G,int:function(e){return"bytes"===X(e)?x(e):q(e)},number:F,float:F,bytes:x,string:function(e){return Y(e)?e:C(e)},function:function(e){return function(e){for(var t=self,n=e.split("."),r=null;r=n.shift();)if(!(t=t[r]))return null;return t}(e)},serverapi:function(e){return(r={}).url=U(n=e)?n:n.url||"",r.timeout=n.timeout?parseInt(n.timeout,10):0,r.headers=n.headers?n.headers:{},t(k,function(e){r[e]=j(e,n[e],k[e],r.timeout,r.headers)}),r.process=n.process||U(n)||n.url?r.process:null,r.remove=n.remove||null,delete r.headers,r;var n,r},object:function(e){try{return JSON.parse(e.replace(/{\s*'/g,'{"').replace(/'\s*}/g,'"}').replace(/'\s*:/g,'":').replace(/:\s*'/g,':"').replace(/,\s*'/g,',"').replace(/'\s*,/g,'",'))}catch(e){return null}}},z=function(e,t,n){if(e===t)return e;var r,o=X(e);if(o!==n){var i=(r=e,W[n](r));if(o=X(i),null===i)throw'Trying to assign value with incorrect type to "'+option+'", allowed type: "'+n+'"';e=i}return e},Q=function(e){var r={};return t(e,function(t){var n,o,i,a=e[t];r[t]=(n=a[0],o=a[1],i=n,{enumerable:!0,get:function(){return i},set:function(e){i=z(e,n,o)}})}),n(r)},Z=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"-";return e.split(/(?=[A-Z])/).map(function(e){return e.toLowerCase()}).join(t)},$=function(e){return function(n,r,o){var i={};return t(e,function(e){var t=Z(e,"_").toUpperCase();i["SET_"+t]=function(r){try{o.options[e]=r.value}catch(e){}n("DID_SET_"+t,{value:o.options[e]})}}),i}},K=function(e){return function(n){var r={};return t(e,function(e){r["GET_"+Z(e,"_").toUpperCase()]=function(t){return n.options[e]}}),r}},J=1,ee=2,te=3,ne=4,re=5,oe=function(){return Math.random().toString(36).substr(2,9)};function ie(e){this.wrapped=e}function ae(e){var t,n;function r(t,n){try{var i=e[t](n),a=i.value,s=a instanceof ie;Promise.resolve(s?a.wrapped:a).then(function(e){s?r("next",e):o(i.done?"return":"normal",e)},function(e){r("throw",e)})}catch(e){o("throw",e)}}function o(e,o){switch(e){case"return":t.resolve({value:o,done:!0});break;case"throw":t.reject(o);break;default:t.resolve({value:o,done:!1})}(t=t.next)?r(t.key,t.arg):n=null}this._invoke=function(e,o){return new Promise(function(i,a){var s={key:e,arg:o,resolve:i,reject:a,next:null};n?n=n.next=s:(t=n=s,r(e,o))})},"function"!=typeof e.return&&(this.return=void 0)}function se(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}"function"==typeof Symbol&&Symbol.asyncIterator&&(ae.prototype[Symbol.asyncIterator]=function(){return this}),ae.prototype.next=function(e){return this._invoke("next",e)},ae.prototype.throw=function(e){return this._invoke("throw",e)},ae.prototype.return=function(e){return this._invoke("return",e)};function ue(e){return function(e){if(Array.isArray(e)){for(var t=0,n=new Array(e.length);t1?t-1:0),o=1;o1?t-1:0),o=1;oBrowse',ge.STRING],labelInvalidField:["Field contains invalid files",ge.STRING],labelFileWaitingForSize:["Waiting for size",ge.STRING],labelFileSizeNotAvailable:["Size not available",ge.STRING],labelFileCountSingular:["file in list",ge.STRING],labelFileCountPlural:["files in list",ge.STRING],labelFileLoading:["Loading",ge.STRING],labelFileAdded:["Added",ge.STRING],labelFileLoadError:["Error during load",ge.STRING],labelFileRemoved:["Removed",ge.STRING],labelFileRemoveError:["Error during remove",ge.STRING],labelFileProcessing:["Uploading",ge.STRING],labelFileProcessingComplete:["Upload complete",ge.STRING],labelFileProcessingAborted:["Upload cancelled",ge.STRING],labelFileProcessingError:["Error during upload",ge.STRING],labelFileProcessingRevertError:["Error during revert",ge.STRING],labelTapToCancel:["tap to cancel",ge.STRING],labelTapToRetry:["tap to retry",ge.STRING],labelTapToUndo:["tap to undo",ge.STRING],labelButtonRemoveItem:["Remove",ge.STRING],labelButtonAbortItemLoad:["Abort",ge.STRING],labelButtonRetryItemLoad:["Retry",ge.STRING],labelButtonAbortItemProcessing:["Cancel",ge.STRING],labelButtonUndoItemProcessing:["Undo",ge.STRING],labelButtonRetryItemProcessing:["Retry",ge.STRING],labelButtonProcessItem:["Upload",ge.STRING],iconRemove:['',ge.STRING],iconProcess:['',ge.STRING],iconRetry:['',ge.STRING],iconUndo:['',ge.STRING],iconDone:['',ge.STRING],oninit:[null,ge.FUNCTION],onwarning:[null,ge.FUNCTION],onerror:[null,ge.FUNCTION],onactivatefile:[null,ge.FUNCTION],oninitfile:[null,ge.FUNCTION],onaddfilestart:[null,ge.FUNCTION],onaddfileprogress:[null,ge.FUNCTION],onaddfile:[null,ge.FUNCTION],onprocessfilestart:[null,ge.FUNCTION],onprocessfileprogress:[null,ge.FUNCTION],onprocessfileabort:[null,ge.FUNCTION],onprocessfilerevert:[null,ge.FUNCTION],onprocessfile:[null,ge.FUNCTION],onprocessfiles:[null,ge.FUNCTION],onremovefile:[null,ge.FUNCTION],onpreparefile:[null,ge.FUNCTION],onupdatefiles:[null,ge.FUNCTION],onreorderfiles:[null,ge.FUNCTION],beforeDropFile:[null,ge.FUNCTION],beforeAddFile:[null,ge.FUNCTION],beforeRemoveFile:[null,ge.FUNCTION],beforePrepareFile:[null,ge.FUNCTION],stylePanelLayout:[null,ge.STRING],stylePanelAspectRatio:[null,ge.STRING],styleItemPanelAspectRatio:[null,ge.STRING],styleButtonRemoveItemPosition:["left",ge.STRING],styleButtonProcessItemPosition:["right",ge.STRING],styleLoadIndicatorPosition:["right",ge.STRING],styleProgressIndicatorPosition:["right",ge.STRING],styleButtonRemoveItemAlign:[!1,ge.BOOLEAN],files:[[],ge.ARRAY],credits:[["https://pqina.nl/","Powered by PQINA"],ge.ARRAY]},Le=function(e,t){return M(t)?e[0]||null:V(t)?e[t]||null:("object"==typeof t&&(t=t.id),e.find(function(e){return e.id===t})||null)},Pe=function(e){if(M(e))return e;if(/:/.test(e)){var t=e.split(":");return t[1]/t[0]}return parseFloat(e)},be=function(e){return e.filter(function(e){return!e.archived})},Me={EMPTY:0,IDLE:1,ERROR:2,BUSY:3,READY:4},we=null,Ce=[Ie.LOAD_ERROR,Ie.PROCESSING_ERROR,Ie.PROCESSING_REVERT_ERROR],Ne=[Ie.LOADING,Ie.PROCESSING,Ie.PROCESSING_QUEUED,Ie.INIT],Ge=[Ie.PROCESSING_COMPLETE],Ue=function(e){return Ce.includes(e.status)},Be=function(e){return Ne.includes(e.status)},qe=function(e){return Ge.includes(e.status)},Fe=function(e){return H(e.options.server)&&(H(e.options.server.process)||Y(e.options.server.process))},Ve=function(e){return{GET_STATUS:function(){var t=be(e.items),n=Me.EMPTY,r=Me.ERROR,o=Me.BUSY,i=Me.IDLE,a=Me.READY;return 0===t.length?n:t.some(Ue)?r:t.some(Be)?o:t.some(qe)?a:i},GET_ITEM:function(t){return Le(e.items,t)},GET_ACTIVE_ITEM:function(t){return Le(be(e.items),t)},GET_ACTIVE_ITEMS:function(){return be(e.items)},GET_ITEMS:function(){return e.items},GET_ITEM_NAME:function(t){var n=Le(e.items,t);return n?n.filename:null},GET_ITEM_SIZE:function(t){var n=Le(e.items,t);return n?n.fileSize:null},GET_STYLES:function(){return Object.keys(e.options).filter(function(e){return/^style/.test(e)}).map(function(t){return{name:t,value:e.options[t]}})},GET_PANEL_ASPECT_RATIO:function(){return/circle/.test(e.options.stylePanelLayout)?1:Pe(e.options.stylePanelAspectRatio)},GET_ITEM_PANEL_ASPECT_RATIO:function(){return e.options.styleItemPanelAspectRatio},GET_ITEMS_BY_STATUS:function(t){return be(e.items).filter(function(e){return e.status===t})},GET_TOTAL_ITEMS:function(){return be(e.items).length},SHOULD_UPDATE_FILE_INPUT:function(){return e.options.storeAsFile&&function(){if(null===we)try{var e=new DataTransfer;e.items.add(new File(["hello world"],"This_Works.txt"));var t=document.createElement("input");t.setAttribute("type","file"),t.files=e.files,we=1===t.files.length}catch(e){we=!1}return we}()&&!Fe(e)},IS_ASYNC:function(){return Fe(e)}}},xe=function(e,t,n){return Math.max(Math.min(n,e),t)},Ye=function(e){return/^\s*data:([a-z]+\/[a-z0-9-+.]+(;[a-z-]+=[a-z0-9-]+)?)?(;base64)?,([a-z0-9!$&',()*+;=\-._~:@\/?%\s]*)\s*$/i.test(e)},ke=function(e){return e.split("/").pop().split("?").shift()},je=function(e){return e.split(".").pop()},He=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return(t+e).slice(-t.length)},Xe=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:new Date;return e.getFullYear()+"-"+He(e.getMonth()+1,"00")+"-"+He(e.getDate(),"00")+"_"+He(e.getHours(),"00")+"-"+He(e.getMinutes(),"00")+"-"+He(e.getSeconds(),"00")},We=function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,o="string"==typeof n?e.slice(0,e.size,n):e.slice(0,e.size,e.type);return o.lastModifiedDate=new Date,e._relativePath&&(o._relativePath=e._relativePath),U(t)||(t=Xe()),t&&null===r&&je(t)?o.name=t:(r=r||function(e){if("string"!=typeof e)return"";var t=e.split("/").pop();return/svg/.test(t)?"svg":/zip|compressed/.test(t)?"zip":/plain/.test(t)?"txt":/msword/.test(t)?"doc":/[a-z]+/.test(t)?"jpeg"===t?"jpg":t:""}(o.type),o.name=t+(r?"."+r:"")),o},ze=function(e,t){var n=window.BlobBuilder=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder;if(n){var r=new n;return r.append(e),r.getBlob(t)}return new Blob([e],{type:t})},Qe=function(e){return(/^data:(.+);/.exec(e)||[])[1]||null},Ze=function(e){var t=Qe(e);return function(e,t){for(var n=new ArrayBuffer(e.length),r=new Uint8Array(n),o=0;o=200&&a.status<300?r.onload(a):r.onerror(a)},a.onerror=function(){return r.onerror(a)},a.onabort=function(){o=!0,r.onabort()},a.ontimeout=function(){return r.ontimeout(a)},a.open(n.method,t,!0),V(n.timeout)&&(a.timeout=n.timeout),Object.keys(n.headers).forEach(function(e){var t=unescape(encodeURIComponent(n.headers[e]));a.setRequestHeader(e,t)}),n.responseType&&(a.responseType=n.responseType),n.withCredentials&&(a.withCredentials=!0),a.send(e),r},ot=function(e,t,n,r){return{type:e,code:t,body:n,headers:r}},it=function(e){return function(t){e(ot("error",0,"Timeout",t.getAllResponseHeaders()))}},at=function(e){return/\?/.test(e)},st=function(){for(var e="",t=arguments.length,n=new Array(t),r=0;r0&&void 0!==arguments[0]?arguments[0]:"",t=arguments.length>1?arguments[1]:void 0;if("function"==typeof t)return t;if(!t||!U(t.url))return null;var n=t.onload||function(e){return e},r=t.onerror||function(e){return null};return function(o,i,a,s,u,l){var c=rt(o,st(e,t.url),Object.assign({},t,{responseType:"blob"}));return c.onload=function(e){var r=e.getAllResponseHeaders(),a=et(r).name||ke(o);i(ot("load",e.status,"HEAD"===t.method?null:We(n(e.response),a),r))},c.onerror=function(e){a(ot("error",e.status,r(e.response)||e.statusText,e.getAllResponseHeaders()))},c.onheaders=function(e){l(ot("headers",e.status,null,e.getAllResponseHeaders()))},c.ontimeout=it(a),c.onprogress=s,c.onabort=u,c}},lt=0,ct=1,ft=2,dt=3,pt=4,Et=function(e,t,n,r,o,i,a,s,u,l,c){for(var f=[],d=c.chunkTransferId,p=c.chunkServer,E=c.chunkSize,_=c.chunkRetryDelays,T={serverId:d,aborted:!1},I=t.ondata||function(e){return e},v=t.onload||function(e,t){return"HEAD"===t?e.getResponseHeader("Upload-Offset"):e.response},m=t.onerror||function(e){return null},h=Math.floor(r.size/E),g=0;g<=h;g++){var R=g*E,O=r.slice(R,R+E,"application/offset+octet-stream");f[g]={index:g,size:O.size,offset:R,data:O,file:r,progress:0,retries:ue(_),status:lt,error:null,request:null,timeout:null}}var D,y,S,A,L=function(e){return e.status===lt||e.status===dt},P=function(t){if(!T.aborted)if(t=t||f.find(L)){t.status=ft,t.progress=null;var n=p.ondata||function(e){return e},o=p.onerror||function(e){return null},s=st(e,p.url,T.serverId),l="function"==typeof p.headers?p.headers(t):Object.assign({},p.headers,{"Content-Type":"application/offset+octet-stream","Upload-Offset":t.offset,"Upload-Length":r.size,"Upload-Name":r.name}),c=t.request=rt(n(t.data),s,Object.assign({},p,{headers:l}));c.onload=function(){t.status=ct,t.request=null,w()},c.onprogress=function(e,n,r){t.progress=e?n:null,M()},c.onerror=function(e){t.status=dt,t.request=null,t.error=o(e.response)||e.statusText,b(t)||a(ot("error",e.status,o(e.response)||e.statusText,e.getAllResponseHeaders()))},c.ontimeout=function(e){t.status=dt,t.request=null,b(t)||it(a)(e)},c.onabort=function(){t.status=lt,t.request=null,u()}}else f.every(function(e){return e.status===ct})&&i(T.serverId)},b=function(e){return 0!==e.retries.length&&(e.status=pt,clearTimeout(e.timeout),e.timeout=setTimeout(function(){P(e)},e.retries.shift()),!0)},M=function(){var e=f.reduce(function(e,t){return null===e||null===t.progress?null:e+t.progress},0);if(null===e)return s(!1,0,0);var t=f.reduce(function(e,t){return e+t.size},0);s(!0,e,t)},w=function(){f.filter(function(e){return e.status===ft}).length>=1||P()};return T.serverId?(D=function(e){T.aborted||(f.filter(function(t){return t.offset0&&void 0!==arguments[0]?arguments[0]:"",t=arguments.length>1?arguments[1]:void 0,n=arguments.length>2?arguments[2]:void 0,r=arguments.length>3?arguments[3]:void 0;return"function"==typeof t?function(){for(var e=arguments.length,o=new Array(e),i=0;ir.chunkSize,p=f&&(d||r.chunkForce);if(o instanceof Blob&&p)return Et(e,t,n,o,i,a,s,u,l,c,r);var E=t.ondata||function(e){return e},_=t.onload||function(e){return e},T=t.onerror||function(e){return null},I="function"==typeof t.headers?t.headers(o,i)||{}:Object.assign({},t.headers),v=Object.assign({},t,{headers:I}),m=new FormData;H(i)&&m.append(n,JSON.stringify(i)),(o instanceof Blob?[{name:null,file:o}]:o).forEach(function(e){m.append(n,e.file,null===e.name?e.file.name:""+e.name+e.file.name)});var h=rt(E(m),st(e,t.url),v);return h.onload=function(e){a(ot("load",e.status,_(e.response),e.getAllResponseHeaders()))},h.onerror=function(e){s(ot("error",e.status,T(e.response)||e.statusText,e.getAllResponseHeaders()))},h.ontimeout=it(s),h.onprogress=u,h.onabort=l,h}}}(e,t,n,r):null},Tt=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",t=arguments.length>1?arguments[1]:void 0;if("function"==typeof t)return t;if(!t||!U(t.url))return function(e,t){return t()};var n=t.onload||function(e){return e},r=t.onerror||function(e){return null};return function(o,i,a){var s=rt(o,e+t.url,t);return s.onload=function(e){i(ot("load",e.status,n(e.response),e.getAllResponseHeaders()))},s.onerror=function(e){a(ot("error",e.status,r(e.response)||e.statusText,e.getAllResponseHeaders()))},s.ontimeout=it(a),s}},It=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;return e+Math.random()*(t-e)},vt=function(e,t){var n={complete:!1,perceivedProgress:0,perceivedPerformanceUpdater:null,progress:null,timestamp:null,perceivedDuration:0,duration:0,request:null,response:null},r=t.allowMinimumUploadDuration,o=function(){n.request&&(n.perceivedPerformanceUpdater.clear(),n.request.abort&&n.request.abort(),n.complete=!0)},i=r?function(){return n.progress?Math.min(n.progress,n.perceivedProgress):null}:function(){return n.progress||null},a=r?function(){return Math.min(n.duration,n.perceivedDuration)}:function(){return n.duration},s=Object.assign({},pe(),{process:function(t,o){var i=function(){0!==n.duration&&null!==n.progress&&s.fire("progress",s.getProgress())},a=function(){n.complete=!0,s.fire("load-perceived",n.response.body)};s.fire("start"),n.timestamp=Date.now(),n.perceivedPerformanceUpdater=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1e3,n=(arguments.length>2&&void 0!==arguments[2]&&arguments[2],arguments.length>3&&void 0!==arguments[3]?arguments[3]:25),r=arguments.length>4&&void 0!==arguments[4]?arguments[4]:250,o=null,i=Date.now();return t>0&&function a(){var s=Date.now()-i,u=It(n,r);s+u>t&&(u=s+u-t);var l=s/t;l>=1||document.hidden?e(1):(e(l),o=setTimeout(a,u))}(),{clear:function(){clearTimeout(o)}}}(function(e){n.perceivedProgress=e,n.perceivedDuration=Date.now()-n.timestamp,i(),n.response&&1===n.perceivedProgress&&!n.complete&&a()},r?It(750,1500):0),n.request=e(t,o,function(e){n.response=H(e)?e:{type:"load",code:200,body:""+e,headers:{}},n.duration=Date.now()-n.timestamp,n.progress=1,s.fire("load",n.response.body),(!r||r&&1===n.perceivedProgress)&&a()},function(e){n.perceivedPerformanceUpdater.clear(),s.fire("error",H(e)?e:{type:"error",code:0,body:""+e})},function(e,t,r){n.duration=Date.now()-n.timestamp,n.progress=e?t/r:null,i()},function(){n.perceivedPerformanceUpdater.clear(),s.fire("abort",n.response?n.response.body:null)},function(e){s.fire("transfer",e)})},abort:o,getProgress:i,getDuration:a,reset:function(){o(),n.complete=!1,n.perceivedProgress=0,n.progress=0,n.timestamp=null,n.perceivedDuration=0,n.duration=0,n.request=null,n.response=null}});return s},mt=function(e){return e.substr(0,e.lastIndexOf("."))||e},ht=function(e){return!!(e instanceof File||e instanceof Blob&&e.name)},gt=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,o=oe(),i={archived:!1,frozen:!1,released:!1,source:null,file:r,serverFileReference:t,transferId:null,processingAborted:!1,status:t?Ie.PROCESSING_COMPLETE:Ie.INIT,activeLoader:null,activeProcessor:null},a=null,s={},u=function(e){return i.status=e},l=function(e){if(!i.released&&!i.frozen){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r1?t-1:0),r=1;r0&&void 0!==arguments[0]?arguments[0]:{},r=n.query,o=n.success,i=void 0===o?function(){}:o,a=n.failure,s=void 0===a?function(){}:a,u=se(n,["query","success","failure"]),l=Le(e.items,r);l?t(l,i,s,u||{}):s({error:ot("error",0,"Item not found"),file:null})}},bt=function(e,n,r){return{ABORT_ALL:function(){be(r.items).forEach(function(e){e.freeze(),e.abortLoad(),e.abortProcessing()})},DID_SET_FILES:function(t){var n=t.value,o=(void 0===n?[]:n).map(function(e){return{source:e.source?e.source:e,options:e.options}}),i=be(r.items);i.forEach(function(t){o.find(function(e){return e.source===t.source||e.source===t.file})||e("REMOVE_ITEM",{query:t,remove:!1})}),i=be(r.items),o.forEach(function(t,n){i.find(function(e){return e.source===t.source||e.file===t.source})||e("ADD_ITEM",Object.assign({},t,{interactionMethod:re,index:n}))})},DID_UPDATE_ITEM_METADATA:function(t){var o=t.id,i=t.action,a=t.change;a.silent||(clearTimeout(r.itemUpdateTimeout),r.itemUpdateTimeout=setTimeout(function(){var t=Rt(r.items,o);if(n("IS_ASYNC")){t.origin===ve.LOCAL&&e("DID_LOAD_ITEM",{id:t.id,error:null,serverFileReference:t.source});var s,u=function(){setTimeout(function(){e("REQUEST_ITEM_PROCESSING",{query:o})},32)};return t.status===Ie.PROCESSING_COMPLETE?(s=r.options.instantUpload,void t.revert(Tt(r.options.server.url,r.options.server.revert),n("GET_FORCE_REVERT")).then(s?u:function(){}).catch(function(){})):t.status===Ie.PROCESSING?function(e){t.abortProcessing().then(e?u:function(){})}(r.options.instantUpload):void(r.options.instantUpload&&u())}Oe("SHOULD_PREPARE_OUTPUT",!1,{item:t,query:n,action:i,change:a}).then(function(r){var i=n("GET_BEFORE_PREPARE_FILE");i&&(r=i(t,r)),r&&e("REQUEST_PREPARE_OUTPUT",{query:o,item:t,success:function(t){e("DID_PREPARE_OUTPUT",{id:o,file:t})}},!0)})},0))},MOVE_ITEM:function(e){var t=e.query,n=e.index,o=Le(r.items,t);if(o){var i=r.items.indexOf(o);i!==(n=xe(n,0,r.items.length-1))&&r.items.splice(n,0,r.items.splice(i,1)[0])}},SORT:function(t){var o=t.compare;Lt(r,o),e("DID_SORT_ITEMS",{items:n("GET_ACTIVE_ITEMS")})},ADD_ITEMS:function(t){var r=t.items,o=t.index,i=t.interactionMethod,a=t.success,s=void 0===a?function(){}:a,u=t.failure,l=void 0===u?function(){}:u,c=o;if(-1===o||void 0===o){var f=n("GET_ITEM_INSERT_LOCATION"),d=n("GET_TOTAL_ITEMS");c="before"===f?0:d}var p=n("GET_IGNORED_FILES"),E=r.filter(function(e){return ht(e)?!p.includes(e.name.toLowerCase()):!M(e)}).map(function(t){return new Promise(function(n,r){e("ADD_ITEM",{interactionMethod:i,source:t.source||t,success:n,failure:r,index:c++,options:t.options||{}})})});Promise.all(E).then(s).catch(l)},ADD_ITEM:function(t){var o=t.source,i=t.index,a=void 0===i?-1:i,s=t.interactionMethod,u=t.success,l=void 0===u?function(){}:u,c=t.failure,f=void 0===c?function(){}:c,d=t.options,p=void 0===d?{}:d;if(M(o))f({error:ot("error",0,"No source"),file:null});else if(!ht(o)||!r.options.ignoredFiles.includes(o.name.toLowerCase())){if(!function(e){var t=be(e.items).length;if(!e.options.allowMultiple)return 0===t;var n=e.options.maxFiles;return null===n||t=400&&t.code<500)return e("DID_THROW_ITEM_INVALID",{id:h,error:t,status:{main:n,sub:t.code+" ("+t.body+")"}}),void f({error:t,file:Te(v)});e("DID_THROW_ITEM_LOAD_ERROR",{id:h,error:t,status:{main:n,sub:r.options.labelTapToRetry}})}),v.on("load-file-error",function(t){e("DID_THROW_ITEM_INVALID",{id:h,error:t.status,status:t.status}),f({error:t.status,file:Te(v)})}),v.on("load-abort",function(){e("REMOVE_ITEM",{query:h})}),v.on("load-skip",function(){e("COMPLETE_LOAD_ITEM",{query:h,item:v,data:{source:o,success:l}})}),v.on("load",function(){var t=function(t){t?(v.on("metadata-update",function(t){e("DID_UPDATE_ITEM_METADATA",{id:h,change:t})}),Oe("SHOULD_PREPARE_OUTPUT",!1,{item:v,query:n}).then(function(t){var i=n("GET_BEFORE_PREPARE_FILE");i&&(t=i(v,t));var a=function(){e("COMPLETE_LOAD_ITEM",{query:h,item:v,data:{source:o,success:l}}),St(e,r)};t?e("REQUEST_PREPARE_OUTPUT",{query:h,item:v,success:function(t){e("DID_PREPARE_OUTPUT",{id:h,file:t}),a()}},!0):a()})):e("REMOVE_ITEM",{query:h})};Oe("DID_LOAD_ITEM",v,{query:n,dispatch:e}).then(function(){At(n("GET_BEFORE_ADD_FILE"),Te(v)).then(t)}).catch(function(n){if(!n||!n.error||!n.status)return t(!1);e("DID_THROW_ITEM_INVALID",{id:h,error:n.error,status:n.status})})}),v.on("process-start",function(){e("DID_START_ITEM_PROCESSING",{id:h})}),v.on("process-progress",function(t){e("DID_UPDATE_ITEM_PROCESS_PROGRESS",{id:h,progress:t})}),v.on("process-error",function(t){e("DID_THROW_ITEM_PROCESSING_ERROR",{id:h,error:t,status:{main:yt(r.options.labelFileProcessingError)(t),sub:r.options.labelTapToRetry}})}),v.on("process-revert-error",function(t){e("DID_THROW_ITEM_PROCESSING_REVERT_ERROR",{id:h,error:t,status:{main:yt(r.options.labelFileProcessingRevertError)(t),sub:r.options.labelTapToRetry}})}),v.on("process-complete",function(t){e("DID_COMPLETE_ITEM_PROCESSING",{id:h,error:null,serverFileReference:t}),e("DID_DEFINE_VALUE",{id:h,value:t})}),v.on("process-abort",function(){e("DID_ABORT_ITEM_PROCESSING",{id:h})}),v.on("process-revert",function(){e("DID_REVERT_ITEM_PROCESSING",{id:h}),e("DID_DEFINE_VALUE",{id:h,value:null})}),e("DID_ADD_ITEM",{id:h,index:a,interactionMethod:s}),St(e,r);var g=r.options.server||{},R=g.url,O=g.load,D=g.restore,y=g.fetch;v.load(o,tt(I===ve.INPUT?U(o)&&function(e){return(e.indexOf(":")>-1||e.indexOf("//")>-1)&&Dt(location.href)!==Dt(e)}(o)&&y?ut(R,y):Ot:ut(R,I===ve.LIMBO?D:O)),function(e,t,r){Oe("LOAD_FILE",e,{query:n}).then(t).catch(r)})}},REQUEST_PREPARE_OUTPUT:function(e){var t=e.item,r=e.success,o=e.failure,i=void 0===o?function(){}:o,a={error:ot("error",0,"Item not found"),file:null};if(t.archived)return i(a);Oe("PREPARE_OUTPUT",t.file,{query:n,item:t}).then(function(e){Oe("COMPLETE_PREPARE_OUTPUT",e,{query:n,item:t}).then(function(e){if(t.archived)return i(a);r(e)})})},COMPLETE_LOAD_ITEM:function(t){var o=t.item,i=t.data,a=i.success,s=i.source,u=n("GET_ITEM_INSERT_LOCATION");if(Y(u)&&s&&Lt(r,u),e("DID_LOAD_ITEM",{id:o.id,error:null,serverFileReference:o.origin===ve.INPUT?null:s}),a(Te(o)),o.origin!==ve.LOCAL)return o.origin===ve.LIMBO?(e("DID_COMPLETE_ITEM_PROCESSING",{id:o.id,error:null,serverFileReference:s}),void e("DID_DEFINE_VALUE",{id:o.id,value:o.serverId||s})):void(n("IS_ASYNC")&&r.options.instantUpload&&e("REQUEST_ITEM_PROCESSING",{query:o.id}));e("DID_LOAD_LOCAL_ITEM",{id:o.id})},RETRY_ITEM_LOAD:Pt(r,function(e){e.retryLoad()}),REQUEST_ITEM_PREPARE:Pt(r,function(t,n,r){e("REQUEST_PREPARE_OUTPUT",{query:t.id,item:t,success:function(r){e("DID_PREPARE_OUTPUT",{id:t.id,file:r}),n({file:t,output:r})},failure:r},!0)}),REQUEST_ITEM_PROCESSING:Pt(r,function(t,o,i){if(t.status===Ie.IDLE||t.status===Ie.PROCESSING_ERROR)t.status!==Ie.PROCESSING_QUEUED&&(t.requestProcessing(),e("DID_REQUEST_ITEM_PROCESSING",{id:t.id}),e("PROCESS_ITEM",{query:t,success:o,failure:i},!0));else{var a=function(){return e("REQUEST_ITEM_PROCESSING",{query:t,success:o,failure:i})},s=function(){return document.hidden?a():setTimeout(a,32)};t.status===Ie.PROCESSING_COMPLETE||t.status===Ie.PROCESSING_REVERT_ERROR?t.revert(Tt(r.options.server.url,r.options.server.revert),n("GET_FORCE_REVERT")).then(s).catch(function(){}):t.status===Ie.PROCESSING&&t.abortProcessing().then(s)}}),PROCESS_ITEM:Pt(r,function(t,o,i){var a=n("GET_MAX_PARALLEL_UPLOADS");if(n("GET_ITEMS_BY_STATUS",Ie.PROCESSING).length!==a){if(t.status!==Ie.PROCESSING){var s=function t(){var n=r.processingQueue.shift();if(n){var o=n.id,i=n.success,a=n.failure,s=Le(r.items,o);s&&!s.archived?e("PROCESS_ITEM",{query:o,success:i,failure:a},!0):t()}};t.onOnce("process-complete",function(){o(Te(t)),s();var i=r.options.server;if(r.options.instantUpload&&t.origin===ve.LOCAL&&Y(i.remove)){var a=function(){};t.origin=ve.LIMBO,r.options.server.remove(t.source,a,a)}n("GET_ITEMS_BY_STATUS",Ie.PROCESSING_COMPLETE).length===r.items.length&&e("DID_COMPLETE_ITEM_PROCESSING_ALL")}),t.onOnce("process-error",function(e){i({error:e,file:Te(t)}),s()});var u=r.options;t.process(vt(_t(u.server.url,u.server.process,u.name,{chunkTransferId:t.transferId,chunkServer:u.server.patch,chunkUploads:u.chunkUploads,chunkForce:u.chunkForce,chunkSize:u.chunkSize,chunkRetryDelays:u.chunkRetryDelays}),{allowMinimumUploadDuration:n("GET_ALLOW_MINIMUM_UPLOAD_DURATION")}),function(r,o,i){Oe("PREPARE_OUTPUT",r,{query:n,item:t}).then(function(n){e("DID_PREPARE_OUTPUT",{id:t.id,file:n}),o(n)}).catch(i)})}}else r.processingQueue.push({id:t.id,success:o,failure:i})}),RETRY_ITEM_PROCESSING:Pt(r,function(t){e("REQUEST_ITEM_PROCESSING",{query:t})}),REQUEST_REMOVE_ITEM:Pt(r,function(t){At(n("GET_BEFORE_REMOVE_FILE"),Te(t)).then(function(n){n&&e("REMOVE_ITEM",{query:t})})}),RELEASE_ITEM:Pt(r,function(e){e.release()}),REMOVE_ITEM:Pt(r,function(t,o,i,a){var s=function(){var n=t.id;Rt(r.items,n).archive(),e("DID_REMOVE_ITEM",{error:null,id:n,item:t}),St(e,r),o(Te(t))},u=r.options.server;t.origin===ve.LOCAL&&u&&Y(u.remove)&&!1!==a.remove?(e("DID_START_ITEM_REMOVE",{id:t.id}),u.remove(t.source,function(){return s()},function(n){e("DID_THROW_ITEM_REMOVE_ERROR",{id:t.id,error:ot("error",0,n,null),status:{main:yt(r.options.labelFileRemoveError)(n),sub:r.options.labelTapToRetry}})})):((a.revert&&t.origin!==ve.LOCAL&&null!==t.serverId||r.options.chunkUploads&&t.file.size>r.options.chunkSize||r.options.chunkUploads&&r.options.chunkForce)&&t.revert(Tt(r.options.server.url,r.options.server.revert),n("GET_FORCE_REVERT")),s())}),ABORT_ITEM_LOAD:Pt(r,function(e){e.abortLoad()}),ABORT_ITEM_PROCESSING:Pt(r,function(t){t.serverId?e("REVERT_ITEM_PROCESSING",{id:t.id}):t.abortProcessing().then(function(){r.options.instantUpload&&e("REMOVE_ITEM",{query:t.id})})}),REQUEST_REVERT_ITEM_PROCESSING:Pt(r,function(t){if(r.options.instantUpload){var o=function(n){n&&e("REVERT_ITEM_PROCESSING",{query:t})},i=n("GET_BEFORE_REMOVE_FILE");if(!i)return o(!0);var a=i(Te(t));return null==a?o(!0):"boolean"==typeof a?o(a):void("function"==typeof a.then&&a.then(o))}e("REVERT_ITEM_PROCESSING",{query:t})}),REVERT_ITEM_PROCESSING:Pt(r,function(t){t.revert(Tt(r.options.server.url,r.options.server.revert),n("GET_FORCE_REVERT")).then(function(){(r.options.instantUpload||function(e){return!ht(e.file)}(t))&&e("REMOVE_ITEM",{query:t.id})}).catch(function(){})}),SET_OPTIONS:function(n){var r=n.options;t(r,function(t,n){e("SET_"+Z(t,"_").toUpperCase(),{value:n})})}}},Mt=function(e){return e},wt=function(e){return document.createElement(e)},Ct=function(e,t){var n=e.childNodes[0];n?t!==n.nodeValue&&(n.nodeValue=t):(n=document.createTextNode(t),e.appendChild(n))},Nt=function(e,t,n,r){var o=(r%360-90)*Math.PI/180;return{x:e+n*Math.cos(o),y:t+n*Math.sin(o)}},Gt=function(e,t,n,r,o){var i=1;return o>r&&o-r<=.5&&(i=0),r>o&&r-o>=.5&&(i=0),function(e,t,n,r,o,i){var a=Nt(e,t,n,o),s=Nt(e,t,n,r);return["M",a.x,a.y,"A",n,n,0,i,0,s.x,s.y].join(" ")}(e,t,n,360*Math.min(.9999,r),360*Math.min(.9999,o),i)},Ut=S({tag:"div",name:"progress-indicator",ignoreRectUpdate:!0,ignoreRect:!0,create:function(e){var t=e.root,n=e.props;n.spin=!1,n.progress=0,n.opacity=0;var r=a("svg");t.ref.path=a("path",{"stroke-width":2,"stroke-linecap":"round"}),r.appendChild(t.ref.path),t.ref.svg=r,t.appendChild(r)},write:function(e){var t=e.root,n=e.props;if(0!==n.opacity){n.align&&(t.element.dataset.align=n.align);var o=parseInt(r(t.ref.path,"stroke-width"),10),i=.5*t.rect.element.width,a=0,s=0;n.spin?(a=0,s=.5):(a=0,s=n.progress);var u=Gt(i,i,i-o,a,s);r(t.ref.path,"d",u),r(t.ref.path,"stroke-opacity",n.spin||n.progress>0?1:0)}},mixins:{apis:["progress","spin","align"],styles:["opacity"],animations:{opacity:{type:"tween",duration:500},progress:{type:"spring",stiffness:.95,damping:.65,mass:10}}}}),Bt=S({tag:"button",attributes:{type:"button"},ignoreRect:!0,ignoreRectUpdate:!0,name:"file-action-button",mixins:{apis:["label"],styles:["translateX","translateY","scaleX","scaleY","opacity"],animations:{scaleX:"spring",scaleY:"spring",translateX:"spring",translateY:"spring",opacity:{type:"tween",duration:250}},listeners:!0},create:function(e){var t=e.root,n=e.props;t.element.innerHTML=(n.icon||"")+""+n.label+"",n.isDisabled=!1},write:function(e){var t=e.root,n=e.props,o=n.isDisabled,i=t.query("GET_DISABLED")||0===n.opacity;i&&!o?(n.isDisabled=!0,r(t.element,"disabled","disabled")):!i&&o&&(n.isDisabled=!1,t.element.removeAttribute("disabled"))}}),qt=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:".",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:1e3,r=n,o=n*n,i=n*n*n;return(e=Math.round(Math.abs(e)))0&&(t.height=t.ref.container.rect.element.height)),o&&(t.ref.panel.height=null),t.ref.panel.height=t.height}),vn=S({create:function(e){var t=e.root,n=e.props;t.ref.handleClick=function(e){return t.dispatch("DID_ACTIVATE_ITEM",{id:n.id})},t.element.id="filepond--item-"+n.id,t.element.addEventListener("click",t.ref.handleClick),t.ref.container=t.appendChildView(t.createChildView(cn,{id:n.id})),t.ref.panel=t.appendChildView(t.createChildView(pn,{name:"item-panel"})),t.ref.panel.height=null,n.markedForRemoval=!1,t.query("GET_ALLOW_REORDER")&&(t.element.dataset.dragState="idle",t.element.addEventListener("pointerdown",function(e){if(e.isPrimary){var r=!1,o=e.pageX,i=e.pageY;n.dragOrigin={x:t.translateX,y:t.translateY},n.dragCenter={x:e.offsetX,y:e.offsetY};var a,s,u,l=(a=t.query("GET_ACTIVE_ITEMS"),s=a.map(function(e){return e.id}),u=void 0,{setIndex:function(e){u=e},getIndex:function(){return u},getItemIndex:function(e){return s.indexOf(e.id)}});t.dispatch("DID_GRAB_ITEM",{id:n.id,dragState:l});var c=function(e){e.isPrimary&&(e.stopPropagation(),e.preventDefault(),n.dragOffset={x:e.pageX-o,y:e.pageY-i},n.dragOffset.x*n.dragOffset.x+n.dragOffset.y*n.dragOffset.y>16&&!r&&(r=!0,t.element.removeEventListener("click",t.ref.handleClick)),t.dispatch("DID_DRAG_ITEM",{id:n.id,dragState:l}))};document.addEventListener("pointermove",c),document.addEventListener("pointerup",function e(a){a.isPrimary&&(document.removeEventListener("pointermove",c),document.removeEventListener("pointerup",e),n.dragOffset={x:a.pageX-o,y:a.pageY-i},t.dispatch("DID_DROP_ITEM",{id:n.id,dragState:l}),r&&setTimeout(function(){return t.element.addEventListener("click",t.ref.handleClick)},0))})}}))},write:In,destroy:function(e){var t=e.root,n=e.props;t.element.removeEventListener("click",t.ref.handleClick),t.dispatch("RELEASE_ITEM",{query:n.id})},tag:"li",name:"item",mixins:{apis:["id","interactionMethod","markedForRemoval","spawnDate","dragCenter","dragOrigin","dragOffset"],styles:["translateX","translateY","scaleX","scaleY","opacity","height"],animations:{scaleX:"spring",scaleY:"spring",translateX:En,translateY:En,opacity:{type:"tween",duration:150}}}}),mn=function(e,t){return Math.max(1,Math.floor((e+1)/t))},hn=function(e,t,n){if(n){var r=e.rect.element.width,o=t.length,i=null;if(0===o||n.topv){if(n.left3&&void 0!==arguments[3]?arguments[3]:0,o=arguments.length>4&&void 0!==arguments[4]?arguments[4]:1;e.dragOffset?(e.translateX=null,e.translateY=null,e.translateX=e.dragOrigin.x+e.dragOffset.x,e.translateY=e.dragOrigin.y+e.dragOffset.y,e.scaleX=1.025,e.scaleY=1.025):(e.translateX=t,e.translateY=n,Date.now()>e.spawnDate&&(0===e.opacity&&On(e,t,n,r,o),e.scaleX=1,e.scaleY=1,e.opacity=1))},On=function(e,t,n,r,o){e.interactionMethod===re?(e.translateX=null,e.translateX=t,e.translateY=null,e.translateY=n):e.interactionMethod===ee?(e.translateX=null,e.translateX=t-20*r,e.translateY=null,e.translateY=n-10*o,e.scaleX=.8,e.scaleY=.8):e.interactionMethod===te?(e.translateY=null,e.translateY=n-30):e.interactionMethod===J&&(e.translateX=null,e.translateX=t-30,e.translateY=null)},Dn=function(e){return e.rect.element.height+.5*e.rect.element.marginBottom+.5*e.rect.element.marginTop},yn=A({DID_ADD_ITEM:function(e){var t=e.root,n=e.action,r=n.id,o=n.index,i=n.interactionMethod;t.ref.addIndex=o;var a=Date.now(),s=a,u=1;if(i!==re){u=0;var l=t.query("GET_ITEM_INSERT_INTERVAL"),c=a-t.ref.lastItemSpanwDate;s=cs&&(E=s);var _=Math.floor(s/E+1);gn.setHeight=d*_,gn.setWidth=p*E;var T={y:Math.floor(f/d),x:Math.floor(c/p),getGridIndex:function(){return f>gn.getHeight||f<0||c>gn.getWidth||c<0?u:this.y*E+this.x},getColIndex:function(){for(var e=t.query("GET_ACTIVE_ITEMS"),n=t.childViews.filter(function(e){return e.rect.element.height}),r=e.map(function(e){return n.find(function(t){return t.id===e.id})}),o=r.findIndex(function(e){return e===a}),i=Dn(a),s=r.length,u=s,l=0,c=0,d=0,p=0;pp){if(f1?T.getGridIndex():T.getColIndex();t.dispatch("MOVE_ITEM",{query:a,index:I});var v=o.getIndex();if(void 0===v||v!==I){if(o.setIndex(I),void 0===v)return;t.dispatch("DID_REORDER_ITEMS",{items:t.query("GET_ACTIVE_ITEMS"),origin:u,target:I})}}}}),Sn=S({create:function(e){var t=e.root;r(t.element,"role","list"),t.ref.lastItemSpanwDate=Date.now()},write:function(e){var t=e.root,n=e.props,r=e.actions,o=e.shouldOptimize;yn({root:t,props:n,actions:r});var i=n.dragCoordinates,a=t.rect.element.width,s=t.childViews.filter(function(e){return e.rect.element.height}),u=t.query("GET_ACTIVE_ITEMS").map(function(e){return s.find(function(t){return t.id===e.id})}).filter(function(e){return e}),l=i?hn(t,u,i):null,c=t.ref.addIndex||null;t.ref.addIndex=null;var f=0,d=0,p=0;if(0!==u.length){var E=u[0].rect.element,_=E.marginTop+E.marginBottom,T=E.marginLeft+E.marginRight,I=E.width+T,v=E.height+_,m=mn(a,I);if(1===m){var h=0,g=0;u.forEach(function(e,t){if(l){var n=t-l;g=-2===n?.25*-_:-1===n?.75*-_:0===n?.75*_:1===n?.25*_:0}o&&(e.translateX=null,e.translateY=null),e.markedForRemoval||Rn(e,0,h+g);var r=(e.rect.element.height+_)*(e.markedForRemoval?e.opacity:1);h+=r})}else{var R=0,O=0;u.forEach(function(e,t){t===l&&(f=1),t===c&&(p+=1),e.markedForRemoval&&e.opacity<.5&&(d-=1);var n=t+p+f+d,r=n%m,i=Math.floor(n/m),a=r*I,s=i*v,u=Math.sign(a-R),E=Math.sign(s-O);R=a,O=s,e.markedForRemoval||(o&&(e.translateX=null,e.translateY=null),Rn(e,a,s,u,E))})}}},tag:"ul",name:"list",didWriteView:function(e){var t=e.root;t.childViews.filter(function(e){return e.markedForRemoval&&0===e.opacity&&e.resting}).forEach(function(e){e._destroy(),t.removeChildView(e)})},filterFrameActionsForChild:function(e,t){return t.filter(function(t){return!t.data||!t.data.id||e.id===t.data.id})},mixins:{apis:["dragCoordinates"]}}),An=A({DID_DRAG:function(e){var t=e.root,n=e.props,r=e.action;t.query("GET_ITEM_INSERT_LOCATION_FREEDOM")&&(n.dragCoordinates={left:r.position.scopeLeft-t.ref.list.rect.element.left,top:r.position.scopeTop-(t.rect.outer.top+t.rect.element.marginTop+t.rect.element.scrollTop)})},DID_END_DRAG:function(e){e.props.dragCoordinates=null}}),Ln=S({create:function(e){var t=e.root,n=e.props;t.ref.list=t.appendChildView(t.createChildView(Sn)),n.dragCoordinates=null,n.overflowing=!1},write:function(e){var t=e.root,n=e.props,r=e.actions;if(An({root:t,props:n,actions:r}),t.ref.list.dragCoordinates=n.dragCoordinates,n.overflowing&&!n.overflow&&(n.overflowing=!1,t.element.dataset.state="",t.height=null),n.overflow){var o=Math.round(n.overflow);o!==t.height&&(n.overflowing=!0,t.element.dataset.state="overflow",t.height=o)}},name:"list-scroller",mixins:{apis:["overflow","dragCoordinates"],styles:["height","translateY"],animations:{translateY:"spring"}}}),Pn=function(e,t,n){var o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"";n?r(e,t,o):e.removeAttribute(t)},bn=function(e){var t=e.root,n=e.action;t.query("GET_ALLOW_SYNC_ACCEPT_ATTRIBUTE")&&Pn(t.element,"accept",!!n.value,n.value?n.value.join(","):"")},Mn=function(e){var t=e.root,n=e.action;Pn(t.element,"multiple",n.value)},wn=function(e){var t=e.root,n=e.action;Pn(t.element,"webkitdirectory",n.value)},Cn=function(e){var t=e.root,n=t.query("GET_DISABLED"),r=t.query("GET_ALLOW_BROWSE"),o=n||!r;Pn(t.element,"disabled",o)},Nn=function(e){var t=e.root;e.action.value?0===t.query("GET_TOTAL_ITEMS")&&Pn(t.element,"required",!0):Pn(t.element,"required",!1)},Gn=function(e){var t=e.root,n=e.action;Pn(t.element,"capture",!!n.value,!0===n.value?"":n.value)},Un=function(e){var t=e.root,n=t.element;t.query("GET_TOTAL_ITEMS")>0?(Pn(n,"required",!1),Pn(n,"name",!1)):(Pn(n,"name",!0,t.query("GET_NAME")),t.query("GET_CHECK_VALIDITY")&&n.setCustomValidity(""),t.query("GET_REQUIRED")&&Pn(n,"required",!0))},Bn=S({tag:"input",name:"browser",ignoreRect:!0,ignoreRectUpdate:!0,attributes:{type:"file"},create:function(e){var t=e.root,n=e.props;t.element.id="filepond--browser-"+n.id,r(t.element,"name",t.query("GET_NAME")),r(t.element,"aria-controls","filepond--assistant-"+n.id),r(t.element,"aria-labelledby","filepond--drop-label-"+n.id),bn({root:t,action:{value:t.query("GET_ACCEPTED_FILE_TYPES")}}),Mn({root:t,action:{value:t.query("GET_ALLOW_MULTIPLE")}}),wn({root:t,action:{value:t.query("GET_ALLOW_DIRECTORIES_ONLY")}}),Cn({root:t}),Nn({root:t,action:{value:t.query("GET_REQUIRED")}}),Gn({root:t,action:{value:t.query("GET_CAPTURE_METHOD")}}),t.ref.handleChange=function(e){if(t.element.value){var r=Array.from(t.element.files).map(function(e){return e._relativePath=e.webkitRelativePath,e});setTimeout(function(){n.onload(r),function(e){if(e&&""!==e.value){try{e.value=""}catch(e){}if(e.value){var t=wt("form"),n=e.parentNode,r=e.nextSibling;t.appendChild(e),t.reset(),r?n.insertBefore(e,r):n.appendChild(e)}}}(t.element)},250)}},t.element.addEventListener("change",t.ref.handleChange)},destroy:function(e){var t=e.root;t.element.removeEventListener("change",t.ref.handleChange)},write:A({DID_LOAD_ITEM:Un,DID_REMOVE_ITEM:Un,DID_THROW_ITEM_INVALID:function(e){var t=e.root;t.query("GET_CHECK_VALIDITY")&&t.element.setCustomValidity(t.query("GET_LABEL_INVALID_FIELD"))},DID_SET_DISABLED:Cn,DID_SET_ALLOW_BROWSE:Cn,DID_SET_ALLOW_DIRECTORIES_ONLY:wn,DID_SET_ALLOW_MULTIPLE:Mn,DID_SET_ACCEPTED_FILE_TYPES:bn,DID_SET_CAPTURE_METHOD:Gn,DID_SET_REQUIRED:Nn})}),qn=13,Fn=32,Vn=function(e,t){e.innerHTML=t;var n=e.querySelector(".filepond--label-action");return n&&r(n,"tabindex","0"),t},xn=S({name:"drop-label",ignoreRect:!0,create:function(e){var t=e.root,n=e.props,o=wt("label");r(o,"for","filepond--browser-"+n.id),r(o,"id","filepond--drop-label-"+n.id),r(o,"aria-hidden","true"),t.ref.handleKeyDown=function(e){(e.keyCode===qn||e.keyCode===Fn)&&(e.preventDefault(),t.ref.label.click())},t.ref.handleClick=function(e){e.target===o||o.contains(e.target)||t.ref.label.click()},o.addEventListener("keydown",t.ref.handleKeyDown),t.element.addEventListener("click",t.ref.handleClick),Vn(o,n.caption),t.appendChild(o),t.ref.label=o},destroy:function(e){var t=e.root;t.ref.label.addEventListener("keydown",t.ref.handleKeyDown),t.element.removeEventListener("click",t.ref.handleClick)},write:A({DID_SET_LABEL_IDLE:function(e){var t=e.root,n=e.action;Vn(t.ref.label,n.value)}}),mixins:{styles:["opacity","translateX","translateY"],animations:{opacity:{type:"tween",duration:150},translateX:"spring",translateY:"spring"}}}),Yn=S({name:"drip-blob",ignoreRect:!0,mixins:{styles:["translateX","translateY","scaleX","scaleY","opacity"],animations:{scaleX:"spring",scaleY:"spring",translateX:"spring",translateY:"spring",opacity:{type:"tween",duration:250}}}}),kn=A({DID_DRAG:function(e){var t=e.root,n=e.action;t.ref.blob?(t.ref.blob.translateX=n.position.scopeLeft,t.ref.blob.translateY=n.position.scopeTop,t.ref.blob.scaleX=1,t.ref.blob.scaleY=1,t.ref.blob.opacity=1):function(e){var t=e.root,n=.5*t.rect.element.width,r=.5*t.rect.element.height;t.ref.blob=t.appendChildView(t.createChildView(Yn,{opacity:0,scaleX:2.5,scaleY:2.5,translateX:n,translateY:r}))}({root:t})},DID_DROP:function(e){var t=e.root;t.ref.blob&&(t.ref.blob.scaleX=2.5,t.ref.blob.scaleY=2.5,t.ref.blob.opacity=0)},DID_END_DRAG:function(e){var t=e.root;t.ref.blob&&(t.ref.blob.opacity=0)}}),jn=S({ignoreRect:!0,ignoreRectUpdate:!0,name:"drip",write:function(e){var t=e.root,n=e.props,r=e.actions;kn({root:t,props:n,actions:r});var o=t.ref.blob;0===r.length&&o&&0===o.opacity&&(t.removeChildView(o),t.ref.blob=null)}}),Hn=function(e,t){try{var n=new DataTransfer;t.forEach(function(e){e instanceof File?n.items.add(e):n.items.add(new File([e],e.name,{type:e.type}))}),e.files=n.files}catch(e){return!1}return!0},Xn=function(e,t){return e.ref.fields[t]},Wn=function(e){e.query("GET_ACTIVE_ITEMS").forEach(function(t){e.ref.fields[t.id]&&e.element.appendChild(e.ref.fields[t.id])})},zn=function(e){var t=e.root;return Wn(t)},Qn=A({DID_SET_DISABLED:function(e){var t=e.root;t.element.disabled=t.query("GET_DISABLED")},DID_ADD_ITEM:function(e){var t=e.root,n=e.action,r=!(t.query("GET_ITEM",n.id).origin===ve.LOCAL)&&t.query("SHOULD_UPDATE_FILE_INPUT"),o=wt("input");o.type=r?"file":"hidden",o.name=t.query("GET_NAME"),o.disabled=t.query("GET_DISABLED"),t.ref.fields[n.id]=o,Wn(t)},DID_LOAD_ITEM:function(e){var t=e.root,n=e.action,r=Xn(t,n.id);if(r&&(null!==n.serverFileReference&&(r.value=n.serverFileReference),t.query("SHOULD_UPDATE_FILE_INPUT"))){var o=t.query("GET_ITEM",n.id);Hn(r,[o.file])}},DID_REMOVE_ITEM:function(e){var t=e.root,n=e.action,r=Xn(t,n.id);r&&(r.parentNode&&r.parentNode.removeChild(r),delete t.ref.fields[n.id])},DID_DEFINE_VALUE:function(e){var t=e.root,n=e.action,r=Xn(t,n.id);r&&(null===n.value?r.removeAttribute("value"):r.value=n.value,Wn(t))},DID_PREPARE_OUTPUT:function(e){var t=e.root,n=e.action;t.query("SHOULD_UPDATE_FILE_INPUT")&&setTimeout(function(){var e=Xn(t,n.id);e&&Hn(e,[n.file])},0)},DID_REORDER_ITEMS:zn,DID_SORT_ITEMS:zn}),Zn=S({tag:"fieldset",name:"data",create:function(e){return e.root.ref.fields={}},write:Qn,ignoreRect:!0}),$n=["jpg","jpeg","png","gif","bmp","webp","svg","tiff"],Kn=["css","csv","html","txt"],Jn={zip:"zip|compressed",epub:"application/epub+zip"},er=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";return e=e.toLowerCase(),$n.includes(e)?"image/"+("jpg"===e?"jpeg":"svg"===e?"svg+xml":e):Kn.includes(e)?"text/"+e:Jn[e]||""},tr=function(e){return new Promise(function(t,n){var r=fr(e);if(r.length&&!nr(e))return t(r);rr(e).then(t)})},nr=function(e){return!!e.files&&e.files.length>0},rr=function(e){return new Promise(function(t,n){var r=(e.items?Array.from(e.items):[]).filter(function(e){return or(e)}).map(function(e){return ir(e)});r.length?Promise.all(r).then(function(e){var n=[];e.forEach(function(e){n.push.apply(n,e)}),t(n.filter(function(e){return e}).map(function(e){return e._relativePath||(e._relativePath=e.webkitRelativePath),e}))}).catch(console.error):t(e.files?Array.from(e.files):[])})},or=function(e){if(lr(e)){var t=cr(e);if(t)return t.isFile||t.isDirectory}return"file"===e.kind},ir=function(e){return new Promise(function(t,n){ur(e)?ar(cr(e)).then(t).catch(n):t([e.getAsFile()])})},ar=function(e){return new Promise(function(t,n){var r=[],o=0,i=0,a=function(){0===i&&0===o&&t(r)};!function e(t){o++;var s=t.createReader();!function t(){s.readEntries(function(n){if(0===n.length)return o--,void a();n.forEach(function(t){t.isDirectory?e(t):(i++,t.file(function(e){var n=sr(e);t.fullPath&&(n._relativePath=t.fullPath),r.push(n),i--,a()}))}),t()},n)}()}(e)})},sr=function(e){if(e.type.length)return e;var t=e.lastModifiedDate,n=e.name,r=er(je(e.name));return r.length?((e=e.slice(0,e.size,r)).name=n,e.lastModifiedDate=t,e):e},ur=function(e){return lr(e)&&(cr(e)||{}).isDirectory},lr=function(e){return"webkitGetAsEntry"in e},cr=function(e){return e.webkitGetAsEntry()},fr=function(e){var t=[];try{if((t=pr(e)).length)return t;t=dr(e)}catch(e){}return t},dr=function(e){var t=e.getData("url");return"string"==typeof t&&t.length?[t]:[]},pr=function(e){var t=e.getData("text/html");if("string"==typeof t&&t.length){var n=t.match(/src\s*=\s*"(.+?)"/);if(n)return[n[1]]}return[]},Er=[],_r=function(e){return{pageLeft:e.pageX,pageTop:e.pageY,scopeLeft:e.offsetX||e.layerX,scopeTop:e.offsetY||e.layerY}},Tr=function(e){var t=Er.find(function(t){return t.element===e});if(t)return t;var n=Ir(e);return Er.push(n),n},Ir=function(e){var n=[],r={dragenter:gr,dragover:Rr,dragleave:Dr,drop:Or},o={};t(r,function(t,r){o[t]=r(e,n),e.addEventListener(t,o[t],!1)});var i={element:e,addListener:function(a){return n.push(a),function(){n.splice(n.indexOf(a),1),0===n.length&&(Er.splice(Er.indexOf(i),1),t(r,function(t){e.removeEventListener(t,o[t],!1)}))}}};return i},vr=function(e,t){var n,r=function(e,t){return"elementFromPoint"in e||(e=document),e.elementFromPoint(t.x,t.y)}("getRootNode"in(n=t)?n.getRootNode():document,{x:e.pageX-window.pageXOffset,y:e.pageY-window.pageYOffset});return r===t||t.contains(r)},mr=null,hr=function(e,t){try{e.dropEffect=t}catch(e){}},gr=function(e,t){return function(e){e.preventDefault(),mr=e.target,t.forEach(function(t){var n=t.element,r=t.onenter;vr(e,n)&&(t.state="enter",r(_r(e)))})}},Rr=function(e,t){return function(e){e.preventDefault();var n=e.dataTransfer;tr(n).then(function(r){var o=!1;t.some(function(t){var i=t.filterElement,a=t.element,s=t.onenter,u=t.onexit,l=t.ondrag,c=t.allowdrop;hr(n,"copy");var f=c(r);if(f)if(vr(e,a)){if(o=!0,null===t.state)return t.state="enter",void s(_r(e));if(t.state="over",i&&!f)return void hr(n,"none");l(_r(e))}else i&&!o&&hr(n,"none"),t.state&&(t.state=null,u(_r(e)));else hr(n,"none")})})}},Or=function(e,t){return function(e){e.preventDefault();var n=e.dataTransfer;tr(n).then(function(n){t.forEach(function(t){var r=t.filterElement,o=t.element,i=t.ondrop,a=t.onexit,s=t.allowdrop;if(t.state=null,!r||vr(e,o))return s(n)?void i(_r(e),n):a(_r(e))})})}},Dr=function(e,t){return function(e){mr===e.target&&t.forEach(function(t){var n=t.onexit;t.state=null,n(_r(e))})}},yr=function(e,t,n){e.classList.add("filepond--hopper");var r=n.catchesDropsOnPage,o=n.requiresDropOnElement,i=n.filterItems,a=void 0===i?function(e){return e}:i,s=function(e,t,n){var r=Tr(t),o={element:e,filterElement:n,state:null,ondrop:function(){},onenter:function(){},ondrag:function(){},onexit:function(){},onload:function(){},allowdrop:function(){}};return o.destroy=r.addListener(o),o}(e,r?document.documentElement:e,o),u="",l="";s.allowdrop=function(e){return t(a(e))},s.ondrop=function(e,n){var r=a(n);t(r)?(l="drag-drop",c.onload(r,e)):c.ondragend(e)},s.ondrag=function(e){c.ondrag(e)},s.onenter=function(e){l="drag-over",c.ondragstart(e)},s.onexit=function(e){l="drag-exit",c.ondragend(e)};var c={updateHopperState:function(){u!==l&&(e.dataset.hopperState=l,u=l)},onload:function(){},ondragstart:function(){},ondrag:function(){},ondragend:function(){},destroy:function(){s.destroy()}};return c},Sr=!1,Ar=[],Lr=function(e){var t=document.activeElement;if(t&&/textarea|input/i.test(t.nodeName)){for(var n=!1,r=t;r!==document.body;){if(r.classList.contains("filepond--root")){n=!0;break}r=r.parentNode}if(!n)return}tr(e.clipboardData).then(function(e){e.length&&Ar.forEach(function(t){return t(e)})})},Pr=function(){var e=function(e){t.onload(e)},t={destroy:function(){var t;t=e,de(Ar,Ar.indexOf(t)),0===Ar.length&&(document.removeEventListener("paste",Lr),Sr=!1)},onload:function(){}};return function(e){Ar.includes(e)||(Ar.push(e),Sr||(Sr=!0,document.addEventListener("paste",Lr)))}(e),t},br=null,Mr=null,wr=[],Cr=function(e,t){e.element.textContent=t},Nr=function(e,t,n){var r=e.query("GET_TOTAL_ITEMS");Cr(e,n+" "+t+", "+r+" "+(1===r?e.query("GET_LABEL_FILE_COUNT_SINGULAR"):e.query("GET_LABEL_FILE_COUNT_PLURAL"))),clearTimeout(Mr),Mr=setTimeout(function(){!function(e){e.element.textContent=""}(e)},1500)},Gr=function(e){return e.element.parentNode.contains(document.activeElement)},Ur=function(e){var t=e.root,n=e.action,r=t.query("GET_ITEM",n.id).filename,o=t.query("GET_LABEL_FILE_PROCESSING_ABORTED");Cr(t,r+" "+o)},Br=function(e){var t=e.root,n=e.action,r=t.query("GET_ITEM",n.id).filename;Cr(t,n.status.main+" "+r+" "+n.status.sub)},qr=S({create:function(e){var t=e.root,n=e.props;t.element.id="filepond--assistant-"+n.id,r(t.element,"role","status"),r(t.element,"aria-live","polite"),r(t.element,"aria-relevant","additions")},ignoreRect:!0,ignoreRectUpdate:!0,write:A({DID_LOAD_ITEM:function(e){var t=e.root,n=e.action;if(Gr(t)){t.element.textContent="";var r=t.query("GET_ITEM",n.id);wr.push(r.filename),clearTimeout(br),br=setTimeout(function(){Nr(t,wr.join(", "),t.query("GET_LABEL_FILE_ADDED")),wr.length=0},750)}},DID_REMOVE_ITEM:function(e){var t=e.root,n=e.action;if(Gr(t)){var r=n.item;Nr(t,r.filename,t.query("GET_LABEL_FILE_REMOVED"))}},DID_COMPLETE_ITEM_PROCESSING:function(e){var t=e.root,n=e.action,r=t.query("GET_ITEM",n.id).filename,o=t.query("GET_LABEL_FILE_PROCESSING_COMPLETE");Cr(t,r+" "+o)},DID_ABORT_ITEM_PROCESSING:Ur,DID_REVERT_ITEM_PROCESSING:Ur,DID_THROW_ITEM_REMOVE_ERROR:Br,DID_THROW_ITEM_LOAD_ERROR:Br,DID_THROW_ITEM_INVALID:Br,DID_THROW_ITEM_PROCESSING_ERROR:Br}),tag:"span",name:"assistant"}),Fr=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"-";return e.replace(new RegExp(t+".","g"),function(e){return e.charAt(1).toUpperCase()})},Vr=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:16,n=!(arguments.length>2&&void 0!==arguments[2])||arguments[2],r=Date.now(),o=null;return function(){for(var i=arguments.length,a=new Array(i),s=0;s=0?1:0,_=a.find(function(e){return e.markedForRemoval&&e.opacity<.45})?-1:0,T=a.length+E+_,I=mn(s,d);return 1===I?a.forEach(function(e){var r=e.rect.element.height+c;n+=r,t+=r*e.opacity}):(n=Math.ceil(T/I)*p,t=n),{visual:t,bounds:n}},jr=function(e){var t=e.ref.measureHeight||null;return{cappedHeight:parseInt(e.style.maxHeight,10)||null,fixedHeight:0===t?null:t}},Hr=function(e,t){var n=e.query("GET_ALLOW_REPLACE"),r=e.query("GET_ALLOW_MULTIPLE"),o=e.query("GET_TOTAL_ITEMS"),i=e.query("GET_MAX_FILES"),a=t.length;return!r&&a>1||!!(V(i=r?i:n?i:1)&&o+a>i)&&(e.dispatch("DID_THROW_MAX_FILES",{source:t,error:ot("warning",0,"Max files")}),!0)},Xr=function(e,t,n){var r=e.childViews[0];return hn(r,t,{left:n.scopeLeft-r.rect.element.left,top:n.scopeTop-(e.rect.outer.top+e.rect.element.marginTop+e.rect.element.scrollTop)})},Wr=function(e){var t=e.query("GET_ALLOW_DROP"),n=e.query("GET_DISABLED"),r=t&&!n;if(r&&!e.ref.hopper){var o=yr(e.element,function(t){var n=e.query("GET_BEFORE_DROP_FILE")||function(){return!0};return!e.query("GET_DROP_VALIDATION")||t.every(function(t){return De("ALLOW_HOPPER_ITEM",t,{query:e.query}).every(function(e){return!0===e})&&n(t)})},{filterItems:function(t){var n=e.query("GET_IGNORED_FILES");return t.filter(function(e){return!ht(e)||!n.includes(e.name.toLowerCase())})},catchesDropsOnPage:e.query("GET_DROP_ON_PAGE"),requiresDropOnElement:e.query("GET_DROP_ON_ELEMENT")});o.onload=function(t,n){var r=e.ref.list.childViews[0].childViews.filter(function(e){return e.rect.element.height}),o=e.query("GET_ACTIVE_ITEMS").map(function(e){return r.find(function(t){return t.id===e.id})}).filter(function(e){return e});Oe("ADD_ITEMS",t,{dispatch:e.dispatch}).then(function(t){if(Hr(e,t))return!1;e.dispatch("ADD_ITEMS",{items:t,index:Xr(e.ref.list,o,n),interactionMethod:ee})}),e.dispatch("DID_DROP",{position:n}),e.dispatch("DID_END_DRAG",{position:n})},o.ondragstart=function(t){e.dispatch("DID_START_DRAG",{position:t})},o.ondrag=Vr(function(t){e.dispatch("DID_DRAG",{position:t})}),o.ondragend=function(t){e.dispatch("DID_END_DRAG",{position:t})},e.ref.hopper=o,e.ref.drip=e.appendChildView(e.createChildView(jn))}else!r&&e.ref.hopper&&(e.ref.hopper.destroy(),e.ref.hopper=null,e.removeChildView(e.ref.drip))},zr=function(e,t){var n=e.query("GET_ALLOW_BROWSE"),r=e.query("GET_DISABLED"),o=n&&!r;o&&!e.ref.browser?e.ref.browser=e.appendChildView(e.createChildView(Bn,Object.assign({},t,{onload:function(t){Oe("ADD_ITEMS",t,{dispatch:e.dispatch}).then(function(t){if(Hr(e,t))return!1;e.dispatch("ADD_ITEMS",{items:t,index:-1,interactionMethod:te})})}})),0):!o&&e.ref.browser&&(e.removeChildView(e.ref.browser),e.ref.browser=null)},Qr=function(e){var t=e.query("GET_ALLOW_PASTE"),n=e.query("GET_DISABLED"),r=t&&!n;r&&!e.ref.paster?(e.ref.paster=Pr(),e.ref.paster.onload=function(t){Oe("ADD_ITEMS",t,{dispatch:e.dispatch}).then(function(t){if(Hr(e,t))return!1;e.dispatch("ADD_ITEMS",{items:t,index:-1,interactionMethod:ne})})}):!r&&e.ref.paster&&(e.ref.paster.destroy(),e.ref.paster=null)},Zr=A({DID_SET_ALLOW_BROWSE:function(e){var t=e.root,n=e.props;zr(t,n)},DID_SET_ALLOW_DROP:function(e){var t=e.root;Wr(t)},DID_SET_ALLOW_PASTE:function(e){var t=e.root;Qr(t)},DID_SET_DISABLED:function(e){var t=e.root,n=e.props;Wr(t),Qr(t),zr(t,n),t.query("GET_DISABLED")?t.element.dataset.disabled="disabled":t.element.removeAttribute("data-disabled")}}),$r=S({name:"root",read:function(e){var t=e.root;t.ref.measure&&(t.ref.measureHeight=t.ref.measure.offsetHeight)},create:function(e){var t=e.root,n=e.props,r=t.query("GET_ID");r&&(t.element.id=r);var o=t.query("GET_CLASS_NAME");o&&o.split(" ").filter(function(e){return e.length}).forEach(function(e){t.element.classList.add(e)}),t.ref.label=t.appendChildView(t.createChildView(xn,Object.assign({},n,{translateY:null,caption:t.query("GET_LABEL_IDLE")}))),t.ref.list=t.appendChildView(t.createChildView(Ln,{translateY:null})),t.ref.panel=t.appendChildView(t.createChildView(pn,{name:"panel-root"})),t.ref.assistant=t.appendChildView(t.createChildView(qr,Object.assign({},n))),t.ref.data=t.appendChildView(t.createChildView(Zn,Object.assign({},n))),t.ref.measure=wt("div"),t.ref.measure.style.height="100%",t.element.appendChild(t.ref.measure),t.ref.bounds=null,t.query("GET_STYLES").filter(function(e){return!M(e.value)}).map(function(e){var n=e.name,r=e.value;t.element.dataset[n]=r}),t.ref.widthPrevious=null,t.ref.widthUpdated=Vr(function(){t.ref.updateHistory=[],t.dispatch("DID_RESIZE_ROOT")},250),t.ref.previousAspectRatio=null,t.ref.updateHistory=[];var i=window.matchMedia("(pointer: fine) and (hover: hover)").matches,a="PointerEvent"in window;t.query("GET_ALLOW_REORDER")&&a&&!i&&(t.element.addEventListener("touchmove",xr,{passive:!1}),t.element.addEventListener("gesturestart",xr));var s=t.query("GET_CREDITS");if(2===s.length){var u=document.createElement("a");u.className="filepond--credits",u.setAttribute("aria-hidden","true"),u.href=s[0],u.tabindex=-1,u.target="_blank",u.rel="noopener noreferrer",u.textContent=s[1],t.element.appendChild(u),t.ref.credits=u}},write:function(e){var t=e.root,n=e.props,r=e.actions;if(Zr({root:t,props:n,actions:r}),r.filter(function(e){return/^DID_SET_STYLE_/.test(e.type)}).filter(function(e){return!M(e.data.value)}).map(function(e){var n=e.type,r=e.data,o=Fr(n.substr(8).toLowerCase(),"_");t.element.dataset[o]=r.value,t.invalidateLayout()}),!t.rect.element.hidden){t.rect.element.width!==t.ref.widthPrevious&&(t.ref.widthPrevious=t.rect.element.width,t.ref.widthUpdated());var o=t.ref.bounds;o||(o=t.ref.bounds=jr(t),t.element.removeChild(t.ref.measure),t.ref.measure=null);var i=t.ref,a=i.hopper,s=i.label,u=i.list,l=i.panel;a&&a.updateHopperState();var c=t.query("GET_PANEL_ASPECT_RATIO"),f=t.query("GET_ALLOW_MULTIPLE"),d=t.query("GET_TOTAL_ITEMS"),p=d===(f?t.query("GET_MAX_FILES")||1e6:1),E=r.find(function(e){return"DID_ADD_ITEM"===e.type});if(p&&E){var _=E.data.interactionMethod;s.opacity=0,f?s.translateY=-40:_===J?s.translateX=40:s.translateY=_===te?40:30}else p||(s.opacity=1,s.translateX=0,s.translateY=0);var T=Yr(t),I=kr(t),v=s.rect.element.height,m=!f||p?0:v,h=p?u.rect.element.marginTop:0,g=0===d?0:u.rect.element.marginBottom,R=m+h+I.visual+g,O=m+h+I.bounds+g;if(u.translateY=Math.max(0,m-u.rect.element.marginTop)-T.top,c){var D=t.rect.element.width,y=D*c;c!==t.ref.previousAspectRatio&&(t.ref.previousAspectRatio=c,t.ref.updateHistory=[]);var S=t.ref.updateHistory;if(S.push(D),S.length>4)for(var A=S.length,L=A-10,P=0,b=A;b>=L;b--)if(S[b]===S[b-2]&&P++,P>=2)return;l.scalable=!1,l.height=y;var w=y-m-(g-T.bottom)-(p?h:0);I.visual>w?u.overflow=w:u.overflow=null,t.height=y}else if(o.fixedHeight){l.scalable=!1;var C=o.fixedHeight-m-(g-T.bottom)-(p?h:0);I.visual>C?u.overflow=C:u.overflow=null}else if(o.cappedHeight){var N=R>=o.cappedHeight,G=Math.min(o.cappedHeight,R);l.scalable=!0,l.height=N?G:G-T.top-T.bottom;var U=G-m-(g-T.bottom)-(p?h:0);R>o.cappedHeight&&I.visual>U?u.overflow=U:u.overflow=null,t.height=Math.min(o.cappedHeight,O-T.top-T.bottom)}else{var B=d>0?T.top+T.bottom:0;l.scalable=!0,l.height=Math.max(v,R-B),t.height=Math.max(v,O-B)}t.ref.credits&&l.heightCurrent&&(t.ref.credits.style.transform="translateY("+l.heightCurrent+"px)")}},destroy:function(e){var t=e.root;t.ref.paster&&t.ref.paster.destroy(),t.ref.hopper&&t.ref.hopper.destroy(),t.element.removeEventListener("touchmove",xr),t.element.removeEventListener("gesturestart",xr)},mixins:{styles:["height"]}}),Kr=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=null,o=Se(),i=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],r=Object.assign({},e),o=[],i=[],a=function(e,t,n){!n||document.hidden?(c[e]&&c[e](t),o.push({type:e,data:t})):i.push({type:e,data:t})},s=function(e){for(var t,n=arguments.length,r=new Array(n>1?n-1:0),o=1;o1&&void 0!==arguments[1]?arguments[1]:{};return new Promise(function(n,r){D([{source:e,options:t}],{index:t.index}).then(function(e){return n(e&&e[0])}).catch(r)})},addFiles:D,getFile:function(e){return i.query("GET_ACTIVE_ITEM",e)},processFile:S,prepareFile:R,removeFile:O,moveFile:function(e,t){return i.dispatch("MOVE_ITEM",{query:e,index:t})},getFiles:y,processFiles:function(){for(var e=arguments.length,t=new Array(e),n=0;n0&&void 0!==arguments[0]?arguments[0]:{},n={};return t(Se(),function(e,t){n[e]=t[0]}),Kr(Object.assign({},n,{},e))},eo=function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},o=[];t(e.attributes,function(t){o.push(e.attributes[t])});var i=o.filter(function(e){return e.name}).reduce(function(t,n){var o,i=r(e,n.name);return t[(o=n.name,Fr(o.replace(/^data-/,"")))]=i===n.name||i,t},{});return function e(n,r){t(r,function(r,o){t(n,function(e,t){var i=new RegExp(r);if(i.test(e)&&(delete n[e],!1!==o))if(U(o))n[o]=t;else{var a,s=o.group;H(o)&&!n[s]&&(n[s]={}),n[s][(a=e.replace(i,""),a.charAt(0).toLowerCase()+a.slice(1))]=t}}),o.mapping&&e(n[o.group],o.mapping)})}(i,n),i},to=function(){return(arguments.length<=0?void 0:arguments[0])instanceof HTMLElement?function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n={"^class$":"className","^multiple$":"allowMultiple","^capture$":"captureMethod","^webkitdirectory$":"allowDirectoriesOnly","^server":{group:"server",mapping:{"^process":{group:"process"},"^revert":{group:"revert"},"^fetch":{group:"fetch"},"^restore":{group:"restore"},"^load":{group:"load"}}},"^type$":!1,"^files$":!1};De("SET_ATTRIBUTE_TO_OPTION_MAP",n);var r=Object.assign({},t),o=eo("FIELDSET"===e.nodeName?e.querySelector("input[type=file]"):e,n);Object.keys(o).forEach(function(e){H(o[e])?(H(r[e])||(r[e]={}),Object.assign(r[e],o[e])):r[e]=o[e]}),r.files=(t.files||[]).concat(Array.from(e.querySelectorAll("input:not([type=file])")).map(function(e){return{source:e.value,options:{type:e.dataset.type}}}));var i=Jr(r);return e.files&&Array.from(e.files).forEach(function(e){i.addFile(e)}),i.replaceElement(e),i}.apply(void 0,arguments):Jr.apply(void 0,arguments)},no=["fire","_read","_write"],ro=function(e){var t={};return Ee(e,t,no),t},oo=function(e,t){return e.replace(/(?:{([a-zA-Z]+)})/g,function(e,n){return t[n]})},io=function(e){var t=new Blob(["(",e.toString(),")()"],{type:"application/javascript"}),n=URL.createObjectURL(t),r=new Worker(n);return{transfer:function(e,t){},post:function(e,t,n){var o=oe();r.onmessage=function(e){e.data.id===o&&t(e.data.message)},r.postMessage({id:o,message:e},n)},terminate:function(){r.terminate(),URL.revokeObjectURL(n)}}},ao=function(e){return new Promise(function(t,n){var r=new Image;r.onload=function(){t(r)},r.onerror=function(e){n(e)},r.src=e})},so=function(e,t){var n=e.slice(0,e.size,e.type);return n.lastModifiedDate=e.lastModifiedDate,n.name=t,n},uo=function(e){return so(e,e.name)},lo=[],co=function(e){if(!lo.includes(e)){lo.push(e);var n,r=e({addFilter:ye,utils:{Type:ge,forin:t,isString:U,isFile:ht,toNaturalFileSize:qt,replaceInString:oo,getExtensionFromFilename:je,getFilenameWithoutExtension:mt,guesstimateMimeType:er,getFileFromBlob:We,getFilenameFromURL:ke,createRoute:A,createWorker:io,createView:S,createItemAPI:Te,loadImage:ao,copyFile:uo,renameFile:so,createBlob:ze,applyFilterChain:Oe,text:Ct,getNumericAspectRatioFromString:Pe},views:{fileActionButton:Bt}});n=r.options,Object.assign(Ae,n)}},fo=(Zt=c()&&!("[object OperaMini]"===Object.prototype.toString.call(window.operamini))&&"visibilityState"in document&&"Promise"in window&&"slice"in Blob.prototype&&"URL"in window&&"createObjectURL"in window.URL&&"performance"in window&&("supports"in(window.CSS||{})||/MSIE|Trident/.test(window.navigator.userAgent)),function(){return Zt}),po={apps:[]},Eo=function(){};if(e.Status={},e.FileStatus={},e.FileOrigin={},e.OptionTypes={},e.create=Eo,e.destroy=Eo,e.parse=Eo,e.find=Eo,e.registerPlugin=Eo,e.getOptions=Eo,e.setOptions=Eo,fo()){!function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:60,r="__framePainter";if(window[r])return window[r].readers.push(e),void window[r].writers.push(t);window[r]={readers:[e],writers:[t]};var o=window[r],i=1e3/n,a=null,s=null,u=null,l=null,c=function(){document.hidden?(u=function(){return window.setTimeout(function(){return f(performance.now())},i)},l=function(){return window.clearTimeout(s)}):(u=function(){return window.requestAnimationFrame(f)},l=function(){return window.cancelAnimationFrame(s)})};document.addEventListener("visibilitychange",function(){l&&l(),c(),f(performance.now())});var f=function e(t){s=u(e),a||(a=t);var n=t-a;n<=i||(a=t-n%i,o.readers.forEach(function(e){return e()}),o.writers.forEach(function(e){return e(t)}))};c(),f(performance.now())}(function(){po.apps.forEach(function(e){return e._read()})},function(e){po.apps.forEach(function(t){return t._write(e)})});var _o=function t(){document.dispatchEvent(new CustomEvent("FilePond:loaded",{detail:{supported:fo,create:e.create,destroy:e.destroy,parse:e.parse,find:e.find,registerPlugin:e.registerPlugin,setOptions:e.setOptions}})),document.removeEventListener("DOMContentLoaded",t)};"loading"!==document.readyState?setTimeout(function(){return _o()},0):document.addEventListener("DOMContentLoaded",_o);var To=function(){return t(Se(),function(t,n){e.OptionTypes[t]=n[1]})};e.Status=Object.assign({},Me),e.FileOrigin=Object.assign({},ve),e.FileStatus=Object.assign({},Ie),e.OptionTypes={},To(),e.create=function(){var t=to.apply(void 0,arguments);return t.on("destroy",e.destroy),po.apps.push(t),ro(t)},e.destroy=function(e){var t=po.apps.findIndex(function(t){return t.isAttachedTo(e)});return t>=0&&(po.apps.splice(t,1)[0].restoreElement(),!0)},e.parse=function(t){return Array.from(t.querySelectorAll(".filepond")).filter(function(e){return!po.apps.find(function(t){return t.isAttachedTo(e)})}).map(function(t){return e.create(t)})},e.find=function(e){var t=po.apps.find(function(t){return t.isAttachedTo(e)});return t?ro(t):null},e.registerPlugin=function(){for(var e=arguments.length,t=new Array(e),n=0;n 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 25 | 26 | 27 |
28 |   ____  _   _ ____  _   _   _____ ___    _  _____ _   _ ____  _     _____ _ 
29 |  |  _ \| | | / ___|| | | | |_   _/ _ \  | |/ /_ _| \ | |  _ \| |   | ____| |
30 |  | |_) | | | \___ \| |_| |   | || | | | | ' / | ||  \| | | | | |   |  _| | |
31 |  |  __/| |_| |___) |  _  |   | || |_| | | . \ | || |\  | |_| | |___| |___|_|
32 |  |_|    \___/|____/|_| |_|   |_| \___/  |_|\_\___|_| \_|____/|_____|_____(_)
34 | 35 | 36 | -------------------------------------------------------------------------------- /app/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | {{ title }} 10 | 15 | 20 | 21 | 22 | 23 | 24 |
25 |
26 | {{ title }} 27 |
28 |
29 | {{ title }} 是一个开源工具,可以往你的 Kindle 34 | 上推送文档,只要👇四步你的泡面板就多了一个用处啦。 35 |
36 |
37 | 1 38 |
39 |
40 | 将 41 | {{ from_user }} 42 | 添加到你亚马逊账号的已认可发件人电子邮箱列表中。啥意思? 47 |
48 |
49 |
50 |
51 | 2 52 |
53 | 59 |
60 | 你的 Kindle 邮箱会不会填错啦,应该是类似这样的格式:ilove@kindle.cn 64 |
65 |
66 |
67 |
68 | 3 69 |
70 | 71 |
72 | 刚上传的文件格式不支持,会被忽略的哦。 73 |
74 |
75 |
76 |
77 | 4 78 |
79 | 80 |
81 | 请好好检查你的 Kindle 邮箱! 82 |
83 |
84 | 确保你还有未推送且符合格式的文件! 85 |
86 |
87 |
88 |
89 |
90 | 目前支持一次推送 5 个文档,单个文档最大只能 24M 哦。 91 |
92 |
93 | 目前支持的文件格式:[.jpeg, .jpg, .gif, .png, .doc, .docx, .html, .htm, .rtf, .mobi, 98 | .azw, .bmp, .pdf, .txt],其他格式的文件将会被忽略哦。 99 |
100 |
101 | 对于 .azw3 和 .epub 格式的文档,可以先用 102 | calibre 转换成 103 | .mobi 格式。 104 |
105 |
106 | 本网站承诺保护你的文件隐私安全,文件上传后会在一天内自动删除。 107 |
108 |
109 | 如果在使用过程中遇到问题或者有什么建议,请 110 | 邮件联系作者 111 | ,或在 QQ 群 112 | 178459233 跟我说哦~ 113 |
114 |
115 | 最后,欢迎光临我的个人主页 🥳 116 |
117 |
118 | © 2019 PUSH TO KINDLE!    粤ICP备2021087752号 122 |
123 |
124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 330 | 331 | 332 | -------------------------------------------------------------------------------- /app/utils.py: -------------------------------------------------------------------------------- 1 | import math 2 | 3 | from googletrans import Translator 4 | 5 | _translator = Translator(service_urls=["translate.google.cn"]) 6 | 7 | 8 | def translate(text, src="zh-CN", dest="en"): 9 | return _translator.translate(text, src=src, dest=dest).text 10 | 11 | 12 | def convert_file_size_to_mb(size_bytes): 13 | return math.ceil(size_bytes / math.pow(1024, 2)) 14 | -------------------------------------------------------------------------------- /config.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | 4 | class Config: 5 | # app 6 | APP_NAME = "PUSH TO KINDLE!" 7 | UPLOAD_FOLDER = os.environ.get("UPLOAD_FOLDER") 8 | ACCEPTED_FILE_TYPES = [ 9 | ".jpeg", 10 | ".jpg", 11 | ".gif", 12 | ".png", 13 | ".doc", 14 | ".docx", 15 | ".html", 16 | ".htm", 17 | ".rtf", 18 | ".mobi", 19 | ".azw", 20 | ".azw3", 21 | ".bmp", 22 | ".pdf", 23 | ".txt", 24 | ".epub", 25 | ".zip", 26 | ] 27 | TRANSFER_FILE_TYPES = [".epub"] 28 | MAX_CONTENT_LENGTH = 120 * 1024 * 1024 29 | # mailgun 30 | MG_DOMAIN_NAME = "push.tokindle.top" 31 | MG_API_KEY = os.environ.get("MG_API_KEY") 32 | MG_EMAIL_FROM = "please@%s" % MG_DOMAIN_NAME 33 | MG_EMAIL_FROM_USER = "%s <%s>" % (APP_NAME, MG_EMAIL_FROM) 34 | MG_EMAIL_SUBJECT = "convert" 35 | MG_EMAIL_TEXT = "Documents have been pushed to your kindle." 36 | 37 | @staticmethod 38 | def init_app(app): 39 | pass 40 | 41 | 42 | class DevelopmentConfig(Config): 43 | DEBUG = True 44 | HOST = "http://127.0.0.1:8001" 45 | MG_EMAIL_TO = os.environ.get("MG_EMAIL_TO_FOR_TEST") 46 | 47 | 48 | class ProductionConfig(Config): 49 | DEBUG = False 50 | HOST = os.environ.get("PRODUCTION_HOST") 51 | 52 | 53 | config = { 54 | "development": DevelopmentConfig, 55 | "production": ProductionConfig, 56 | "default": DevelopmentConfig, 57 | } 58 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | web: 5 | image: aneureka/push-to-kindle:latest 6 | build: . 7 | ports: 8 | - "8001:8001" 9 | volumes: 10 | - /tmp/push-to-kindle:/tmp/push-to-kindle/ 11 | restart: unless-stopped 12 | -------------------------------------------------------------------------------- /manager.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from flask_script import Manager, Shell 4 | 5 | from app import create_app 6 | 7 | app = create_app(os.getenv("FLASK_ENV") or "default") 8 | manager = Manager(app) 9 | 10 | 11 | def make_shell_context(): 12 | return dict(app=app) 13 | 14 | 15 | manager.add_command("shell", Shell(make_context=make_shell_context)) 16 | 17 | 18 | if __name__ == "__main__": 19 | manager.run() 20 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Flask==1.0.2 2 | Flask-Cors>=3.0.9 3 | Flask-Script==2.0.6 4 | googletrans==2.4.0 5 | jinja2>=2.11.3 6 | requests==2.22.0 7 | urllib3==1.25.3 8 | uWSGI==2.0.18 9 | Werkzeug==0.15.3 10 | -------------------------------------------------------------------------------- /uwsgi.ini: -------------------------------------------------------------------------------- 1 | [uwsgi] 2 | http = :8001 3 | chdir = /app 4 | wsgi-file = manager.py 5 | callable = app 6 | processes = 8 7 | threads = 8 8 | stats = 127.0.0.1:9191 9 | harakiri = 240 10 | socket-timeout = 240 11 | http-timeout = 240 12 | limit-post = 0 13 | --------------------------------------------------------------------------------