Compare commits

...

4 Commits

Author SHA1 Message Date
Patrick Jentsch
8f960cf359 explicitly set permissions to false for anonymous users 2024-04-11 15:46:58 +02:00
Patrick Jentsch
ccf484c9bc make is_administrator a property, add back db events 2024-04-11 14:33:47 +02:00
Patrick Jentsch
d0d2a8abd6 Move external static content into external directory 2024-04-11 14:13:04 +02:00
Patrick Jentsch
03876f6a39 Self host external css/fonts/js 2024-04-11 11:08:37 +02:00
195 changed files with 1553526 additions and 82 deletions

View File

@ -77,7 +77,7 @@ def delete_job(job_id):
job = Job.query.get(job_id) job = Job.query.get(job_id)
if job is None: if job is None:
abort(404) abort(404)
if not (job.user == current_user or current_user.is_administrator()): if not (job.user == current_user or current_user.is_administrator):
abort(403) abort(403)
try: try:
job.delete() job.delete()
@ -97,6 +97,6 @@ def get_job(job_id):
job = Job.query.get(job_id) job = Job.query.get(job_id)
if job is None: if job is None:
abort(404) abort(404)
if not (job.user == current_user or current_user.is_administrator()): if not (job.user == current_user or current_user.is_administrator):
abort(403) abort(403)
return job return job

View File

@ -60,7 +60,7 @@ def delete_user(user_id):
user = User.query.get(user_id) user = User.query.get(user_id)
if user is None: if user is None:
abort(404) abort(404)
if not (user == current_user or current_user.is_administrator()): if not (user == current_user or current_user.is_administrator):
abort(403) abort(403)
user.delete() user.delete()
db.session.commit() db.session.commit()
@ -78,7 +78,7 @@ def get_user(user_id):
user = User.query.get(user_id) user = User.query.get(user_id)
if user is None: if user is None:
abort(404) abort(404)
if not (user == current_user or current_user.is_administrator()): if not (user == current_user or current_user.is_administrator):
abort(403) abort(403)
return user return user
@ -94,6 +94,6 @@ def get_user_by_username(username):
user = User.query.filter(User.username == username).first() user = User.query.filter(User.username == username).first()
if user is None: if user is None:
abort(404) abort(404)
if not (user == current_user or current_user.is_administrator()): if not (user == current_user or current_user.is_administrator):
abort(403) abort(403)
return user return user

View File

