├── .gitignore
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── api
├── .dockerignore
├── Dockerfile
├── docbleach.py
├── docbleach
│ ├── __init__.py
│ ├── config
│ │ └── __init__.py
│ ├── controllers
│ │ ├── __init__.py
│ │ ├── base.py
│ │ ├── ping.py
│ │ ├── static.py
│ │ ├── task.py
│ │ └── upload.py
│ ├── tasks
│ │ └── __init__.py
│ └── utils
│ │ └── __init__.py
├── requirements.txt
└── static
│ ├── css
│ ├── bootstrap-3.3.7.css
│ ├── docbleach.css
│ └── sweetalert2.min.css
│ ├── favicon
│ ├── android-chrome-192x192.png
│ ├── android-chrome-512x512.png
│ ├── apple-touch-icon.png
│ ├── browserconfig.xml
│ ├── favicon-16x16.png
│ ├── favicon-32x32.png
│ ├── favicon.ico
│ ├── manifest.json
│ ├── mstile-144x144.png
│ ├── mstile-150x150.png
│ ├── mstile-310x150.png
│ ├── mstile-310x310.png
│ ├── mstile-70x70.png
│ └── safari-pinned-tab.svg
│ ├── index.html
│ ├── js
│ ├── docbleach.js
│ ├── html5shiv.js
│ ├── jquery.min.js
│ ├── respond.min.js
│ └── sweetalert2.min.js
│ ├── swagger.yaml
│ └── swagger
│ ├── docbleach-conf.js
│ ├── index.html
│ ├── swagger-ui-bundle.js
│ ├── swagger-ui-bundle.js.map
│ ├── swagger-ui-standalone-preset.js
│ ├── swagger-ui-standalone-preset.js.map
│ ├── swagger-ui.css
│ ├── swagger-ui.css.map
│ ├── swagger-ui.js
│ └── swagger-ui.js.map
├── autoscale
├── .dockerignore
├── Dockerfile
├── autoscale2.py
├── entrypoint.sh
└── requirements.txt
├── docker-compose.yml
├── docs
├── Chooseafile.png
├── clickhere.png
└── downloadyourfile.png
└── worker
├── .dockerignore
├── Dockerfile
├── docbleach
├── __init__.py
├── celeryconfig.py
└── tasks
│ └── __init__.py
├── entrypoint.sh
└── requirements.txt
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Created by https://www.gitignore.io/api/pycharm,python,virtualenv,intellij+iml
3 |
4 | ### Intellij+iml ###
5 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
6 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
7 |
8 | # User-specific stuff:
9 | .idea/**/workspace.xml
10 | .idea/**/tasks.xml
11 | .idea/dictionaries
12 |
13 | # Sensitive or high-churn files:
14 | .idea/**/dataSources/
15 | .idea/**/dataSources.ids
16 | .idea/**/dataSources.xml
17 | .idea/**/dataSources.local.xml
18 | .idea/**/sqlDataSources.xml
19 | .idea/**/dynamic.xml
20 | .idea/**/uiDesigner.xml
21 |
22 | # Gradle:
23 | .idea/**/gradle.xml
24 | .idea/**/libraries
25 |
26 | # Mongo Explorer plugin:
27 | .idea/**/mongoSettings.xml
28 |
29 | ## File-based project format:
30 | *.iws
31 |
32 | ## Plugin-specific files:
33 |
34 | # IntelliJ
35 | /out/
36 |
37 | # mpeltonen/sbt-idea plugin
38 | .idea_modules/
39 |
40 | # JIRA plugin
41 | atlassian-ide-plugin.xml
42 |
43 | # Cursive Clojure plugin
44 | .idea/replstate.xml
45 |
46 | # Crashlytics plugin (for Android Studio and IntelliJ)
47 | com_crashlytics_export_strings.xml
48 | crashlytics.properties
49 | crashlytics-build.properties
50 | fabric.properties
51 |
52 | ### Intellij+iml Patch ###
53 | # Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023
54 |
55 | *.iml
56 | modules.xml
57 | .idea/misc.xml
58 | *.ipr
59 |
60 | ### PyCharm ###
61 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
62 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
63 |
64 | # User-specific stuff:
65 |
66 | # Sensitive or high-churn files:
67 |
68 | # Gradle:
69 |
70 | # Mongo Explorer plugin:
71 |
72 | ## File-based project format:
73 |
74 | ## Plugin-specific files:
75 |
76 | # IntelliJ
77 |
78 | # mpeltonen/sbt-idea plugin
79 |
80 | # JIRA plugin
81 |
82 | # Cursive Clojure plugin
83 |
84 | # Crashlytics plugin (for Android Studio and IntelliJ)
85 |
86 | ### PyCharm Patch ###
87 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
88 |
89 | # *.iml
90 | # modules.xml
91 | # .idea/misc.xml
92 | # *.ipr
93 |
94 | # Sonarlint plugin
95 | .idea/sonarlint
96 |
97 | ### Python ###
98 | # Byte-compiled / optimized / DLL files
99 | __pycache__/
100 | *.py[cod]
101 | *$py.class
102 |
103 | # C extensions
104 | *.so
105 |
106 | # Distribution / packaging
107 | .Python
108 | env/
109 | build/
110 | develop-eggs/
111 | dist/
112 | downloads/
113 | eggs/
114 | .eggs/
115 | lib/
116 | lib64/
117 | parts/
118 | sdist/
119 | var/
120 | wheels/
121 | *.egg-info/
122 | .installed.cfg
123 | *.egg
124 |
125 | # PyInstaller
126 | # Usually these files are written by a python script from a template
127 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
128 | *.manifest
129 | *.spec
130 |
131 | # Installer logs
132 | pip-log.txt
133 | pip-delete-this-directory.txt
134 |
135 | # Unit test / coverage reports
136 | htmlcov/
137 | .tox/
138 | .coverage
139 | .coverage.*
140 | .cache
141 | nosetests.xml
142 | coverage.xml
143 | *,cover
144 | .hypothesis/
145 |
146 | # Translations
147 | *.mo
148 | *.pot
149 |
150 | # Django stuff:
151 | *.log
152 | local_settings.py
153 |
154 | # Flask stuff:
155 | instance/
156 | .webassets-cache
157 |
158 | # Scrapy stuff:
159 | .scrapy
160 |
161 | # Sphinx documentation
162 | docs/_build/
163 |
164 | # PyBuilder
165 | target/
166 |
167 | # Jupyter Notebook
168 | .ipynb_checkpoints
169 |
170 | # pyenv
171 | .python-version
172 |
173 | # celery beat schedule file
174 | celerybeat-schedule
175 |
176 | # SageMath parsed files
177 | *.sage.py
178 |
179 | # dotenv
180 | .env
181 |
182 | # virtualenv
183 | .venv
184 | venv/
185 | ENV/
186 |
187 | # Spyder project settings
188 | .spyderproject
189 |
190 | # Rope project settings
191 | .ropeproject
192 |
193 | ### VirtualEnv ###
194 | # Virtualenv
195 | # http://iamzed.com/2009/05/07/a-primer-on-virtualenv/
196 | [Bb]in
197 | [Ii]nclude
198 | [Ll]ib
199 | [Ll]ib64
200 | [Ll]ocal
201 | [Ss]cripts
202 | pyvenv.cfg
203 | pip-selfcheck.json
204 |
205 | # End of https://www.gitignore.io/api/pycharm,python,virtualenv,intellij+iml
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | :tada: :+1: *Thanks for reading this \o/ You're already helping us!* :tada:
4 |
5 |
6 | DocBleach is a young project, but contributing means a lot of different things.
7 | Providing feedback on a feature, reporting bugs or even fixing typos in the code are contributions.
8 | Knowing how to code is great, but not a requirement.
9 |
10 | When contributing to this repository, please first discuss the change you wish to make via issue,
11 | email, or any other method with the owners of this repository before making a change.
12 |
13 | Please note we have a code of conduct, please follow it in all your interactions with the project.
14 |
15 |
16 | ## Pull Request Process
17 |
18 | 1. Relax, take your time and be fearless. The PR Process is there to ensure the project moves in one
19 | direction, not to challenge you ;-)
20 | 2. Ensure your code works.
21 | 3. Match the existing code style (PEP 8 for Python files).
22 | 4. Send the PR on GitHub \o/
23 |
24 |
25 |
26 | ## Code of Conduct
27 |
28 | ### Our Pledge
29 |
30 | In the interest of fostering an open and welcoming environment, we as
31 | contributors and maintainers pledge to making participation in our project and
32 | our community a harassment-free experience for everyone, regardless of age, body
33 | size, disability, ethnicity, gender identity and expression, level of experience,
34 | nationality, personal appearance, race, religion, or sexual identity and
35 | orientation.
36 |
37 | ### Our Standards
38 |
39 | Examples of behavior that contributes to creating a positive environment
40 | include:
41 |
42 | * Using welcoming and inclusive language
43 | * Being respectful of differing viewpoints and experiences
44 | * Gracefully accepting constructive criticism
45 | * Focusing on what is best for the community
46 | * Showing empathy towards other community members
47 |
48 | Examples of unacceptable behavior by participants include:
49 |
50 | * The use of sexualized language or imagery and unwelcome sexual attention or
51 | advances
52 | * Trolling, insulting/derogatory comments, and personal or political attacks
53 | * Public or private harassment
54 | * Publishing others' private information, such as a physical or electronic
55 | address, without explicit permission
56 | * Other conduct which could reasonably be considered inappropriate in a
57 | professional setting
58 |
59 | ### Our Responsibilities
60 |
61 | Project maintainers are responsible for clarifying the standards of acceptable
62 | behavior and are expected to take appropriate and fair corrective action in
63 | response to any instances of unacceptable behavior.
64 |
65 | Project maintainers have the right and responsibility to remove, edit, or
66 | reject comments, commits, code, wiki edits, issues, and other contributions
67 | that are not aligned to this Code of Conduct, or to ban temporarily or
68 | permanently any contributor for other behaviors that they deem inappropriate,
69 | threatening, offensive, or harmful.
70 |
71 | ### Scope
72 |
73 | This Code of Conduct applies both within project spaces and in public spaces
74 | when an individual is representing the project or its community. Examples of
75 | representing a project or community include using an official project e-mail
76 | address, posting via an official social media account, or acting as an appointed
77 | representative at an online or offline event. Representation of a project may be
78 | further defined and clarified by project maintainers.
79 |
80 | ### Enforcement
81 |
82 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
83 | reported by contacting the project team at [INSERT EMAIL ADDRESS]. All
84 | complaints will be reviewed and investigated and will result in a response that
85 | is deemed necessary and appropriate to the circumstances. The project team is
86 | obligated to maintain confidentiality with regard to the reporter of an incident.
87 | Further details of specific enforcement policies may be posted separately.
88 |
89 | Project maintainers who do not follow or enforce the Code of Conduct in good
90 | faith may face temporary or permanent repercussions as determined by other
91 | members of the project's leadership.
92 |
93 | ### Attribution
94 |
95 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
96 | available at [http://contributor-covenant.org/version/1/4][version].
97 |
98 | [homepage]: http://contributor-covenant.org
99 | [version]: http://contributor-covenant.org/version/1/4/
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Maxime Guerreiro
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DocBleach aaS - Sanitize your documents in the cloud™
2 |
3 | [DocBleach][github] allows you to sanitize your Word, Excel, PowerPoint, PDF, ... documents. This repository contains the
4 | DocBleach Web API, packaged as a docker service. Two clicks and you'll feel safer.
5 |
6 | [](https://www.codacy.com/app/DocBleach/DocBleach-Web?utm_source=github.com&utm_medium=referral&utm_content=docbleach/DocBleach-Web&utm_campaign=Badge_Grade)
7 |
8 | You have files to sanitize but you can't install Java, may it be because you run on an embedded system or you deploy
9 | your PHP app on a shared hosting and Java is not available ... This package is the solution to your issues!
10 |
11 | # Installation
12 |
13 | Three modules are present in this repository:
14 | - *api*
15 | contains the Web API, a lightweight Python Flask app that
16 | receives the files and responds to status requests.
17 | - *worker* contains DocBleach and launches it using Python Celery.
18 | - *autoscale* auto-scaling for Mesos Marathon, documentation still has to be written.
19 |
20 | Thanks to Docker, you are able to easily deploy this app.
21 |
22 | Celery requires a message broker and a backend to store its results.
23 | Using something as easy to setup as Redis is fine, as it is able to serve
24 | both roles, but you may use [another broker][1] or another [backend storage][backend_celery].
25 |
26 | Configuration is given to each component thru environment variables,
27 | namely `CELERY_BROKER` and `CELERY_RESULT_BACKEND`. They accept URI as
28 | valid values, for instance to use a local Redis server protected by the
29 | password `PASS123` you would use this:
30 | `CELERY_BROKER=redis://:PASS123@127.0.0.1/`.
31 |
32 | In order to pass the files from the API to the Worker, a storage backend is required.
33 | Plik is used, because it is easy to setup (unlike OpenStack/AWS), Open-Source and supports `expire` out of the box.
34 |
35 | By default using Docker Compose, an internal Plik instance is started and the sanitized files are stored on plik.root.gg
36 |
37 | You may change this using the `INTERNAL_PLIK_SERVER` and `FINAL_PLIK_SERVER` env variables.
38 |
39 | # Howto's
40 | To run the containers using Docker Compose, just call `docker-compose up -d` in this project's directory.
41 | Docker will take care of the boring stuff for you! :)
42 | ```bash
43 | $ docbleach-rest$ docker-compose up -d
44 | Starting docbleachrest_worker_1
45 | Starting docbleachrest_plik_1
46 | Starting docbleachrest_web_1
47 | Starting docbleachrest_redis_1
48 | $ docker ps
49 | CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
50 | 5d258cfac1d6 docbleach/api:latest "/usr/src/app/entrypo" About a minute ago Up 41 seconds 0.0.0.0:9000->5000/tcp docbleachrest_web_1
51 | 5c3d91acba01 docbleach/worker:latest "/usr/src/app/entrypo" About a minute ago Up 41 seconds docbleachrest_worker_1
52 | ebcef5f636d5 rootgg/plik "/bin/sh -c ./plikd" 9 days ago Up 41 seconds 8080/tcp docbleachrest_plik_1
53 | eb69034e73f5 redis "docker-entrypoint.sh" 10 days ago Up 41 seconds 6379/tcp docbleachrest_redis_1
54 | ```
55 |
56 | As you can see, DocBleach-api is running on your port `5000`.
57 | Just open `127.0.0.1:5000` in your browser to try it out :wink:.
58 |
59 |
60 | ## Get the sources
61 |
62 | ```bash
63 | git clone https://github.com/docbleach/DocBleach-Web.git
64 | cd DocBleach-Web
65 | ```
66 |
67 | A `Dockerfile` makes it easy to hack on a part of this project.
68 |
69 | You've developed a new cool feature ? Fixed an annoying bug ? We'd be happy
70 | to hear from you !
71 |
72 |
73 | Documentation uses [Swagger][swagger], and thus is rendered client-side using the specifications in
74 | `api/static/swagger.yaml`.
75 |
76 | # How to Sanitize
77 |
78 | to start sanitizing your file, click on the "pick a file" button
79 | 
80 | then choose the file you want to sanitize
81 | 
82 | Finaly, click "Download the sanitized file" to get your file back
83 | 
84 |
85 | # Related links
86 |
87 | * Contribute: https://github.com/docbleach/DocBleach-Web
88 | * Report bugs: https://github.com/docbleach/DocBleach-Web/issues
89 | * Get latest version: https://hub.docker.com/u/docbleach/
90 |
91 | # License
92 |
93 | See https://github.com/docbleach/DocBleach-Web/blob/master/LICENSE
94 |
95 | # Project status
96 |
97 | This project works, but would be greatly improved with little tweaks.
98 |
99 | For instance, it would be really great to:
100 | - Write more documentation, because there's never enough of it. :-(
101 | - Have an improved design.
102 | - Improve the API once the [code base is rewamped](issue_codebase), to give an extended output, allow configuration...
103 | - Remove dependencies, having Java and Python code in a docker file is a bad practice. For now, it works.
104 |
105 |
106 |
107 | [1]: http://docs.celeryproject.org/en/latest/getting-started/brokers/
108 | [backend_celery]: http://docs.celeryproject.org/en/latest/getting-started/first-steps-with-celery.html#keeping-results
109 | [swagger]: https://swagger.io/
110 | [github]: https://github.com/docbleach/DocBleach
111 | [logo_link]: https://github.com/docbleach/DocBleach/404
112 | [issue_codebase]: https://github.com/docbleach/DocBleach/issues/2
113 |
--------------------------------------------------------------------------------
/api/.dockerignore:
--------------------------------------------------------------------------------
1 | .dockerignore
2 | *.iml
3 | .idea
4 | .venv
5 | .git
6 | .gitignore
7 | Dockerfile
--------------------------------------------------------------------------------
/api/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.7-alpine
2 |
3 | EXPOSE 5000
4 | HEALTHCHECK CMD curl --fail http://localhost:5000/ping
5 |
6 | ENV INTERNAL_PLIK_SERVER https://plik.root.gg
7 |
8 | # We add the Plik binary file
9 | ADD https://plik.root.gg/clients/linux-amd64/plik /usr/bin/plik
10 |
11 | RUN apk add -t build --no-cache --update-cache \
12 | # Having up to date SSL certificates is always a good thing. :)
13 | ca-certificates \
14 | openssl \
15 | # For the healthcheck
16 | curl \
17 | && \
18 | update-ca-certificates && \
19 |
20 | # Add glibc, wanted by plik (compiled with Go)
21 | wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub && \
22 | wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.23-r3/glibc-2.23-r3.apk && \
23 | apk add glibc-2.23-r3.apk && \
24 |
25 | # Remove openssl, only needed for wget
26 | apk del build wget unzip && \
27 |
28 | # We add an user
29 | adduser -S -u 1000 worker && \
30 |
31 | # Add default config for Plik, required
32 | chmod o+x /usr/bin/plik && \
33 | echo 'URL = "https://plik.root.gg"' > /home/worker/.plikrc
34 |
35 |
36 | # Install the python dependencies
37 | ADD requirements.txt /app/
38 | WORKDIR /app/
39 |
40 | RUN pip3 install --no-cache-dir -r requirements.txt
41 |
42 | COPY . /app/
43 | RUN chown -R worker /app/; chmod -R 770 /app/
44 |
45 | USER worker
46 | ENTRYPOINT ["python3", "/app/docbleach.py"]
47 |
--------------------------------------------------------------------------------
/api/docbleach.py:
--------------------------------------------------------------------------------
1 | import tornado.ioloop
2 |
3 | from docbleach import application
4 |
5 | if __name__ == "__main__":
6 | print("Listening on port 5000")
7 | application.listen(5000)
8 | tornado.ioloop.IOLoop.instance().start()
9 |
--------------------------------------------------------------------------------
/api/docbleach/__init__.py:
--------------------------------------------------------------------------------
1 | import tornado.web
2 | from tornado.log import enable_pretty_logging
3 |
4 | from .config import debug_mode
5 | from .controllers import *
6 | from .utils import static
7 |
8 | application = tornado.web.Application([
9 | (r'/static/(.*)', StaticFileHandler, {'path': static()}),
10 | (r'/doc/()', StaticFileHandler, {'path': static('swagger', 'index.html')}),
11 | (r'/doc/(.*)', StaticFileHandler, {'path': static('swagger')}),
12 | (r'/()', StaticFileHandler, {'path': static('index.html')}),
13 |
14 | (r'/ping', PingHandler),
15 | (r'/v1/ping', PingHandler),
16 | (r'/v1/tasks', UploadHandler),
17 | (r'/v1/tasks/(.*)', TaskHandler),
18 | ], debug=debug_mode)
19 |
20 | enable_pretty_logging()
21 |
--------------------------------------------------------------------------------
/api/docbleach/config/__init__.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | __UPLOADS__ = 'uploads/'
4 |
5 | internal_plik_server = os.getenv('INTERNAL_PLIK_SERVER', 'https://plik.root.gg')
6 |
7 | celery_broker = os.getenv('CELERY_BROKER')
8 |
9 | celery_result_backend = os.getenv('CELERY_RESULT_BACKEND')
10 |
11 | debug_mode = os.getenv('DEBUG', 'true').lower() == 'true'
12 |
13 | advertise_server = os.getenv('DOCBLEACH_AS_SERVER_HEADER', 'false') == 'true'
14 |
15 | PLIK_COMMAND = [
16 | 'plik',
17 | '--server', internal_plik_server,
18 | '-t', '3h',
19 | '-q'
20 | ]
21 |
--------------------------------------------------------------------------------
/api/docbleach/controllers/__init__.py:
--------------------------------------------------------------------------------
1 | from .base import BaseHandler
2 | from .ping import PingHandler
3 | from .static import StaticFileHandler
4 | from .task import TaskHandler
5 | from .upload import UploadHandler
6 |
--------------------------------------------------------------------------------
/api/docbleach/controllers/base.py:
--------------------------------------------------------------------------------
1 | import tornado.web
2 |
3 | from ..config import advertise_server
4 |
5 | CSP_POLICY = "default-src 'self' https:;" + \
6 | "style-src 'self' 'unsafe-inline' https:;" + \
7 | "img-src 'self' data: https:;" + \
8 | "frame-ancestors 'none';" + \
9 | "form-action *;"
10 |
11 | REFERRER_POLICY = 'no-referrer, strict-origin-when-cross-origin'
12 |
13 |
14 | class BaseHandler(tornado.web.RequestHandler):
15 | def set_default_headers(self):
16 | super(BaseHandler, self).set_default_headers()
17 |
18 | if advertise_server:
19 | self.set_header('Server', 'DocBleach')
20 | else:
21 | self.clear_header('Server')
22 |
23 | self.set_header('X-Frame-Options', 'DENY')
24 | self.set_header('Referrer-Policy', REFERRER_POLICY)
25 | self.set_header('Content-Security-Policy', CSP_POLICY)
26 | self.set_header('X-Content-Type-Options', 'nosniff')
27 | self.set_header('X-XSS-Protection', '1; mode=block')
28 |
29 |
30 | class BaseApiHandler(BaseHandler):
31 | def set_default_headers(self):
32 | super(BaseApiHandler, self).set_default_headers()
33 | self.set_header('Access-Control-Allow-Origin', '*')
34 | self.set_header('Access-Control-Allow-Headers', 'x-requested-with')
35 | self.set_header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS')
36 |
37 | def options(self, *args, **kwargs):
38 | self.set_status(204)
39 | self.finish()
40 |
41 | def write_error(self, status_code, **kwargs):
42 | if status_code in [500, 503]:
43 | self.write('Error %s' % status_code)
44 |
--------------------------------------------------------------------------------
/api/docbleach/controllers/ping.py:
--------------------------------------------------------------------------------
1 | import tornado.web
2 |
3 |
4 | class PingHandler(tornado.web.RequestHandler):
5 | def get(self):
6 | self.finish('pong')
7 |
--------------------------------------------------------------------------------
/api/docbleach/controllers/static.py:
--------------------------------------------------------------------------------
1 | import tornado.web
2 |
3 | from .base import BaseHandler
4 |
5 |
6 | class StaticFileHandler(tornado.web.StaticFileHandler, BaseHandler):
7 | pass
8 |
--------------------------------------------------------------------------------
/api/docbleach/controllers/task.py:
--------------------------------------------------------------------------------
1 | import tornado.gen
2 |
3 | from .base import BaseApiHandler
4 | from ..tasks import cel
5 |
6 |
7 | class TaskHandler(BaseApiHandler):
8 | @tornado.gen.coroutine
9 | def get(self, task_id):
10 | data = yield self.get_task_meta(task_id)
11 | result_data = {'result': data['result'], 'status': data['status']}
12 |
13 | self.finish(result_data)
14 |
15 | @staticmethod
16 | @tornado.gen.coroutine
17 | def get_task_meta(task_id):
18 | return cel.backend.get_task_meta(task_id)
19 |
--------------------------------------------------------------------------------
/api/docbleach/controllers/upload.py:
--------------------------------------------------------------------------------
1 | from subprocess import Popen, PIPE
2 |
3 | import tornado.gen
4 | import tornado.web
5 |
6 | from .base import BaseApiHandler
7 | from ..config import PLIK_COMMAND
8 | from ..tasks import cel
9 | from ..utils import secure_uuid
10 |
11 |
12 | class UploadHandler(BaseApiHandler):
13 | @tornado.gen.coroutine
14 | def post(self):
15 | if 'file' not in self.request.files:
16 | raise tornado.web.HTTPError(404)
17 |
18 | fileinfo = self.request.files['file']
19 | if isinstance(fileinfo, list):
20 | fileinfo = fileinfo[0]
21 |
22 | filename = str(fileinfo['filename'].strip())
23 |
24 | link = yield self.store_on_plik(fileinfo)
25 | async_res = yield self.add_task(link, filename)
26 |
27 | self.set_status(202)
28 | self.finish({'task_id': async_res.id})
29 |
30 | @staticmethod
31 | @tornado.gen.coroutine
32 | def store_on_plik(fileinfo):
33 | p = Popen(PLIK_COMMAND, stdout=PIPE, stdin=PIPE, stderr=PIPE)
34 | link, err = p.communicate(input=fileinfo.body)
35 |
36 | if err:
37 | print(err)
38 |
39 | link = link.strip().decode('utf-8')
40 |
41 | return link
42 |
43 | @staticmethod
44 | @tornado.gen.coroutine
45 | def add_task(link, filename):
46 | task_id = secure_uuid()
47 | args = [link, filename]
48 | return cel.send_task('sanitize',
49 | task_id=task_id,
50 | # TTL for the event, equal to Plik's TTL
51 | expires=3 * 3600,
52 | args=args,
53 | kwargs={})
54 |
--------------------------------------------------------------------------------
/api/docbleach/tasks/__init__.py:
--------------------------------------------------------------------------------
1 | from celery import Celery
2 |
3 | from ..config import celery_broker, celery_result_backend
4 |
5 | cel = Celery(
6 | 'docbleach',
7 | broker=celery_broker,
8 | backend=celery_result_backend
9 | )
10 |
--------------------------------------------------------------------------------
/api/docbleach/utils/__init__.py:
--------------------------------------------------------------------------------
1 | import os
2 | import string
3 | from random import SystemRandom
4 |
5 | cryptogen = SystemRandom()
6 |
7 |
8 | def secure_uuid():
9 | """
10 | Strength: 6*3 random characters from a list of 62, approx. 64^18 possible
11 | strings, or 2^100. Should be enough to prevent a successful bruteforce, as
12 | download links are only valid for 3 hours
13 | :return:
14 | """
15 | return id_generator() + "-" + id_generator() + "-" + id_generator()
16 |
17 |
18 | def id_generator(size=6, chars=string.ascii_letters + string.digits):
19 | return ''.join(cryptogen.choice(chars) for _ in range(size))
20 |
21 |
22 | def static(*args):
23 | return os.path.join('static', *args)
24 |
--------------------------------------------------------------------------------
/api/requirements.txt:
--------------------------------------------------------------------------------
1 | celery[redis]~=4.0.2
2 | tornado~=4.4
3 |
--------------------------------------------------------------------------------
/api/static/css/docbleach.css:
--------------------------------------------------------------------------------
1 | .docbleach_severe {
2 | color: darkred;
3 | font-weight: 600;
4 | }
5 |
6 | .docbleach_warning {
7 | color: red;
8 | }
9 |
10 | .docbleach_info {
11 | color: #0091D7;
12 | }
13 |
14 | /* Used by docbleach's drop zone */
15 |
16 | .js .inputfile,
17 | .js #subButton {
18 | width: 0;
19 | height: 0;
20 | opacity: 0;
21 | overflow: hidden;
22 | position: absolute;
23 | z-index: -1;
24 | }
25 |
26 | .inputfile + label {
27 | max-width: 80%;
28 | font-size: 1.25rem;
29 | font-weight: 700;
30 | text-overflow: ellipsis;
31 | white-space: nowrap;
32 | cursor: pointer;
33 | display: inline-block;
34 | overflow: hidden;
35 | padding: 0.625rem 1.25rem;
36 | }
37 |
38 | .inputfile + label {
39 | color: #f1e5e6;
40 | background-color: #d3394c;
41 | }
42 |
43 | .inputfile:focus + label,
44 | .inputfile.has-focus + label,
45 | .inputfile + label:hover {
46 | background-color: #722040;
47 | }
--------------------------------------------------------------------------------
/api/static/css/sweetalert2.min.css:
--------------------------------------------------------------------------------
1 | .swal2-container,body.swal2-iosfix{position:fixed;left:0;right:0}body.swal2-in{overflow-y:hidden}.swal2-container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;top:0;bottom:0;padding:10px;background-color:transparent;z-index:1060}.swal2-container:not(.swal2-in){pointer-events:none}.swal2-container.swal2-fade{-webkit-transition:background-color .1s;transition:background-color .1s}.swal2-container.swal2-in{background-color:rgba(0,0,0,.4)}.swal2-modal{background-color:#fff;font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;border-radius:5px;box-sizing:border-box;text-align:center;margin:auto;overflow-x:hidden;overflow-y:auto;display:none;position:relative}.swal2-modal:focus{outline:0}.swal2-modal.swal2-loading{overflow-y:hidden}.swal2-modal .swal2-title{color:#595959;font-size:30px;text-align:center;font-weight:600;text-transform:none;position:relative;margin:0;padding:0;line-height:60px;display:block}.swal2-modal .swal2-spacer{height:10px;color:transparent;border:0}.swal2-modal .swal2-styled{border:0;border-radius:3px;box-shadow:none;color:#fff;cursor:pointer;font-size:17px;font-weight:500;margin:0 5px;padding:10px 32px}.swal2-modal .swal2-styled:not(.swal2-loading)[disabled]{opacity:.4;cursor:no-drop}.swal2-modal .swal2-styled.swal2-loading{box-sizing:border-box;border:4px solid transparent;width:40px;height:40px;padding:0;margin:-2px 30px;vertical-align:top;background-color:transparent!important;color:transparent;cursor:default;border-radius:100%;-webkit-animation:rotate-loading 1.5s linear 0s infinite normal;animation:rotate-loading 1.5s linear 0s infinite normal;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.swal2-modal :not(.swal2-styled).swal2-loading::after{display:inline-block;content:'';margin-left:5px;vertical-align:-1px;height:6px;width:6px;border:3px solid #999;border-right-color:transparent;border-radius:50%;-webkit-animation:rotate-loading 1.5s linear 0s infinite normal;animation:rotate-loading 1.5s linear 0s infinite normal}.swal2-modal .swal2-checkbox input,.swal2-modal .swal2-checkbox span,.swal2-modal .swal2-radio input,.swal2-modal .swal2-radio span{vertical-align:middle}.swal2-modal .swal2-image{margin:20px auto;max-width:100%}.swal2-modal .swal2-close{font-size:36px;line-height:36px;font-family:serif;position:absolute;top:5px;right:13px;cursor:pointer;color:#ccc;-webkit-transition:color .1s ease;transition:color .1s ease}.swal2-modal .swal2-close:hover{color:#d55}.swal2-modal>.swal2-checkbox,.swal2-modal>.swal2-file,.swal2-modal>.swal2-input,.swal2-modal>.swal2-radio,.swal2-modal>.swal2-select,.swal2-modal>.swal2-textarea{display:none}.swal2-modal .swal2-content{font-size:18px;text-align:center;font-weight:300;position:relative;float:none;margin:0;padding:0;line-height:normal;color:#545454}.swal2-modal .swal2-checkbox,.swal2-modal .swal2-file,.swal2-modal .swal2-input,.swal2-modal .swal2-radio,.swal2-modal .swal2-select,.swal2-modal .swal2-textarea{margin:20px auto}.swal2-modal .swal2-file,.swal2-modal .swal2-input,.swal2-modal .swal2-textarea{width:100%;box-sizing:border-box;border-radius:3px;border:1px solid #d9d9d9;font-size:18px;box-shadow:inset 0 1px 1px rgba(0,0,0,.06);-webkit-transition:border-color box-shadow .3s;transition:border-color box-shadow .3s}.swal2-modal .swal2-file.swal2-inputerror,.swal2-modal .swal2-input.swal2-inputerror,.swal2-modal .swal2-textarea.swal2-inputerror{border-color:#f06e57}.swal2-modal .swal2-file:focus,.swal2-modal .swal2-input:focus,.swal2-modal .swal2-textarea:focus{outline:0;box-shadow:0 0 3px #c4e6f5;border:1px solid #b4dbed}.swal2-modal .swal2-file:focus::-webkit-input-placeholder,.swal2-modal .swal2-input:focus::-webkit-input-placeholder,.swal2-modal .swal2-textarea:focus::-webkit-input-placeholder{-webkit-transition:opacity .3s .03s ease;transition:opacity .3s .03s ease;opacity:.8}.swal2-modal .swal2-file:focus::-moz-placeholder,.swal2-modal .swal2-input:focus::-moz-placeholder,.swal2-modal .swal2-textarea:focus::-moz-placeholder{-webkit-transition:opacity .3s .03s ease;transition:opacity .3s .03s ease;opacity:.8}.swal2-modal .swal2-file:focus:-ms-input-placeholder,.swal2-modal .swal2-input:focus:-ms-input-placeholder,.swal2-modal .swal2-textarea:focus:-ms-input-placeholder{-webkit-transition:opacity .3s .03s ease;transition:opacity .3s .03s ease;opacity:.8}.swal2-modal .swal2-file:focus::placeholder,.swal2-modal .swal2-input:focus::placeholder,.swal2-modal .swal2-textarea:focus::placeholder{-webkit-transition:opacity .3s .03s ease;transition:opacity .3s .03s ease;opacity:.8}.swal2-modal .swal2-file::-webkit-input-placeholder,.swal2-modal .swal2-input::-webkit-input-placeholder,.swal2-modal .swal2-textarea::-webkit-input-placeholder{color:#e6e6e6}.swal2-modal .swal2-file::-moz-placeholder,.swal2-modal .swal2-input::-moz-placeholder,.swal2-modal .swal2-textarea::-moz-placeholder{color:#e6e6e6}.swal2-modal .swal2-file:-ms-input-placeholder,.swal2-modal .swal2-input:-ms-input-placeholder,.swal2-modal .swal2-textarea:-ms-input-placeholder{color:#e6e6e6}.swal2-modal .swal2-file::placeholder,.swal2-modal .swal2-input::placeholder,.swal2-modal .swal2-textarea::placeholder{color:#e6e6e6}.swal2-modal .swal2-range input{float:left;width:80%}.swal2-modal .swal2-range output{float:right;width:20%;font-size:20px;font-weight:600;text-align:center}.swal2-modal .swal2-range input,.swal2-modal .swal2-range output{height:43px;line-height:43px;vertical-align:middle;margin:20px auto;padding:0}.swal2-modal .swal2-input{height:43px;padding:0 12px}.swal2-modal .swal2-input[type=number]{max-width:150px}.swal2-modal .swal2-file{font-size:20px}.swal2-modal .swal2-textarea{height:108px;padding:12px}.swal2-modal .swal2-select{color:#545454;font-size:inherit;padding:5px 10px;min-width:40%;max-width:100%}.swal2-modal .swal2-radio{border:0}.swal2-modal .swal2-radio label:not(:first-child){margin-left:20px}.swal2-modal .swal2-radio input{margin:0 3px 0 0}.swal2-modal .swal2-checkbox{color:#545454}.swal2-modal .swal2-validationerror{background-color:#f0f0f0;margin:0 -20px;overflow:hidden;padding:10px;color:gray;font-size:16px;font-weight:300;display:none}.swal2-modal .swal2-validationerror::before{content:'!';display:inline-block;width:24px;height:24px;border-radius:50%;background-color:#ea7d7d;color:#fff;line-height:24px;text-align:center;margin-right:10px}.swal2-icon.swal2-info,.swal2-icon.swal2-question,.swal2-icon.swal2-warning{font-size:60px;line-height:80px;text-align:center}@supports (-ms-accelerator:true){.swal2-range input{width:100%!important}.swal2-range output{display:none}}@media all and (-ms-high-contrast:none),(-ms-high-contrast:active){.swal2-range input{width:100%!important}.swal2-range output{display:none}}.swal2-icon{width:80px;height:80px;border:4px solid transparent;border-radius:50%;margin:20px auto 30px;padding:0;position:relative;box-sizing:content-box;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.swal2-icon.swal2-error{border-color:#f27474}.swal2-icon.swal2-error .x-mark{position:relative;display:block}.swal2-icon.swal2-error .line{position:absolute;height:5px;width:47px;background-color:#f27474;display:block;top:37px;border-radius:2px}.swal2-icon.swal2-error .line.left{-webkit-transform:rotate(45deg);transform:rotate(45deg);left:17px}.swal2-icon.swal2-error .line.right{-webkit-transform:rotate(-45deg);transform:rotate(-45deg);right:16px}.swal2-icon.swal2-warning{font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;color:#f8bb86;border-color:#facea8}.swal2-icon.swal2-info{font-family:'Open Sans',sans-serif;color:#3fc3ee;border-color:#9de0f6}.swal2-icon.swal2-question{font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;color:#87adbd;border-color:#c9dae1}.swal2-icon.swal2-success{border-color:#a5dc86}.swal2-icon.swal2-success::after,.swal2-icon.swal2-success::before{content:'';position:absolute;width:60px;height:120px;background:#fff}.swal2-icon.swal2-success::before{border-radius:120px 0 0 120px;top:-7px;left:-33px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);-webkit-transform-origin:60px 60px;transform-origin:60px 60px}.swal2-icon.swal2-success::after{border-radius:0 120px 120px 0;top:-11px;left:30px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);-webkit-transform-origin:0 60px;transform-origin:0 60px}.swal2-icon.swal2-success .placeholder{width:80px;height:80px;border:4px solid rgba(165,220,134,.2);border-radius:50%;box-sizing:content-box;position:absolute;left:-4px;top:-4px;z-index:2}.swal2-icon.swal2-success .fix{width:7px;height:90px;background-color:#fff;position:absolute;left:28px;top:8px;z-index:1;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.swal2-icon.swal2-success .line{height:5px;background-color:#a5dc86;display:block;border-radius:2px;position:absolute;z-index:2}.swal2-icon.swal2-success .line.tip{width:25px;left:14px;top:46px;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.swal2-icon.swal2-success .line.long{width:47px;right:8px;top:38px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.swal2-progresssteps{font-weight:600;margin:0 0 20px;padding:0}.swal2-progresssteps li{display:inline-block;position:relative}.swal2-progresssteps .swal2-progresscircle{background:#3085d6;border-radius:2em;color:#fff;height:2em;line-height:2em;text-align:center;width:2em;z-index:20}.swal2-progresssteps .swal2-progresscircle:first-child{margin-left:0}.swal2-progresssteps .swal2-progresscircle:last-child{margin-right:0}.swal2-progresssteps .swal2-progresscircle.swal2-activeprogressstep{background:#3085d6}.swal2-progresssteps .swal2-progresscircle.swal2-activeprogressstep~.swal2-progresscircle,.swal2-progresssteps .swal2-progresscircle.swal2-activeprogressstep~.swal2-progressline{background:#add8e6}.swal2-progresssteps .swal2-progressline{background:#3085d6;height:.4em;margin:0 -1px;z-index:10}[class^=swal2]{-webkit-tap-highlight-color:transparent}@-webkit-keyframes showSweetAlert{0%{-webkit-transform:scale(.7);transform:scale(.7)}45%{-webkit-transform:scale(1.05);transform:scale(1.05)}80%{-webkit-transform:scale(.95);transform:scale(.95)}100%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes showSweetAlert{0%{-webkit-transform:scale(.7);transform:scale(.7)}45%{-webkit-transform:scale(1.05);transform:scale(1.05)}80%{-webkit-transform:scale(.95);transform:scale(.95)}100%{-webkit-transform:scale(1);transform:scale(1)}}@-webkit-keyframes hideSweetAlert{0%{-webkit-transform:scale(1);transform:scale(1);opacity:1}100%{-webkit-transform:scale(.5);transform:scale(.5);opacity:0}}@keyframes hideSweetAlert{0%{-webkit-transform:scale(1);transform:scale(1);opacity:1}100%{-webkit-transform:scale(.5);transform:scale(.5);opacity:0}}.swal2-show{-webkit-animation:showSweetAlert .3s;animation:showSweetAlert .3s}.swal2-show.swal2-noanimation{-webkit-animation:none;animation:none}.swal2-hide{-webkit-animation:hideSweetAlert .15s forwards;animation:hideSweetAlert .15s forwards}.swal2-hide.swal2-noanimation{-webkit-animation:none;animation:none}@-webkit-keyframes animate-success-tip{0%,54%{width:0;left:1px;top:19px}70%{width:50px;left:-8px;top:37px}84%{width:17px;left:21px;top:48px}100%{width:25px;left:14px;top:45px}}@keyframes animate-success-tip{0%,54%{width:0;left:1px;top:19px}70%{width:50px;left:-8px;top:37px}84%{width:17px;left:21px;top:48px}100%{width:25px;left:14px;top:45px}}@-webkit-keyframes animate-success-long{0%,65%{width:0;right:46px;top:54px}84%{width:55px;right:0;top:35px}100%{width:47px;right:8px;top:38px}}@keyframes animate-success-long{0%,65%{width:0;right:46px;top:54px}84%{width:55px;right:0;top:35px}100%{width:47px;right:8px;top:38px}}@-webkit-keyframes rotatePlaceholder{0%,5%{-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}100%,12%{-webkit-transform:rotate(-405deg);transform:rotate(-405deg)}}@keyframes rotatePlaceholder{0%,5%{-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}100%,12%{-webkit-transform:rotate(-405deg);transform:rotate(-405deg)}}.animate-success-tip{-webkit-animation:animate-success-tip .75s;animation:animate-success-tip .75s}.animate-success-long{-webkit-animation:animate-success-long .75s;animation:animate-success-long .75s}.swal2-success.animate::after{-webkit-animation:rotatePlaceholder 4.25s ease-in;animation:rotatePlaceholder 4.25s ease-in}@-webkit-keyframes animate-error-icon{0%{-webkit-transform:rotateX(100deg);transform:rotateX(100deg);opacity:0}100%{-webkit-transform:rotateX(0);transform:rotateX(0);opacity:1}}@keyframes animate-error-icon{0%{-webkit-transform:rotateX(100deg);transform:rotateX(100deg);opacity:0}100%{-webkit-transform:rotateX(0);transform:rotateX(0);opacity:1}}.animate-error-icon{-webkit-animation:animate-error-icon .5s;animation:animate-error-icon .5s}@-webkit-keyframes animate-x-mark{0%,50%{-webkit-transform:scale(.4);transform:scale(.4);margin-top:26px;opacity:0}80%{-webkit-transform:scale(1.15);transform:scale(1.15);margin-top:-6px}100%{-webkit-transform:scale(1);transform:scale(1);margin-top:0;opacity:1}}@keyframes animate-x-mark{0%,50%{-webkit-transform:scale(.4);transform:scale(.4);margin-top:26px;opacity:0}80%{-webkit-transform:scale(1.15);transform:scale(1.15);margin-top:-6px}100%{-webkit-transform:scale(1);transform:scale(1);margin-top:0;opacity:1}}.animate-x-mark{-webkit-animation:animate-x-mark .5s;animation:animate-x-mark .5s}@-webkit-keyframes pulse-warning{0%{border-color:#f8d486}100%{border-color:#f8bb86}}@keyframes pulse-warning{0%{border-color:#f8d486}100%{border-color:#f8bb86}}.pulse-warning{-webkit-animation:pulse-warning .75s infinite alternate;animation:pulse-warning .75s infinite alternate}@-webkit-keyframes rotate-loading{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes rotate-loading{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}
--------------------------------------------------------------------------------
/api/static/favicon/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docbleach/DocBleach-Web/13657e45d41f7deae689cf6fae0e62d3d7c947df/api/static/favicon/android-chrome-192x192.png
--------------------------------------------------------------------------------
/api/static/favicon/android-chrome-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docbleach/DocBleach-Web/13657e45d41f7deae689cf6fae0e62d3d7c947df/api/static/favicon/android-chrome-512x512.png
--------------------------------------------------------------------------------
/api/static/favicon/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docbleach/DocBleach-Web/13657e45d41f7deae689cf6fae0e62d3d7c947df/api/static/favicon/apple-touch-icon.png
--------------------------------------------------------------------------------
/api/static/favicon/browserconfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | #2b5797
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/api/static/favicon/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docbleach/DocBleach-Web/13657e45d41f7deae689cf6fae0e62d3d7c947df/api/static/favicon/favicon-16x16.png
--------------------------------------------------------------------------------
/api/static/favicon/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docbleach/DocBleach-Web/13657e45d41f7deae689cf6fae0e62d3d7c947df/api/static/favicon/favicon-32x32.png
--------------------------------------------------------------------------------
/api/static/favicon/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docbleach/DocBleach-Web/13657e45d41f7deae689cf6fae0e62d3d7c947df/api/static/favicon/favicon.ico
--------------------------------------------------------------------------------
/api/static/favicon/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "",
3 | "icons": [
4 | {
5 | "src": "\/android-chrome-192x192.png?v=GvJQap5OwL",
6 | "sizes": "192x192",
7 | "type": "image\/png"
8 | },
9 | {
10 | "src": "\/android-chrome-512x512.png?v=GvJQap5OwL",
11 | "sizes": "512x512",
12 | "type": "image\/png"
13 | }
14 | ],
15 | "theme_color": "#ffffff",
16 | "display": "standalone",
17 | "orientation": "portrait"
18 | }
19 |
--------------------------------------------------------------------------------
/api/static/favicon/mstile-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docbleach/DocBleach-Web/13657e45d41f7deae689cf6fae0e62d3d7c947df/api/static/favicon/mstile-144x144.png
--------------------------------------------------------------------------------
/api/static/favicon/mstile-150x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docbleach/DocBleach-Web/13657e45d41f7deae689cf6fae0e62d3d7c947df/api/static/favicon/mstile-150x150.png
--------------------------------------------------------------------------------
/api/static/favicon/mstile-310x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docbleach/DocBleach-Web/13657e45d41f7deae689cf6fae0e62d3d7c947df/api/static/favicon/mstile-310x150.png
--------------------------------------------------------------------------------
/api/static/favicon/mstile-310x310.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docbleach/DocBleach-Web/13657e45d41f7deae689cf6fae0e62d3d7c947df/api/static/favicon/mstile-310x310.png
--------------------------------------------------------------------------------
/api/static/favicon/mstile-70x70.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docbleach/DocBleach-Web/13657e45d41f7deae689cf6fae0e62d3d7c947df/api/static/favicon/mstile-70x70.png
--------------------------------------------------------------------------------
/api/static/favicon/safari-pinned-tab.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
66 |
--------------------------------------------------------------------------------
/api/static/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | DocBleach
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
33 |
34 |
35 |
36 |
37 |
38 |
68 |
69 |
70 |
71 |
72 |
73 |
DocBleach
74 |
Sanitizes a potentially dangerous file (Office Document, PDF), by removing macros and other active contents.
75 |
76 |
77 |
78 |
79 |
80 |
Friendly reminder: do NOT post sensitive documents here, unless you trust this page owner.
81 |
82 |
83 |
84 |
85 |
86 |
Sanitize a file
87 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
--------------------------------------------------------------------------------
/api/static/js/docbleach.js:
--------------------------------------------------------------------------------
1 | document.body.classList.add('js');
2 | var docbleach_endpoint = "/v1/";
3 |
4 | (function () {
5 | var formElement = document.querySelector("form#uploadForm");
6 | var labelElement = document.querySelector("form#uploadForm label span");
7 | var inputElement = document.querySelector("input#file");
8 |
9 | if (window.FileReader) {
10 | addEventHandler(labelElement, 'dragover', function (e) {
11 | e.preventDefault();
12 | });
13 |
14 | addEventHandler(labelElement, 'dragleave', function (e) {
15 | e.preventDefault();
16 | });
17 |
18 | addEventHandler(labelElement, 'drop', function (e) {
19 | e = e || window.event; // get window.event if e argument missing (in IE)
20 | e.preventDefault();
21 |
22 | var dt = e.dataTransfer;
23 | var files = dt.files;
24 | for (var i = 0; i < files.length; i++) {
25 | var file = files[i];
26 |
27 | var formData = new FormData();
28 | formData.append("file", file);
29 | convertFile(formData);
30 | }
31 | return false;
32 | });
33 | }
34 |
35 | addEventHandler(inputElement, "change", function (e) {
36 | convertFile(new FormData(formElement));
37 | }, false);
38 |
39 | function addEventHandler(obj, evt, handler) {
40 | if (obj === null) {
41 | return;
42 | }
43 | if (obj.addEventListener) {
44 | // W3C method
45 | obj.addEventListener(evt, handler, false);
46 | } else if (obj.attachEvent) {
47 | // IE method.
48 | obj.attachEvent('on' + evt, handler);
49 | } else {
50 | // Old school method.
51 | obj['on' + evt] = handler;
52 | }
53 | }
54 |
55 | function convertFile(formData) {
56 | swal({
57 | title: "Uploading file",
58 | text: "...",
59 | type: "info",
60 | allowOutsideClick: false,
61 | allowEscapeKey: false
62 | });
63 | swal.showLoading();
64 | $.ajax({
65 | type: "POST",
66 | url: docbleach_endpoint + "tasks",
67 | data: formData,
68 | processData: false,
69 | contentType: false,
70 | success: function (data) {
71 | swal({
72 | title: "Sanitizing file",
73 | text: "...",
74 | type: "info",
75 | allowOutsideClick: false,
76 | allowEscapeKey: false
77 | });
78 | swal.showLoading();
79 | var task_id = data["task_id"];
80 | console.log("Got a task id: " + task_id);
81 | setTimeout(function () {
82 | checkFileStatus(task_id);
83 | }, 250);
84 | }
85 | });
86 | }
87 |
88 | function checkFileStatus(task_id) {
89 | $.ajax({
90 | type: "GET",
91 | url: docbleach_endpoint + "tasks/" + task_id,
92 | success: function (data) {
93 | console.log(data);
94 | console.log("Got a task id state: " + task_id);
95 | if (data.status === "PENDING") {
96 | setTimeout(function () {
97 | checkFileStatus(task_id);
98 | }, 250);
99 | return;
100 | }
101 | displayResponse(
102 | {infos: [data.result.output], link: data.result.final_file});
103 | }
104 | });
105 | }
106 | })();
107 |
108 | function displayResponse(response) {
109 | if (response.errors && response.errors.join) {
110 | console.log(response.errors);
111 | swal("An error occured", "", "error");
112 | return;
113 | }
114 | if (response.infos && response.infos.join) {
115 | var htmlCode = parseDocbleach(response.infos.join("\n"));
116 |
117 | var modalData = {
118 | title: "Results",
119 | html: htmlCode,
120 | type: "success",
121 | allowOutsideClick: true,
122 | confirmButtonColor: "#73B6D6",
123 | width: "60%"
124 | };
125 | if (response.link) {
126 | modalData["confirmButtonText"] = "Download the sanitized file";
127 | } else {
128 | modalData["timer"] = 2000;
129 | }
130 | swal.hideLoading();
131 | swal(modalData).then(function () {
132 | if (response.link) {
133 | download(response.link);
134 | }
135 | });
136 | } else if (response.link) {
137 | download(response.link);
138 | swal.hideLoading();
139 | swal({
140 | text: "Download started",
141 | type: "success",
142 | timer: 2000
143 | });
144 | }
145 | }
146 |
147 | function parseDocbleach(infos) {
148 | var parent = document.createElement("div");
149 | var lines = infos.split(/\r?\n/); // Allow multiple lines per blob
150 |
151 | lines.forEach(function (line) {
152 | var child = document.createElement("p");
153 |
154 | if (line.indexOf("WARN ") === 0) {
155 | child.classList.add("docbleach_warning");
156 | line = line.substring("WARN ".length);
157 | } else if (line.indexOf("INFO ") === 0) {
158 | child.classList.add("docbleach_info");
159 | line = line.substring("INFO ".length);
160 | } else if (line.indexOf("ERROR ") === 0) {
161 | child.classList.add("docbleach_severe");
162 | line = line.substring("ERROR ".length);
163 | } else if (line.indexOf("FATAL ") === 0) {
164 | child.classList.add("docbleach_severe");
165 | line = line.substring("FATAL ".length);
166 | }
167 | child.innerText = line;
168 | parent.appendChild(child);
169 | });
170 | return parent.innerHTML;
171 | }
172 |
173 | function download(link) {
174 | var anchor = document.createElement('a');
175 | anchor.href = link;
176 | // anchor.target = '_blank';
177 | anchor.setAttribute("download", "");
178 | document.body.appendChild(anchor);
179 | anchor.click();
180 | }
181 |
--------------------------------------------------------------------------------
/api/static/js/html5shiv.js:
--------------------------------------------------------------------------------
1 | /*
2 | HTML5 Shiv v3.7.0 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
3 | */
4 | (function(l,f){function m(){var a=e.elements;return"string"==typeof a?a.split(" "):a}function i(a){var b=n[a[o]];b||(b={},h++,a[o]=h,n[h]=b);return b}function p(a,b,c){b||(b=f);if(g)return b.createElement(a);c||(c=i(b));b=c.cache[a]?c.cache[a].cloneNode():r.test(a)?(c.cache[a]=c.createElem(a)).cloneNode():c.createElem(a);return b.canHaveChildren&&!s.test(a)?c.frag.appendChild(b):b}function t(a,b){if(!b.cache)b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag();
5 | a.createElement=function(c){return!e.shivMethods?b.createElem(c):p(c,a,b)};a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/[\w\-]+/g,function(a){b.createElem(a);b.frag.createElement(a);return'c("'+a+'")'})+");return n}")(e,b.frag)}function q(a){a||(a=f);var b=i(a);if(e.shivCSS&&!j&&!b.hasCSS){var c,d=a;c=d.createElement("p");d=d.getElementsByTagName("head")[0]||d.documentElement;c.innerHTML="x";
6 | c=d.insertBefore(c.lastChild,d.firstChild);b.hasCSS=!!c}g||t(a,b);return a}var k=l.html5||{},s=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,r=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,j,o="_html5shiv",h=0,n={},g;(function(){try{var a=f.createElement("a");a.innerHTML="";j="hidden"in a;var b;if(!(b=1==a.childNodes.length)){f.createElement("a");var c=f.createDocumentFragment();b="undefined"==typeof c.cloneNode||
7 | "undefined"==typeof c.createDocumentFragment||"undefined"==typeof c.createElement}g=b}catch(d){g=j=!0}})();var e={elements:k.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:"3.7.0",shivCSS:!1!==k.shivCSS,supportsUnknownElements:g,shivMethods:!1!==k.shivMethods,type:"default",shivDocument:q,createElement:p,createDocumentFragment:function(a,b){a||(a=f);
8 | if(g)return a.createDocumentFragment();for(var b=b||i(a),c=b.frag.cloneNode(),d=0,e=m(),h=e.length;d #mq-test-1 { width: 42px; }',c.insertBefore(e,d),b=42===f.offsetWidth,c.removeChild(e),{matches:b,media:a}}}(a.document)}(this),function(a){"use strict";function b(){u(!0)}var c={};a.respond=c,c.update=function(){};var d=[],e=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}(),f=function(a,b){var c=e();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))};if(c.ajax=f,c.queue=d,c.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\([\s]*min\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/,maxw:/\([\s]*max\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/},c.mediaQueriesSupported=a.matchMedia&&null!==a.matchMedia("only all")&&a.matchMedia("only all").matches,!c.mediaQueriesSupported){var g,h,i,j=a.document,k=j.documentElement,l=[],m=[],n=[],o={},p=30,q=j.getElementsByTagName("head")[0]||k,r=j.getElementsByTagName("base")[0],s=q.getElementsByTagName("link"),t=function(){var a,b=j.createElement("div"),c=j.body,d=k.style.fontSize,e=c&&c.style.fontSize,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",c||(c=f=j.createElement("body"),c.style.background="none"),k.style.fontSize="100%",c.style.fontSize="100%",c.appendChild(b),f&&k.insertBefore(c,k.firstChild),a=b.offsetWidth,f?k.removeChild(c):c.removeChild(b),k.style.fontSize=d,e&&(c.style.fontSize=e),a=i=parseFloat(a)},u=function(b){var c="clientWidth",d=k[c],e="CSS1Compat"===j.compatMode&&d||j.body[c]||d,f={},o=s[s.length-1],r=(new Date).getTime();if(b&&g&&p>r-g)return a.clearTimeout(h),h=a.setTimeout(u,p),void 0;g=r;for(var v in l)if(l.hasOwnProperty(v)){var w=l[v],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?i||t():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?i||t():1)),w.hasquery&&(z&&A||!(z||e>=x)||!(A||y>=e))||(f[w.media]||(f[w.media]=[]),f[w.media].push(m[w.rules]))}for(var C in n)n.hasOwnProperty(C)&&n[C]&&n[C].parentNode===q&&q.removeChild(n[C]);n.length=0;for(var D in f)if(f.hasOwnProperty(D)){var E=j.createElement("style"),F=f[D].join("\n");E.type="text/css",E.media=D,q.insertBefore(E,o.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(j.createTextNode(F)),n.push(E)}},v=function(a,b,d){var e=a.replace(c.regex.keyframes,"").match(c.regex.media),f=e&&e.length||0;b=b.substring(0,b.lastIndexOf("/"));var g=function(a){return a.replace(c.regex.urls,"$1"+b+"$2$3")},h=!f&&d;b.length&&(b+="/"),h&&(f=1);for(var i=0;f>i;i++){var j,k,n,o;h?(j=d,m.push(g(a))):(j=e[i].match(c.regex.findStyles)&&RegExp.$1,m.push(RegExp.$2&&g(RegExp.$2))),n=j.split(","),o=n.length;for(var p=0;o>p;p++)k=n[p],l.push({media:k.split("(")[0].match(c.regex.only)&&RegExp.$2||"all",rules:m.length-1,hasquery:k.indexOf("(")>-1,minw:k.match(c.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:k.match(c.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}u()},w=function(){if(d.length){var b=d.shift();f(b.href,function(c){v(c,b.href,b.media),o[b.href]=!0,a.setTimeout(function(){w()},0)})}},x=function(){for(var b=0;b\n \n \n \n
\n ?
\n !
\n i
\n \n
\n \n \n \n \n \n \n \n
\n \n \n \n \n \n
\n \n \n ×\n \n').replace(/(^|\n)\s*/g,""),a=void 0,l=document.getElementsByClassName(n.container);l.length?a=l[0]:(a=document.createElement("div"),a.className=n.container,a.innerHTML=i);var s=function(e,t){e=String(e).replace(/[^0-9a-f]/gi,""),e.length<6&&(e=e[0]+e[0]+e[1]+e[1]+e[2]+e[2]),t=t||0;for(var n="#",o=0;o<3;o++){var r=parseInt(e.substr(2*o,2),16);r=Math.round(Math.min(Math.max(0,r+r*t),255)).toString(16),n+=("00"+r).substr(r.length)}return n},c={previousWindowKeyDown:null,previousActiveElement:null,previousBodyPadding:null},u=function(){if("undefined"==typeof document)return void console.error("SweetAlert2 requires document to initialize");if(!document.getElementsByClassName(n.container).length){document.body.appendChild(a);var e=p(),t=P(e,n.input),o=P(e,n.file),r=e.querySelector("."+n.range+" input"),i=e.querySelector("."+n.range+" output"),l=P(e,n.select),s=e.querySelector("."+n.checkbox+" input"),c=P(e,n.textarea);return t.oninput=function(){F.resetValidationError()},t.onkeydown=function(e){setTimeout(function(){13===e.keyCode&&(e.stopPropagation(),F.clickConfirm())},0)},o.onchange=function(){F.resetValidationError()},r.oninput=function(){F.resetValidationError(),i.value=r.value},r.onchange=function(){F.resetValidationError(),r.previousSibling.value=r.value},l.onchange=function(){F.resetValidationError()},s.onchange=function(){F.resetValidationError()},c.oninput=function(){F.resetValidationError()},e}},d=function(e){return a.querySelector("."+e)},p=function(){return document.body.querySelector("."+n.modal)||u()},f=function(){var e=p();return e.querySelectorAll("."+n.icon)},m=function(){return d(n.title)},v=function(){return d(n.content)},h=function(){return d(n.image)},y=function(){return d(n.spacer)},g=function(){return d(n.progresssteps)},b=function(){return d(n.validationerror)},w=function(){return d(n.confirm)},C=function(){return d(n.cancel)},k=function(){return d(n.close)},S=function(t){var n=[w(),C()];return t&&n.reverse(),n.concat(Array.prototype.slice.call(p().querySelectorAll("button:not([class^="+e+"]), input:not([type=hidden]), textarea, select")))},x=function(e,t){return!!e.classList&&e.classList.contains(t)},E=function(e){if(e.focus(),"file"!==e.type){var t=e.value;e.value="",e.value=t}},A=function(e,t){if(e&&t){var n=t.split(/\s+/).filter(Boolean);n.forEach(function(t){e.classList.add(t)})}},B=function(e,t){if(e&&t){var n=t.split(/\s+/).filter(Boolean);n.forEach(function(t){e.classList.remove(t)})}},P=function(e,t){for(var n=0;n"),e.text||e.html){if("object"===D(e.html))if(l.innerHTML="",0 in e.html)for(var d=0;d in e.html;d++)l.appendChild(e.html[d].cloneNode(!0));else l.appendChild(e.html.cloneNode(!0));else e.html?l.innerHTML=e.html:e.text&&(l.innerHTML=(""+e.text).split("\n").join("
"));L(l)}else q(l);e.showCloseButton?L(u):q(u),t.className=n.modal,e.customClass&&A(t,e.customClass);var b=g(),S=parseInt(null===e.currentProgressStep?F.getQueueStep():e.currentProgressStep,10);e.progressSteps.length?(L(b),M(b),S>=e.progressSteps.length&&console.warn("SweetAlert2: Invalid currentProgressStep parameter, it should be less than progressSteps.length (currentProgressStep like JS arrays starts from 0)"),e.progressSteps.forEach(function(t,o){var r=document.createElement("li");if(A(r,n.progresscircle),r.innerHTML=t,o===S&&A(r,n.activeprogressstep),b.appendChild(r),o!==e.progressSteps.length-1){var i=document.createElement("li");A(i,n.progressline),i.style.width=e.progressStepsDistance,b.appendChild(i)}})):q(b);for(var x=f(),E=0;Ewindow.innerHeight&&(c.previousBodyPadding=document.body.style.paddingRight,document.body.style.paddingRight=j()+"px")},Y=function(){null!==c.previousBodyPadding&&(document.body.style.paddingRight=c.previousBodyPadding,c.previousBodyPadding=null)},Z=function(){var e=/iPad|iPhone|iPod/.test(navigator.userAgent)&&!window.MSStream;if(e&&!x(document.body,n.iosfix)){var t=document.body.scrollTop;document.body.style.top=t*-1+"px",A(document.body,n.iosfix)}},J=function(){if(x(document.body,n.iosfix)){var e=parseInt(document.body.style.top,10);B(document.body,n.iosfix),document.body.style.top="",document.body.scrollTop=e*-1}},$=function(){for(var e=arguments.length,t=Array(e),o=0;o
2 |
3 |
4 |
5 |
6 | Swagger UI
7 |
8 |
9 |
10 |
11 |
30 |
31 |
32 |
33 |
34 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/api/static/swagger/swagger-ui-bundle.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"swagger-ui-bundle.js","sources":["webpack:///swagger-ui-bundle.js"],"mappings":"AAAA;AAu/FA;AA6+FA;;;;;;;;;;;;;;;;;;;;;;;;;;AAsdA;AAkoJA;AAyiCA;;;;;AAskCA;AAq7IA;AAo7FA;AA0wGA;AAgmEA;AA+9CA;AA0gDA;AA0rCA;AAm6DA;AAm4IA;;;;;;;;;;;;;;AAmtFA;AAyoIA;AAiuJA;AAglHA;AA+mGA;AAmkEA;AA42DA;AAwxDA;AA69BA;;;;;;AAixEA;AAo2FA;;;;;AA23CA;AA2qFA;AAo2CA;AAihCA;AAomDA;AAiuEA;AAkjGA;;;;;;;;;AAkpBA;AA2zIA;AAg4DA;AAywDA;;;;;;AAyzBA;AA8iHA;AAipGA","sourceRoot":""}
--------------------------------------------------------------------------------
/api/static/swagger/swagger-ui-standalone-preset.js:
--------------------------------------------------------------------------------
1 | !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.SwaggerUIStandalonePreset=t():e.SwaggerUIStandalonePreset=t()}(this,function(){return function(e){function t(r){if(o[r])return o[r].exports;var n=o[r]={exports:{},id:r,loaded:!1};return e[r].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var o={};return t.m=e,t.c=o,t.p="/dist",t(0)}([function(e,t,o){e.exports=o(1)},function(e,t,o){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var n=o(2),i=r(n);o(30);var a=o(34),s=r(a),l=[s.default,function(){return{components:{StandaloneLayout:i.default}}}];t.default=l},function(e,t,o){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function i(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var s=function(){function e(e,t){for(var o=0;o1){for(var m=Array(b),x=0;x1){for(var h=Array(w),y=0;y>"),j={array:a("array"),bool:a("boolean"),func:a("function"),number:a("number"),object:a("object"),string:a("string"),symbol:a("symbol"),any:s(),arrayOf:l,element:p(),instanceOf:u,node:g(),objectOf:f,oneOf:c,oneOfType:d,shape:b};n.prototype=Error.prototype,e.exports=j},function(e,t){"use strict";var o="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED";e.exports=o},function(e,t){"use strict";e.exports="15.4.2"},function(e,t,o){"use strict";function r(e){return i.isValidElement(e)?void 0:n("143"),e}var n=o(8),i=o(10);o(9);e.exports=r},function(e,t,o){var r=o(31);"string"==typeof r&&(r=[[e.id,r,""]]);o(33)(r,{});r.locals&&(e.exports=r.locals)},function(e,t,o){t=e.exports=o(32)(),t.push([e.id,"@charset \"UTF-8\";.swagger-ui html{box-sizing:border-box}.swagger-ui *,.swagger-ui :after,.swagger-ui :before{box-sizing:inherit}.swagger-ui body{margin:0;background:#fafafa}.swagger-ui .wrapper{width:100%;max-width:1460px;margin:0 auto;padding:0 20px}.swagger-ui .opblock-tag-section{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.swagger-ui .opblock-tag{display:-webkit-box;display:-ms-flexbox;display:flex;padding:10px 20px 10px 10px;cursor:pointer;-webkit-transition:all .2s;transition:all .2s;border-bottom:1px solid rgba(59,65,81,.3);-webkit-box-align:center;-ms-flex-align:center;align-items:center}.swagger-ui .opblock-tag:hover{background:rgba(0,0,0,.02)}.swagger-ui .opblock-tag{font-size:24px;margin:0 0 5px;font-family:Titillium Web,sans-serif;color:#3b4151}.swagger-ui .opblock-tag.no-desc span{-webkit-box-flex:1;-ms-flex:1;flex:1}.swagger-ui .opblock-tag svg{-webkit-transition:all .4s;transition:all .4s}.swagger-ui .opblock-tag small{font-size:14px;font-weight:400;padding:0 10px;-webkit-box-flex:1;-ms-flex:1;flex:1;font-family:Open Sans,sans-serif;color:#3b4151}.swagger-ui .parаmeter__type{font-size:12px;padding:5px 0;font-family:Source Code Pro,monospace;font-weight:600;color:#3b4151}.swagger-ui .view-line-link{position:relative;top:3px;width:20px;margin:0 5px;cursor:pointer;-webkit-transition:all .5s;transition:all .5s}.swagger-ui .opblock{margin:0 0 15px;border:1px solid #000;border-radius:4px;box-shadow:0 0 3px rgba(0,0,0,.19)}.swagger-ui .opblock.is-open .opblock-summary{border-bottom:1px solid #000}.swagger-ui .opblock .opblock-section-header{padding:8px 20px;background:hsla(0,0%,100%,.8);box-shadow:0 1px 2px rgba(0,0,0,.1)}.swagger-ui .opblock .opblock-section-header,.swagger-ui .opblock .opblock-section-header label{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.swagger-ui .opblock .opblock-section-header label{font-size:12px;font-weight:700;margin:0;font-family:Titillium Web,sans-serif;color:#3b4151}.swagger-ui .opblock .opblock-section-header label span{padding:0 10px 0 0}.swagger-ui .opblock .opblock-section-header h4{font-size:14px;margin:0;-webkit-box-flex:1;-ms-flex:1;flex:1;font-family:Titillium Web,sans-serif;color:#3b4151}.swagger-ui .opblock .opblock-summary-method{font-size:14px;font-weight:700;min-width:80px;padding:6px 15px;text-align:center;border-radius:3px;background:#000;text-shadow:0 1px 0 rgba(0,0,0,.1);font-family:Titillium Web,sans-serif;color:#fff}.swagger-ui .opblock .opblock-summary-path,.swagger-ui .opblock .opblock-summary-path__deprecated{font-size:16px;display:-webkit-box;display:-ms-flexbox;display:flex;padding:0 10px;font-family:Source Code Pro,monospace;font-weight:600;color:#3b4151;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.swagger-ui .opblock .opblock-summary-path .view-line-link,.swagger-ui .opblock .opblock-summary-path__deprecated .view-line-link{position:relative;top:2px;width:0;margin:0;cursor:pointer;-webkit-transition:all .5s;transition:all .5s}.swagger-ui .opblock .opblock-summary-path:hover .view-line-link,.swagger-ui .opblock .opblock-summary-path__deprecated:hover .view-line-link{width:18px;margin:0 5px}.swagger-ui .opblock .opblock-summary-path__deprecated{text-decoration:line-through}.swagger-ui .opblock .opblock-summary-description{font-size:13px;-webkit-box-flex:1;-ms-flex:1;flex:1;font-family:Open Sans,sans-serif;color:#3b4151}.swagger-ui .opblock .opblock-summary{display:-webkit-box;display:-ms-flexbox;display:flex;padding:5px;cursor:pointer;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.swagger-ui .opblock.opblock-post{border-color:#49cc90;background:rgba(73,204,144,.1)}.swagger-ui .opblock.opblock-post .opblock-summary-method{background:#49cc90}.swagger-ui .opblock.opblock-post .opblock-summary{border-color:#49cc90}.swagger-ui .opblock.opblock-put{border-color:#fca130;background:rgba(252,161,48,.1)}.swagger-ui .opblock.opblock-put .opblock-summary-method{background:#fca130}.swagger-ui .opblock.opblock-put .opblock-summary{border-color:#fca130}.swagger-ui .opblock.opblock-delete{border-color:#f93e3e;background:rgba(249,62,62,.1)}.swagger-ui .opblock.opblock-delete .opblock-summary-method{background:#f93e3e}.swagger-ui .opblock.opblock-delete .opblock-summary{border-color:#f93e3e}.swagger-ui .opblock.opblock-get{border-color:#61affe;background:rgba(97,175,254,.1)}.swagger-ui .opblock.opblock-get .opblock-summary-method{background:#61affe}.swagger-ui .opblock.opblock-get .opblock-summary{border-color:#61affe}.swagger-ui .opblock.opblock-patch{border-color:#50e3c2;background:rgba(80,227,194,.1)}.swagger-ui .opblock.opblock-patch .opblock-summary-method{background:#50e3c2}.swagger-ui .opblock.opblock-patch .opblock-summary{border-color:#50e3c2}.swagger-ui .opblock.opblock-head{border-color:#9012fe;background:rgba(144,18,254,.1)}.swagger-ui .opblock.opblock-head .opblock-summary-method{background:#9012fe}.swagger-ui .opblock.opblock-head .opblock-summary{border-color:#9012fe}.swagger-ui .opblock.opblock-options{border-color:#0d5aa7;background:rgba(13,90,167,.1)}.swagger-ui .opblock.opblock-options .opblock-summary-method{background:#0d5aa7}.swagger-ui .opblock.opblock-options .opblock-summary{border-color:#0d5aa7}.swagger-ui .opblock.opblock-deprecated{opacity:.6;border-color:#ebebeb;background:hsla(0,0%,92%,.1)}.swagger-ui .opblock.opblock-deprecated .opblock-summary-method{background:#ebebeb}.swagger-ui .opblock.opblock-deprecated .opblock-summary{border-color:#ebebeb}.swagger-ui .tab{display:-webkit-box;display:-ms-flexbox;display:flex;margin:20px 0 10px;padding:0;list-style:none}.swagger-ui .tab li{font-size:12px;min-width:100px;min-width:90px;padding:0;cursor:pointer;font-family:Titillium Web,sans-serif;color:#3b4151}.swagger-ui .tab li:first-of-type{position:relative;padding-left:0}.swagger-ui .tab li:first-of-type:after{position:absolute;top:0;right:6px;width:1px;height:100%;content:\"\";background:rgba(0,0,0,.2)}.swagger-ui .tab li.active{font-weight:700}.swagger-ui .opblock-description-wrapper,.swagger-ui .opblock-title_normal{padding:15px 20px}.swagger-ui .opblock-description-wrapper,.swagger-ui .opblock-description-wrapper h4,.swagger-ui .opblock-title_normal,.swagger-ui .opblock-title_normal h4{font-size:12px;margin:0 0 5px;font-family:Open Sans,sans-serif;color:#3b4151}.swagger-ui .opblock-description-wrapper p,.swagger-ui .opblock-title_normal p{font-size:14px;margin:0;font-family:Open Sans,sans-serif;color:#3b4151}.swagger-ui .execute-wrapper{padding:20px;text-align:right}.swagger-ui .execute-wrapper .btn{width:100%;padding:8px 40px}.swagger-ui .body-param-options{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.swagger-ui .body-param-options .body-param-edit{padding:10px 0}.swagger-ui .body-param-options label{padding:8px 0}.swagger-ui .body-param-options label select{margin:3px 0 0}.swagger-ui .responses-inner{padding:20px}.swagger-ui .responses-inner h4,.swagger-ui .responses-inner h5{font-size:12px;margin:10px 0 5px;font-family:Open Sans,sans-serif;color:#3b4151}.swagger-ui .response-col_status{font-size:14px;font-family:Open Sans,sans-serif;color:#3b4151}.swagger-ui .response-col_status .response-undocumented{font-size:11px;font-family:Source Code Pro,monospace;font-weight:600;color:#999}.swagger-ui .response-col_description__inner span{font-size:12px;font-style:italic;display:block;margin:10px 0;padding:10px;border-radius:4px;background:#41444e;font-family:Source Code Pro,monospace;font-weight:600;color:#fff}.swagger-ui .response-col_description__inner span p{margin:0}.swagger-ui .opblock-body pre{font-size:12px;margin:0;padding:10px;white-space:pre-wrap;border-radius:4px;background:#41444e;font-family:Source Code Pro,monospace;font-weight:600;color:#fff}.swagger-ui .opblock-body pre span{color:#fff!important}.swagger-ui .scheme-container{margin:0 0 20px;padding:30px 0;background:#fff;box-shadow:0 1px 2px 0 rgba(0,0,0,.15)}.swagger-ui .scheme-container .schemes{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.swagger-ui .scheme-container .schemes>label{font-size:12px;font-weight:700;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin:-20px 15px 0 0;font-family:Titillium Web,sans-serif;color:#3b4151}.swagger-ui .scheme-container .schemes>label select{min-width:130px;text-transform:uppercase}.swagger-ui .loading-container{padding:40px 0 60px}.swagger-ui .loading-container .loading{position:relative}.swagger-ui .loading-container .loading:after{font-size:10px;font-weight:700;position:absolute;top:50%;left:50%;content:\"loading\";-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);text-transform:uppercase;font-family:Titillium Web,sans-serif;color:#3b4151}.swagger-ui .loading-container .loading:before{position:absolute;top:50%;left:50%;display:block;width:60px;height:60px;margin:-30px;content:\"\";-webkit-animation:rotation 1s infinite linear,opacity .5s;animation:rotation 1s infinite linear,opacity .5s;opacity:1;border:2px solid rgba(85,85,85,.1);border-top-color:rgba(0,0,0,.6);border-radius:100%;-webkit-backface-visibility:hidden;backface-visibility:hidden}@-webkit-keyframes rotation{to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes rotation{to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@-webkit-keyframes blinker{50%{opacity:0}}@keyframes blinker{50%{opacity:0}}.swagger-ui .btn{font-size:14px;font-weight:700;padding:5px 23px;-webkit-transition:all .3s;transition:all .3s;border:2px solid #888;border-radius:4px;background:transparent;box-shadow:0 1px 2px rgba(0,0,0,.1);font-family:Titillium Web,sans-serif;color:#3b4151}.swagger-ui .btn[disabled]{cursor:not-allowed;opacity:.3}.swagger-ui .btn:hover{box-shadow:0 0 5px rgba(0,0,0,.3)}.swagger-ui .btn.cancel{border-color:#ff6060;font-family:Titillium Web,sans-serif;color:#ff6060}.swagger-ui .btn.authorize{line-height:1;display:inline;color:#49cc90;border-color:#49cc90}.swagger-ui .btn.authorize span{float:left;padding:4px 20px 0 0}.swagger-ui .btn.authorize svg{fill:#49cc90}.swagger-ui .btn.execute{-webkit-animation:pulse 2s infinite;animation:pulse 2s infinite;color:#fff;border-color:#4990e2}@-webkit-keyframes pulse{0%{color:#fff;background:#4990e2;box-shadow:0 0 0 0 rgba(73,144,226,.8)}70%{box-shadow:0 0 0 5px rgba(73,144,226,0)}to{color:#fff;background:#4990e2;box-shadow:0 0 0 0 rgba(73,144,226,0)}}@keyframes pulse{0%{color:#fff;background:#4990e2;box-shadow:0 0 0 0 rgba(73,144,226,.8)}70%{box-shadow:0 0 0 5px rgba(73,144,226,0)}to{color:#fff;background:#4990e2;box-shadow:0 0 0 0 rgba(73,144,226,0)}}.swagger-ui .btn-group{display:-webkit-box;display:-ms-flexbox;display:flex;padding:30px}.swagger-ui .btn-group .btn{-webkit-box-flex:1;-ms-flex:1;flex:1}.swagger-ui .btn-group .btn:first-child{border-radius:4px 0 0 4px}.swagger-ui .btn-group .btn:last-child{border-radius:0 4px 4px 0}.swagger-ui .authorization__btn{padding:0 10px;border:none;background:none}.swagger-ui .authorization__btn.locked{opacity:1}.swagger-ui .authorization__btn.unlocked{opacity:.4}.swagger-ui .expand-methods,.swagger-ui .expand-operation{border:none;background:none}.swagger-ui .expand-methods svg,.swagger-ui .expand-operation svg{width:20px;height:20px}.swagger-ui .expand-methods{padding:0 10px}.swagger-ui .expand-methods:hover svg{fill:#444}.swagger-ui .expand-methods svg{-webkit-transition:all .3s;transition:all .3s;fill:#777}.swagger-ui button{cursor:pointer;outline:none}.swagger-ui select{font-size:14px;font-weight:700;padding:5px 40px 5px 10px;border:2px solid #41444e;border-radius:4px;background:#f7f7f7 url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMCAyMCI+ICAgIDxwYXRoIGQ9Ik0xMy40MTggNy44NTljLjI3MS0uMjY4LjcwOS0uMjY4Ljk3OCAwIC4yNy4yNjguMjcyLjcwMSAwIC45NjlsLTMuOTA4IDMuODNjLS4yNy4yNjgtLjcwNy4yNjgtLjk3OSAwbC0zLjkwOC0zLjgzYy0uMjctLjI2Ny0uMjctLjcwMSAwLS45NjkuMjcxLS4yNjguNzA5LS4yNjguOTc4IDBMMTAgMTFsMy40MTgtMy4xNDF6Ii8+PC9zdmc+) right 10px center no-repeat;background-size:20px;box-shadow:0 1px 2px 0 rgba(0,0,0,.25);font-family:Titillium Web,sans-serif;color:#3b4151;-webkit-appearance:none;-moz-appearance:none;appearance:none}.swagger-ui select[multiple]{margin:5px 0;padding:5px;background:#f7f7f7}.swagger-ui .opblock-body select{min-width:230px}.swagger-ui label{font-size:12px;font-weight:700;margin:0 0 5px;font-family:Titillium Web,sans-serif;color:#3b4151}.swagger-ui input[type=email],.swagger-ui input[type=password],.swagger-ui input[type=search],.swagger-ui input[type=text]{min-width:100px;margin:5px 0;padding:8px 10px;border:1px solid #d9d9d9;border-radius:4px;background:#fff}.swagger-ui input[type=email].invalid,.swagger-ui input[type=password].invalid,.swagger-ui input[type=search].invalid,.swagger-ui input[type=text].invalid{-webkit-animation:shake .4s 1;animation:shake .4s 1;border-color:#f93e3e;background:#feebeb}@-webkit-keyframes shake{10%,90%{-webkit-transform:translate3d(-1px,0,0);transform:translate3d(-1px,0,0)}20%,80%{-webkit-transform:translate3d(2px,0,0);transform:translate3d(2px,0,0)}30%,50%,70%{-webkit-transform:translate3d(-4px,0,0);transform:translate3d(-4px,0,0)}40%,60%{-webkit-transform:translate3d(4px,0,0);transform:translate3d(4px,0,0)}}@keyframes shake{10%,90%{-webkit-transform:translate3d(-1px,0,0);transform:translate3d(-1px,0,0)}20%,80%{-webkit-transform:translate3d(2px,0,0);transform:translate3d(2px,0,0)}30%,50%,70%{-webkit-transform:translate3d(-4px,0,0);transform:translate3d(-4px,0,0)}40%,60%{-webkit-transform:translate3d(4px,0,0);transform:translate3d(4px,0,0)}}.swagger-ui textarea{font-size:12px;width:100%;min-height:280px;padding:10px;border:none;border-radius:4px;outline:none;background:hsla(0,0%,100%,.8);font-family:Source Code Pro,monospace;font-weight:600;color:#3b4151}.swagger-ui textarea:focus{border:2px solid #61affe}.swagger-ui textarea.curl{font-size:12px;min-height:100px;margin:0;padding:10px;resize:none;border-radius:4px;background:#41444e;font-family:Source Code Pro,monospace;font-weight:600;color:#fff}.swagger-ui .checkbox{padding:5px 0 10px;-webkit-transition:opacity .5s;transition:opacity .5s;color:#333}.swagger-ui .checkbox label{display:-webkit-box;display:-ms-flexbox;display:flex}.swagger-ui .checkbox p{font-weight:400!important;font-style:italic;margin:0!important;font-family:Source Code Pro,monospace;font-weight:600;color:#3b4151}.swagger-ui .checkbox input[type=checkbox]{display:none}.swagger-ui .checkbox input[type=checkbox]+label>.item{position:relative;top:3px;display:inline-block;width:16px;height:16px;margin:0 8px 0 0;padding:5px;cursor:pointer;border-radius:1px;background:#e8e8e8;box-shadow:0 0 0 2px #e8e8e8;-webkit-box-flex:0;-ms-flex:none;flex:none}.swagger-ui .checkbox input[type=checkbox]+label>.item:active{-webkit-transform:scale(.9);transform:scale(.9)}.swagger-ui .checkbox input[type=checkbox]:checked+label>.item{background:#e8e8e8 url(\"data:image/svg+xml;charset=utf-8,%3Csvg width='10' height='8' viewBox='3 7 10 8' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%2341474E' fill-rule='evenodd' d='M6.333 15L3 11.667l1.333-1.334 2 2L11.667 7 13 8.333z'/%3E%3C/svg%3E\") 50% no-repeat}.swagger-ui .dialog-ux{position:fixed;z-index:9999;top:0;right:0;bottom:0;left:0}.swagger-ui .dialog-ux .backdrop-ux{position:fixed;top:0;right:0;bottom:0;left:0;background:rgba(0,0,0,.8)}.swagger-ui .dialog-ux .modal-ux{position:absolute;z-index:9999;top:50%;left:50%;width:100%;min-width:300px;max-width:650px;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);border:1px solid #ebebeb;border-radius:4px;background:#fff;box-shadow:0 10px 30px 0 rgba(0,0,0,.2)}.swagger-ui .dialog-ux .modal-ux-content{overflow-y:auto;max-height:540px;padding:20px}.swagger-ui .dialog-ux .modal-ux-content p{font-size:12px;margin:0 0 5px;color:#41444e;font-family:Open Sans,sans-serif;color:#3b4151}.swagger-ui .dialog-ux .modal-ux-content h4{font-size:18px;font-weight:600;margin:15px 0 0;font-family:Titillium Web,sans-serif;color:#3b4151}.swagger-ui .dialog-ux .modal-ux-header{display:-webkit-box;display:-ms-flexbox;display:flex;padding:12px 0;border-bottom:1px solid #ebebeb;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.swagger-ui .dialog-ux .modal-ux-header .close-modal{padding:0 10px;border:none;background:none;-webkit-appearance:none;-moz-appearance:none;appearance:none}.swagger-ui .dialog-ux .modal-ux-header h3{font-size:20px;font-weight:600;margin:0;padding:0 20px;-webkit-box-flex:1;-ms-flex:1;flex:1;font-family:Titillium Web,sans-serif;color:#3b4151}.swagger-ui .model{font-size:12px;font-weight:300;font-family:Source Code Pro,monospace;font-weight:600;color:#3b4151}.swagger-ui .model-toggle{font-size:10px;position:relative;top:6px;display:inline-block;margin:auto .3em;cursor:pointer;-webkit-transition:-webkit-transform .15s ease-in;transition:-webkit-transform .15s ease-in;transition:transform .15s ease-in;transition:transform .15s ease-in,-webkit-transform .15s ease-in;-webkit-transform:rotate(90deg);transform:rotate(90deg);-webkit-transform-origin:50% 50%;transform-origin:50% 50%}.swagger-ui .model-toggle.collapsed{-webkit-transform:rotate(0deg);transform:rotate(0deg)}.swagger-ui .model-toggle:after{display:block;width:20px;height:20px;content:\"\";background:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath d='M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z'/%3E%3C/svg%3E\") 50% no-repeat;background-size:100%}.swagger-ui .model-jump-to-path{position:relative;cursor:pointer}.swagger-ui .model-jump-to-path .view-line-link{position:absolute;top:-.4em;cursor:pointer}.swagger-ui .model-title{position:relative}.swagger-ui .model-title:hover .model-hint{visibility:visible}.swagger-ui .model-hint{position:absolute;top:-1.8em;visibility:hidden;padding:.1em .5em;white-space:nowrap;color:#ebebeb;border-radius:4px;background:rgba(0,0,0,.7)}.swagger-ui section.models{margin:30px 0;border:1px solid rgba(59,65,81,.3);border-radius:4px}.swagger-ui section.models.is-open{padding:0 0 20px}.swagger-ui section.models.is-open h4{margin:0 0 5px;border-bottom:1px solid rgba(59,65,81,.3)}.swagger-ui section.models.is-open h4 svg{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.swagger-ui section.models h4{font-size:16px;display:-webkit-box;display:-ms-flexbox;display:flex;margin:0;padding:10px 20px 10px 10px;cursor:pointer;-webkit-transition:all .2s;transition:all .2s;font-family:Titillium Web,sans-serif;color:#777;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.swagger-ui section.models h4 svg{-webkit-transition:all .4s;transition:all .4s}.swagger-ui section.models h4 span{-webkit-box-flex:1;-ms-flex:1;flex:1}.swagger-ui section.models h4:hover{background:rgba(0,0,0,.02)}.swagger-ui section.models h5{font-size:16px;margin:0 0 10px;font-family:Titillium Web,sans-serif;color:#777}.swagger-ui section.models .model-jump-to-path{position:relative;top:5px}.swagger-ui section.models .model-container{margin:0 20px 15px;-webkit-transition:all .5s;transition:all .5s;border-radius:4px;background:rgba(0,0,0,.05)}.swagger-ui section.models .model-container:hover{background:rgba(0,0,0,.07)}.swagger-ui section.models .model-container:first-of-type{margin:20px}.swagger-ui section.models .model-container:last-of-type{margin:0 20px}.swagger-ui section.models .model-box{background:none}.swagger-ui .model-box{padding:10px;border-radius:4px;background:rgba(0,0,0,.1)}.swagger-ui .model-box .model-jump-to-path{position:relative;top:4px}.swagger-ui .model-title{font-size:16px;font-family:Titillium Web,sans-serif;color:#555}.swagger-ui span>span.model,.swagger-ui span>span.model .brace-close{padding:0 0 0 10px}.swagger-ui .prop-type{color:#55a}.swagger-ui .prop-enum{display:block}.swagger-ui .prop-format{color:#999}.swagger-ui table{width:100%;padding:0 10px;border-collapse:collapse}.swagger-ui table.model tbody tr td{padding:0;vertical-align:top}.swagger-ui table.model tbody tr td:first-of-type{width:100px;padding:0}.swagger-ui table.headers td{font-size:12px;font-weight:300;vertical-align:middle;font-family:Source Code Pro,monospace;font-weight:600;color:#3b4151}.swagger-ui table tbody tr td{padding:10px 0 0;vertical-align:top}.swagger-ui table tbody tr td:first-of-type{width:20%;padding:10px 0}.swagger-ui table thead tr td,.swagger-ui table thead tr th{font-size:12px;font-weight:700;padding:12px 0;text-align:left;border-bottom:1px solid rgba(59,65,81,.2);font-family:Open Sans,sans-serif;color:#3b4151}.swagger-ui .parameters-col_description p{font-size:14px;margin:0;font-family:Open Sans,sans-serif;color:#3b4151}.swagger-ui .parameters-col_description input[type=text]{width:100%;max-width:340px}.swagger-ui .parameter__name{font-size:16px;font-weight:400;font-family:Titillium Web,sans-serif;color:#3b4151}.swagger-ui .parameter__name.required{font-weight:700}.swagger-ui .parameter__name.required:after{font-size:10px;position:relative;top:-6px;padding:5px;content:\"required\";color:rgba(255,0,0,.6)}.swagger-ui .parameter__in{font-size:12px;font-style:italic;font-family:Source Code Pro,monospace;font-weight:600;color:#888}.swagger-ui .table-container{padding:20px}.swagger-ui .topbar{padding:8px 30px;background-color:#89bf04}.swagger-ui .topbar .topbar-wrapper{-ms-flex-align:center}.swagger-ui .topbar .topbar-wrapper,.swagger-ui .topbar a{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;align-items:center}.swagger-ui .topbar a{font-size:1.5em;font-weight:700;text-decoration:none;-webkit-box-flex:1;-ms-flex:1;flex:1;-ms-flex-align:center;font-family:Titillium Web,sans-serif;color:#fff}.swagger-ui .topbar a span{margin:0;padding:0 10px}.swagger-ui .topbar .download-url-wrapper{display:-webkit-box;display:-ms-flexbox;display:flex}.swagger-ui .topbar .download-url-wrapper input[type=text]{min-width:350px;margin:0;border:2px solid #547f00;border-radius:4px 0 0 4px;outline:none}.swagger-ui .topbar .download-url-wrapper .download-url-button{font-size:16px;font-weight:700;padding:4px 40px;border:none;border-radius:0 4px 4px 0;background:#547f00;font-family:Titillium Web,sans-serif;color:#fff}.swagger-ui .info{margin:50px 0}.swagger-ui .info hgroup.main{margin:0 0 20px}.swagger-ui .info hgroup.main a{font-size:12px}.swagger-ui .info p{font-size:14px;font-family:Open Sans,sans-serif;color:#3b4151}.swagger-ui .info code{padding:3px 5px;border-radius:4px;background:rgba(0,0,0,.05);font-family:Source Code Pro,monospace;font-weight:600;color:#9012fe}.swagger-ui .info a{font-size:14px;-webkit-transition:all .4s;transition:all .4s;font-family:Open Sans,sans-serif;color:#4990e2}.swagger-ui .info a:hover{color:#1f69c0}.swagger-ui .info>div{margin:0 0 5px}.swagger-ui .info .base-url{font-size:12px;font-weight:300!important;margin:0;font-family:Source Code Pro,monospace;font-weight:600;color:#3b4151}.swagger-ui .info .title{font-size:36px;margin:0;font-family:Open Sans,sans-serif;color:#3b4151}.swagger-ui .info .title small{font-size:10px;position:relative;top:-5px;display:inline-block;margin:0 0 0 5px;padding:2px 4px;vertical-align:super;border-radius:57px;background:#7d8492}.swagger-ui .info .title small pre{margin:0;font-family:Titillium Web,sans-serif;color:#fff}.swagger-ui .auth-btn-wrapper{display:-webkit-box;display:-ms-flexbox;display:flex;padding:10px 0;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.swagger-ui .auth-wrapper{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-ms-flex:1;flex:1;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}.swagger-ui .auth-wrapper .authorize{padding-right:20px}.swagger-ui .auth-container{margin:0 0 10px;padding:10px 20px;border-bottom:1px solid #ebebeb}.swagger-ui .auth-container:last-of-type{margin:0;padding:10px 20px;border:0}.swagger-ui .auth-container h4{margin:5px 0 15px!important}.swagger-ui .auth-container .wrapper{margin:0;padding:0}.swagger-ui .auth-container input[type=password],.swagger-ui .auth-container input[type=text]{min-width:230px}.swagger-ui .auth-container .errors{font-size:12px;padding:10px;border-radius:4px;font-family:Source Code Pro,monospace;font-weight:600;color:#3b4151}.swagger-ui .scopes h2{font-size:14px;font-family:Titillium Web,sans-serif;color:#3b4151}.swagger-ui .scope-def{padding:0 0 20px}.swagger-ui .errors-wrapper{margin:20px;padding:10px 20px;-webkit-animation:scaleUp .5s;animation:scaleUp .5s;border:2px solid #f93e3e;border-radius:4px;background:rgba(249,62,62,.1)}.swagger-ui .errors-wrapper .error-wrapper{margin:0 0 10px}.swagger-ui .errors-wrapper .errors h4{font-size:14px;margin:0;font-family:Source Code Pro,monospace;font-weight:600;color:#3b4151}.swagger-ui .errors-wrapper hgroup{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.swagger-ui .errors-wrapper hgroup h4{font-size:20px;margin:0;-webkit-box-flex:1;-ms-flex:1;flex:1;font-family:Titillium Web,sans-serif;color:#3b4151}@-webkit-keyframes scaleUp{0%{-webkit-transform:scale(.8);transform:scale(.8);opacity:0}to{-webkit-transform:scale(1);transform:scale(1);opacity:1}}@keyframes scaleUp{0%{-webkit-transform:scale(.8);transform:scale(.8);opacity:0}to{-webkit-transform:scale(1);transform:scale(1);opacity:1}}",""]);
7 | },function(e,t){e.exports=function(){var e=[];return e.toString=function(){for(var e=[],t=0;t=0&&h.splice(t,1)}function s(e){var t=document.createElement("style");return t.type="text/css",i(e,t),t}function l(e){var t=document.createElement("link");return t.rel="stylesheet",i(e,t),t}function p(e,t){var o,r,n;if(t.singleton){var i=w++;o=x||(x=s(t)),r=u.bind(null,o,i,!1),n=u.bind(null,o,i,!0)}else e.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(o=l(t),r=f.bind(null,o),n=function(){a(o),o.href&&URL.revokeObjectURL(o.href)}):(o=s(t),r=c.bind(null,o),n=function(){a(o)});return r(e),function(t){if(t){if(t.css===e.css&&t.media===e.media&&t.sourceMap===e.sourceMap)return;r(e=t)}else n()}}function u(e,t,o,r){var n=o?"":r.css;if(e.styleSheet)e.styleSheet.cssText=y(t,n);else{var i=document.createTextNode(n),a=e.childNodes;a[t]&&e.removeChild(a[t]),a.length?e.insertBefore(i,a[t]):e.appendChild(i)}}function c(e,t){var o=t.css,r=t.media;t.sourceMap;if(r&&e.setAttribute("media",r),e.styleSheet)e.styleSheet.cssText=o;else{for(;e.firstChild;)e.removeChild(e.firstChild);e.appendChild(document.createTextNode(o))}}function f(e,t){var o=t.css,r=(t.media,t.sourceMap);r&&(o+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(r))))+" */");var n=new Blob([o],{type:"text/css"}),i=e.href;e.href=URL.createObjectURL(n),i&&URL.revokeObjectURL(i)}var d={},g=function(e){var t;return function(){return"undefined"==typeof t&&(t=e.apply(this,arguments)),t}},b=g(function(){return/msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase())}),m=g(function(){return document.head||document.getElementsByTagName("head")[0]}),x=null,w=0,h=[];e.exports=function(e,t){t=t||{},"undefined"==typeof t.singleton&&(t.singleton=b()),"undefined"==typeof t.insertAt&&(t.insertAt="bottom");var o=n(e);return r(o,t),function(e){for(var i=[],a=0;alabel{font-size:12px;font-weight:700;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin:-20px 15px 0 0;font-family:Titillium Web,sans-serif;color:#3b4151}.swagger-ui .scheme-container .schemes>label select{min-width:130px;text-transform:uppercase}.swagger-ui .loading-container{padding:40px 0 60px}.swagger-ui .loading-container .loading{position:relative}.swagger-ui .loading-container .loading:after{font-size:10px;font-weight:700;position:absolute;top:50%;left:50%;content:"loading";-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);text-transform:uppercase;font-family:Titillium Web,sans-serif;color:#3b4151}.swagger-ui .loading-container .loading:before{position:absolute;top:50%;left:50%;display:block;width:60px;height:60px;margin:-30px;content:"";-webkit-animation:rotation 1s infinite linear,opacity .5s;animation:rotation 1s infinite linear,opacity .5s;opacity:1;border:2px solid rgba(85,85,85,.1);border-top-color:rgba(0,0,0,.6);border-radius:100%;-webkit-backface-visibility:hidden;backface-visibility:hidden}@-webkit-keyframes rotation{to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes rotation{to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@-webkit-keyframes blinker{50%{opacity:0}}@keyframes blinker{50%{opacity:0}}.swagger-ui .btn{font-size:14px;font-weight:700;padding:5px 23px;-webkit-transition:all .3s;transition:all .3s;border:2px solid #888;border-radius:4px;background:transparent;box-shadow:0 1px 2px rgba(0,0,0,.1);font-family:Titillium Web,sans-serif;color:#3b4151}.swagger-ui .btn[disabled]{cursor:not-allowed;opacity:.3}.swagger-ui .btn:hover{box-shadow:0 0 5px rgba(0,0,0,.3)}.swagger-ui .btn.cancel{border-color:#ff6060;font-family:Titillium Web,sans-serif;color:#ff6060}.swagger-ui .btn.authorize{line-height:1;display:inline;color:#49cc90;border-color:#49cc90}.swagger-ui .btn.authorize span{float:left;padding:4px 20px 0 0}.swagger-ui .btn.authorize svg{fill:#49cc90}.swagger-ui .btn.execute{-webkit-animation:pulse 2s infinite;animation:pulse 2s infinite;color:#fff;border-color:#4990e2}@-webkit-keyframes pulse{0%{color:#fff;background:#4990e2;box-shadow:0 0 0 0 rgba(73,144,226,.8)}70%{box-shadow:0 0 0 5px rgba(73,144,226,0)}to{color:#fff;background:#4990e2;box-shadow:0 0 0 0 rgba(73,144,226,0)}}@keyframes pulse{0%{color:#fff;background:#4990e2;box-shadow:0 0 0 0 rgba(73,144,226,.8)}70%{box-shadow:0 0 0 5px rgba(73,144,226,0)}to{color:#fff;background:#4990e2;box-shadow:0 0 0 0 rgba(73,144,226,0)}}.swagger-ui .btn-group{display:-webkit-box;display:-ms-flexbox;display:flex;padding:30px}.swagger-ui .btn-group .btn{-webkit-box-flex:1;-ms-flex:1;flex:1}.swagger-ui .btn-group .btn:first-child{border-radius:4px 0 0 4px}.swagger-ui .btn-group .btn:last-child{border-radius:0 4px 4px 0}.swagger-ui .authorization__btn{padding:0 10px;border:none;background:none}.swagger-ui .authorization__btn.locked{opacity:1}.swagger-ui .authorization__btn.unlocked{opacity:.4}.swagger-ui .expand-methods,.swagger-ui .expand-operation{border:none;background:none}.swagger-ui .expand-methods svg,.swagger-ui .expand-operation svg{width:20px;height:20px}.swagger-ui .expand-methods{padding:0 10px}.swagger-ui .expand-methods:hover svg{fill:#444}.swagger-ui .expand-methods svg{-webkit-transition:all .3s;transition:all .3s;fill:#777}.swagger-ui button{cursor:pointer;outline:none}.swagger-ui select{font-size:14px;font-weight:700;padding:5px 40px 5px 10px;border:2px solid #41444e;border-radius:4px;background:#f7f7f7 url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMCAyMCI+ICAgIDxwYXRoIGQ9Ik0xMy40MTggNy44NTljLjI3MS0uMjY4LjcwOS0uMjY4Ljk3OCAwIC4yNy4yNjguMjcyLjcwMSAwIC45NjlsLTMuOTA4IDMuODNjLS4yNy4yNjgtLjcwNy4yNjgtLjk3OSAwbC0zLjkwOC0zLjgzYy0uMjctLjI2Ny0uMjctLjcwMSAwLS45NjkuMjcxLS4yNjguNzA5LS4yNjguOTc4IDBMMTAgMTFsMy40MTgtMy4xNDF6Ii8+PC9zdmc+) right 10px center no-repeat;background-size:20px;box-shadow:0 1px 2px 0 rgba(0,0,0,.25);font-family:Titillium Web,sans-serif;color:#3b4151;-webkit-appearance:none;-moz-appearance:none;appearance:none}.swagger-ui select[multiple]{margin:5px 0;padding:5px;background:#f7f7f7}.swagger-ui .opblock-body select{min-width:230px}.swagger-ui label{font-size:12px;font-weight:700;margin:0 0 5px;font-family:Titillium Web,sans-serif;color:#3b4151}.swagger-ui input[type=email],.swagger-ui input[type=password],.swagger-ui input[type=search],.swagger-ui input[type=text]{min-width:100px;margin:5px 0;padding:8px 10px;border:1px solid #d9d9d9;border-radius:4px;background:#fff}.swagger-ui input[type=email].invalid,.swagger-ui input[type=password].invalid,.swagger-ui input[type=search].invalid,.swagger-ui input[type=text].invalid{-webkit-animation:shake .4s 1;animation:shake .4s 1;border-color:#f93e3e;background:#feebeb}@-webkit-keyframes shake{10%,90%{-webkit-transform:translate3d(-1px,0,0);transform:translate3d(-1px,0,0)}20%,80%{-webkit-transform:translate3d(2px,0,0);transform:translate3d(2px,0,0)}30%,50%,70%{-webkit-transform:translate3d(-4px,0,0);transform:translate3d(-4px,0,0)}40%,60%{-webkit-transform:translate3d(4px,0,0);transform:translate3d(4px,0,0)}}@keyframes shake{10%,90%{-webkit-transform:translate3d(-1px,0,0);transform:translate3d(-1px,0,0)}20%,80%{-webkit-transform:translate3d(2px,0,0);transform:translate3d(2px,0,0)}30%,50%,70%{-webkit-transform:translate3d(-4px,0,0);transform:translate3d(-4px,0,0)}40%,60%{-webkit-transform:translate3d(4px,0,0);transform:translate3d(4px,0,0)}}.swagger-ui textarea{font-size:12px;width:100%;min-height:280px;padding:10px;border:none;border-radius:4px;outline:none;background:hsla(0,0%,100%,.8);font-family:Source Code Pro,monospace;font-weight:600;color:#3b4151}.swagger-ui textarea:focus{border:2px solid #61affe}.swagger-ui textarea.curl{font-size:12px;min-height:100px;margin:0;padding:10px;resize:none;border-radius:4px;background:#41444e;font-family:Source Code Pro,monospace;font-weight:600;color:#fff}.swagger-ui .checkbox{padding:5px 0 10px;-webkit-transition:opacity .5s;transition:opacity .5s;color:#333}.swagger-ui .checkbox label{display:-webkit-box;display:-ms-flexbox;display:flex}.swagger-ui .checkbox p{font-weight:400!important;font-style:italic;margin:0!important;font-family:Source Code Pro,monospace;font-weight:600;color:#3b4151}.swagger-ui .checkbox input[type=checkbox]{display:none}.swagger-ui .checkbox input[type=checkbox]+label>.item{position:relative;top:3px;display:inline-block;width:16px;height:16px;margin:0 8px 0 0;padding:5px;cursor:pointer;border-radius:1px;background:#e8e8e8;box-shadow:0 0 0 2px #e8e8e8;-webkit-box-flex:0;-ms-flex:none;flex:none}.swagger-ui .checkbox input[type=checkbox]+label>.item:active{-webkit-transform:scale(.9);transform:scale(.9)}.swagger-ui .checkbox input[type=checkbox]:checked+label>.item{background:#e8e8e8 url("data:image/svg+xml;charset=utf-8,%3Csvg width='10' height='8' viewBox='3 7 10 8' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%2341474E' fill-rule='evenodd' d='M6.333 15L3 11.667l1.333-1.334 2 2L11.667 7 13 8.333z'/%3E%3C/svg%3E") 50% no-repeat}.swagger-ui .dialog-ux{position:fixed;z-index:9999;top:0;right:0;bottom:0;left:0}.swagger-ui .dialog-ux .backdrop-ux{position:fixed;top:0;right:0;bottom:0;left:0;background:rgba(0,0,0,.8)}.swagger-ui .dialog-ux .modal-ux{position:absolute;z-index:9999;top:50%;left:50%;width:100%;min-width:300px;max-width:650px;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);border:1px solid #ebebeb;border-radius:4px;background:#fff;box-shadow:0 10px 30px 0 rgba(0,0,0,.2)}.swagger-ui .dialog-ux .modal-ux-content{overflow-y:auto;max-height:540px;padding:20px}.swagger-ui .dialog-ux .modal-ux-content p{font-size:12px;margin:0 0 5px;color:#41444e;font-family:Open Sans,sans-serif;color:#3b4151}.swagger-ui .dialog-ux .modal-ux-content h4{font-size:18px;font-weight:600;margin:15px 0 0;font-family:Titillium Web,sans-serif;color:#3b4151}.swagger-ui .dialog-ux .modal-ux-header{display:-webkit-box;display:-ms-flexbox;display:flex;padding:12px 0;border-bottom:1px solid #ebebeb;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.swagger-ui .dialog-ux .modal-ux-header .close-modal{padding:0 10px;border:none;background:none;-webkit-appearance:none;-moz-appearance:none;appearance:none}.swagger-ui .dialog-ux .modal-ux-header h3{font-size:20px;font-weight:600;margin:0;padding:0 20px;-webkit-box-flex:1;-ms-flex:1;flex:1;font-family:Titillium Web,sans-serif;color:#3b4151}.swagger-ui .model{font-size:12px;font-weight:300;font-family:Source Code Pro,monospace;font-weight:600;color:#3b4151}.swagger-ui .model-toggle{font-size:10px;position:relative;top:6px;display:inline-block;margin:auto .3em;cursor:pointer;-webkit-transition:-webkit-transform .15s ease-in;transition:-webkit-transform .15s ease-in;transition:transform .15s ease-in;transition:transform .15s ease-in,-webkit-transform .15s ease-in;-webkit-transform:rotate(90deg);transform:rotate(90deg);-webkit-transform-origin:50% 50%;transform-origin:50% 50%}.swagger-ui .model-toggle.collapsed{-webkit-transform:rotate(0deg);transform:rotate(0deg)}.swagger-ui .model-toggle:after{display:block;width:20px;height:20px;content:"";background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath d='M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z'/%3E%3C/svg%3E") 50% no-repeat;background-size:100%}.swagger-ui .model-jump-to-path{position:relative;cursor:pointer}.swagger-ui .model-jump-to-path .view-line-link{position:absolute;top:-.4em;cursor:pointer}.swagger-ui .model-title{position:relative}.swagger-ui .model-title:hover .model-hint{visibility:visible}.swagger-ui .model-hint{position:absolute;top:-1.8em;visibility:hidden;padding:.1em .5em;white-space:nowrap;color:#ebebeb;border-radius:4px;background:rgba(0,0,0,.7)}.swagger-ui section.models{margin:30px 0;border:1px solid rgba(59,65,81,.3);border-radius:4px}.swagger-ui section.models.is-open{padding:0 0 20px}.swagger-ui section.models.is-open h4{margin:0 0 5px;border-bottom:1px solid rgba(59,65,81,.3)}.swagger-ui section.models.is-open h4 svg{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.swagger-ui section.models h4{font-size:16px;display:-webkit-box;display:-ms-flexbox;display:flex;margin:0;padding:10px 20px 10px 10px;cursor:pointer;-webkit-transition:all .2s;transition:all .2s;font-family:Titillium Web,sans-serif;color:#777;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.swagger-ui section.models h4 svg{-webkit-transition:all .4s;transition:all .4s}.swagger-ui section.models h4 span{-webkit-box-flex:1;-ms-flex:1;flex:1}.swagger-ui section.models h4:hover{background:rgba(0,0,0,.02)}.swagger-ui section.models h5{font-size:16px;margin:0 0 10px;font-family:Titillium Web,sans-serif;color:#777}.swagger-ui section.models .model-jump-to-path{position:relative;top:5px}.swagger-ui section.models .model-container{margin:0 20px 15px;-webkit-transition:all .5s;transition:all .5s;border-radius:4px;background:rgba(0,0,0,.05)}.swagger-ui section.models .model-container:hover{background:rgba(0,0,0,.07)}.swagger-ui section.models .model-container:first-of-type{margin:20px}.swagger-ui section.models .model-container:last-of-type{margin:0 20px}.swagger-ui section.models .model-box{background:none}.swagger-ui .model-box{padding:10px;border-radius:4px;background:rgba(0,0,0,.1)}.swagger-ui .model-box .model-jump-to-path{position:relative;top:4px}.swagger-ui .model-title{font-size:16px;font-family:Titillium Web,sans-serif;color:#555}.swagger-ui span>span.model,.swagger-ui span>span.model .brace-close{padding:0 0 0 10px}.swagger-ui .prop-type{color:#55a}.swagger-ui .prop-enum{display:block}.swagger-ui .prop-format{color:#999}.swagger-ui table{width:100%;padding:0 10px;border-collapse:collapse}.swagger-ui table.model tbody tr td{padding:0;vertical-align:top}.swagger-ui table.model tbody tr td:first-of-type{width:100px;padding:0}.swagger-ui table.headers td{font-size:12px;font-weight:300;vertical-align:middle;font-family:Source Code Pro,monospace;font-weight:600;color:#3b4151}.swagger-ui table tbody tr td{padding:10px 0 0;vertical-align:top}.swagger-ui table tbody tr td:first-of-type{width:20%;padding:10px 0}.swagger-ui table thead tr td,.swagger-ui table thead tr th{font-size:12px;font-weight:700;padding:12px 0;text-align:left;border-bottom:1px solid rgba(59,65,81,.2);font-family:Open Sans,sans-serif;color:#3b4151}.swagger-ui .parameters-col_description p{font-size:14px;margin:0;font-family:Open Sans,sans-serif;color:#3b4151}.swagger-ui .parameters-col_description input[type=text]{width:100%;max-width:340px}.swagger-ui .parameter__name{font-size:16px;font-weight:400;font-family:Titillium Web,sans-serif;color:#3b4151}.swagger-ui .parameter__name.required{font-weight:700}.swagger-ui .parameter__name.required:after{font-size:10px;position:relative;top:-6px;padding:5px;content:"required";color:rgba(255,0,0,.6)}.swagger-ui .parameter__in{font-size:12px;font-style:italic;font-family:Source Code Pro,monospace;font-weight:600;color:#888}.swagger-ui .table-container{padding:20px}.swagger-ui .topbar{padding:8px 30px;background-color:#89bf04}.swagger-ui .topbar .topbar-wrapper{-ms-flex-align:center}.swagger-ui .topbar .topbar-wrapper,.swagger-ui .topbar a{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;align-items:center}.swagger-ui .topbar a{font-size:1.5em;font-weight:700;text-decoration:none;-webkit-box-flex:1;-ms-flex:1;flex:1;-ms-flex-align:center;font-family:Titillium Web,sans-serif;color:#fff}.swagger-ui .topbar a span{margin:0;padding:0 10px}.swagger-ui .topbar .download-url-wrapper{display:-webkit-box;display:-ms-flexbox;display:flex}.swagger-ui .topbar .download-url-wrapper input[type=text]{min-width:350px;margin:0;border:2px solid #547f00;border-radius:4px 0 0 4px;outline:none}.swagger-ui .topbar .download-url-wrapper .download-url-button{font-size:16px;font-weight:700;padding:4px 40px;border:none;border-radius:0 4px 4px 0;background:#547f00;font-family:Titillium Web,sans-serif;color:#fff}.swagger-ui .info{margin:50px 0}.swagger-ui .info hgroup.main{margin:0 0 20px}.swagger-ui .info hgroup.main a{font-size:12px}.swagger-ui .info p{font-size:14px;font-family:Open Sans,sans-serif;color:#3b4151}.swagger-ui .info code{padding:3px 5px;border-radius:4px;background:rgba(0,0,0,.05);font-family:Source Code Pro,monospace;font-weight:600;color:#9012fe}.swagger-ui .info a{font-size:14px;-webkit-transition:all .4s;transition:all .4s;font-family:Open Sans,sans-serif;color:#4990e2}.swagger-ui .info a:hover{color:#1f69c0}.swagger-ui .info>div{margin:0 0 5px}.swagger-ui .info .base-url{font-size:12px;font-weight:300!important;margin:0;font-family:Source Code Pro,monospace;font-weight:600;color:#3b4151}.swagger-ui .info .title{font-size:36px;margin:0;font-family:Open Sans,sans-serif;color:#3b4151}.swagger-ui .info .title small{font-size:10px;position:relative;top:-5px;display:inline-block;margin:0 0 0 5px;padding:2px 4px;vertical-align:super;border-radius:57px;background:#7d8492}.swagger-ui .info .title small pre{margin:0;font-family:Titillium Web,sans-serif;color:#fff}.swagger-ui .auth-btn-wrapper{display:-webkit-box;display:-ms-flexbox;display:flex;padding:10px 0;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.swagger-ui .auth-wrapper{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-ms-flex:1;flex:1;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}.swagger-ui .auth-wrapper .authorize{padding-right:20px}.swagger-ui .auth-container{margin:0 0 10px;padding:10px 20px;border-bottom:1px solid #ebebeb}.swagger-ui .auth-container:last-of-type{margin:0;padding:10px 20px;border:0}.swagger-ui .auth-container h4{margin:5px 0 15px!important}.swagger-ui .auth-container .wrapper{margin:0;padding:0}.swagger-ui .auth-container input[type=password],.swagger-ui .auth-container input[type=text]{min-width:230px}.swagger-ui .auth-container .errors{font-size:12px;padding:10px;border-radius:4px;font-family:Source Code Pro,monospace;font-weight:600;color:#3b4151}.swagger-ui .scopes h2{font-size:14px;font-family:Titillium Web,sans-serif;color:#3b4151}.swagger-ui .scope-def{padding:0 0 20px}.swagger-ui .errors-wrapper{margin:20px;padding:10px 20px;-webkit-animation:scaleUp .5s;animation:scaleUp .5s;border:2px solid #f93e3e;border-radius:4px;background:rgba(249,62,62,.1)}.swagger-ui .errors-wrapper .error-wrapper{margin:0 0 10px}.swagger-ui .errors-wrapper .errors h4{font-size:14px;margin:0;font-family:Source Code Pro,monospace;font-weight:600;color:#3b4151}.swagger-ui .errors-wrapper hgroup{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.swagger-ui .errors-wrapper hgroup h4{font-size:20px;margin:0;-webkit-box-flex:1;-ms-flex:1;flex:1;font-family:Titillium Web,sans-serif;color:#3b4151}@-webkit-keyframes scaleUp{0%{-webkit-transform:scale(.8);transform:scale(.8);opacity:0}to{-webkit-transform:scale(1);transform:scale(1);opacity:1}}@keyframes scaleUp{0%{-webkit-transform:scale(.8);transform:scale(.8);opacity:0}to{-webkit-transform:scale(1);transform:scale(1);opacity:1}}.swagger-ui .Resizer.vertical.disabled{display:none}
2 | /*# sourceMappingURL=swagger-ui.css.map*/
--------------------------------------------------------------------------------
/api/static/swagger/swagger-ui.css.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"swagger-ui.css","sources":[],"mappings":"","sourceRoot":""}
--------------------------------------------------------------------------------
/api/static/swagger/swagger-ui.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"swagger-ui.js","sources":["webpack:///swagger-ui.js"],"mappings":"AAAA;AAsoGA;AAy4HA;AA67FA;AA4mCA;AAs+BA;AAsiCA;AAm5BA","sourceRoot":""}
--------------------------------------------------------------------------------
/autoscale/.dockerignore:
--------------------------------------------------------------------------------
1 | .dockerignore
2 | *.iml
3 | .idea
4 | .venv
5 | .git
6 | .gitignore
--------------------------------------------------------------------------------
/autoscale/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.7
2 |
3 | WORKDIR /app/
4 | COPY . /app/
5 |
6 | RUN pip3 install -r requirements.txt
7 |
8 | CMD ["/app/entrypoint.sh"]
9 |
--------------------------------------------------------------------------------
/autoscale/autoscale2.py:
--------------------------------------------------------------------------------
1 | import os
2 | import sys
3 | import time
4 |
5 | from marathon import MarathonClient
6 | from marathon import MarathonError
7 | from redis import StrictRedis
8 |
9 | dcos_master = os.getenv('DCOS_MASTER') or input("Enter the DNS hostname or IP of your Marathon Instance: ")
10 | userid = os.getenv('MARATHON_USER') or input('Enter the username for the DCOS cluster: ')
11 | password = os.getenv('MARATHON_PWD') or input('Enter the password for the DCOS cluster: ')
12 | marathon_app = os.getenv('APP_NAME') or input("Enter the Marathon Application Name to scale (eg: /worker): ")
13 | redis_uri = os.getenv('REDIS_URI') or input("Enter the Redis URI, including password (eg: redis://localhost:8999/2): ")
14 | max_instances = os.getenv('MAX_INSTANCES') or 10
15 | min_instances = os.getenv('MIN_INSTANCES') or 1
16 |
17 | c = MarathonClient(dcos_master, username=userid, password=password)
18 | r = StrictRedis.from_url(redis_uri)
19 |
20 | while True:
21 | print("Loop!")
22 | app = None
23 | while app is None:
24 | try:
25 | app = c.get_app(marathon_app)
26 | except MarathonError as err:
27 | print(err)
28 | app = None
29 | time.sleep(1)
30 |
31 | waitingDocs = r.llen("celery")
32 |
33 | instances = app.instances
34 |
35 | if waitingDocs == instances:
36 | pass
37 | elif waitingDocs > instances:
38 | instances += 1
39 | else:
40 | instances -= 1
41 |
42 | instances = min(max_instances, max(min_instances, instances))
43 | print("App instances: ", app.instances, " - New value: ", instances)
44 | if app.instances != instances:
45 | print("Delta: ", (app.instances - instances))
46 | c.scale_app(marathon_app, instances=instances, force=True)
47 | sys.stdout.flush()
48 | time.sleep(2)
49 |
--------------------------------------------------------------------------------
/autoscale/entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | echo "Starting the AutoScale thing"
5 | exec python autoscale2.py
--------------------------------------------------------------------------------
/autoscale/requirements.txt:
--------------------------------------------------------------------------------
1 | marathon==0.8.9
2 | redis==2.10.5
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '2.1'
2 |
3 | services:
4 | # Redis
5 | redis:
6 | image: redis
7 |
8 | # Our rest API
9 | web:
10 | build:
11 | context: api
12 | dockerfile: Dockerfile
13 | image: docbleach/api:latest
14 | environment:
15 | - CELERY_BROKER=redis://redis/
16 | - CELERY_RESULT_BACKEND=redis://redis/
17 | - INTERNAL_PLIK_SERVER=${FINAL_PLIK_SERVER:-http://plik:8080}
18 | ports:
19 | - "${EXTERNAL_PORT:-9000}:5000"
20 | tmpfs: /tmp
21 |
22 | # Celery worker, the one you should be scaling using, ie to have 10 instances:
23 | # `docker-compose scale worker=10`
24 | worker:
25 | build:
26 | context: worker
27 | dockerfile: Dockerfile
28 | image: docbleach/worker:latest
29 | environment:
30 | - CELERY_BROKER=redis://redis/
31 | - CELERY_RESULT_BACKEND=redis://redis/
32 | - FINAL_PLIK_SERVER=${FINAL_PLIK_SERVER:-https://plik.root.gg}
33 | tmpfs: /tmp
34 |
35 | plik:
36 | image: rootgg/plik
37 | expose:
38 | - 8080
--------------------------------------------------------------------------------
/docs/Chooseafile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docbleach/DocBleach-Web/13657e45d41f7deae689cf6fae0e62d3d7c947df/docs/Chooseafile.png
--------------------------------------------------------------------------------
/docs/clickhere.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docbleach/DocBleach-Web/13657e45d41f7deae689cf6fae0e62d3d7c947df/docs/clickhere.png
--------------------------------------------------------------------------------
/docs/downloadyourfile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docbleach/DocBleach-Web/13657e45d41f7deae689cf6fae0e62d3d7c947df/docs/downloadyourfile.png
--------------------------------------------------------------------------------
/worker/.dockerignore:
--------------------------------------------------------------------------------
1 | .dockerignore
2 | *.iml
3 | .idea
4 | .venv
5 | .git
6 | .gitignore
7 | Dockerfile
--------------------------------------------------------------------------------
/worker/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM openjdk:8-jre-alpine
2 |
3 | ENTRYPOINT ["/app/entrypoint.sh"]
4 |
5 | HEALTHCHECK CMD /usr/bin/celery inspect ping -A docbleach.tasks -d celery@$HOSTNAME
6 |
7 | ENV FINAL_PLIK_SERVER https://plik.root.gg
8 |
9 | # Stored on Plik for now, as we don't yet have the GitHub Link
10 | ENV DOCBLEACH_JAR https://github.com/docbleach/DocBleach/releases/download/v0.0.9/docbleach.jar
11 |
12 | # We add the Plik binary file
13 | ADD https://plik.root.gg/clients/linux-amd64/plik /usr/bin/plik
14 |
15 | RUN apk add --no-cache --update-cache \
16 | # Having up to date SSL certificates is always a good thing. :)
17 | ca-certificates \
18 | openssl \
19 | python3 \
20 | && \
21 | update-ca-certificates && \
22 |
23 | # Add glibc, wanted by plik (compiled with Go)
24 | wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub && \
25 | wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.23-r3/glibc-2.23-r3.apk && \
26 | apk add glibc-2.23-r3.apk && \
27 |
28 | # Setup Python 3
29 | python3 -m ensurepip && \
30 | rm -r /usr/lib/python*/ensurepip && \
31 | pip3 install --upgrade pip setuptools && \
32 | rm -r /root/.cache && \
33 | # Remove openssl, only needed for wget
34 | apk del openssl wget unzip && \
35 |
36 | # We add an user
37 | adduser -S -u 1000 worker && \
38 |
39 | # Add default config for Plik, required
40 | chmod o+x /usr/bin/plik && \
41 | echo 'URL = "https://plik.root.gg"' > /home/worker/.plikrc
42 |
43 | # Install the celery dependency
44 | ADD requirements.txt ${DOCBLEACH_JAR} /app/
45 |
46 | WORKDIR /app/
47 |
48 | RUN pip3 install --no-cache-dir -r requirements.txt && \
49 | chown -R worker /app/; chmod -R 770 /app/
50 |
51 | USER worker
52 | COPY . /app/
53 |
--------------------------------------------------------------------------------
/worker/docbleach/__init__.py:
--------------------------------------------------------------------------------
1 | # Required for docbleach to be a valid python package
2 |
--------------------------------------------------------------------------------
/worker/docbleach/celeryconfig.py:
--------------------------------------------------------------------------------
1 | # Same TTL as Plik
2 | result_expires = 12 * 3600
3 | task_reject_on_worker_lost = True
4 |
--------------------------------------------------------------------------------
/worker/docbleach/tasks/__init__.py:
--------------------------------------------------------------------------------
1 | import os
2 | import time
3 | from subprocess import PIPE, Popen
4 |
5 | from celery import Celery
6 |
7 | external_plik_server = os.getenv('FINAL_PLIK_SERVER', 'https://plik.root.gg')
8 |
9 | cel = Celery(
10 | 'docbleach',
11 | broker=os.getenv('CELERY_BROKER'),
12 | backend=os.getenv('CELERY_RESULT_BACKEND')
13 | )
14 |
15 | cel.config_from_object('docbleach.celeryconfig')
16 |
17 | def get_wget_command(original_uri):
18 | return ['wget', '-qO-', original_uri]
19 |
20 | def get_docbleach_command():
21 | return ['java',
22 | '-jar', 'docbleach.jar',
23 | '-in', '-',
24 | '-out', '-'
25 | ]
26 |
27 |
28 | def get_plik_command(original_filename):
29 | return ['plik',
30 | '-q',
31 | '--server', external_plik_server,
32 | '-t', '12h',
33 | '-n', original_filename
34 | ]
35 |
36 |
37 | @cel.task(name="sanitize")
38 | def sanitize_task(original_uri, original_filename):
39 | wget_command = get_wget_command(original_uri)
40 | docbleach_command = get_docbleach_command()
41 | plik_command = get_plik_command(original_filename)
42 |
43 | p0 = Popen(wget_command, stdout=PIPE)
44 | p1 = Popen(docbleach_command, stdin=p0.stdout, stdout=PIPE, stderr=PIPE)
45 | p2 = Popen(plik_command, stdin=p1.stdout, stdout=PIPE)
46 |
47 | plik_link, plik_err = p2.communicate()
48 | _, docbleach_output = p1.communicate()
49 | _, _ = p0.communicate()
50 |
51 | # We build a "pretty" output to be displayed
52 | total_output = ""
53 | if docbleach_output:
54 | total_output += docbleach_output.decode('utf-8').strip()
55 | if plik_err:
56 | total_output += "\n"
57 |
58 | if plik_err:
59 | total_output += 'SEVERE ' + plik_err.decode('utf-8').strip()
60 |
61 | if p1.returncode == 0 and p2.returncode == 0:
62 | return {
63 | 'output': total_output,
64 | 'exit_code': 0,
65 | 'final_file': plik_link.decode('utf-8').strip()
66 | }
67 |
68 | # return_code is the first non null exit code
69 | return_code = p1.returncode or p2.returncode
70 |
71 | return {
72 | 'exit_code': return_code,
73 | 'output': total_output
74 | }
75 |
76 |
--------------------------------------------------------------------------------
/worker/entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 |
4 | export CELERY_WORKER_MAX_TASKS=${CELERY_WORKER_MAX_TASKS:=1000}
5 | export CELERY_QUEUES=${CELERY_QUEUES:=celery}
6 | export C_FORCE_ROOT="true"
7 |
8 | echo "Starting celery worker"
9 | exec celery worker \
10 | -A docbleach.tasks \
11 | -Q ${CELERY_QUEUES} \
12 | --maxtasksperchild=${CELERY_WORKER_MAX_TASKS} \
13 | --loglevel=INFO
14 |
--------------------------------------------------------------------------------
/worker/requirements.txt:
--------------------------------------------------------------------------------
1 | celery[redis]==4.3.0
2 |
--------------------------------------------------------------------------------