@ -17,7 +17,7 @@ def delete_spacy_model(spacy_nlp_pipeline_model_id):
db.session.commit() db.session.commit()
snpm = SpaCyNLPPipelineModel.query.get_or_404(spacy_nlp_pipeline_model_id) snpm = SpaCyNLPPipelineModel.query.get_or_404(spacy_nlp_pipeline_model_id)
if not (snpm.user == current_user or current_user.is_administrator()): if not (snpm.user == current_user or current_user.is_administrator):
abort(403) abort(403)
thread = Thread( thread = Thread(
target=_delete_spacy_model, target=_delete_spacy_model,
@ -39,7 +39,7 @@ def update_spacy_nlp_pipeline_model_is_public(spacy_nlp_pipeline_model_id):
if not isinstance(is_public, bool): if not isinstance(is_public, bool):
abort(400) abort(400)
snpm = SpaCyNLPPipelineModel.query.get_or_404(spacy_nlp_pipeline_model_id) snpm = SpaCyNLPPipelineModel.query.get_or_404(spacy_nlp_pipeline_model_id)
if not (snpm.user == current_user or current_user.is_administrator()): if not (snpm.user == current_user or current_user.is_administrator):
abort(403) abort(403)
snpm.is_public = is_public snpm.is_public = is_public
db.session.commit() db.session.commit()

View File

@ -58,7 +58,7 @@ def create_spacy_nlp_pipeline_model():
@register_breadcrumb(bp, '.spacy_nlp_pipeline_models.entity', '', dynamic_list_constructor=spacy_nlp_pipeline_model_dlc) @register_breadcrumb(bp, '.spacy_nlp_pipeline_models.entity', '', dynamic_list_constructor=spacy_nlp_pipeline_model_dlc)
def spacy_nlp_pipeline_model(spacy_nlp_pipeline_model_id): def spacy_nlp_pipeline_model(spacy_nlp_pipeline_model_id):
snpm = SpaCyNLPPipelineModel.query.get_or_404(spacy_nlp_pipeline_model_id) snpm = SpaCyNLPPipelineModel.query.get_or_404(spacy_nlp_pipeline_model_id)
if not (snpm.user == current_user or current_user.is_administrator()): if not (snpm.user == current_user or current_user.is_administrator):
abort(403) abort(403)
form = UpdateSpaCyNLPPipelineModelForm(data=snpm.to_json_serializeable()) form = UpdateSpaCyNLPPipelineModelForm(data=snpm.to_json_serializeable())
if form.validate_on_submit(): if form.validate_on_submit():

View File

@ -17,7 +17,7 @@ def delete_tesseract_model(tesseract_ocr_pipeline_model_id):
db.session.commit() db.session.commit()
topm = TesseractOCRPipelineModel.query.get_or_404(tesseract_ocr_pipeline_model_id) topm = TesseractOCRPipelineModel.query.get_or_404(tesseract_ocr_pipeline_model_id)
if not (topm.user == current_user or current_user.is_administrator()): if not (topm.user == current_user or current_user.is_administrator):
abort(403) abort(403)
thread = Thread( thread = Thread(
target=_delete_tesseract_ocr_pipeline_model, target=_delete_tesseract_ocr_pipeline_model,
@ -39,7 +39,7 @@ def update_tesseract_ocr_pipeline_model_is_public(tesseract_ocr_pipeline_model_i
if not isinstance(is_public, bool): if not isinstance(is_public, bool):
abort(400) abort(400)
topm = TesseractOCRPipelineModel.query.get_or_404(tesseract_ocr_pipeline_model_id) topm = TesseractOCRPipelineModel.query.get_or_404(tesseract_ocr_pipeline_model_id)
if not (topm.user == current_user or current_user.is_administrator()): if not (topm.user == current_user or current_user.is_administrator):
abort(403) abort(403)
topm.is_public = is_public topm.is_public = is_public
db.session.commit() db.session.commit()

View File

@ -57,7 +57,7 @@ def create_tesseract_ocr_pipeline_model():
@register_breadcrumb(bp, '.tesseract_ocr_pipeline_models.entity', '', dynamic_list_constructor=tesseract_ocr_pipeline_model_dlc) @register_breadcrumb(bp, '.tesseract_ocr_pipeline_models.entity', '', dynamic_list_constructor=tesseract_ocr_pipeline_model_dlc)
def tesseract_ocr_pipeline_model(tesseract_ocr_pipeline_model_id): def tesseract_ocr_pipeline_model(tesseract_ocr_pipeline_model_id):
topm = TesseractOCRPipelineModel.query.get_or_404(tesseract_ocr_pipeline_model_id) topm = TesseractOCRPipelineModel.query.get_or_404(tesseract_ocr_pipeline_model_id)
if not (topm.user == current_user or current_user.is_administrator()): if not (topm.user == current_user or current_user.is_administrator):
abort(403) abort(403)
form = UpdateTesseractOCRPipelineModelForm(data=topm.to_json_serializeable()) form = UpdateTesseractOCRPipelineModelForm(data=topm.to_json_serializeable())
if form.validate_on_submit(): if form.validate_on_submit():

View File

@ -99,7 +99,7 @@ class CQiNamespace(Namespace):
return {'code': 404, 'msg': 'Not Found'} return {'code': 404, 'msg': 'Not Found'}
if not (db_corpus.user == current_user if not (db_corpus.user == current_user
or current_user.is_following_corpus(db_corpus) or current_user.is_following_corpus(db_corpus)
or current_user.is_administrator()): or current_user.is_administrator):
return {'code': 403, 'msg': 'Forbidden'} return {'code': 403, 'msg': 'Forbidden'}
if db_corpus.status not in [ if db_corpus.status not in [
CorpusStatus.BUILT, CorpusStatus.BUILT,

View File

@ -10,7 +10,7 @@ def corpus_follower_permission_required(*permissions):
def decorated_function(*args, **kwargs): def decorated_function(*args, **kwargs):
corpus_id = kwargs.get('corpus_id') corpus_id = kwargs.get('corpus_id')
corpus = Corpus.query.get_or_404(corpus_id) corpus = Corpus.query.get_or_404(corpus_id)
if not (corpus.user == current_user or current_user.is_administrator()): if not (corpus.user == current_user or current_user.is_administrator):
cfa = CorpusFollowerAssociation.query.filter_by(corpus_id=corpus_id, follower_id=current_user.id).first() cfa = CorpusFollowerAssociation.query.filter_by(corpus_id=corpus_id, follower_id=current_user.id).first()
if cfa is None: if cfa is None:
abort(403) abort(403)
@ -26,7 +26,7 @@ def corpus_owner_or_admin_required(f):
def decorated_function(*args, **kwargs): def decorated_function(*args, **kwargs):
corpus_id = kwargs.get('corpus_id') corpus_id = kwargs.get('corpus_id')
corpus = Corpus.query.get_or_404(corpus_id) corpus = Corpus.query.get_or_404(corpus_id)
if not (corpus.user == current_user or current_user.is_administrator()): if not (corpus.user == current_user or current_user.is_administrator):
abort(403) abort(403)
return f(*args, **kwargs) return f(*args, **kwargs)
return decorated_function return decorated_function

View File

@ -15,7 +15,7 @@ def get_corpus(corpus_hashid):
if not ( if not (
corpus.is_public corpus.is_public
or corpus.user == current_user or corpus.user == current_user
or current_user.is_administrator() or current_user.is_administrator
): ):
return {'options': {'status': 403, 'statusText': 'Forbidden'}} return {'options': {'status': 403, 'statusText': 'Forbidden'}}
return { return {
@ -38,7 +38,7 @@ def subscribe_corpus(corpus_hashid):
if not ( if not (
corpus.is_public corpus.is_public
or corpus.user == current_user or corpus.user == current_user
or current_user.is_administrator() or current_user.is_administrator
): ):
return {'options': {'status': 403, 'statusText': 'Forbidden'}} return {'options': {'status': 403, 'statusText': 'Forbidden'}}
join_room(f'/corpora/{corpus.hashid}') join_room(f'/corpora/{corpus.hashid}')

View File

@ -58,7 +58,7 @@ def delete_corpus_follower(corpus_id, follower_id):
current_user.id == follower_id current_user.id == follower_id
or current_user == cfa.corpus.user or current_user == cfa.corpus.user
or CorpusFollowerAssociation.query.filter_by(corpus_id=corpus_id, follower_id=current_user.id).first().role.has_permission('MANAGE_FOLLOWERS') or CorpusFollowerAssociation.query.filter_by(corpus_id=corpus_id, follower_id=current_user.id).first().role.has_permission('MANAGE_FOLLOWERS')
or current_user.is_administrator()): or current_user.is_administrator):
abort(403) abort(403)
if current_user.id == follower_id: if current_user.id == follower_id:
flash(f'You are no longer following "{cfa.corpus.title}"', 'corpus') flash(f'You are no longer following "{cfa.corpus.title}"', 'corpus')

View File

@ -55,13 +55,13 @@ def corpus(corpus_id):
users = User.query.filter(User.is_public == True, User.id != current_user.id, User.id != corpus.user.id, User.role_id < 4).all() users = User.query.filter(User.is_public == True, User.id != current_user.id, User.id != corpus.user.id, User.role_id < 4).all()
cfa = CorpusFollowerAssociation.query.filter_by(corpus_id=corpus_id, follower_id=current_user.id).first() cfa = CorpusFollowerAssociation.query.filter_by(corpus_id=corpus_id, follower_id=current_user.id).first()
if cfa is None: if cfa is None:
if corpus.user == current_user or current_user.is_administrator(): if corpus.user == current_user or current_user.is_administrator:
cfr = CorpusFollowerRole.query.filter_by(name='Administrator').first() cfr = CorpusFollowerRole.query.filter_by(name='Administrator').first()
else: else:
cfr = CorpusFollowerRole.query.filter_by(name='Anonymous').first() cfr = CorpusFollowerRole.query.filter_by(name='Anonymous').first()
else: else:
cfr = cfa.role cfr = cfa.role
if corpus.user == current_user or current_user.is_administrator(): if corpus.user == current_user or current_user.is_administrator:
return render_template( return render_template(
'corpora/corpus.html.j2', 'corpora/corpus.html.j2',
title=corpus.title, title=corpus.title,

View File

@ -17,7 +17,7 @@ def delete_job(job_id):
db.session.commit() db.session.commit()
job = Job.query.get_or_404(job_id) job = Job.query.get_or_404(job_id)
if not (job.user == current_user or current_user.is_administrator()): if not (job.user == current_user or current_user.is_administrator):
abort(403) abort(403)
thread = Thread( thread = Thread(
target=_delete_job, target=_delete_job,
@ -56,7 +56,7 @@ def restart_job(job_id):
db.session.commit() db.session.commit()
job = Job.query.get_or_404(job_id) job = Job.query.get_or_404(job_id)
if not (job.user == current_user or current_user.is_administrator()): if not (job.user == current_user or current_user.is_administrator):
abort(403) abort(403)
if job.status == JobStatus.FAILED: if job.status == JobStatus.FAILED:
response = {'errors': {'message': 'Job status is not "failed"'}} response = {'errors': {'message': 'Job status is not "failed"'}}

View File

@ -22,7 +22,7 @@ def corpora():
@register_breadcrumb(bp, '.entity', '', dynamic_list_constructor=job_dlc) @register_breadcrumb(bp, '.entity', '', dynamic_list_constructor=job_dlc)
def job(job_id): def job(job_id):
job = Job.query.get_or_404(job_id) job = Job.query.get_or_404(job_id)
if not (job.user == current_user or current_user.is_administrator()): if not (job.user == current_user or current_user.is_administrator):
abort(403) abort(403)
return render_template( return render_template(
'jobs/job.html.j2', 'jobs/job.html.j2',
@ -34,7 +34,7 @@ def job(job_id):
@bp.route('/<hashid:job_id>/inputs/<hashid:job_input_id>/download') @bp.route('/<hashid:job_id>/inputs/<hashid:job_input_id>/download')
def download_job_input(job_id, job_input_id): def download_job_input(job_id, job_input_id):
job_input = JobInput.query.filter_by(job_id=job_id, id=job_input_id).first_or_404() job_input = JobInput.query.filter_by(job_id=job_id, id=job_input_id).first_or_404()
if not (job_input.job.user == current_user or current_user.is_administrator()): if not (job_input.job.user == current_user or current_user.is_administrator):
abort(403) abort(403)
return send_from_directory( return send_from_directory(
job_input.path.parent, job_input.path.parent,
@ -48,7 +48,7 @@ def download_job_input(job_id, job_input_id):
@bp.route('/<hashid:job_id>/results/<hashid:job_result_id>/download') @bp.route('/<hashid:job_id>/results/<hashid:job_result_id>/download')
def download_job_result(job_id, job_result_id): def download_job_result(job_id, job_result_id):
job_result = JobResult.query.filter_by(job_id=job_id, id=job_result_id).first_or_404() job_result = JobResult.query.filter_by(job_id=job_id, id=job_result_id).first_or_404()
if not (job_result.job.user == current_user or current_user.is_administrator()): if not (job_result.job.user == current_user or current_user.is_administrator):
abort(403) abort(403)
return send_from_directory( return send_from_directory(
job_result.path.parent, job_result.path.parent,

View File

@ -1,3 +1,7 @@
from enum import Enum
from flask_login import AnonymousUserMixin
from app import db, login, mail, socketio
from app.email import create_message
from .avatar import * from .avatar import *
from .corpus_file import * from .corpus_file import *
from .corpus_follower_association import * from .corpus_follower_association import *
@ -11,7 +15,142 @@ from .spacy_nlp_pipeline_model import *
from .tesseract_ocr_pipeline_model import * from .tesseract_ocr_pipeline_model import *
from .token import * from .token import *
from .user import * from .user import *
from app import login
@db.event.listens_for(Corpus, 'after_delete')
@db.event.listens_for(CorpusFile, 'after_delete')
@db.event.listens_for(Job, 'after_delete')
@db.event.listens_for(JobInput, 'after_delete')
@db.event.listens_for(JobResult, 'after_delete')
@db.event.listens_for(SpaCyNLPPipelineModel, 'after_delete')
@db.event.listens_for(TesseractOCRPipelineModel, 'after_delete')
def resource_after_delete(mapper, connection, resource):
print('[START] resource_after_delete')
jsonpatch = [
{
'op': 'remove',
'path': resource.jsonpatch_path
}
]
room = f'/users/{resource.user_hashid}'
print('[EMIT] PATCH', jsonpatch)
socketio.emit('PATCH', jsonpatch, room=room)
print('[END] resource_after_delete')
@db.event.listens_for(CorpusFollowerAssociation, 'after_delete')
def cfa_after_delete_handler(mapper, connection, cfa):
jsonpatch_path = f'/users/{cfa.corpus.user.hashid}/corpora/{cfa.corpus.hashid}/corpus_follower_associations/{cfa.hashid}'
jsonpatch = [
{
'op': 'remove',
'path': jsonpatch_path
}
]
room = f'/users/{cfa.corpus.user.hashid}'
socketio.emit('PATCH', jsonpatch, room=room)
@db.event.listens_for(Corpus, 'after_insert')
@db.event.listens_for(CorpusFile, 'after_insert')
@db.event.listens_for(Job, 'after_insert')
@db.event.listens_for(JobInput, 'after_insert')
@db.event.listens_for(JobResult, 'after_insert')
@db.event.listens_for(SpaCyNLPPipelineModel, 'after_insert')
@db.event.listens_for(TesseractOCRPipelineModel, 'after_insert')
def resource_after_insert_handler(mapper, connection, resource):
jsonpatch_value = resource.to_json_serializeable()
for attr in mapper.relationships:
jsonpatch_value[attr.key] = {}
jsonpatch = [
{
'op': 'add',
'path': resource.jsonpatch_path,
'value': jsonpatch_value
}
]
room = f'/users/{resource.user_hashid}'
socketio.emit('PATCH', jsonpatch, room=room)
@db.event.listens_for(CorpusFollowerAssociation, 'after_insert')
def cfa_after_insert_handler(mapper, connection, cfa):
jsonpatch_value = cfa.to_json_serializeable()
jsonpatch_path = f'/users/{cfa.corpus.user.hashid}/corpora/{cfa.corpus.hashid}/corpus_follower_associations/{cfa.hashid}'
jsonpatch = [
{
'op': 'add',
'path': jsonpatch_path,
'value': jsonpatch_value
}
]
room = f'/users/{cfa.corpus.user.hashid}'
socketio.emit('PATCH', jsonpatch, room=room)
@db.event.listens_for(Corpus, 'after_update')
@db.event.listens_for(CorpusFile, 'after_update')
@db.event.listens_for(Job, 'after_update')
@db.event.listens_for(JobInput, 'after_update')
@db.event.listens_for(JobResult, 'after_update')
@db.event.listens_for(SpaCyNLPPipelineModel, 'after_update')
@db.event.listens_for(TesseractOCRPipelineModel, 'after_update')
def resource_after_update_handler(mapper, connection, resource):
jsonpatch = []
for attr in db.inspect(resource).attrs:
if attr.key in mapper.relationships:
continue
if not attr.load_history().has_changes():
continue
jsonpatch_path = f'{resource.jsonpatch_path}/{attr.key}'
if isinstance(attr.value, datetime):
jsonpatch_value = f'{attr.value.isoformat()}Z'
elif isinstance(attr.value, Enum):
jsonpatch_value = attr.value.name
else:
jsonpatch_value = attr.value
jsonpatch.append(
{
'op': 'replace',
'path': jsonpatch_path,
'value': jsonpatch_value
}
)
if jsonpatch:
room = f'/users/{resource.user_hashid}'
socketio.emit('PATCH', jsonpatch, room=room)
@db.event.listens_for(Job, 'after_update')
def job_after_update_handler(mapper, connection, job):
for attr in db.inspect(job).attrs:
if attr.key != 'status':
continue
if not attr.load_history().has_changes():
return
if job.user.setting_job_status_mail_notification_level == UserSettingJobStatusMailNotificationLevel.NONE:
return
if job.user.setting_job_status_mail_notification_level == UserSettingJobStatusMailNotificationLevel.END:
if job.status not in [JobStatus.COMPLETED, JobStatus.FAILED]:
return
msg = create_message(
job.user.email,
f'Status update for your Job "{job.title}"',
'tasks/email/notification',
job=job
)
mail.send(msg)
class AnonymousUser(AnonymousUserMixin):
def can(self, permissions):
return False
@property
def is_administrator(self):
return False
login.anonymous_user = AnonymousUser
@login.user_loader @login.user_loader

View File

@ -132,6 +132,10 @@ class User(HashidMixin, UserMixin, db.Model):
def __repr__(self): def __repr__(self):
return f'<User {self.username}>' return f'<User {self.username}>'
@property
def is_administrator(self):
return self.can(Permission.ADMINISTRATE)
@property @property
def jsonpatch_path(self): def jsonpatch_path(self):
return f'/users/{self.hashid}' return f'/users/{self.hashid}'
@ -294,9 +298,6 @@ class User(HashidMixin, UserMixin, db.Model):
algorithm='HS256' algorithm='HS256'
) )
def is_administrator(self):
return self.can(Permission.ADMINISTRATE)
def ping(self): def ping(self):
self.last_seen = datetime.utcnow() self.last_seen = datetime.utcnow()

22
app/static/external/JSON-Patch/LICENSE vendored Normal file
View File

@ -0,0 +1,22 @@
(The MIT License)
Copyright (c) 2013, 2014, 2020 Joachim Wester
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1 @@
3.1.1

View File

@ -0,0 +1,928 @@
/*! fast-json-patch, version: 3.1.1 */
var jsonpatch =
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 2);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports) {
/*!
* https://github.com/Starcounter-Jack/JSON-Patch
* (c) 2017-2022 Joachim Wester
* MIT licensed
*/
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var _hasOwnProperty = Object.prototype.hasOwnProperty;
function hasOwnProperty(obj, key) {
return _hasOwnProperty.call(obj, key);
}
exports.hasOwnProperty = hasOwnProperty;
function _objectKeys(obj) {
if (Array.isArray(obj)) {
var keys_1 = new Array(obj.length);
for (var k = 0; k < keys_1.length; k++) {
keys_1[k] = "" + k;
}
return keys_1;
}
if (Object.keys) {
return Object.keys(obj);
}
var keys = [];
for (var i in obj) {
if (hasOwnProperty(obj, i)) {
keys.push(i);
}
}
return keys;
}
exports._objectKeys = _objectKeys;
;
/**
* Deeply clone the object.
* https://jsperf.com/deep-copy-vs-json-stringify-json-parse/25 (recursiveDeepCopy)
* @param {any} obj value to clone
* @return {any} cloned obj
*/
function _deepClone(obj) {
switch (typeof obj) {
case "object":
return JSON.parse(JSON.stringify(obj)); //Faster than ES5 clone - http://jsperf.com/deep-cloning-of-objects/5
case "undefined":
return null; //this is how JSON.stringify behaves for array items
default:
return obj; //no need to clone primitives
}
}
exports._deepClone = _deepClone;
//3x faster than cached /^\d+$/.test(str)
function isInteger(str) {
var i = 0;
var len = str.length;
var charCode;
while (i < len) {
charCode = str.charCodeAt(i);
if (charCode >= 48 && charCode <= 57) {
i++;
continue;
}
return false;
}
return true;
}
exports.isInteger = isInteger;
/**
* Escapes a json pointer path
* @param path The raw pointer
* @return the Escaped path
*/
function escapePathComponent(path) {
if (path.indexOf('/') === -1 && path.indexOf('~') === -1)
return path;
return path.replace(/~/g, '~0').replace(/\//g, '~1');
}
exports.escapePathComponent = escapePathComponent;
/**
* Unescapes a json pointer path
* @param path The escaped pointer
* @return The unescaped path
*/
function unescapePathComponent(path) {
return path.replace(/~1/g, '/').replace(/~0/g, '~');
}
exports.unescapePathComponent = unescapePathComponent;
function _getPathRecursive(root, obj) {
var found;
for (var key in root) {
if (hasOwnProperty(root, key)) {
if (root[key] === obj) {
return escapePathComponent(key) + '/';
}
else if (typeof root[key] === 'object') {
found = _getPathRecursive(root[key], obj);
if (found != '') {
return escapePathComponent(key) + '/' + found;
}
}
}
}
return '';
}
exports._getPathRecursive = _getPathRecursive;
function getPath(root, obj) {
if (root === obj) {
return '/';
}
var path = _getPathRecursive(root, obj);
if (path === '') {
throw new Error("Object not found in root");
}
return "/" + path;
}
exports.getPath = getPath;
/**
* Recursively checks whether an object has any undefined values inside.
*/
function hasUndefined(obj) {
if (obj === undefined) {
return true;
}
if (obj) {
if (Array.isArray(obj)) {
for (var i_1 = 0, len = obj.length; i_1 < len; i_1++) {
if (hasUndefined(obj[i_1])) {
return true;
}
}
}
else if (typeof obj === "object") {
var objKeys = _objectKeys(obj);
var objKeysLength = objKeys.length;
for (var i = 0; i < objKeysLength; i++) {
if (hasUndefined(obj[objKeys[i]])) {
return true;
}
}
}
}
return false;
}
exports.hasUndefined = hasUndefined;
function patchErrorMessageFormatter(message, args) {
var messageParts = [message];
for (var key in args) {
var value = typeof args[key] === 'object' ? JSON.stringify(args[key], null, 2) : args[key]; // pretty print
if (typeof value !== 'undefined') {
messageParts.push(key + ": " + value);
}
}
return messageParts.join('\n');
}
var PatchError = /** @class */ (function (_super) {
__extends(PatchError, _super);
function PatchError(message, name, index, operation, tree) {
var _newTarget = this.constructor;
var _this = _super.call(this, patchErrorMessageFormatter(message, { name: name, index: index, operation: operation, tree: tree })) || this;
_this.name = name;
_this.index = index;
_this.operation = operation;
_this.tree = tree;
Object.setPrototypeOf(_this, _newTarget.prototype); // restore prototype chain, see https://stackoverflow.com/a/48342359
_this.message = patchErrorMessageFormatter(message, { name: name, index: index, operation: operation, tree: tree });
return _this;
}
return PatchError;
}(Error));
exports.PatchError = PatchError;
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
Object.defineProperty(exports, "__esModule", { value: true });
var helpers_js_1 = __webpack_require__(0);
exports.JsonPatchError = helpers_js_1.PatchError;
exports.deepClone = helpers_js_1._deepClone;
/* We use a Javascript hash to store each
function. Each hash entry (property) uses
the operation identifiers specified in rfc6902.
In this way, we can map each patch operation
to its dedicated function in efficient way.
*/
/* The operations applicable to an object */
var objOps = {
add: function (obj, key, document) {
obj[key] = this.value;
return { newDocument: document };
},
remove: function (obj, key, document) {
var removed = obj[key];
delete obj[key];
return { newDocument: document, removed: removed };
},
replace: function (obj, key, document) {
var removed = obj[key];
obj[key] = this.value;
return { newDocument: document, removed: removed };
},
move: function (obj, key, document) {
/* in case move target overwrites an existing value,
return the removed value, this can be taxing performance-wise,
and is potentially unneeded */
var removed = getValueByPointer(document, this.path);
if (removed) {
removed = helpers_js_1._deepClone(removed);
}
var originalValue = applyOperation(document, { op: "remove", path: this.from }).removed;
applyOperation(document, { op: "add", path: this.path, value: originalValue });
return { newDocument: document, removed: removed };
},
copy: function (obj, key, document) {
var valueToCopy = getValueByPointer(document, this.from);
// enforce copy by value so further operations don't affect source (see issue #177)
applyOperation(document, { op: "add", path: this.path, value: helpers_js_1._deepClone(valueToCopy) });
return { newDocument: document };
},
test: function (obj, key, document) {
return { newDocument: document, test: _areEquals(obj[key], this.value) };
},
_get: function (obj, key, document) {
this.value = obj[key];
return { newDocument: document };
}
};
/* The operations applicable to an array. Many are the same as for the object */
var arrOps = {
add: function (arr, i, document) {
if (helpers_js_1.isInteger(i)) {
arr.splice(i, 0, this.value);
}
else { // array props
arr[i] = this.value;
}
// this may be needed when using '-' in an array
return { newDocument: document, index: i };
},
remove: function (arr, i, document) {
var removedList = arr.splice(i, 1);
return { newDocument: document, removed: removedList[0] };
},
replace: function (arr, i, document) {
var removed = arr[i];
arr[i] = this.value;
return { newDocument: document, removed: removed };
},
move: objOps.move,
copy: objOps.copy,
test: objOps.test,
_get: objOps._get
};
/**
* Retrieves a value from a JSON document by a JSON pointer.
* Returns the value.
*
* @param document The document to get the value from
* @param pointer an escaped JSON pointer
* @return The retrieved value
*/
function getValueByPointer(document, pointer) {
if (pointer == '') {
return document;
}
var getOriginalDestination = { op: "_get", path: pointer };
applyOperation(document, getOriginalDestination);
return getOriginalDestination.value;
}
exports.getValueByPointer = getValueByPointer;
/**
* Apply a single JSON Patch Operation on a JSON document.
* Returns the {newDocument, result} of the operation.
* It modifies the `document` and `operation` objects - it gets the values by reference.
* If you would like to avoid touching your values, clone them:
* `jsonpatch.applyOperation(document, jsonpatch._deepClone(operation))`.
*
* @param document The document to patch
* @param operation The operation to apply
* @param validateOperation `false` is without validation, `true` to use default jsonpatch's validation, or you can pass a `validateOperation` callback to be used for validation.
* @param mutateDocument Whether to mutate the original document or clone it before applying
* @param banPrototypeModifications Whether to ban modifications to `__proto__`, defaults to `true`.
* @return `{newDocument, result}` after the operation
*/
function applyOperation(document, operation, validateOperation, mutateDocument, banPrototypeModifications, index) {
if (validateOperation === void 0) { validateOperation = false; }
if (mutateDocument === void 0) { mutateDocument = true; }
if (banPrototypeModifications === void 0) { banPrototypeModifications = true; }
if (index === void 0) { index = 0; }
if (validateOperation) {
if (typeof validateOperation == 'function') {
validateOperation(operation, 0, document, operation.path);
}
else {
validator(operation, 0);
}
}
/* ROOT OPERATIONS */
if (operation.path === "") {
var returnValue = { newDocument: document };
if (operation.op === 'add') {
returnValue.newDocument = operation.value;
return returnValue;
}
else if (operation.op === 'replace') {
returnValue.newDocument = operation.value;
returnValue.removed = document; //document we removed
return returnValue;
}
else if (operation.op === 'move' || operation.op === 'copy') { // it's a move or copy to root
returnValue.newDocument = getValueByPointer(document, operation.from); // get the value by json-pointer in `from` field
if (operation.op === 'move') { // report removed item
returnValue.removed = document;
}
return returnValue;
}
else if (operation.op === 'test') {
returnValue.test = _areEquals(document, operation.value);
if (returnValue.test === false) {
throw new exports.JsonPatchError("Test operation failed", 'TEST_OPERATION_FAILED', index, operation, document);
}
returnValue.newDocument = document;
return returnValue;
}
else if (operation.op === 'remove') { // a remove on root
returnValue.removed = document;
returnValue.newDocument = null;
return returnValue;
}
else if (operation.op === '_get') {
operation.value = document;
return returnValue;
}
else { /* bad operation */
if (validateOperation) {
throw new exports.JsonPatchError('Operation `op` property is not one of operations defined in RFC-6902', 'OPERATION_OP_INVALID', index, operation, document);
}
else {
return returnValue;
}
}
} /* END ROOT OPERATIONS */
else {
if (!mutateDocument) {
document = helpers_js_1._deepClone(document);
}
var path = operation.path || "";
var keys = path.split('/');
var obj = document;
var t = 1; //skip empty element - http://jsperf.com/to-shift-or-not-to-shift
var len = keys.length;
var existingPathFragment = undefined;
var key = void 0;
var validateFunction = void 0;
if (typeof validateOperation == 'function') {
validateFunction = validateOperation;
}
else {
validateFunction = validator;
}
while (true) {
key = keys[t];
if (key && key.indexOf('~') != -1) {
key = helpers_js_1.unescapePathComponent(key);
}
if (banPrototypeModifications &&
(key == '__proto__' ||
(key == 'prototype' && t > 0 && keys[t - 1] == 'constructor'))) {
throw new TypeError('JSON-Patch: modifying `__proto__` or `constructor/prototype` prop is banned for security reasons, if this was on purpose, please set `banPrototypeModifications` flag false and pass it to this function. More info in fast-json-patch README');
}
if (validateOperation) {
if (existingPathFragment === undefined) {
if (obj[key] === undefined) {
existingPathFragment = keys.slice(0, t).join('/');
}
else if (t == len - 1) {
existingPathFragment = operation.path;
}
if (existingPathFragment !== undefined) {
validateFunction(operation, 0, document, existingPathFragment);
}
}
}
t++;
if (Array.isArray(obj)) {
if (key === '-') {
key = obj.length;
}
else {
if (validateOperation && !helpers_js_1.isInteger(key)) {
throw new exports.JsonPatchError("Expected an unsigned base-10 integer value, making the new referenced value the array element with the zero-based index", "OPERATION_PATH_ILLEGAL_ARRAY_INDEX", index, operation, document);
} // only parse key when it's an integer for `arr.prop` to work
else if (helpers_js_1.isInteger(key)) {
key = ~~key;
}
}
if (t >= len) {
if (validateOperation && operation.op === "add" && key > obj.length) {
throw new exports.JsonPatchError("The specified index MUST NOT be greater than the number of elements in the array", "OPERATION_VALUE_OUT_OF_BOUNDS", index, operation, document);
}
var returnValue = arrOps[operation.op].call(operation, obj, key, document); // Apply patch
if (returnValue.test === false) {
throw new exports.JsonPatchError("Test operation failed", 'TEST_OPERATION_FAILED', index, operation, document);
}
return returnValue;
}
}
else {
if (t >= len) {
var returnValue = objOps[operation.op].call(operation, obj, key, document); // Apply patch
if (returnValue.test === false) {
throw new exports.JsonPatchError("Test operation failed", 'TEST_OPERATION_FAILED', index, operation, document);
}
return returnValue;
}
}
obj = obj[key];
// If we have more keys in the path, but the next value isn't a non-null object,
// throw an OPERATION_PATH_UNRESOLVABLE error instead of iterating again.
if (validateOperation && t < len && (!obj || typeof obj !== "object")) {
throw new exports.JsonPatchError('Cannot perform operation at the desired path', 'OPERATION_PATH_UNRESOLVABLE', index, operation, document);
}
}
}
}
exports.applyOperation = applyOperation;
/**
* Apply a full JSON Patch array on a JSON document.
* Returns the {newDocument, result} of the patch.
* It modifies the `document` object and `patch` - it gets the values by reference.
* If you would like to avoid touching your values, clone them:
* `jsonpatch.applyPatch(document, jsonpatch._deepClone(patch))`.
*
* @param document The document to patch
* @param patch The patch to apply
* @param validateOperation `false` is without validation, `true` to use default jsonpatch's validation, or you can pass a `validateOperation` callback to be used for validation.
* @param mutateDocument Whether to mutate the original document or clone it before applying
* @param banPrototypeModifications Whether to ban modifications to `__proto__`, defaults to `true`.
* @return An array of `{newDocument, result}` after the patch
*/
function applyPatch(document, patch, validateOperation, mutateDocument, banPrototypeModifications) {
if (mutateDocument === void 0) { mutateDocument = true; }
if (banPrototypeModifications === void 0) { banPrototypeModifications = true; }
if (validateOperation) {
if (!Array.isArray(patch)) {
throw new exports.JsonPatchError('Patch sequence must be an array', 'SEQUENCE_NOT_AN_ARRAY');
}
}
if (!mutateDocument) {
document = helpers_js_1._deepClone(document);
}
var results = new Array(patch.length);
for (var i = 0, length_1 = patch.length; i < length_1; i++) {
// we don't need to pass mutateDocument argument because if it was true, we already deep cloned the object, we'll just pass `true`
results[i] = applyOperation(document, patch[i], validateOperation, true, banPrototypeModifications, i);
document = results[i].newDocument; // in case root was replaced
}
results.newDocument = document;
return results;
}
exports.applyPatch = applyPatch;
/**
* Apply a single JSON Patch Operation on a JSON document.
* Returns the updated document.
* Suitable as a reducer.
*
* @param document The document to patch
* @param operation The operation to apply
* @return The updated document
*/
function applyReducer(document, operation, index) {
var operationResult = applyOperation(document, operation);
if (operationResult.test === false) { // failed test
throw new exports.JsonPatchError("Test operation failed", 'TEST_OPERATION_FAILED', index, operation, document);
}
return operationResult.newDocument;
}
exports.applyReducer = applyReducer;
/**
* Validates a single operation. Called from `jsonpatch.validate`. Throws `JsonPatchError` in case of an error.
* @param {object} operation - operation object (patch)
* @param {number} index - index of operation in the sequence
* @param {object} [document] - object where the operation is supposed to be applied
* @param {string} [existingPathFragment] - comes along with `document`
*/
function validator(operation, index, document, existingPathFragment) {
if (typeof operation !== 'object' || operation === null || Array.isArray(operation)) {
throw new exports.JsonPatchError('Operation is not an object', 'OPERATION_NOT_AN_OBJECT', index, operation, document);
}
else if (!objOps[operation.op]) {
throw new exports.JsonPatchError('Operation `op` property is not one of operations defined in RFC-6902', 'OPERATION_OP_INVALID', index, operation, document);
}
else if (typeof operation.path !== 'string') {
throw new exports.JsonPatchError('Operation `path` property is not a string', 'OPERATION_PATH_INVALID', index, operation, document);
}
else if (operation.path.indexOf('/') !== 0 && operation.path.length > 0) {
// paths that aren't empty string should start with "/"
throw new exports.JsonPatchError('Operation `path` property must start with "/"', 'OPERATION_PATH_INVALID', index, operation, document);
}
else if ((operation.op === 'move' || operation.op === 'copy') && typeof operation.from !== 'string') {
throw new exports.JsonPatchError('Operation `from` property is not present (applicable in `move` and `copy` operations)', 'OPERATION_FROM_REQUIRED', index, operation, document);
}
else if ((operation.op === 'add' || operation.op === 'replace' || operation.op === 'test') && operation.value === undefined) {
throw new exports.JsonPatchError('Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)', 'OPERATION_VALUE_REQUIRED', index, operation, document);
}
else if ((operation.op === 'add' || operation.op === 'replace' || operation.op === 'test') && helpers_js_1.hasUndefined(operation.value)) {
throw new exports.JsonPatchError('Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)', 'OPERATION_VALUE_CANNOT_CONTAIN_UNDEFINED', index, operation, document);
}
else if (document) {
if (operation.op == "add") {
var pathLen = operation.path.split("/").length;
var existingPathLen = existingPathFragment.split("/").length;
if (pathLen !== existingPathLen + 1 && pathLen !== existingPathLen) {
throw new exports.JsonPatchError('Cannot perform an `add` operation at the desired path', 'OPERATION_PATH_CANNOT_ADD', index, operation, document);
}
}
else if (operation.op === 'replace' || operation.op === 'remove' || operation.op === '_get') {
if (operation.path !== existingPathFragment) {
throw new exports.JsonPatchError('Cannot perform the operation at a path that does not exist', 'OPERATION_PATH_UNRESOLVABLE', index, operation, document);
}
}
else if (operation.op === 'move' || operation.op === 'copy') {
var existingValue = { op: "_get", path: operation.from, value: undefined };
var error = validate([existingValue], document);
if (error && error.name === 'OPERATION_PATH_UNRESOLVABLE') {
throw new exports.JsonPatchError('Cannot perform the operation from a path that does not exist', 'OPERATION_FROM_UNRESOLVABLE', index, operation, document);
}
}
}
}
exports.validator = validator;
/**
* Validates a sequence of operations. If `document` parameter is provided, the sequence is additionally validated against the object document.
* If error is encountered, returns a JsonPatchError object
* @param sequence
* @param document
* @returns {JsonPatchError|undefined}
*/
function validate(sequence, document, externalValidator) {
try {
if (!Array.isArray(sequence)) {
throw new exports.JsonPatchError('Patch sequence must be an array', 'SEQUENCE_NOT_AN_ARRAY');
}
if (document) {
//clone document and sequence so that we can safely try applying operations
applyPatch(helpers_js_1._deepClone(document), helpers_js_1._deepClone(sequence), externalValidator || true);
}
else {
externalValidator = externalValidator || validator;
for (var i = 0; i < sequence.length; i++) {
externalValidator(sequence[i], i, document, undefined);
}
}
}
catch (e) {
if (e instanceof exports.JsonPatchError) {
return e;
}
else {
throw e;
}
}
}
exports.validate = validate;
// based on https://github.com/epoberezkin/fast-deep-equal
// MIT License
// Copyright (c) 2017 Evgeny Poberezkin
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
function _areEquals(a, b) {
if (a === b)
return true;
if (a && b && typeof a == 'object' && typeof b == 'object') {
var arrA = Array.isArray(a), arrB = Array.isArray(b), i, length, key;
if (arrA && arrB) {
length = a.length;
if (length != b.length)
return false;
for (i = length; i-- !== 0;)
if (!_areEquals(a[i], b[i]))
return false;
return true;
}
if (arrA != arrB)
return false;
var keys = Object.keys(a);
length = keys.length;
if (length !== Object.keys(b).length)
return false;
for (i = length; i-- !== 0;)
if (!b.hasOwnProperty(keys[i]))
return false;
for (i = length; i-- !== 0;) {
key = keys[i];
if (!_areEquals(a[key], b[key]))
return false;
}
return true;
}
return a !== a && b !== b;
}
exports._areEquals = _areEquals;
;
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
var core = __webpack_require__(1);
Object.assign(exports, core);
var duplex = __webpack_require__(3);
Object.assign(exports, duplex);
var helpers = __webpack_require__(0);
exports.JsonPatchError = helpers.PatchError;
exports.deepClone = helpers._deepClone;
exports.escapePathComponent = helpers.escapePathComponent;
exports.unescapePathComponent = helpers.unescapePathComponent;
/***/ }),
/* 3 */
/***/ (function(module, exports, __webpack_require__) {
Object.defineProperty(exports, "__esModule", { value: true });
/*!
* https://github.com/Starcounter-Jack/JSON-Patch
* (c) 2017-2021 Joachim Wester
* MIT license
*/
var helpers_js_1 = __webpack_require__(0);
var core_js_1 = __webpack_require__(1);
var beforeDict = new WeakMap();
var Mirror = /** @class */ (function () {
function Mirror(obj) {
this.observers = new Map();
this.obj = obj;
}
return Mirror;
}());
var ObserverInfo = /** @class */ (function () {
function ObserverInfo(callback, observer) {
this.callback = callback;
this.observer = observer;
}
return ObserverInfo;
}());
function getMirror(obj) {
return beforeDict.get(obj);
}
function getObserverFromMirror(mirror, callback) {
return mirror.observers.get(callback);
}
function removeObserverFromMirror(mirror, observer) {
mirror.observers.delete(observer.callback);
}
/**
* Detach an observer from an object
*/
function unobserve(root, observer) {
observer.unobserve();
}
exports.unobserve = unobserve;
/**
* Observes changes made to an object, which can then be retrieved using generate
*/
function observe(obj, callback) {
var patches = [];
var observer;
var mirror = getMirror(obj);
if (!mirror) {
mirror = new Mirror(obj);
beforeDict.set(obj, mirror);
}
else {
var observerInfo = getObserverFromMirror(mirror, callback);
observer = observerInfo && observerInfo.observer;
}
if (observer) {
return observer;
}
observer = {};
mirror.value = helpers_js_1._deepClone(obj);
if (callback) {
observer.callback = callback;
observer.next = null;
var dirtyCheck = function () {
generate(observer);
};
var fastCheck = function () {
clearTimeout(observer.next);
observer.next = setTimeout(dirtyCheck);
};
if (typeof window !== 'undefined') { //not Node
window.addEventListener('mouseup', fastCheck);
window.addEventListener('keyup', fastCheck);
window.addEventListener('mousedown', fastCheck);
window.addEventListener('keydown', fastCheck);
window.addEventListener('change', fastCheck);
}
}
observer.patches = patches;
observer.object = obj;
observer.unobserve = function () {
generate(observer);
clearTimeout(observer.next);
removeObserverFromMirror(mirror, observer);
if (typeof window !== 'undefined') {
window.removeEventListener('mouseup', fastCheck);
window.removeEventListener('keyup', fastCheck);
window.removeEventListener('mousedown', fastCheck);
window.removeEventListener('keydown', fastCheck);
window.removeEventListener('change', fastCheck);
}
};
mirror.observers.set(callback, new ObserverInfo(callback, observer));
return observer;
}
exports.observe = observe;
/**
* Generate an array of patches from an observer
*/
function generate(observer, invertible) {
if (invertible === void 0) { invertible = false; }
var mirror = beforeDict.get(observer.object);
_generate(mirror.value, observer.object, observer.patches, "", invertible);
if (observer.patches.length) {
core_js_1.applyPatch(mirror.value, observer.patches);
}
var temp = observer.patches;
if (temp.length > 0) {
observer.patches = [];
if (observer.callback) {
observer.callback(temp);
}
}
return temp;
}
exports.generate = generate;
// Dirty check if obj is different from mirror, generate patches and update mirror
function _generate(mirror, obj, patches, path, invertible) {
if (obj === mirror) {
return;
}
if (typeof obj.toJSON === "function") {
obj = obj.toJSON();
}
var newKeys = helpers_js_1._objectKeys(obj);
var oldKeys = helpers_js_1._objectKeys(mirror);
var changed = false;
var deleted = false;
//if ever "move" operation is implemented here, make sure this test runs OK: "should not generate the same patch twice (move)"
for (var t = oldKeys.length - 1; t >= 0; t--) {
var key = oldKeys[t];
var oldVal = mirror[key];
if (helpers_js_1.hasOwnProperty(obj, key) && !(obj[key] === undefined && oldVal !== undefined && Array.isArray(obj) === false)) {
var newVal = obj[key];
if (typeof oldVal == "object" && oldVal != null && typeof newVal == "object" && newVal != null && Array.isArray(oldVal) === Array.isArray(newVal)) {
_generate(oldVal, newVal, patches, path + "/" + helpers_js_1.escapePathComponent(key), invertible);
}
else {
if (oldVal !== newVal) {
changed = true;
if (invertible) {
patches.push({ op: "test", path: path + "/" + helpers_js_1.escapePathComponent(key), value: helpers_js_1._deepClone(oldVal) });
}
patches.push({ op: "replace", path: path + "/" + helpers_js_1.escapePathComponent(key), value: helpers_js_1._deepClone(newVal) });
}
}
}
else if (Array.isArray(mirror) === Array.isArray(obj)) {
if (invertible) {
patches.push({ op: "test", path: path + "/" + helpers_js_1.escapePathComponent(key), value: helpers_js_1._deepClone(oldVal) });
}
patches.push({ op: "remove", path: path + "/" + helpers_js_1.escapePathComponent(key) });
deleted = true; // property has been deleted
}
else {
if (invertible) {
patches.push({ op: "test", path: path, value: mirror });
}
patches.push({ op: "replace", path: path, value: obj });
changed = true;
}
}
if (!deleted && newKeys.length == oldKeys.length) {
return;
}
for (var t = 0; t < newKeys.length; t++) {
var key = newKeys[t];
if (!helpers_js_1.hasOwnProperty(mirror, key) && obj[key] !== undefined) {
patches.push({ op: "add", path: path + "/" + helpers_js_1.escapePathComponent(key), value: helpers_js_1._deepClone(obj[key]) });
}
}
}
/**
* Create an array of patches from the differences in two objects
*/
function compare(tree1, tree2, invertible) {
if (invertible === void 0) { invertible = false; }
var patches = [];
_generate(tree1, tree2, patches, '', invertible);
return patches;
}
exports.compare = compare;
/***/ })
/******/ ]);

File diff suppressed because one or more lines are too long

21
app/static/external/list.js/LICENSE vendored Normal file
View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2011-2018 Jonny Strömberg, jonnystromberg.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

1
app/static/external/list.js/VERSION vendored Normal file
View File

@ -0,0 +1 @@
2.3.1

2020
app/static/external/list.js/js/list.js vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"version":3,"file":"list.min.js","sources":["webpack://List/list.min.js"],"mappings":"AAAA","sourceRoot":""}

View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1 @@
https://github.com/google/material-design-icons/tree/f7bd4f25f3764883717c09a1fd867f560c9a9581

View File

@ -0,0 +1,37 @@
@font-face {
font-family: "Material Icons";
font-style: normal;
font-weight: 400;
/* For IE6-8 */
/* src: url("../font/MaterialIcons-Regular.eot"); */
src: local("Material Icons"),
local("MaterialIcons-Regular"),
/* url("../font/MaterialIcons-Regular.woff2") format('woff2'), */
/* url("../font/MaterialIcons-Regular.woff") format('woff'), */
url("../font/MaterialIcons-Regular.ttf") format("truetype");
}
.material-icons {
font-family: 'Material Icons';
font-weight: normal;
font-style: normal;
font-size: 24px; /* Preferred icon size */
display: inline-block;
line-height: 1;
text-transform: none;
letter-spacing: normal;
word-wrap: normal;
white-space: nowrap;
direction: ltr;
/* Support for all WebKit browsers. */
-webkit-font-smoothing: antialiased;
/* Support for Safari and Chrome. */
text-rendering: optimizeLegibility;
/* Support for Firefox. */
-moz-osx-font-smoothing: grayscale;
/* Support for IE. */
font-feature-settings: 'liga';
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

21
app/static/external/materialize/LICENSE vendored Normal file
View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014-2018 Materialize
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1 @@
1.0.0

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

21
app/static/external/pako/LICENSE vendored Normal file
View File

@ -0,0 +1,21 @@
(The MIT License)
Copyright (C) 2014-2017 by Vitaly Puzrin and Andrei Tuputcyn
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

1
app/static/external/pako/VERSION vendored Normal file
View File

@ -0,0 +1 @@
2.1.0

6688
app/static/external/pako/js/pako.es5.js vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

6877
app/static/external/pako/js/pako.esm.mjs vendored Normal file

File diff suppressed because it is too large Load Diff

6896
app/static/external/pako/js/pako.js vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

21
app/static/external/plotly.js/LICENSE vendored Normal file
View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2021 Plotly, Inc
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

1
app/static/external/plotly.js/VERSION vendored Normal file
View File

@ -0,0 +1 @@
2.31.0

View File

@ -0,0 +1,271 @@
# Using distributed files
All plotly.js bundles inject an object `Plotly` into the global scope.
Import plotly.js as:
```html
<script src="plotly.min.js"></script>
```
or the un-minified version as:
```html
<script src="plotly.js" charset="utf-8"></script>
```
### To include localization
Plotly.js defaults to US English (en-US) and includes British English (en) in the standard bundle.
Many other localizations are available - here is an example using Swiss-German (de-CH),
see the contents of this directory for the full list.
Note that the file names are all lowercase, even though the region is uppercase when you apply a locale.
*After* the plotly.js script tag, add:
```html
<script src="plotly-locale-de-ch.js"></script>
<script>Plotly.setPlotConfig({locale: 'de-CH'})</script>
```
The first line loads and registers the locale definition with plotly.js, the second sets it as the default for all Plotly plots.
You can also include multiple locale definitions and apply them to each plot separately as a `config` parameter:
```js
Plotly.newPlot(graphDiv, data, layout, {locale: 'de-CH'})
```
# Bundle information
The main plotly.js bundle includes all trace modules.
The main plotly.js bundles weight in at:
| plotly.js | plotly.min.js | plotly.min.js + gzip | plotly-with-meta.js |
|-----------|---------------|----------------------|---------------------|
| 8.2 MB | 3.5 MB | 1 MB | 8.5 MB |
#### CDN links
> https://cdn.plot.ly/plotly-2.31.0.js
> https://cdn.plot.ly/plotly-2.31.0.min.js
#### npm packages
> [plotly.js](https://www.npmjs.com/package/plotly.js)
> [plotly.js-dist](https://www.npmjs.com/package/plotly.js-dist)
> [plotly.js-dist-min](https://www.npmjs.com/package/plotly.js-dist-min)
#### Meta information
> If you would like to have access to the attribute meta information (including attribute descriptions as on the [schema reference page](https://plotly.com/javascript/reference/)), use dist file `dist/plotly-with-meta.js`
---
## Partial bundles
plotly.js also ships with several _partial_ bundles:
- [basic](#plotlyjs-basic)
- [cartesian](#plotlyjs-cartesian)
- [geo](#plotlyjs-geo)
- [gl3d](#plotlyjs-gl3d)
- [gl2d](#plotlyjs-gl2d)
- [mapbox](#plotlyjs-mapbox)
- [finance](#plotlyjs-finance)
- [strict](#plotlyjs-strict)
> Each plotly.js partial bundle has a corresponding npm package with no dependencies.
> The minified version of each partial bundle is also published to npm in a separate "dist-min" package.
> The strict bundle now includes all traces, but the regl-based traces are built differently to avoid function constructors. This results in about a 10% larger bundle size, which is why this method is not used by default. Over time we intend to use the strict bundle to work on other strict CSP issues such as inline CSS.
---
### plotly.js basic
The `basic` partial bundle contains trace modules `bar`, `pie` and `scatter`.
#### Stats
| Raw size | Minified size | Minified + gzip size |
|------|-----------------|------------------------|
| 2.6 MB | 987.8 kB | 330.7 kB |
#### CDN links
> https://cdn.plot.ly/plotly-basic-2.31.0.js
> https://cdn.plot.ly/plotly-basic-2.31.0.min.js
#### npm packages
> [plotly.js-basic-dist](https://www.npmjs.com/package/plotly.js-basic-dist)
> [plotly.js-basic-dist-min](https://www.npmjs.com/package/plotly.js-basic-dist-min)
---
### plotly.js cartesian
The `cartesian` partial bundle contains trace modules `bar`, `box`, `contour`, `heatmap`, `histogram`, `histogram2d`, `histogram2dcontour`, `image`, `pie`, `scatter`, `scatterternary` and `violin`.
#### Stats
| Raw size | Minified size | Minified + gzip size |
|------|-----------------|------------------------|
| 3.3 MB | 1.2 MB | 418.2 kB |
#### CDN links
> https://cdn.plot.ly/plotly-cartesian-2.31.0.js
> https://cdn.plot.ly/plotly-cartesian-2.31.0.min.js
#### npm packages
> [plotly.js-cartesian-dist](https://www.npmjs.com/package/plotly.js-cartesian-dist)
> [plotly.js-cartesian-dist-min](https://www.npmjs.com/package/plotly.js-cartesian-dist-min)
---
### plotly.js geo
The `geo` partial bundle contains trace modules `choropleth`, `scatter` and `scattergeo`.
#### Stats
| Raw size | Minified size | Minified + gzip size |
|------|-----------------|------------------------|
| 3.1 MB | 1.1 MB | 373.4 kB |
#### CDN links
> https://cdn.plot.ly/plotly-geo-2.31.0.js
> https://cdn.plot.ly/plotly-geo-2.31.0.min.js
#### npm packages
> [plotly.js-geo-dist](https://www.npmjs.com/package/plotly.js-geo-dist)
> [plotly.js-geo-dist-min](https://www.npmjs.com/package/plotly.js-geo-dist-min)
---
### plotly.js gl3d
The `gl3d` partial bundle contains trace modules `cone`, `isosurface`, `mesh3d`, `scatter`, `scatter3d`, `streamtube`, `surface` and `volume`.
#### Stats
| Raw size | Minified size | Minified + gzip size |
|------|-----------------|------------------------|
| 3.6 MB | 1.5 MB | 494.1 kB |
#### CDN links
> https://cdn.plot.ly/plotly-gl3d-2.31.0.js
> https://cdn.plot.ly/plotly-gl3d-2.31.0.min.js
#### npm packages
> [plotly.js-gl3d-dist](https://www.npmjs.com/package/plotly.js-gl3d-dist)
> [plotly.js-gl3d-dist-min](https://www.npmjs.com/package/plotly.js-gl3d-dist-min)
---
### plotly.js gl2d
The `gl2d` partial bundle contains trace modules `heatmapgl`, `parcoords`, `pointcloud`, `scatter`, `scattergl` and `splom`.
#### Stats
| Raw size | Minified size | Minified + gzip size |
|------|-----------------|------------------------|
| 4.4 MB | 1.9 MB | 601 kB |
#### CDN links
> https://cdn.plot.ly/plotly-gl2d-2.31.0.js
> https://cdn.plot.ly/plotly-gl2d-2.31.0.min.js
#### npm packages
> [plotly.js-gl2d-dist](https://www.npmjs.com/package/plotly.js-gl2d-dist)
> [plotly.js-gl2d-dist-min](https://www.npmjs.com/package/plotly.js-gl2d-dist-min)
---
### plotly.js mapbox
The `mapbox` partial bundle contains trace modules `choroplethmapbox`, `densitymapbox`, `scatter` and `scattermapbox`.
#### Stats
| Raw size | Minified size | Minified + gzip size |
|------|-----------------|------------------------|
| 4.4 MB | 1.8 MB | 532.3 kB |
#### CDN links
> https://cdn.plot.ly/plotly-mapbox-2.31.0.js
> https://cdn.plot.ly/plotly-mapbox-2.31.0.min.js
#### npm packages
> [plotly.js-mapbox-dist](https://www.npmjs.com/package/plotly.js-mapbox-dist)
> [plotly.js-mapbox-dist-min](https://www.npmjs.com/package/plotly.js-mapbox-dist-min)
---
### plotly.js finance
The `finance` partial bundle contains trace modules `bar`, `candlestick`, `funnel`, `funnelarea`, `histogram`, `indicator`, `ohlc`, `pie`, `scatter` and `waterfall`.
#### Stats
| Raw size | Minified size | Minified + gzip size |
|------|-----------------|------------------------|
| 2.8 MB | 1.1 MB | 359.9 kB |
#### CDN links
> https://cdn.plot.ly/plotly-finance-2.31.0.js
> https://cdn.plot.ly/plotly-finance-2.31.0.min.js
#### npm packages
> [plotly.js-finance-dist](https://www.npmjs.com/package/plotly.js-finance-dist)
> [plotly.js-finance-dist-min](https://www.npmjs.com/package/plotly.js-finance-dist-min)
---
### plotly.js strict
The `strict` partial bundle contains trace modules `bar`, `barpolar`, `box`, `candlestick`, `carpet`, `choropleth`, `choroplethmapbox`, `cone`, `contour`, `contourcarpet`, `densitymapbox`, `funnel`, `funnelarea`, `heatmap`, `heatmapgl`, `histogram`, `histogram2d`, `histogram2dcontour`, `icicle`, `image`, `indicator`, `isosurface`, `mesh3d`, `ohlc`, `parcats`, `parcoords`, `pie`, `pointcloud`, `sankey`, `scatter`, `scattergl`, `scatter3d`, `scattercarpet`, `scattergeo`, `scattermapbox`, `scatterpolar`, `scatterpolargl`, `scattersmith`, `scatterternary`, `splom`, `streamtube`, `sunburst`, `surface`, `table`, `treemap`, `violin`, `volume` and `waterfall`.
#### Stats
| Raw size | Minified size | Minified + gzip size |
|------|-----------------|------------------------|
| 8.7 MB | 3.8 MB | 1.1 MB |
#### CDN links
> https://cdn.plot.ly/plotly-strict-2.31.0.js
> https://cdn.plot.ly/plotly-strict-2.31.0.min.js
#### npm packages
> [plotly.js-strict-dist](https://www.npmjs.com/package/plotly.js-strict-dist)
> [plotly.js-strict-dist-min](https://www.npmjs.com/package/plotly.js-strict-dist-min)
---
_This file is auto-generated by `npm run stats`. Please do not edit this file directly._

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
var locale={moduleType:"locale",name:"af",dictionary:{},format:{days:["Sondag","Maandag","Dinsdag","Woensdag","Donderdag","Vrydag","Saterdag"],shortDays:["Son","Maan","Dins","Woens","Don","Vry","Sat"],months:["Januarie","Februarie","Maart","April","Mei","Junie","Julie","Augustus","September","Oktober","November","Desember"],shortMonths:["Jan","Feb","Mrt","Apr","Mei","Jun","Jul","Aug","Sep","Okt","Nov","Des"],date:"%d/%m/%Y"}};"undefined"==typeof Plotly?(window.PlotlyLocales=window.PlotlyLocales||[],window.PlotlyLocales.push(locale)):Plotly.register(locale);

View File

@ -0,0 +1 @@
var locale={moduleType:"locale",name:"am",dictionary:{},format:{days:["\u1230\u1295\u12f4\u12ed","\u1218\u1295\u12f4\u12ed","\u1275\u12e9\u1235\u12f4\u12ed","\u12cc\u1295\u1235\u12f4\u12ed","\u1270\u122d\u1230\u12f4\u12ed","\u134d\u122b\u12ed\u12f4\u12ed","\u1233\u1270\u122d\u12f4\u12ed"],shortDays:["\u1230\u1295\u12f4","\u1218\u1295\u12f4","\u1275\u12e9\u1235","\u12cc\u1295\u1235","\u1270\u122d\u1230","\u134d\u122b\u12ed","\u1233\u1270\u122d"],months:["\u1303\u1295\u12cb\u122a","\u1348\u1265\u122d\u12cb\u122a","\u121b\u122d\u127d","\u12a0\u1355\u122a\u120d","\u121c\u12ed","\u1301\u1295","\u1301\u120b\u12ed","\u12a6\u1308\u1235\u1275","\u1234\u1355\u1274\u121d\u1260\u122d","\u12a6\u12ad\u1276\u1260\u122d","\u1296\u126c\u121d\u1260\u122d","\u12f2\u1234\u121d\u1260\u122d"],shortMonths:["\u1303\u1295\u12cb","\u1348\u1265\u122d","\u121b\u122d\u127d","\u12a0\u1355\u122a","\u121c\u12ed","\u1301\u1295","\u1301\u120b\u12ed","\u12a6\u1308\u1235","\u1234\u1355\u1274","\u12a6\u12ad\u1276","\u1296\u126c\u121d","\u12f2\u1234\u121d"],date:"%d/%m/%Y"}};"undefined"==typeof Plotly?(window.PlotlyLocales=window.PlotlyLocales||[],window.PlotlyLocales.push(locale)):Plotly.register(locale);

View File

@ -0,0 +1 @@
var locale={moduleType:"locale",name:"ar-DZ",dictionary:{},format:{days:["\u0627\u0644\u0623\u062d\u062f","\u0627\u0644\u0627\u062b\u0646\u064a\u0646","\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621","\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621","\u0627\u0644\u062e\u0645\u064a\u0633","\u0627\u0644\u062c\u0645\u0639\u0629","\u0627\u0644\u0633\u0628\u062a"],shortDays:["\u0627\u0644\u0623\u062d\u062f","\u0627\u0644\u0627\u062b\u0646\u064a\u0646","\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621","\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621","\u0627\u0644\u062e\u0645\u064a\u0633","\u0627\u0644\u062c\u0645\u0639\u0629","\u0627\u0644\u0633\u0628\u062a"],months:["\u062c\u0627\u0646\u0641\u064a","\u0641\u064a\u0641\u0631\u064a","\u0645\u0627\u0631\u0633","\u0623\u0641\u0631\u064a\u0644","\u0645\u0627\u064a","\u062c\u0648\u0627\u0646","\u062c\u0648\u064a\u0644\u064a\u0629","\u0623\u0648\u062a","\u0633\u0628\u062a\u0645\u0628\u0631","\u0623\u0643\u062a\u0648\u0628\u0631","\u0646\u0648\u0641\u0645\u0628\u0631","\u062f\u064a\u0633\u0645\u0628\u0631"],shortMonths:["1","2","3","4","5","6","7","8","9","10","11","12"],date:"%d/%m/%Y"}};"undefined"==typeof Plotly?(window.PlotlyLocales=window.PlotlyLocales||[],window.PlotlyLocales.push(locale)):Plotly.register(locale);

View File

@ -0,0 +1 @@
var locale={moduleType:"locale",name:"ar-EG",dictionary:{},format:{days:["\u0627\u0644\u0623\u062d\u062f","\u0627\u0644\u0627\u062b\u0646\u064a\u0646","\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621","\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621","\u0627\u0644\u062e\u0645\u064a\u0633","\u0627\u0644\u062c\u0645\u0639\u0629","\u0627\u0644\u0633\u0628\u062a"],shortDays:["\u0623\u062d\u062f","\u0627\u062b\u0646\u064a\u0646","\u062b\u0644\u0627\u062b\u0627\u0621","\u0623\u0631\u0628\u0639\u0627\u0621","\u062e\u0645\u064a\u0633","\u062c\u0645\u0639\u0629","\u0633\u0628\u062a"],months:["\u064a\u0646\u0627\u064a\u0631","\u0641\u0628\u0631\u0627\u064a\u0631","\u0645\u0627\u0631\u0633","\u0625\u0628\u0631\u064a\u0644","\u0645\u0627\u064a\u0648","\u064a\u0648\u0646\u064a\u0629","\u064a\u0648\u0644\u064a\u0648","\u0623\u063a\u0633\u0637\u0633","\u0633\u0628\u062a\u0645\u0628\u0631","\u0623\u0643\u062a\u0648\u0628\u0631","\u0646\u0648\u0641\u0645\u0628\u0631","\u062f\u064a\u0633\u0645\u0628\u0631"],shortMonths:["1","2","3","4","5","6","7","8","9","10","11","12"],date:"%d/%m/%Y"}};"undefined"==typeof Plotly?(window.PlotlyLocales=window.PlotlyLocales||[],window.PlotlyLocales.push(locale)):Plotly.register(locale);

View File

@ -0,0 +1 @@
var locale={moduleType:"locale",name:"ar",dictionary:{},format:{days:["\u0627\u0644\u0623\u062d\u062f","\u0627\u0644\u0627\u062b\u0646\u064a\u0646","\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621","\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621","\u0627\u0644\u062e\u0645\u064a\u0633","\u0627\u0644\u062c\u0645\u0639\u0629","\u0627\u0644\u0633\u0628\u062a"],shortDays:["\u0627\u0644\u0623\u062d\u062f","\u0627\u0644\u0627\u062b\u0646\u064a\u0646","\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621","\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621","\u0627\u0644\u062e\u0645\u064a\u0633","\u0627\u0644\u062c\u0645\u0639\u0629","\u0627\u0644\u0633\u0628\u062a"],months:["\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a","\u0634\u0628\u0627\u0637","\u0622\u0630\u0627\u0631","\u0646\u064a\u0633\u0627\u0646","\u0622\u0630\u0627\u0631","\u062d\u0632\u064a\u0631\u0627\u0646","\u062a\u0645\u0648\u0632","\u0622\u0628","\u0623\u064a\u0644\u0648\u0644","\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644","\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a","\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644"],shortMonths:["1","2","3","4","5","6","7","8","9","10","11","12"],date:"%d/%m/%Y"}};"undefined"==typeof Plotly?(window.PlotlyLocales=window.PlotlyLocales||[],window.PlotlyLocales.push(locale)):Plotly.register(locale);

View File

@ -0,0 +1 @@
var locale={moduleType:"locale",name:"az",dictionary:{},format:{days:["Bazar","Bazar ert\u0259si","\xc7\u0259r\u015f\u0259nb\u0259 ax\u015fam\u0131","\xc7\u0259r\u015f\u0259nb\u0259","C\xfcm\u0259 ax\u015fam\u0131","C\xfcm\u0259","\u015e\u0259nb\u0259"],shortDays:["B","Be","\xc7a","\xc7","Ca","C","\u015e"],months:["Yanvar","Fevral","Mart","Aprel","May","\u0130yun","\u0130yul","Avqust","Sentyabr","Oktyabr","Noyabr","Dekabr"],shortMonths:["Yan","Fev","Mar","Apr","May","\u0130yun","\u0130yul","Avq","Sen","Okt","Noy","Dek"],date:"%d.%m.%Y"}};"undefined"==typeof Plotly?(window.PlotlyLocales=window.PlotlyLocales||[],window.PlotlyLocales.push(locale)):Plotly.register(locale);

View File

@ -0,0 +1 @@
var locale={moduleType:"locale",name:"bg",dictionary:{},format:{days:["\u041d\u0435\u0434\u0435\u043b\u044f","\u041f\u043e\u043d\u0435\u0434\u0435\u043b\u043d\u0438\u043a","\u0412\u0442\u043e\u0440\u043d\u0438\u043a","\u0421\u0440\u044f\u0434\u0430","\u0427\u0435\u0442\u0432\u044a\u0440\u0442\u044a\u043a","\u041f\u0435\u0442\u044a\u043a","\u0421\u044a\u0431\u043e\u0442\u0430"],shortDays:["\u041d\u0435\u0434","\u041f\u043e\u043d","\u0412\u0442\u043e","\u0421\u0440\u044f","\u0427\u0435\u0442","\u041f\u0435\u0442","\u0421\u044a\u0431"],months:["\u042f\u043d\u0443\u0430\u0440\u0438","\u0424\u0435\u0432\u0440\u0443\u0430\u0440\u0438","\u041c\u0430\u0440\u0442","\u0410\u043f\u0440\u0438\u043b","\u041c\u0430\u0439","\u042e\u043d\u0438","\u042e\u043b\u0438","\u0410\u0432\u0433\u0443\u0441\u0442","\u0421\u0435\u043f\u0442\u0435\u043c\u0432\u0440\u0438","\u041e\u043a\u0442\u043e\u043c\u0432\u0440\u0438","\u041d\u043e\u0435\u043c\u0432\u0440\u0438","\u0414\u0435\u043a\u0435\u043c\u0432\u0440\u0438"],shortMonths:["\u042f\u043d\u0443","\u0424\u0435\u0432","\u041c\u0430\u0440","\u0410\u043f\u0440","\u041c\u0430\u0439","\u042e\u043d\u0438","\u042e\u043b\u0438","\u0410\u0432\u0433","\u0421\u0435\u043f","\u041e\u043a\u0442","\u041d\u043e\u0432","\u0414\u0435\u043a"],date:"%d.%m.%Y"}};"undefined"==typeof Plotly?(window.PlotlyLocales=window.PlotlyLocales||[],window.PlotlyLocales.push(locale)):Plotly.register(locale);

View File

@ -0,0 +1 @@
var locale={moduleType:"locale",name:"bs",dictionary:{},format:{days:["Nedelja","Ponedeljak","Utorak","Srijeda","\u010cetvrtak","Petak","Subota"],shortDays:["Ned","Pon","Uto","Sri","\u010cet","Pet","Sub"],months:["Januar","Februar","Mart","April","Maj","Juni","Juli","August","Septembar","Oktobar","Novembar","Decembar"],shortMonths:["Jan","Feb","Mar","Apr","Maj","Jun","Jul","Aug","Sep","Okt","Nov","Dec"],date:"%d.%m.%Y"}};"undefined"==typeof Plotly?(window.PlotlyLocales=window.PlotlyLocales||[],window.PlotlyLocales.push(locale)):Plotly.register(locale);

View File

@ -0,0 +1 @@
var locale={moduleType:"locale",name:"ca",dictionary:{},format:{days:["Diumenge","Dilluns","Dimarts","Dimecres","Dijous","Divendres","Dissabte"],shortDays:["Dug","Dln","Dmt","Dmc","Djs","Dvn","Dsb"],months:["Gener","Febrer","Mar\xe7","Abril","Maig","Juny","Juliol","Agost","Setembre","Octubre","Novembre","Desembre"],shortMonths:["Gen","Feb","Mar","Abr","Mai","Jun","Jul","Ago","Set","Oct","Nov","Des"],date:"%d/%m/%Y"}};"undefined"==typeof Plotly?(window.PlotlyLocales=window.PlotlyLocales||[],window.PlotlyLocales.push(locale)):Plotly.register(locale);

View File

@ -0,0 +1 @@
var locale={moduleType:"locale",name:"cs",dictionary:{Autoscale:"Auto rozsah","Box Select":"Obd\xe9ln\xedkov\xfd v\xfdb\u011br","Click to enter Colorscale title":"Klikn\u011bte pro zad\xe1n\xed n\xe1zvu barevn\xe9 \u0161k\xe1ly","Click to enter Component A title":"Klikn\u011bte pro zad\xe1n\xed n\xe1zvu komponenty A","Click to enter Component B title":"Klikn\u011bte pro zad\xe1n\xed n\xe1zvu komponenty B","Click to enter Component C title":"Klikn\u011bte pro zad\xe1n\xed n\xe1zvu komponenty C","Click to enter Plot title":"Klikn\u011bte pro zad\xe1n\xed n\xe1zvu grafu","Click to enter X axis title":"Klikn\u011bte pro zad\xe1n\xed n\xe1zvu osy X","Click to enter Y axis title":"Klikn\u011bte pro zad\xe1n\xed n\xe1zvu osy Y","Click to enter radial axis title":"Klikn\u011bte pro zad\xe1n\xed n\xe1zvu radi\xe1ln\xed osy","Compare data on hover":"Porovnat hodnoty p\u0159i najet\xed my\u0161\xed","Double-click on legend to isolate one trace":"Dvojklikem na legendu izolujete jedinou datovou sadu","Double-click to zoom back out":"Dvojklikem vr\xe1t\xedte zv\u011bt\u0161en\xed","Download plot as a png":"Ulo\u017eit jako PNG","Download plot":"Ulo\u017eit","Edit in Chart Studio":"Editovat v Chart Studio","IE only supports svg. Changing format to svg.":"IE podporuje pouze SVG form\xe1t. Zm\u011bn\u011bno na SVG.","Lasso Select":"Vyb\u011br lasem","Orbital rotation":"Rotace (orbit\xe1ln\xed)",Pan:"Posunovat","Produced with Plotly.js":"Vytvo\u0159eno pomoc\xed Plotly.js",Reset:"Obnovit nastaven\xed","Reset axes":"Obnovit nastaven\xed os","Reset camera to default":"Obnovit nastaven\xed kamery na v\xfdchoz\xed stav","Reset camera to last save":"Obnovit nastaven\xed kamery na posledn\xed ulo\u017een\xfd stav","Reset view":"Obnovit nastaven\xed pohledu","Reset views":"Obnovit nastaven\xed pohled\u016f","Show closest data on hover":"Zobrazit najbli\u017e\u0161\xed hodnotu p\u0159i najet\xed my\u0161\xed","Snapshot succeeded":"Sn\xedmek vytvo\u0159en","Sorry, there was a problem downloading your snapshot!":"Omlouv\xe1me se, ale do\u0161lo k chyb\u011b stahov\xe1n\xed sn\xedmku!","Taking snapshot - this may take a few seconds":"Vytv\xe1\u0159\xed se sn\xedmek - m\u016f\u017ee zabrat p\xe1r vte\u0159in",Zoom:"Zv\u011bt\u0161en\xed","Zoom in":"Zv\u011bt\u0161it","Zoom out":"Zmen\u0161it","close:":"zav\u0159\xedt:",trace:"datov\xe1 sada","lat:":"Lat.:","lon:":"Lon.:","q1:":"q1:","q3:":"q3:","source:":"zdroj:","target:":"c\xedl:","lower fence:":"doln\xed limit:","upper fence:":"horn\xed limit:","max:":"max.:","mean \xb1 \u03c3:":"pr\u016fm\u011br \xb1 \u03c3:","mean:":"pr\u016fm\u011br:","median:":"medi\xe1n:","min:":"min.:","new text":"nov\xfd text","Turntable rotation":"Rotace (oto\u010dn\xfd st\u016fl)","Toggle Spike Lines":"P\u0159epnout zobrazen\xed vod\xedc\xedch \u010dar","open:":"otev\u0159\xedt:","high:":"horn\xed:","low:":"doln\xed:","Toggle show closest data on hover":"P\u0159epnout zobrazov\xe1n\xed nejbli\u017e\u0161i hodnoty p\u0159i najet\xed my\u0161\xed","incoming flow count:":"po\u010det dat na vstupu:","outgoing flow count:":"po\u010det dat na v\xfdstupu:","kde:":"kde:"},format:{days:["ned\u011ble","pond\u011bl\xed","\xfater\xfd","st\u0159eda","\u010dtvrtek","p\xe1tek","sobota"],shortDays:["ne","po","\xfat","st","\u010dt","p\xe1","so"],months:["leden","\xfanor","b\u0159ezen","duben","kv\u011bten","\u010derven","\u010dervenec","srpen","z\xe1\u0159\xed","\u0159\xedjen","listopad","prosinec"],shortMonths:["led","\xfano","b\u0159e","dub","kv\u011b","\u010der","\u010dvc","srp","z\xe1\u0159","\u0159\xedj","lis","pro"],date:"%d.%m.%Y",decimal:",",thousands:" "}};"undefined"==typeof Plotly?(window.PlotlyLocales=window.PlotlyLocales||[],window.PlotlyLocales.push(locale)):Plotly.register(locale);

View File

@ -0,0 +1 @@
var locale={moduleType:"locale",name:"cy",dictionary:{Autoscale:"Graddfa awtomatig","Box Select":"Dewiswch \xe2 blwch","Click to enter Colorscale title":"Cliciwch i nodi teitl Graddfa Liw","Click to enter Component A title":"Cliciwch i nodi teitl Cydran A","Click to enter Component B title":"Cliciwch i nodi teitl Cydran B","Click to enter Plot title":"Cliciwch i nodi teitl y Plot","Click to enter Component C title":"Cliciwch i nodi teitl Cydran C","Click to enter X axis title":"Cliciwch i nodi teitl echelin X","Click to enter Y axis title":"Cliciwch i nodi teitl echelin Y","Click to enter radial axis title":"Cliciwch i nodi teitl echelin reiddiol","Compare data on hover":"Cymharwch ddata wrth hofran","Double-click on legend to isolate one trace":"Dwbl-gliciwch ar yr allwedd i neilltuo un llinell","Double-click to zoom back out":"Dwbl-gliciwch i chwyddo'n \xf4l","Download plot":"Lawrlwythwch blot","Download plot as a png":"Lawrlwythwch y plot fel png","Edit in Chart Studio":"Golygu yn Chart Studio","IE only supports svg. Changing format to svg.":"Dim ond svg mae IE yn ei gefnogi. Newid fformat i svg.","Lasso Select":"Dewiswch \xe2 las\u0175","Orbital rotation":"Cylchdroi orbital",Pan:"Pan","Produced with Plotly.js":"Cynhyrchwyd gyda Plotly.js",Reset:"Ailosod","Reset axes":"Ailosod echelinau","Reset camera to default":"Ailosod camera i'r rhagosodiad","Reset camera to last save":"Ailosod camera i'r cadw diwethaf","Reset view":"Ailosodwch y golwg","Reset views":"Ailosod olygfeydd","Show closest data on hover":"Dangos y data agosaf wrth hofran","Snapshot succeeded":"Llwyddodd y Ciplun","Sorry, there was a problem downloading your snapshot!":"Mae'n ddrwg gennym, roedd problem wrth lawrlwytho eich ciplun!","Taking snapshot - this may take a few seconds":"Tynnu ciplun - gallai hyn gymryd ychydig o eiliadau","Toggle Spike Lines":"Toglo llinellau pigog","Toggle show closest data on hover":"Toglo dangos y data agosaf wrth hofran","Turntable rotation":"Cylchdroi trofwrdd",Zoom:"Chwyddo","Zoom in":"Closio","Zoom out":"Cilio","close:":"cau:","high:":"uchel:","incoming flow count:":"cyfrif llif sy'n dod i mewn:","kde:":"kde:","lat:":"lledred:","lon:":"hydred","low:":"isel:","lower fence:":"ffens isaf:","max:":"uchafbwynt:","mean \xb1 \u03c3:":"cymedr \xb1 \u03c3:","mean:":"cymedr:","median:":"canolrif:","min:":"isafbwynt:","new text":"testun newydd","open:":"agor:","outgoing flow count:":"cyfrif llif sy'n mynd allan:","q1:":"q1:","q3:":"q3:","source:":"ffynhonnell:","target:":"targed:",trace:"olin","upper fence:":"ffens uchaf:"},format:{days:["Dydd Sul","Dydd Llun","Dydd Mawrth","Dydd Mercher","Dydd Iau","Dydd Gwener","Dydd Sadwrn"],shortDays:["Sul","Llun","Maw","Mer","Iau","Gwen","Sad"],months:["Ionawr","Chwefror","Mawrth","Ebrill","Mai","Mehefin","Gorffennaf","Awst","Medi","Hydref","Tachwedd","Rhagfyr"],shortMonths:["Ion","Chw","Maw","Ebr","Mai","Meh","Gor","Awst","Medi","Hyd","Tach","Rhag"],date:"%d/%m/%Y"}};"undefined"==typeof Plotly?(window.PlotlyLocales=window.PlotlyLocales||[],window.PlotlyLocales.push(locale)):Plotly.register(locale);

View File

@ -0,0 +1 @@
var locale={moduleType:"locale",name:"da",dictionary:{},format:{days:["S\xf8ndag","Mandag","Tirsdag","Onsdag","Torsdag","Fredag","L\xf8rdag"],shortDays:["S\xf8n","Man","Tir","Ons","Tor","Fre","L\xf8r"],months:["Januar","Februar","Marts","April","Maj","Juni","Juli","August","September","Oktober","November","December"],shortMonths:["Jan","Feb","Mar","Apr","Maj","Jun","Jul","Aug","Sep","Okt","Nov","Dec"],date:"%d-%m-%Y"}};"undefined"==typeof Plotly?(window.PlotlyLocales=window.PlotlyLocales||[],window.PlotlyLocales.push(locale)):Plotly.register(locale);

View File

@ -0,0 +1 @@
var locale={moduleType:"locale",name:"de-CH",dictionary:{},format:{days:["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"],shortDays:["So","Mo","Di","Mi","Do","Fr","Sa"],months:["Januar","Februar","M\xe4rz","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"],shortMonths:["Jan","Feb","M\xe4r","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],date:"%d.%m.%Y"}};"undefined"==typeof Plotly?(window.PlotlyLocales=window.PlotlyLocales||[],window.PlotlyLocales.push(locale)):Plotly.register(locale);

View File

@ -0,0 +1 @@
var locale={moduleType:"locale",name:"de",dictionary:{Autoscale:"Automatische Skalierung","Box Select":"Rechteckauswahl","Click to enter Colorscale title":"Klicken, um den Farbskalatitel einzugeben","Click to enter Component A title":"Klicken, um den Titel der Komponente A einzugeben","Click to enter Component B title":"Klicken, um den Titel der Komponente B einzugeben","Click to enter Component C title":"Klicken, um den Titel der Komponente C einzugeben","Click to enter Plot title":"Klicken, um den Titel des Graphen einzugeben","Click to enter X axis title":"Klicken, um den Titel der X-Achse einzugeben","Click to enter Y axis title":"Klicken, um den Titel der Y-Achse einzugeben","Compare data on hover":"\xdcber die Daten fahren, um sie zu vergleichen","Double-click on legend to isolate one trace":"Daten isolieren durch Doppelklick in der Legende","Double-click to zoom back out":"Herauszoomen durch Doppelklick","Download plot as a png":"Graphen als PNG herunterladen","Download plot":"Graphen herunterladen","Edit in Chart Studio":"Im Chart Studio bearbeiten","IE only supports svg. Changing format to svg.":"IE unterst\xfctzt nur SVG-Dateien. Format wird zu SVG gewechselt.","Lasso Select":"Lassoauswahl","Orbital rotation":"Orbitalrotation",Pan:"Verschieben","Produced with Plotly.js":"Erstellt mit Plotly.js",Reset:"Zur\xfccksetzen","Reset axes":"Achsen zur\xfccksetzen","Reset camera to default":"Kamera auf Standard zur\xfccksetzen","Reset camera to last save":"Kamera auf letzte Speicherung zur\xfccksetzen","Reset view":"Ansicht zur\xfccksetzen","Reset views":"Ansichten zur\xfccksetzen","Show closest data on hover":"Zeige n\xe4heste Daten beim \xdcberfahren","Snapshot succeeded":"Snapshot erfolgreich","Sorry, there was a problem downloading your snapshot!":"Es gab ein Problem beim Herunterladen des Snapshots","Taking snapshot - this may take a few seconds":"Erstelle einen Snapshot - dies kann einige Sekunden dauern",Zoom:"Zoom","Zoom in":"Hineinzoomen","Zoom out":"Herauszoomen","close:":"Schluss:",trace:"Datenspur","lat:":"Lat.:","lon:":"Lon.:","q1:":"q1:","q3:":"q3:","source:":"Quelle:","target:":"Ziel:","lower fence:":"Untere Schranke:","upper fence:":"Obere Schranke:","max:":"Max.:","mean \xb1 \u03c3:":"Mittelwert \xb1 \u03c3:","mean:":"Mittelwert:","median:":"Median:","min:":"Min.:","Turntable rotation":"Drehscheibenorbit","Toggle Spike Lines":"Bezugslinien an-/abschalten","open:":"Er\xf6ffnung:","high:":"H\xf6chstkurs:","low:":"Tiefstkurs:","Toggle show closest data on hover":"Anzeige der n\xe4hesten Daten an-/abschalten","incoming flow count:":"Anzahl eingehender Verbindungen:","outgoing flow count:":"Anzahl ausgehender Verbindungen:","kde:":"Dichte:"},format:{days:["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"],shortDays:["So","Mo","Di","Mi","Do","Fr","Sa"],months:["Januar","Februar","M\xe4rz","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"],shortMonths:["Jan","Feb","M\xe4r","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],date:"%d.%m.%Y",decimal:",",thousands:"."}};"undefined"==typeof Plotly?(window.PlotlyLocales=window.PlotlyLocales||[],window.PlotlyLocales.push(locale)):Plotly.register(locale);

View File

@ -0,0 +1 @@
var locale={moduleType:"locale",name:"el",dictionary:{},format:{days:["\u039a\u03c5\u03c1\u03b9\u03b1\u03ba\u03ae","\u0394\u03b5\u03c5\u03c4\u03ad\u03c1\u03b1","\u03a4\u03c1\u03af\u03c4\u03b7","\u03a4\u03b5\u03c4\u03ac\u03c1\u03c4\u03b7","\u03a0\u03ad\u03bc\u03c0\u03c4\u03b7","\u03a0\u03b1\u03c1\u03b1\u03c3\u03ba\u03b5\u03c5\u03ae","\u03a3\u03ac\u03b2\u03b2\u03b1\u03c4\u03bf"],shortDays:["\u039a\u03c5\u03c1","\u0394\u03b5\u03c5","\u03a4\u03c1\u03b9","\u03a4\u03b5\u03c4","\u03a0\u03b5\u03bc","\u03a0\u03b1\u03c1","\u03a3\u03b1\u03b2"],months:["\u0399\u03b1\u03bd\u03bf\u03c5\u03ac\u03c1\u03b9\u03bf\u03c2","\u03a6\u03b5\u03b2\u03c1\u03bf\u03c5\u03ac\u03c1\u03b9\u03bf\u03c2","\u039c\u03ac\u03c1\u03c4\u03b9\u03bf\u03c2","\u0391\u03c0\u03c1\u03af\u03bb\u03b9\u03bf\u03c2","\u039c\u03ac\u03b9\u03bf\u03c2","\u0399\u03bf\u03cd\u03bd\u03b9\u03bf\u03c2","\u0399\u03bf\u03cd\u03bb\u03b9\u03bf\u03c2","\u0391\u03cd\u03b3\u03bf\u03c5\u03c3\u03c4\u03bf\u03c2","\u03a3\u03b5\u03c0\u03c4\u03ad\u03bc\u03b2\u03c1\u03b9\u03bf\u03c2","\u039f\u03ba\u03c4\u03ce\u03b2\u03c1\u03b9\u03bf\u03c2","\u039d\u03bf\u03ad\u03bc\u03b2\u03c1\u03b9\u03bf\u03c2","\u0394\u03b5\u03ba\u03ad\u03bc\u03b2\u03c1\u03b9\u03bf\u03c2"],shortMonths:["\u0399\u03b1\u03bd","\u03a6\u03b5\u03b2","\u039c\u03b1\u03c1","\u0391\u03c0\u03c1","\u039c\u03b1\u03b9","\u0399\u03bf\u03c5\u03bd","\u0399\u03bf\u03c5\u03bb","\u0391\u03c5\u03b3","\u03a3\u03b5\u03c0","\u039f\u03ba\u03c4","\u039d\u03bf\u03b5","\u0394\u03b5\u03ba"],date:"%d/%m/%Y"}};"undefined"==typeof Plotly?(window.PlotlyLocales=window.PlotlyLocales||[],window.PlotlyLocales.push(locale)):Plotly.register(locale);

View File

@ -0,0 +1 @@
var locale={moduleType:"locale",name:"eo",dictionary:{},format:{days:["Diman\u0109o","Lundo","Mardo","Merkredo","\u0134a\u016ddo","Vendredo","Sabato"],shortDays:["Dim","Lun","Mar","Mer","\u0134a\u016d","Ven","Sab"],months:["Januaro","Februaro","Marto","Aprilo","Majo","Junio","Julio","A\u016dgusto","Septembro","Oktobro","Novembro","Decembro"],shortMonths:["Jan","Feb","Mar","Apr","Maj","Jun","Jul","A\u016dg","Sep","Okt","Nov","Dec"],date:"%d/%m/%Y"}};"undefined"==typeof Plotly?(window.PlotlyLocales=window.PlotlyLocales||[],window.PlotlyLocales.push(locale)):Plotly.register(locale);

View File

@ -0,0 +1 @@
var locale={moduleType:"locale",name:"es-AR",dictionary:{},format:{days:["Domingo","Lunes","Martes","Mi\xe9rcoles","Jueves","Viernes","S\xe1bado"],shortDays:["Dom","Lun","Mar","Mi\xe9","Juv","Vie","S\xe1b"],months:["Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre"],shortMonths:["Ene","Feb","Mar","Abr","May","Jun","Jul","Ago","Sep","Oct","Nov","Dic"],date:"%d/%m/%Y"}};"undefined"==typeof Plotly?(window.PlotlyLocales=window.PlotlyLocales||[],window.PlotlyLocales.push(locale)):Plotly.register(locale);

View File

@ -0,0 +1 @@
var locale={moduleType:"locale",name:"es-PE",dictionary:{},format:{days:["Domingo","Lunes","Martes","Mi\xe9rcoles","Jueves","Viernes","S\xe1bado"],shortDays:["Dom","Lun","Mar","Mi\xe9","Jue","Vie","Sab"],months:["Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre"],shortMonths:["Ene","Feb","Mar","Abr","May","Jun","Jul","Ago","Sep","Oct","Nov","Dic"],date:"%d/%m/%Y",decimal:".",thousands:",",currency:["S/",""]}};"undefined"==typeof Plotly?(window.PlotlyLocales=window.PlotlyLocales||[],window.PlotlyLocales.push(locale)):Plotly.register(locale);

View File

@ -0,0 +1 @@
var locale={moduleType:"locale",name:"es",dictionary:{Autoscale:"Autoescalar","Box Select":"Seleccionar Caja","Click to enter Colorscale title":"Introducir el t\xedtulo de la Escala de Color","Click to enter Component A title":"Introducir el t\xedtulo del Componente A","Click to enter Component B title":"Introducir el t\xedtulo del Componente B","Click to enter Component C title":"Introducir el t\xedtulo del Componente C","Click to enter Plot title":"Introducir el t\xedtulo de la Gr\xe1fica","Click to enter X axis title":"Introducir el t\xedtulo del eje X","Click to enter Y axis title":"Introducir el t\xedtulo del eje Y","Click to enter radial axis title":"Introducir el t\xedtulo del eje radial","Compare data on hover":"Comparar datos al pasar por encima","Double-click on legend to isolate one trace":"Haga doble-clic en la leyenda para aislar una traza","Double-click to zoom back out":"Haga doble-clic para restaurar la escala","Download plot as a png":"Descargar gr\xe1fica como png","Download plot":"Descargar gr\xe1fica","Edit in Chart Studio":"Editar en Chart Studio","IE only supports svg. Changing format to svg.":"IE solo soporta svg. Cambiando formato a svg.","Lasso Select":"Seleccionar con lazo","Orbital rotation":"Rotaci\xf3n esf\xe9rica",Pan:"Modo Panor\xe1mica","Produced with Plotly.js":"Hecho con Plotly.js",Reset:"Reiniciar","Reset axes":"Reiniciar ejes","Reset camera to default":"Restaurar c\xe1mara predeterminada","Reset camera to last save":"Restaurar anterior c\xe1mara","Reset view":"Restaurar vista","Reset views":"Restaurar vistas","Show closest data on hover":"Mostrar el dato m\xe1s cercano al pasar por encima","Snapshot succeeded":"La captura de la instant\xe1nea finaliz\xf3 correctamente","Sorry, there was a problem downloading your snapshot!":"\xa1La descarga de la instant\xe1nea fall\xf3!","Taking snapshot - this may take a few seconds":"Capturando una instant\xe1nea - podr\xeda tardar unos segundos","Toggle Spike Lines":"Mostrar/Ocultar Gu\xedas","Toggle show closest data on hover":"Activar/Desactivar mostrar el dato m\xe1s cercano al pasar por encima","Turntable rotation":"Rotaci\xf3n plana",Zoom:"Modo Ampliar/Reducir","Zoom in":"Ampliar","Zoom out":"Reducir","close:":"cierre:","high:":"alza:","incoming flow count:":"flujo de entrada:","kde:":"edp:","lat:":"lat:","lon:":"lon:","low:":"baja:","lower fence:":"l\xedmite inferior:","max:":"m\xe1x:","mean \xb1 \u03c3:":"media \xb1 \u03c3:","mean:":"media:","median:":"mediana:","min:":"m\xedn:","new text":"nuevo texto","open:":"apertura:","outgoing flow count:":"flujo de salida:","q1:":"q1:","q3:":"q3:","source:":"fuente:","target:":"destino:",trace:"traza","upper fence:":"l\xedmite superior:"},format:{days:["Domingo","Lunes","Martes","Mi\xe9rcoles","Jueves","Viernes","S\xe1bado"],shortDays:["Dom","Lun","Mar","Mi\xe9","Jue","Vie","S\xe1b"],months:["Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre"],shortMonths:["Ene","Feb","Mar","Abr","May","Jun","Jul","Ago","Sep","Oct","Nov","Dic"],date:"%d/%m/%Y",decimal:",",thousands:" "}};"undefined"==typeof Plotly?(window.PlotlyLocales=window.PlotlyLocales||[],window.PlotlyLocales.push(locale)):Plotly.register(locale);

View File

@ -0,0 +1 @@
var locale={moduleType:"locale",name:"et",dictionary:{},format:{days:["P\xfchap\xe4ev","Esmasp\xe4ev","Teisip\xe4ev","Kolmap\xe4ev","Neljap\xe4ev","Reede","Laup\xe4ev"],shortDays:["P\xfchap","Esmasp","Teisip","Kolmap","Neljap","Reede","Laup"],months:["Jaanuar","Veebruar","M\xe4rts","Aprill","Mai","Juuni","Juuli","August","September","Oktoober","November","Detsember"],shortMonths:["Jaan","Veebr","M\xe4rts","Apr","Mai","Juuni","Juuli","Aug","Sept","Okt","Nov","Dets"],date:"%d.%m.%Y"}};"undefined"==typeof Plotly?(window.PlotlyLocales=window.PlotlyLocales||[],window.PlotlyLocales.push(locale)):Plotly.register(locale);

View File

@ -0,0 +1 @@
var locale={moduleType:"locale",name:"eu",dictionary:{},format:{days:["Igandea","Astelehena","Asteartea","Asteazkena","Osteguna","Ostirala","Larunbata"],shortDays:["Iga","Ast","Ast","Ast","Ost","Ost","Lar"],months:["Urtarrila","Otsaila","Martxoa","Apirila","Maiatza","Ekaina","Uztaila","Abuztua","Iraila","Urria","Azaroa","Abendua"],shortMonths:["Urt","Ots","Mar","Api","Mai","Eka","Uzt","Abu","Ira","Urr","Aza","Abe"],date:"%Y/%m/%d"}};"undefined"==typeof Plotly?(window.PlotlyLocales=window.PlotlyLocales||[],window.PlotlyLocales.push(locale)):Plotly.register(locale);

View File

@ -0,0 +1 @@
var locale={moduleType:"locale",name:"fa",dictionary:{},format:{days:["\u064a\u06a9\u0634\u0646\u0628\u0647","\u062f\u0648\u0634\u0646\u0628\u0647","\u0633\u0647\u200c\u0634\u0646\u0628\u0647","\u0686\u0647\u0627\u0631\u0634\u0646\u0628\u0647","\u067e\u0646\u062c\u0634\u0646\u0628\u0647","\u062c\u0645\u0639\u0647","\u0634\u0646\u0628\u0647"],shortDays:["\u064a","\u062f","\u0633","\u0686","\u067e","\u062c","\u0634"],months:["\u0641\u0631\u0648\u0631\u062f\u064a\u0646","\u0627\u0631\u062f\u064a\u0628\u0647\u0634\u062a","\u062e\u0631\u062f\u0627\u062f","\u062a\u064a\u0631","\u0645\u0631\u062f\u0627\u062f","\u0634\u0647\u0631\u064a\u0648\u0631","\u0645\u0647\u0631","\u0622\u0628\u0627\u0646","\u0622\u0630\u0631","\u062f\u064a","\u0628\u0647\u0645\u0646","\u0627\u0633\u0641\u0646\u062f"],shortMonths:["1","2","3","4","5","6","7","8","9","10","11","12"],date:"%Y/%m/%d"}};"undefined"==typeof Plotly?(window.PlotlyLocales=window.PlotlyLocales||[],window.PlotlyLocales.push(locale)):Plotly.register(locale);

View File

@ -0,0 +1 @@
var locale={moduleType:"locale",name:"fi",dictionary:{Autoscale:"Autoskaalaa","Box Select":"Laatikkovalinta","Click to enter Colorscale title":"Klikkaa antaaksesi v\xe4riskaalan otsikko","Click to enter Component A title":"Klikkaa antaaksesi komponentin A otsikko","Click to enter Component B title":"Klikkaa antaaksesi komponentin B otsikko","Click to enter Component C title":"Klikkaa antaaksesi komponentin C otsikko","Click to enter Plot title":"Klikkaa antaaksesi kuvion otsikko","Click to enter X axis title":"Klikkaa antaaksesi x-akselin otsikko","Click to enter Y axis title":"Klikkaa antaaksesi y-akselin otsikko","Click to enter radial axis title":"Klikkaa antaaksesi radiaalisen akselin otsikko","Compare data on hover":"Vertaa dataa kursorilla","Double-click on legend to isolate one trace":"Kaksoisklikkaa selitett\xe4 erist\xe4\xe4ksesi yksi sarja","Double-click to zoom back out":"Kaksoisklikkaa zoomataksesi ulos","Download plot":"Lataa kuvio","Download plot as a png":"Lataa kuvio png-muodossa","Edit in Chart Studio":"Muokkaa Chart Studiossa","IE only supports svg. Changing format to svg.":"Formaatiksi vaihdetaan IE:n tukema svg.","Lasso Select":"Lassovalinta","Orbital rotation":"Orbitaalikierto",Pan:"Panorointi","Produced with Plotly.js":"Tuotettu Plotly.jsll\xe4",Reset:"Palauta oletusasetukset","Reset axes":"Palauta akselien oletusasetukset","Reset camera to default":"Palauta kameran oletusasetukset","Reset camera to last save":"Palauta kameran viimeksi tallennetut asetukset","Reset view":"Palauta n\xe4kym\xe4n oletusasetukset","Reset views":"Palauta n\xe4kymien oletusasetukset","Show closest data on hover":"N\xe4yt\xe4 kursoria l\xe4hin data","Snapshot succeeded":"Tilannekuvan ottaminen onnistui","Sorry, there was a problem downloading your snapshot!":"Pahoittelut, tilannekuvan lataaminen ep\xe4onnistui!","Taking snapshot - this may take a few seconds":"Otetaan tilannekuvaa - odota hetki","Toggle Spike Lines":"N\xe4yt\xe4 huiput","Toggle show closest data on hover":"N\xe4yt\xe4 kursoria l\xe4hin data","Turntable rotation":"Tasokierto",Zoom:"Zoomaus","Zoom in":"Zoomaa sis\xe4\xe4n","Zoom out":"Zoomaa ulos","close:":"loppu:","high:":"korkein:","incoming flow count:":"saapuva virtaus:","kde:":"ydinestimointi:","lat:":"lat.:","lon:":"lon.:","low:":"matalin:","lower fence:":"alempi raja:","max:":"maks.:","mean \xb1 \u03c3:":"keskiarvo \xb1 \u03c3:","mean:":"keskiarvo:","median:":"mediaani:","min:":"min.:","new text":"uusi teksti","open:":"alku:","outgoing flow count:":"l\xe4htev\xe4 virtaus:","q1:":"q1:","q3:":"q3:","source:":"l\xe4hde:","target:":"kohde:",trace:"sarja","upper fence:":"ylempi raja:"},format:{days:["sunnuntai","maanantai","tiistai","keskiviikko","torstai","perjantai","lauantai"],shortDays:["su","ma","ti","ke","to","pe","la"],months:["tammikuu","helmikuu","maaliskuu","huhtikuu","toukokuu","kes\xe4kuu","hein\xe4kuu","elokuu","syyskuu","lokakuu","marraskuu","joulukuu"],shortMonths:["tammi","helmi","maalis","huhti","touko","kes\xe4","hein\xe4","elo","syys","loka","marras","joulu"],date:"%d.%m.%Y"}};"undefined"==typeof Plotly?(window.PlotlyLocales=window.PlotlyLocales||[],window.PlotlyLocales.push(locale)):Plotly.register(locale);

View File

@ -0,0 +1 @@
var locale={moduleType:"locale",name:"fo",dictionary:{},format:{days:["Sunnudagur","M\xe1nadagur","T\xfdsdagur","Mikudagur","H\xf3sdagur","Fr\xedggjadagur","Leyardagur"],shortDays:["Sun","M\xe1n","T\xfds","Mik","H\xf3s","Fr\xed","Ley"],months:["Januar","Februar","Mars","Apr\xedl","Mei","Juni","Juli","August","September","Oktober","November","Desember"],shortMonths:["Jan","Feb","Mar","Apr","Mei","Jun","Jul","Aug","Sep","Okt","Nov","Des"],date:"%d-%m-%Y"}};"undefined"==typeof Plotly?(window.PlotlyLocales=window.PlotlyLocales||[],window.PlotlyLocales.push(locale)):Plotly.register(locale);

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