diff --git a/.docker/Dockerfile b/.docker/Dockerfile index 5b26c03c927780e804f190ee6c8dee1e6813a18e..7ab3e655cc56687dd36777c620de51e4742aedde 100644 --- a/.docker/Dockerfile +++ b/.docker/Dockerfile @@ -1,34 +1,21 @@ -FROM debian:11 +FROM debian:12 RUN apt-get update && \ apt-get install \ - curl \ - libhdf5-dev \ - pkgconf \ python3 \ python3-pip \ - python3-requests \ - python3-pandas \ - python3-html2text \ - python3-sphinx \ tox \ git \ - openjdk-11-jdk-headless \ - python3-autopep8 \ - python3-pytest \ - libxml2 \ + openjdk-17-jdk-headless \ -y COPY .docker/wait-for-it.sh /wait-for-it.sh ADD https://gitlab.com/api/v4/projects/13656973/repository/branches/dev \ - pylib_version.json -RUN git clone https://gitlab.com/caosdb/caosdb-pylib.git && \ - cd caosdb-pylib && git checkout dev && pip3 install . -# At least recommonmark 0.6 required. -RUN pip3 install -U html2text pycodestyle pylint recommonmark sphinx-rtd-theme gitignore-parser + pylib_version.json +RUN pip install --break-system-packages -U git+https://gitlab.indiscale.com/caosdb/src/caosdb-pylib.git@dev COPY . /git RUN rm -r /git/.git \ - && mv /git/.docker/pycaosdb.ini /git/integrationtests -RUN cd /git && pip3 install .[h5-crawler] + && mv /git/.docker/pylinkahead.ini /git/integrationtests +RUN cd /git && pip install --break-system-packages -U .[all] WORKDIR /git/integrationtests -CMD /wait-for-it.sh caosdb-server:10443 -t 500 -- ./test.sh --force +CMD /wait-for-it.sh docker-linkahead-server-1:10443 -t 300 --strict -- ./test.sh --force diff --git a/.docker/cert.sh b/.docker/cert.sh index e22cfba2995b5fd9d812232f562b7254233fe5b0..c7253c77d5ce60d17bd816b2ae012d176996f297 100755 --- a/.docker/cert.sh +++ b/.docker/cert.sh @@ -1,7 +1,7 @@ #!/bin/bash # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2019 Daniel Hornung, Göttingen # diff --git a/.docker/docker-compose.yml b/.docker/docker-compose.yml index 36964ee68b7e384267a08484524de1f72cdfad6d..61d455f43ec92974207ba0ae8aadf528e15dfcaa 100644 --- a/.docker/docker-compose.yml +++ b/.docker/docker-compose.yml @@ -1,12 +1,12 @@ version: '3.7' services: sqldb: - image: mariadb:10.4 + image: mariadb:10.11 environment: MYSQL_ROOT_PASSWORD: caosdb1234 networks: - caosnet - caosdb-server: + linkahead-server: image: "$CI_REGISTRY/caosdb/src/caosdb-deploy:$CAOSDB_TAG" user: 999:999 depends_on: diff --git a/.docker/local_testing.sh b/.docker/local_testing.sh index bdecf73be670775b3b888846e77d261f22e552df..bbe7d8af408cc40758d48c49119d3ba4db5d0325 100755 --- a/.docker/local_testing.sh +++ b/.docker/local_testing.sh @@ -10,7 +10,7 @@ CI_REGISTRY_IMAGE=registry.indiscale.com/caosdb-advanced-testenv \ CI_REGISTRY=registry.indiscale.com EXEPATH=`pwd` CAOSDB_TAG=dev-latest \ docker-compose -f .docker/docker-compose.yml up -d cd .docker -CAOSHOSTNAME=caosdb-server ./cert.sh +CAOSHOSTNAME=linkahead-server ./cert.sh CI_REGISTRY_IMAGE=registry.indiscale.com/caosdb-advanced-testenv ./run.sh docker-compose down diff --git a/.docker/pycaosdb.ini b/.docker/pylinkahead.ini similarity index 88% rename from .docker/pycaosdb.ini rename to .docker/pylinkahead.ini index 652d536916ad0a4acece723a966eb310a045dd1a..bfa5705b56c31809567b69341470dd065ab3ed74 100644 --- a/.docker/pycaosdb.ini +++ b/.docker/pylinkahead.ini @@ -2,7 +2,7 @@ test_server_side_scripting.bin_dir=../caosdb-server/test_scripting/bin/ [Connection] -url=https://caosdb-server:10443 +url=https://linkahead-server:10443 username=admin cacert=/opt/caosdb/cert/caosdb.cert.pem debug=0 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 61c68e67a7107457e2f3c780b54366a23eae1e78..f300085686c74b6940360cf841703afd2bab19c1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,5 +1,5 @@ # -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2018 Research Group Biomedical Physics, # Max-Planck-Institute for Dynamics and Self-Organization Göttingen @@ -58,7 +58,7 @@ test: - cd .docker - /bin/sh ./run.sh - cd .. - - docker logs docker-caosdb-server-1 &> caosdb_log.txt + - docker logs docker-linkahead-server-1 &> caosdb_log.txt - docker logs docker-sqldb-1 &> mariadb_log.txt - docker-compose -f .docker/docker-compose.yml down - rc=`cat .docker/result` @@ -123,25 +123,25 @@ linting: - make lint allow_failure: true -unittest_py39: +# The Python version provided by the OS. +unittest_py311: tags: [docker] stage: unittest image: $CI_REGISTRY_IMAGE needs: [build-testenv] script: - # First verify that system Python actually is 3.9 - - python3 -c "import sys; assert sys.version.startswith('3.9')" + # First verify that system Python actually is 3.11 + - python3 -c "import sys; assert sys.version.startswith('3.11')" - python3 -c "import linkahead; print('LinkAhead Version:', linkahead.__version__)" - tox -unittest_py38: +unittest_py39: tags: [docker] stage: unittest - image: python:3.8 + image: python:3.9 script: &python_test_script - - pip install pynose pandas pytest pytest-cov gitignore-parser openpyxl>=3.0.7 xlrd==1.2 h5py - - pip install git+https://gitlab.indiscale.com/caosdb/src/caosdb-pylib.git@dev - - pip install . + - pip install --break-system-packages git+https://gitlab.indiscale.com/caosdb/src/caosdb-pylib.git@dev + - pip install --break-system-packages .[all] - pytest --cov=caosadvancedtools unittests unittest_py310: @@ -150,12 +150,6 @@ unittest_py310: image: python:3.10 script: *python_test_script -unittest_py311: - tags: [docker] - stage: unittest - image: python:3.11 - script: *python_test_script - unittest_py312: tags: [docker] stage: unittest @@ -165,15 +159,8 @@ unittest_py312: unittest_py313: tags: [docker] stage: unittest - image: python:3.13-rc - script: - # TODO: Replace by '*python_test_script' as soon as 3.13 has been officially released. - - apt update && apt install -y cargo || true - - pip install meson[ninja] meson-python || true - - pip install pynose pandas pytest pytest-cov gitignore-parser openpyxl>=3.0.7 xlrd==1.2 h5py || true - - pip install git+https://gitlab.indiscale.com/caosdb/src/caosdb-pylib.git@dev || true - - pip install . || true - - pytest --cov=caosadvancedtools unittests || true + image: python:3.13 + script: *python_test_script # Build the sphinx documentation and make it ready for deployment by Gitlab Pages # Special job for serving a static website. See https://docs.gitlab.com/ee/ci/yaml/README.html#pages diff --git a/CHANGELOG.md b/CHANGELOG.md index 92180a7d809b1367baf65132942287d099427572..1375a7d397141205d656eb4d327e953a254a1436 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,48 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.13.0] - 2025-01-16 ## + +### Added ### + +* Official support for Python 3.13 + +### Changed ### + +- Using the official name "LinkAhead" wherever possible without large + effort. This includes the following exposed names / features: + - `models.data_model.LINKAHEAD_INTERNAL_PROPERTIES` + - `export_related.export` exports to `linkahead_data.xml` now. +- Renamed (and added) installation "extra" options: + - `h5` instead of `h5-crawler` + - `dev`, `doc`, `test` and `all` are new, they install the + dependencies for developing, testing, documentation and + everything. +- The `pandoc_header_tools.get_header()` parameter `add_header` has + been renamed to `add_header_to_file` to resolve a name collision. + +### Removed ### + +- Bloxberg code snippets. These were just a proof of concept, untested + and never used in production. +- Labfolder converter. It was broken anyway, not used by anyone we + know and there were no automated tests. For the time being, it lives + on in the `f-labfolder-converter` branch, [issue + 67](https://gitlab.com/linkahead/linkahead-advanced-user-tools/-/issues/67) + is there to coordinate resurrections efforts if someone needs it.. +- Support for Python 3.8 + +### Fixed ### + +- Yaml data model parser adds data types of properties of record types + and other attributes which fixes + https://gitlab.indiscale.com/caosdb/customers/f-fit/management/-/issues/58 +- `XLSXConverter` now checks path validity before parsing the worksheet. + +### Documentation ### + +* Added documentation of `caosadvancedtools.loadFiles` module. + ## [0.12.0] - 2024-07-31 ## ### Added ### @@ -108,6 +150,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * `TableImporter.check_missing` in case of array-valued fields in table * YAML model parser has better description handling. +* YAML model parser shows "LinkAhead" and "the yaml file" in its comparison display + instead of "old" and "new". ### Documentation ### diff --git a/CITATION.cff b/CITATION.cff index c46285346bf68c52232e775a4fa7d57538748987..6e6852194dbe364453ab71dfddfdf9244fd50ee9 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -20,6 +20,6 @@ authors: given-names: Stefan orcid: https://orcid.org/0000-0001-7214-8125 title: CaosDB - Advanced User Tools -version: 0.12.0 +version: 0.13.0 doi: 10.3390/data4020083 -date-released: 2024-07-31 \ No newline at end of file +date-released: 2025-01-16 \ No newline at end of file diff --git a/Makefile b/Makefile index 26f5c8182545b2a57b3921f3745d16ff6305a0cc..1ce56f5b7c88bcf22d731f815c2af2084bca353e 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> # Copyright (C) 2020 Daniel Hornung <d.hornung@indiscale.com> @@ -41,5 +41,5 @@ style: .PHONY: style lint: - pylint --unsafe-load-any-extension=y --fail-under=9.72 -d R,C --ignore=swagger_client src/caosadvancedtools + pylint --unsafe-load-any-extension=y -d R,C --ignore=swagger_client src/caosadvancedtools .PHONY: lint diff --git a/README_SETUP.md b/README_SETUP.md index 3a7f0197a4b06694c7ae787d0baa6e8a89de0e5e..e52885ff5d4f176cf13a79bbf37dadeb5dcea720 100644 --- a/README_SETUP.md +++ b/README_SETUP.md @@ -1,41 +1,35 @@ # Getting started -## Download -The recommended way is: -``` -# Clone the repository: -git clone 'https://gitlab.com/caosdb/caosdb-advanced-user-tools' -``` - -## Dependencies -Dependencies will be installed automatically if you use the below described -procedure. -- `caosdb>=0.6.0` -- `openpyxl>=3.0.7` -- `xlrd>=1.2.0` -- `pandas>=1.2.0` -- `numpy>=1.17.3` - -If you want to use the optional h5-crawler the following dependencies will be -installed additionally: -- `h5py>=3.3.0` - -For testing: -- `tox` +## Installation +To install the advancedtools package, you can run: +`pip install caosadvancedtools` -## Installation -- `pip install . --user` -- `pip install tox --user` +#### Additional dependencies + +To test using tox, you also need to install tox: +`pip install tox` -Optional h5-crawler: -- `pip install .[h5-crawler] --user` +To install dependencies used by optional functionality, the following pip extras +keywords are defined: +- `test` for testing with pytest +- `doc` for building the documentation +- `dev` for code formatting +- `h5` for the h5-crawler +- `all` to install all optional dependencies + +These extras can be installed using: `pip install .[KEYWORD]` + +A current list of the dependencies installed with this program as well as those installed with +the keywords can be found in `setup.py`s `setup_package()` method, in the `metadata` dictionary +entries `install_requires` and `extras_require`. ## Run Unit Tests - All tests: `tox` - One specific test with tox: `tox -- unittests/test_myusecase.py -k expression` -- Or even using only pytest: `pytest unittests/test_myusecase.py -k expression` +- Using only pytest: `pytest unittests` or for running only one test + `pytest unittests/test_myusecase.py -k expression` ## Run Integration Tests Locally @@ -60,12 +54,6 @@ with the Googly style (see link below). Build documentation in `build/` with `make doc`. -### Requirements ## - -- `sphinx` -- `sphinx-autoapi` -- `sphinx-rtd-theme` -- `recommonmark >= 0.6.0` ### How to contribute ### diff --git a/RELEASE_GUIDELINES.md b/RELEASE_GUIDELINES.md index adeab4ddf8a321bdf4e2794f07f18f5c0f4425b3..11c8444601f05d98f7a5143a32bc645364731998 100644 --- a/RELEASE_GUIDELINES.md +++ b/RELEASE_GUIDELINES.md @@ -1,7 +1,7 @@ # Release Guidelines for the CaosDB Python Client Library This document specifies release guidelines in addition to the general release -guidelines of the CaosDB Project +guidelines of the LinkAhead project ([RELEASE_GUIDELINES.md](https://gitlab.com/caosdb/caosdb/blob/dev/RELEASE_GUIDELINES.md)) ## General Prerequisites diff --git a/extra/emacs/snippets/yaml-mode/RecordType b/extra/emacs/snippets/yaml-mode/RecordType index 6b4a9c263806b6d57442470a11a2770d3d417741..8c0382d5989355b7313ded8db084846cb52bfd38 100644 --- a/extra/emacs/snippets/yaml-mode/RecordType +++ b/extra/emacs/snippets/yaml-mode/RecordType @@ -1,5 +1,5 @@ # -*- mode: snippet -*- -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2022 IndiScale GmbH <info@indiscale.com> # Copyright (C) 2022 Daniel Hornung <d.hornung@indiscale.com> diff --git a/integrationtests/clear_database.py b/integrationtests/clear_database.py index 138cf4e6abb256d5710cd2b32f55a1fb51f3fbed..b0b5020f580f7c31e1e56e262bbfa616abf52785 100644 --- a/integrationtests/clear_database.py +++ b/integrationtests/clear_database.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2020 Indiscale GmbH <info@indiscale.com> # Copyright (C) 2020 Florian Spreckelsen <f.spreckelsen@indiscale.com> @@ -23,7 +23,7 @@ # ** end header # """Clear the database before and after the integration tests.""" -import caosdb as db +import linkahead as db def clear_all(): diff --git a/integrationtests/crawl.py b/integrationtests/crawl.py index defed2cb4f5fb0a0f349898e555c5d25924e2f9b..a3e43a1954b62f83a62605348edc452135f21b99 100755 --- a/integrationtests/crawl.py +++ b/integrationtests/crawl.py @@ -2,7 +2,7 @@ # encoding: utf-8 # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2018 Research Group Biomedical Physics, # Max-Planck-Institute for Dynamics and Self-Organization Göttingen @@ -28,7 +28,7 @@ import logging import sys from argparse import RawTextHelpFormatter -import caosdb as db +import linkahead as db from caosadvancedtools.cfood import fileguide from caosadvancedtools.crawler import FileCrawler from caosadvancedtools.guard import INSERT, UPDATE diff --git a/integrationtests/create_analysis.py b/integrationtests/create_analysis.py index 1b7aa0d2d6671f14a3c65cf5ed135dfecb0aa69c..ec2c707c8740c7ec2e7340fd6e1604d6d35d9c5c 100644 --- a/integrationtests/create_analysis.py +++ b/integrationtests/create_analysis.py @@ -2,7 +2,7 @@ # encoding: utf-8 # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2021 Indiscale GmbH <info@indiscale.com> # Copyright (C) 2021 Henrik tom Wörden <h.tomwoerden@indiscale.com> @@ -31,7 +31,7 @@ automated analysis pipeline. import sys from datetime import datetime -import caosdb as db +import linkahead as db def main(): diff --git a/integrationtests/example_hdf5cfood.py b/integrationtests/example_hdf5cfood.py index 5485402d2042b2055a087b99abcba409095a7c70..736885817f2116dbd31f6cb042906ea59e518318 100644 --- a/integrationtests/example_hdf5cfood.py +++ b/integrationtests/example_hdf5cfood.py @@ -2,7 +2,7 @@ # encoding: utf-8 # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2021 IndiScale GmbH <www.indiscale.com> # Copyright (C) 2021 Henrik tom Wörden <h.tomwoerden@indiscale.com> @@ -27,7 +27,7 @@ An exemplary definition of a HDF5 CFood for integration testing """ -import caosdb as db +import linkahead as db from caosadvancedtools.cfoods.h5 import H5CFood from caosadvancedtools.scifolder import ExperimentCFood from caosadvancedtools.scifolder.generic_pattern import readme_pattern diff --git a/integrationtests/insert_model.py b/integrationtests/insert_model.py index 26bf478cdf0d3709e7c0c086fecf722b8c7f90fa..170adbc8a7fe3a3c20ee79b52994027bf6d132f9 100755 --- a/integrationtests/insert_model.py +++ b/integrationtests/insert_model.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -import caosdb as db +import linkahead as db import h5py from caosadvancedtools.cfoods.h5 import H5CFood from caosadvancedtools.models.data_model import DataModel diff --git a/integrationtests/insert_some.py b/integrationtests/insert_some.py index cf16a45ddf1f95ed261af1d9f18edfa1cbf4b450..19a4c1f2a7e2f8664aa42cda8f4acc5f8b3c3ff5 100644 --- a/integrationtests/insert_some.py +++ b/integrationtests/insert_some.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -import caosdb as db +import linkahead as db from caosadvancedtools.scifolder.experiment_cfood import dm # This inserts two identifiables. When no dependencies are possible among diff --git a/integrationtests/test.sh b/integrationtests/test.sh index a31afcfd2f74770b656eef41002b2f444b7962de..952a4dd20c4944c0106cb3450ca2ef3e609d79be 100755 --- a/integrationtests/test.sh +++ b/integrationtests/test.sh @@ -15,7 +15,7 @@ then fi OUT=/tmp/crawler.output ls -cat pycaosdb.ini +cat pylinkahead.ini python3 -c "import linkahead; print('LinkAhead Version:', linkahead.__version__)" rm -rf /tmp/caosdb_identifiable_cache.db set -e diff --git a/integrationtests/test_assure_functions.py b/integrationtests/test_assure_functions.py index e04d481f230936ae96b02fe910401f50e7138a01..91ec14401ef1772e9961acc9626ccd6ad9ac62a4 100644 --- a/integrationtests/test_assure_functions.py +++ b/integrationtests/test_assure_functions.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # encoding: utf-8 # -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2022 IndiScale GmbH <info@indiscale.com> # Copyright (C) 2021 University Medical Center Göttingen, Institute for Medical Informatics @@ -25,7 +25,7 @@ no `to_be_updated` is specified. """ -import caosdb as db +import linkahead as db from caosadvancedtools.cfood import (assure_object_is_in_list) from caosadvancedtools.guard import (global_guard, RETRIEVE, UPDATE) diff --git a/integrationtests/test_base_table_exporter_integration.py b/integrationtests/test_base_table_exporter_integration.py index 5af9caa3e83184f77c37c24073d85ee5aae2184b..0dbfc7e785be0949fb6c3c99a68225d0e5ea7c7a 100644 --- a/integrationtests/test_base_table_exporter_integration.py +++ b/integrationtests/test_base_table_exporter_integration.py @@ -2,7 +2,7 @@ # encoding: utf-8 # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2020 Indiscale GmbH <info@indiscale.com> # Copyright (C) 2020 Florian Sprecklelsen <f.spreckelsen@indiscale.com> @@ -22,7 +22,7 @@ # # ** end header # -import caosdb as db +import linkahead as db import pytest from caosadvancedtools import table_export as te @@ -82,7 +82,7 @@ def setup_module(): """Clear all test entities""" try: db.execute_query("FIND ENTITY Test*").delete() - except BaseException: + except Exception: pass diff --git a/integrationtests/test_cache.py b/integrationtests/test_cache.py index aacef1792e6028bf056093c517f45f6367f471d6..7724cfb4febd3a605419129f1250e9d2dee5e764 100644 --- a/integrationtests/test_cache.py +++ b/integrationtests/test_cache.py @@ -2,7 +2,7 @@ # encoding: utf-8 # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2020 Indiscale GmbH <info@indiscale.com> # Copyright (C) 2020 Florian Spreckelsen <f.spreckelsen@indiscale.com> @@ -26,7 +26,7 @@ import os import unittest from tempfile import NamedTemporaryFile -import caosdb as db +import linkahead as db from caosadvancedtools.cache import UpdateCache @@ -67,7 +67,7 @@ class CacheTest(unittest.TestCase): print(db.execute_query("FIND entity with id="+str(rec.id), unique=True)) try: print(db.execute_query("FIND Record "+str(rec.id), unique=True)) - except BaseException: + except Exception: print("Query does not work as expected") update.insert(cont, run_id) assert len(update.get_updates(run_id)) == 1 diff --git a/integrationtests/test_crawl_with_datamodel_problems.py b/integrationtests/test_crawl_with_datamodel_problems.py index 8623d57d60ded38987953ffaf78b1d30e15a8011..c2b19a950fa86de07470e33d39064bdf23135720 100644 --- a/integrationtests/test_crawl_with_datamodel_problems.py +++ b/integrationtests/test_crawl_with_datamodel_problems.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (c) 2020 IndiScale GmbH <info@indiscale.com> # Copyright (c) 2020 Florian Spreckelsen <f.spreckelsen@indiscale.com> @@ -25,7 +25,7 @@ """ -import caosdb as db +import linkahead as db from caosadvancedtools import loadFiles from caosadvancedtools.cfood import fileguide from caosadvancedtools.crawler import FileCrawler diff --git a/integrationtests/test_crawler_basics.py b/integrationtests/test_crawler_basics.py index 60c09d73e954c39d752b5fa4ae5e272d28000ca1..67317f32981849f4786e3b6719297d6953dffd40 100644 --- a/integrationtests/test_crawler_basics.py +++ b/integrationtests/test_crawler_basics.py @@ -2,7 +2,7 @@ # encoding: utf-8 # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2018 Research Group Biomedical Physics, # Max-Planck-Institute for Dynamics and Self-Organization Göttingen @@ -29,7 +29,7 @@ cfoods. This is tested in test_crawler_with_cfoods.py. """ import unittest -import caosdb as db +import linkahead as db from caosadvancedtools.crawler import Crawler from caosadvancedtools.guard import INSERT @@ -114,7 +114,7 @@ class CrawlerTest(unittest.TestCase): for el in [self.rec1, self.rec2, self.rec3]: try: el.delete() - except BaseException: + except Exception: pass diff --git a/integrationtests/test_crawler_with_cfoods.py b/integrationtests/test_crawler_with_cfoods.py index 1fa5eaa5a4f050d7282b863aae626982ff738c43..472eee0eead393aa6c8b7634e0f9147b1b1f35a0 100755 --- a/integrationtests/test_crawler_with_cfoods.py +++ b/integrationtests/test_crawler_with_cfoods.py @@ -2,7 +2,7 @@ # encoding: utf-8 # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2018 Research Group Biomedical Physics, # Max-Planck-Institute for Dynamics and Self-Organization Göttingen @@ -25,8 +25,8 @@ import os import unittest -import caosdb as db -from caosdb.apiutils import retrieve_entity_with_id +import linkahead as db +from linkahead.apiutils import retrieve_entity_with_id def get_entity_with_id(eid): diff --git a/integrationtests/test_data_model.py b/integrationtests/test_data_model.py index bd74a40bde2540bb57245de1de464a1bfd84bc72..bde9eda9f35e57c409c93469d25ce67029f679bd 100644 --- a/integrationtests/test_data_model.py +++ b/integrationtests/test_data_model.py @@ -1,7 +1,7 @@ import unittest import pytest -import caosdb as db +import linkahead as db from caosadvancedtools.models.data_model import DataModel diff --git a/integrationtests/test_datamodel_problems.py b/integrationtests/test_datamodel_problems.py index 855170338fbc81493e407fbe235415d60958c0f0..1ac32bb880155f723a3cbdd429aa6ad0fdbc9605 100644 --- a/integrationtests/test_datamodel_problems.py +++ b/integrationtests/test_datamodel_problems.py @@ -2,7 +2,7 @@ # encoding: utf-8 # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2020 Indiscale GmbH <info@indiscale.com> # Copyright (C) 2020 Florian Spreckelsen <f.spreckelsen@indiscale.com> @@ -27,10 +27,10 @@ during crawling that tests the integrations of the DataModelProblems class in crawler.py and cfood.py can be found in full-tests. """ -import caosdb as db +import linkahead as db import pytest from caosadvancedtools.datamodel_problems import DataModelProblems -from caosdb.exceptions import (TransactionError, +from linkahead.exceptions import (TransactionError, UnqualifiedParentsError, UnqualifiedPropertiesError) diff --git a/integrationtests/test_im_und_export.py b/integrationtests/test_im_und_export.py index 407faa1a1d3eb609ffd01b9c78d74f1c6a9b231b..5d0aa26bb6bc94de4a3857ffa72d888bc1faafc8 100644 --- a/integrationtests/test_im_und_export.py +++ b/integrationtests/test_im_und_export.py @@ -2,7 +2,7 @@ import os from tempfile import TemporaryDirectory -import caosdb as db +import linkahead as db from caosadvancedtools.export_related import export_related_to from caosadvancedtools.import_from_xml import import_xml @@ -19,7 +19,7 @@ if __name__ == "__main__": assert 0 == len(db.execute_query("FIND File which is stored at " "**/poster.pdf")) print("Importing stored elements") - import_xml(os.path.join(directory.name, "caosdb_data.xml"), interactive=False) + import_xml(os.path.join(directory.name, "linkahead_data.xml"), interactive=False) # The following tests the existence of some required entities. # However, this is not a full list. diff --git a/integrationtests/test_json_schema_datamodel_parser.py b/integrationtests/test_json_schema_datamodel_parser.py index 21ae8d2d7bad5527a7a314220b38af8ff816475f..074c4a067e4a1e3829c5760f97a8b89338a38677 100644 --- a/integrationtests/test_json_schema_datamodel_parser.py +++ b/integrationtests/test_json_schema_datamodel_parser.py @@ -1,5 +1,5 @@ # -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2022 IndiScale GmbH <info@indiscale.com> # Copyright (C) 2022 Florian Spreckelsen <f.spreckelsen@indiscale.com> @@ -20,7 +20,7 @@ import os -import caosdb as db +import linkahead as db from caosadvancedtools.models.parser import parse_model_from_json_schema diff --git a/integrationtests/test_json_schema_exporter.py b/integrationtests/test_json_schema_exporter.py index 44b428263ebbd9696fc2a171ea356d764482d5e3..5b0d758ed66ca9f641948d70c75f8c255442d5c9 100644 --- a/integrationtests/test_json_schema_exporter.py +++ b/integrationtests/test_json_schema_exporter.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # encoding: utf-8 # -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2023 Indiscale GmbH <info@indiscale.com> # Copyright (C) 2023 Florian Spreckelsen <f.spreckelsen@indiscale.com> diff --git a/integrationtests/test_table.py b/integrationtests/test_table.py index b8dfe349f3dac3be9bb741f937f2be4f73b6b2af..4e87a7dbcb8d2b14e05cd004c1d773718afe0835 100644 --- a/integrationtests/test_table.py +++ b/integrationtests/test_table.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # encoding: utf-8 # -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2020 Henrik tom Wörden # @@ -20,7 +20,7 @@ import logging -import caosdb as db +import linkahead as db import pandas as pd from caosadvancedtools.crawler import TableCrawler diff --git a/integrationtests/test_yaml_parser.py b/integrationtests/test_yaml_parser.py index e2a2c4c056ced56d2605d93914186c2cba97e137..9718c4a2a32d6f31257e58d010e54c7ae8d34f77 100644 --- a/integrationtests/test_yaml_parser.py +++ b/integrationtests/test_yaml_parser.py @@ -1,6 +1,6 @@ # encoding: utf-8 # -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2022 IndiScale GmbH <info@indiscale.com> # Copyright (C) 2022 Florian Spreckelsen <f.spreckelsen@indiscale.com> @@ -19,7 +19,7 @@ # with this program. If not, see <https://www.gnu.org/licenses/>. # -import caosdb as db +import linkahead as db from caosadvancedtools.models.parser import parse_model_from_string diff --git a/integrationtests/update_analysis.py b/integrationtests/update_analysis.py index ddebc049f449026400278a26226d341d64e678c8..18ae8332964877816be95acb4384c8b56a46bb8d 100644 --- a/integrationtests/update_analysis.py +++ b/integrationtests/update_analysis.py @@ -2,7 +2,7 @@ # encoding: utf-8 # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2021 Indiscale GmbH <info@indiscale.com> # Copyright (C) 2021 Henrik tom Wörden <h.tomwoerden@indiscale.com> @@ -34,7 +34,7 @@ entities that where changed within a certain period of time. import sys -import caosdb as db +import linkahead as db from caosadvancedtools.serverside.generic_analysis import run diff --git a/manual_tests/test_labfolder_import.py b/manual_tests/test_labfolder_import.py deleted file mode 100644 index c767feb55cdf3958343d8d9780d01fa10c70f6ec..0000000000000000000000000000000000000000 --- a/manual_tests/test_labfolder_import.py +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env python3 -# -# This file is a part of the CaosDB Project. -# -# Copyright (c) 2020 IndiScale GmbH -# Copyright (c) 2020 Daniel Hornung <d.hornung@indiscale.com> -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see <https://www.gnu.org/licenses/>. -# - -""" Imports labfolder exports """ - -import argparse -import sys - -import caosmodels -from caosmodels.parser import parse_model_from_yaml - -from caosadvancedtools.converter import labfolder_export as labfolder - - -def main(args): - """The main function.""" - model = parse_model_from_yaml("./models/model.yml") - - model.sync_data_model() - labfolder.import_data(args.folder) - - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument("folder", default="./example_labfolder_data", - nargs="?", help='folder that contains the data') - args = parser.parse_args() - sys.exit(main(args)) diff --git a/manual_tests/test_labfolder_retrieve.py b/manual_tests/test_labfolder_retrieve.py deleted file mode 100644 index 5bbaf91d0221a402e3a39246a129413adfa5f871..0000000000000000000000000000000000000000 --- a/manual_tests/test_labfolder_retrieve.py +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env python3 -# -# This file is a part of the CaosDB Project. -# -# Copyright (c) 2020 IndiScale GmbH -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see <https://www.gnu.org/licenses/>. -# - -""" Retrieve Labfolder data from API """ - -import argparse -import sys - -import caosmodels -from caosmodels.parser import parse_model_from_yaml - -from caosadvancedtools.converter.labfolder_api import Importer - - -def main(args): - """The main function.""" - model = parse_model_from_yaml("./models/model.yml") - - # model.sync_data_model() - importer = Importer() - importer.import_data() - - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument("folder", default="./example_labfolder_data", - nargs="?", help='folder that contains the data') - args = parser.parse_args() - sys.exit(main(args)) diff --git a/pylintrc b/pylintrc index d3a2e89ae1990480e5377daf443e0a63224342bc..e95afc90a55d72129f1c89ece4b935f40296989b 100644 --- a/pylintrc +++ b/pylintrc @@ -6,7 +6,7 @@ good-names=ii,rt,df # List of module names for which member attributes should not be checked # (useful for modules/projects where namespaces are manipulated during runtime # and thus existing member attributes cannot be deduced by static analysis -ignored-modules=etree,h5py,labfolder +ignored-modules=etree,h5py [MASTER] # TODO: The max_inferred size is necessary for https://github.com/PyCQA/pylint/issues/4577, @@ -19,4 +19,5 @@ init-hook= disable= fixme, logging-format-interpolation, + logging-fstring-interpolation, logging-not-lazy, diff --git a/setup.py b/setup.py index 03c515e6f65f93c9f4a2e685bf2541a8ff4bb66e..d8d28e4d18e11e8f03819e20da3b1ab84aeb5df8 100755 --- a/setup.py +++ b/setup.py @@ -46,7 +46,7 @@ from setuptools import find_packages, setup ######################################################################## MAJOR = 0 -MINOR = 12 +MINOR = 13 MICRO = 0 PRE = "" # e.g. rc0, alpha.1, 0.beta-23 ISRELEASED = True @@ -149,12 +149,12 @@ def setup_package(): metadata = dict( name='caosadvancedtools', version=get_version_info()[0], - description='advanced utilities for caosdb', + description='Advanced utilities for LinkAhead', long_description=long_description, long_description_content_type="text/markdown", author='Henrik tom Wörden', author_email='h.tomwoerden@indiscale.com', - python_requires='>=3.8', + python_requires='>=3.9', install_requires=["linkahead>=0.13.1", "jsonref", "jsonschema[format]>=4.4.0", @@ -163,15 +163,31 @@ def setup_package(): "pandas>=1.2.0", "xlrd>=2.0", ], - extras_require={"h5-crawler": ["h5py>=3.3.0", ], + extras_require={"h5": ["h5py>=3.3.0", ], "gitignore-parser": ["gitignore-parser >=0.1.0", ], + "dev": [ + "autopep8", + "pycodestyle", + "pylint", + ], + "doc": [ + "sphinx", + "sphinx-autoapi", + "sphinx-rtd-theme", + "recommonmark >= 0.6.0", + ], + "test": [ # include: h5, gitignore-parser + "pytest", + "pytest-pythonpath", + "pytest-cov", + "coverage>=4.4.2", + "caosadvancedtools[h5, gitignore-parser]", + ], + "all": [ # include: doc, test + "caosadvancedtools[dev, doc, test]", + ] }, setup_requires=["pytest-runner>=2.0,<3dev"], - tests_require=["pytest", - "pytest-pythonpath", - "pytest-cov", - "coverage>=4.4.2", - ], packages=find_packages('src'), package_dir={'': 'src'}, entry_points={"console_scripts": [ diff --git a/src/caosadvancedtools/bloxberg/__init__.py b/src/caosadvancedtools/bloxberg/__init__.py deleted file mode 100644 index 5ca50276b8fd48370fd84bd0f5358dd1e48d6b8e..0000000000000000000000000000000000000000 --- a/src/caosadvancedtools/bloxberg/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -"""Integration with the Bloxberg proof-of-existence blockchain. -""" - -print("Warning: The Bloxberg module is still experimental and under active development.") diff --git a/src/caosadvancedtools/bloxberg/bloxberg.py b/src/caosadvancedtools/bloxberg/bloxberg.py deleted file mode 100644 index 6aa2eaab94a1beb7735a09de6b22ab7745c0b078..0000000000000000000000000000000000000000 --- a/src/caosadvancedtools/bloxberg/bloxberg.py +++ /dev/null @@ -1,197 +0,0 @@ -# This file is a part of the CaosDB Project. -# -# Copyright (C) 2021 IndiScale GmbH <info@indiscale.com> -# Copyright (C) 2021 Daniel Hornung <d.hornung@indiscale.com> -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see <https://www.gnu.org/licenses/>. -"""Interaction with the Bloxberg blockchain. -""" - - -import hashlib -import json -import secrets - -import caosdb as db - -from ..models.parser import parse_model_from_string -from . import swagger_client - - -__model_yaml = """ -BloxbergCertificate: - obligatory_properties: - pepper: - datatype: TEXT - hash: - datatype: TEXT - proofValue: - datatype: TEXT - certificateJSON: - datatype: TEXT - recommended_properties: - certified: - datatype: REFERENCE -""" -__model = parse_model_from_string(__model_yaml) - - -class Bloxberg: - """A Bloxberg instance can be used to obtain or verify certificates.""" - - def __init__(self, connection=None): - """A Bloxberg instance can be used to obtain or verify certificates. - -Parameters ----------- -connection : dict -A dict with the following keys: - - url : The bloxberg URL. Default is "https://qa.certify.bloxberg.org" - """ - self._create_conf(connection) - self._api_client = swagger_client.ApiClient(configuration=self._conf) - self._api = swagger_client.CertificateApi(self._api_client) - - def _create_conf(self, connection=None): - """Generate a Swagger configuration object.""" - self._conf = swagger_client.Configuration() - if connection: - if "URL" in connection: - self._conf.host = connection["URL"] - - def certify(self, entity): - """Attempt to certify the given `entity` and return a certificate Record. - -Parameters ----------- -entity : caosdb.Entity -The entity to be certified - -Returns -------- -out : caosdb.Record -A BloxbergCertificate Record with all the necessary Properties. -""" - # Calculate hash - pepper = str(secrets.randbits(1024)) - entity.retrieve() - hasher = hashlib.sha256() - hasher.update(pepper.encode(encoding="utf8")) - hasher.update(str(entity).encode(encoding="utf8")) - entity_hash = "0x" + hasher.hexdigest() - print(entity_hash) - pubkey = "0x9858eC18a269EE69ebfD7C38eb297996827DDa98" # TODO The key of the API server? - # Create body - body = swagger_client.Batch(public_key=pubkey, crid=[entity_hash], crid_type="sha2-256", - enable_ipfs=False) - # Submit hash & obtain response - result = self._api.create_bloxberg_certificate_create_bloxberg_certificate_post(body=body) - attribute_map = result[0].attribute_map - cert = result[0].to_dict() - for old, new in attribute_map.items(): - if old == new: - continue - cert[new] = cert.pop(old) - json_s = json.dumps(cert) - # Generate result Record - cert_rec = db.Record().add_parent("BloxbergCertificate") - # Extract information and put into result - cert_rec.add_property(property="certified", value=entity) - cert_rec.add_property(property="pepper", value=pepper) - cert_rec.add_property(property="hash", value=entity_hash) - cert_rec.add_property(property="proofvalue", value=cert["proof"]["proofValue"]) - cert_rec.add_property(property="certificateJSON", value=json_s) - # Return result - return cert_rec - - def verify(self, certificate): - """Attempt to verify the certificate. - -A certificate passes verification if the Bloxberg instance says it is good. Typical use cases may -also include the `validate` step to make sure that the certificate's original data exists and -contains what it claimed to contain when the certificate was created. - -This method does nothing if the verification passes, else it raises an exception. - -Parameters ----------- -certificate : caosdb.Record -The BloxbergCertificate Record which shall be verified. - - """ - raise NotImplementedError("Bloxberg first needs to implement a verification API method.") - - @staticmethod - def json_from_certificate(certificate, filename=None): - """Generate a qa.certify.bloxberg.org JSON string, optionally writing it to a file. - -Parameters ----------- -certificate : caosdb.Record -The BloxbergCertificate Record for which the JSON is generated. - -filename : str -Write the JSON to this file. -""" - content = {} - print(certificate, filename) - - return content - - -def ensure_data_model(force=False): - """Make sure that the data model fits our needs. - - Most importantly, this means that a suitable RecordType "BoxbergCertificate" must exist. - """ - __model.sync_data_model(noquestion=force) - - -def certify_entity(entity, json_filename=None): - """Certify the given entity and store the result in the CaosDB. - -Parameters ----------- -entity : caosdb.Entity - The Entity to be certified. - -json_filename : str - If given, store the JSON here. -""" - if isinstance(entity, int): - entity = db.Entity(id=entity) - - blx = Bloxberg() - print("Obtaining certificate...") - certificate = blx.certify(entity) - print("Certificate was successfully obtained.") - certificate.insert() - print("Certificate was stored in CaosDB.") - - if json_filename: - with open(json_filename, "w") as json_file: - json_file.write(certificate.get_property("certificateJSON").value) - - -def demo_run(): - """Run the core functions for demonstration purposes.""" - print("Making sure that the remote data model is up to date.") - ensure_data_model() - print("Data model is up to date.") - CertRT = db.RecordType(name="BloxbergCertificate").retrieve() - print("Certifying the `BloxbergCertificate` RecordType...") - json_filename = "/tmp/cert.json" - certify_entity(CertRT, json_filename=json_filename) - print("Certificate json file can be found here: {}".format(json_filename)) - print("You can verify the certificate here: https://certify.bloxberg.org/verify") diff --git a/src/caosadvancedtools/bloxberg/swagger_client/__init__.py b/src/caosadvancedtools/bloxberg/swagger_client/__init__.py deleted file mode 100644 index 255d6d3124dc352f10366e22f1eb8b461ff6593d..0000000000000000000000000000000000000000 --- a/src/caosadvancedtools/bloxberg/swagger_client/__init__.py +++ /dev/null @@ -1,35 +0,0 @@ -# coding: utf-8 - -# flake8: noqa - -""" - Research Object Certification - - No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) # noqa: E501 - - OpenAPI spec version: 0.2.0 - - Generated by: https://github.com/swagger-api/swagger-codegen.git -""" - -from __future__ import absolute_import -from swagger_client.models.validation_error import ValidationError -from swagger_client.models.http_validation_error import HTTPValidationError -from swagger_client.models.controller_cert_tools_generate_unsigned_certificate_json_certificate import ControllerCertToolsGenerateUnsignedCertificateJsonCertificate -from swagger_client.models.controller_cert_tools_generate_pdf_json_certificate import ControllerCertToolsGeneratePdfJsonCertificate -from swagger_client.models.batch import Batch -from swagger_client.configuration import Configuration -from swagger_client.api_client import ApiClient -from swagger_client.api.pdf_api import PdfApi -from swagger_client.api.certificate_api import CertificateApi - -# Fake the installation -import sys -import pathlib -__this_dir = str(pathlib.Path(__file__).parent.parent) -if __this_dir not in sys.path: - sys.path.append(__this_dir) - -# import apis into sdk package -# import ApiClient -# import models into sdk package diff --git a/src/caosadvancedtools/bloxberg/swagger_client/api/__init__.py b/src/caosadvancedtools/bloxberg/swagger_client/api/__init__.py deleted file mode 100644 index d33c26ea8bc245108934d5e0e9fdcd046da3232e..0000000000000000000000000000000000000000 --- a/src/caosadvancedtools/bloxberg/swagger_client/api/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -from __future__ import absolute_import - -# flake8: noqa - -# import apis into api package -from swagger_client.api.certificate_api import CertificateApi -from swagger_client.api.pdf_api import PdfApi diff --git a/src/caosadvancedtools/bloxberg/swagger_client/api/certificate_api.py b/src/caosadvancedtools/bloxberg/swagger_client/api/certificate_api.py deleted file mode 100644 index 0f0f1c6a5a51ff4d2338df4c6e233b93fc2a950a..0000000000000000000000000000000000000000 --- a/src/caosadvancedtools/bloxberg/swagger_client/api/certificate_api.py +++ /dev/null @@ -1,132 +0,0 @@ -# coding: utf-8 - -""" - Research Object Certification - - No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) # noqa: E501 - - OpenAPI spec version: 0.2.0 - - Generated by: https://github.com/swagger-api/swagger-codegen.git -""" - -from __future__ import absolute_import - -import re # noqa: F401 - -# python 2 and python 3 compatibility library -import six - -from swagger_client.api_client import ApiClient - - -class CertificateApi(object): - """NOTE: This class is auto generated by the swagger code generator program. - - Do not edit the class manually. - Ref: https://github.com/swagger-api/swagger-codegen - """ - - def __init__(self, api_client=None): - if api_client is None: - api_client = ApiClient() - self.api_client = api_client - - def create_bloxberg_certificate_create_bloxberg_certificate_post(self, body, **kwargs): # noqa: E501 - """Createbloxbergcertificate # noqa: E501 - - Creates, transacts, and signs a research object certificate on the bloxberg blockchain. Hashes must be generated client side for each desired file and provided in an array. Each hash corresponds to one research object certificate returned in a JSON object array. # noqa: E501 - This method makes a synchronous HTTP request by default. To make an - asynchronous HTTP request, please pass async_req=True - >>> thread = api.create_bloxberg_certificate_create_bloxberg_certificate_post(body, async_req=True) - >>> result = thread.get() - - :param async_req bool - :param Batch body: (required) - :return: list[ControllerCertToolsGenerateUnsignedCertificateJsonCertificate] - If the method is called asynchronously, - returns the request thread. - """ - kwargs['_return_http_data_only'] = True - if kwargs.get('async_req'): - return self.create_bloxberg_certificate_create_bloxberg_certificate_post_with_http_info(body, **kwargs) # noqa: E501 - else: - (data) = self.create_bloxberg_certificate_create_bloxberg_certificate_post_with_http_info(body, **kwargs) # noqa: E501 - return data - - def create_bloxberg_certificate_create_bloxberg_certificate_post_with_http_info(self, body, **kwargs): # noqa: E501 - """Createbloxbergcertificate # noqa: E501 - - Creates, transacts, and signs a research object certificate on the bloxberg blockchain. Hashes must be generated client side for each desired file and provided in an array. Each hash corresponds to one research object certificate returned in a JSON object array. # noqa: E501 - This method makes a synchronous HTTP request by default. To make an - asynchronous HTTP request, please pass async_req=True - >>> thread = api.create_bloxberg_certificate_create_bloxberg_certificate_post_with_http_info(body, async_req=True) - >>> result = thread.get() - - :param async_req bool - :param Batch body: (required) - :return: list[ControllerCertToolsGenerateUnsignedCertificateJsonCertificate] - If the method is called asynchronously, - returns the request thread. - """ - - all_params = ['body'] # noqa: E501 - all_params.append('async_req') - all_params.append('_return_http_data_only') - all_params.append('_preload_content') - all_params.append('_request_timeout') - - params = locals() - for key, val in six.iteritems(params['kwargs']): - if key not in all_params: - raise TypeError( - "Got an unexpected keyword argument '%s'" - " to method create_bloxberg_certificate_create_bloxberg_certificate_post" % key - ) - params[key] = val - del params['kwargs'] - # verify the required parameter 'body' is set - if ('body' not in params or - params['body'] is None): - raise ValueError("Missing the required parameter `body` when calling `create_bloxberg_certificate_create_bloxberg_certificate_post`") # noqa: E501 - - collection_formats = {} - - path_params = {} - - query_params = [] - - header_params = {} - - form_params = [] - local_var_files = {} - - body_params = None - if 'body' in params: - body_params = params['body'] - # HTTP header `Accept` - header_params['Accept'] = self.api_client.select_header_accept( - ['application/json']) # noqa: E501 - - # HTTP header `Content-Type` - header_params['Content-Type'] = self.api_client.select_header_content_type( # noqa: E501 - ['application/json']) # noqa: E501 - - # Authentication setting - auth_settings = [] # noqa: E501 - - return self.api_client.call_api( - '/createBloxbergCertificate', 'POST', - path_params, - query_params, - header_params, - body=body_params, - post_params=form_params, - files=local_var_files, - response_type='list[ControllerCertToolsGenerateUnsignedCertificateJsonCertificate]', # noqa: E501 - auth_settings=auth_settings, - async_req=params.get('async_req'), - _return_http_data_only=params.get('_return_http_data_only'), - _preload_content=params.get('_preload_content', True), - _request_timeout=params.get('_request_timeout'), - collection_formats=collection_formats) diff --git a/src/caosadvancedtools/bloxberg/swagger_client/api/pdf_api.py b/src/caosadvancedtools/bloxberg/swagger_client/api/pdf_api.py deleted file mode 100644 index a5a279de21e45735be31eed1ce18fd7c275cf6cb..0000000000000000000000000000000000000000 --- a/src/caosadvancedtools/bloxberg/swagger_client/api/pdf_api.py +++ /dev/null @@ -1,132 +0,0 @@ -# coding: utf-8 - -""" - Research Object Certification - - No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) # noqa: E501 - - OpenAPI spec version: 0.2.0 - - Generated by: https://github.com/swagger-api/swagger-codegen.git -""" - -from __future__ import absolute_import - -import re # noqa: F401 - -# python 2 and python 3 compatibility library -import six - -from swagger_client.api_client import ApiClient - - -class PdfApi(object): - """NOTE: This class is auto generated by the swagger code generator program. - - Do not edit the class manually. - Ref: https://github.com/swagger-api/swagger-codegen - """ - - def __init__(self, api_client=None): - if api_client is None: - api_client = ApiClient() - self.api_client = api_client - - def generate_pdf_generate_pdf_post(self, body, **kwargs): # noqa: E501 - """Generatepdf # noqa: E501 - - Accepts as input the response from the createBloxbergCertificate endpoint, for example a research object JSON array. Returns as response a zip archive with PDF files that correspond to the number of cryptographic identifiers provided. PDF files are embedded with the Research Object Certification which is used for verification. # noqa: E501 - This method makes a synchronous HTTP request by default. To make an - asynchronous HTTP request, please pass async_req=True - >>> thread = api.generate_pdf_generate_pdf_post(body, async_req=True) - >>> result = thread.get() - - :param async_req bool - :param list[ControllerCertToolsGeneratePdfJsonCertificate] body: (required) - :return: Object - If the method is called asynchronously, - returns the request thread. - """ - kwargs['_return_http_data_only'] = True - if kwargs.get('async_req'): - return self.generate_pdf_generate_pdf_post_with_http_info(body, **kwargs) # noqa: E501 - else: - (data) = self.generate_pdf_generate_pdf_post_with_http_info(body, **kwargs) # noqa: E501 - return data - - def generate_pdf_generate_pdf_post_with_http_info(self, body, **kwargs): # noqa: E501 - """Generatepdf # noqa: E501 - - Accepts as input the response from the createBloxbergCertificate endpoint, for example a research object JSON array. Returns as response a zip archive with PDF files that correspond to the number of cryptographic identifiers provided. PDF files are embedded with the Research Object Certification which is used for verification. # noqa: E501 - This method makes a synchronous HTTP request by default. To make an - asynchronous HTTP request, please pass async_req=True - >>> thread = api.generate_pdf_generate_pdf_post_with_http_info(body, async_req=True) - >>> result = thread.get() - - :param async_req bool - :param list[ControllerCertToolsGeneratePdfJsonCertificate] body: (required) - :return: Object - If the method is called asynchronously, - returns the request thread. - """ - - all_params = ['body'] # noqa: E501 - all_params.append('async_req') - all_params.append('_return_http_data_only') - all_params.append('_preload_content') - all_params.append('_request_timeout') - - params = locals() - for key, val in six.iteritems(params['kwargs']): - if key not in all_params: - raise TypeError( - "Got an unexpected keyword argument '%s'" - " to method generate_pdf_generate_pdf_post" % key - ) - params[key] = val - del params['kwargs'] - # verify the required parameter 'body' is set - if ('body' not in params or - params['body'] is None): - raise ValueError("Missing the required parameter `body` when calling `generate_pdf_generate_pdf_post`") # noqa: E501 - - collection_formats = {} - - path_params = {} - - query_params = [] - - header_params = {} - - form_params = [] - local_var_files = {} - - body_params = None - if 'body' in params: - body_params = params['body'] - # HTTP header `Accept` - header_params['Accept'] = self.api_client.select_header_accept( - ['application/json']) # noqa: E501 - - # HTTP header `Content-Type` - header_params['Content-Type'] = self.api_client.select_header_content_type( # noqa: E501 - ['application/json']) # noqa: E501 - - # Authentication setting - auth_settings = [] # noqa: E501 - - return self.api_client.call_api( - '/generatePDF', 'POST', - path_params, - query_params, - header_params, - body=body_params, - post_params=form_params, - files=local_var_files, - response_type='Object', # noqa: E501 - auth_settings=auth_settings, - async_req=params.get('async_req'), - _return_http_data_only=params.get('_return_http_data_only'), - _preload_content=params.get('_preload_content', True), - _request_timeout=params.get('_request_timeout'), - collection_formats=collection_formats) diff --git a/src/caosadvancedtools/bloxberg/swagger_client/api_client.py b/src/caosadvancedtools/bloxberg/swagger_client/api_client.py deleted file mode 100644 index 7337ca334c545b2c2502a20cb5369db331149037..0000000000000000000000000000000000000000 --- a/src/caosadvancedtools/bloxberg/swagger_client/api_client.py +++ /dev/null @@ -1,628 +0,0 @@ -# coding: utf-8 -""" - Research Object Certification - - No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) # noqa: E501 - - OpenAPI spec version: 0.2.0 - - Generated by: https://github.com/swagger-api/swagger-codegen.git -""" -from __future__ import absolute_import - -import datetime -import json -import mimetypes -from multiprocessing.pool import ThreadPool -import os -import re -import tempfile - -# python 2 and python 3 compatibility library -import six -from six.moves.urllib.parse import quote - -from swagger_client.configuration import Configuration -import swagger_client.models -from swagger_client import rest - - -class ApiClient(object): - """Generic API client for Swagger client library builds. - - Swagger generic API client. This client handles the client- - server communication, and is invariant across implementations. Specifics of - the methods and models for each application are generated from the Swagger - templates. - - NOTE: This class is auto generated by the swagger code generator program. - Ref: https://github.com/swagger-api/swagger-codegen - Do not edit the class manually. - - :param configuration: .Configuration object for this client - :param header_name: a header to pass when making calls to the API. - :param header_value: a header value to pass when making calls to - the API. - :param cookie: a cookie to include in the header when making calls - to the API - """ - - PRIMITIVE_TYPES = (float, bool, bytes, six.text_type) + six.integer_types - NATIVE_TYPES_MAPPING = { - 'int': int, - 'long': int if six.PY3 else long, # noqa: F821 - 'float': float, - 'str': str, - 'bool': bool, - 'date': datetime.date, - 'datetime': datetime.datetime, - 'object': object, - } - - def __init__(self, configuration=None, header_name=None, header_value=None, - cookie=None): - if configuration is None: - configuration = Configuration() - self.configuration = configuration - - self.pool = ThreadPool() - self.rest_client = rest.RESTClientObject(configuration) - self.default_headers = {} - if header_name is not None: - self.default_headers[header_name] = header_value - self.cookie = cookie - # Set default User-Agent. - self.user_agent = 'Swagger-Codegen/1.0.0/python' - - def __del__(self): - self.pool.close() - self.pool.join() - - @property - def user_agent(self): - """User agent for this API client""" - return self.default_headers['User-Agent'] - - @user_agent.setter - def user_agent(self, value): - self.default_headers['User-Agent'] = value - - def set_default_header(self, header_name, header_value): - self.default_headers[header_name] = header_value - - def __call_api( - self, resource_path, method, path_params=None, - query_params=None, header_params=None, body=None, post_params=None, - files=None, response_type=None, auth_settings=None, - _return_http_data_only=None, collection_formats=None, - _preload_content=True, _request_timeout=None): - - config = self.configuration - - # header parameters - header_params = header_params or {} - header_params.update(self.default_headers) - if self.cookie: - header_params['Cookie'] = self.cookie - if header_params: - header_params = self.sanitize_for_serialization(header_params) - header_params = dict(self.parameters_to_tuples(header_params, - collection_formats)) - - # path parameters - if path_params: - path_params = self.sanitize_for_serialization(path_params) - path_params = self.parameters_to_tuples(path_params, - collection_formats) - for k, v in path_params: - # specified safe chars, encode everything - resource_path = resource_path.replace( - '{%s}' % k, - quote(str(v), safe=config.safe_chars_for_path_param) - ) - - # query parameters - if query_params: - query_params = self.sanitize_for_serialization(query_params) - query_params = self.parameters_to_tuples(query_params, - collection_formats) - - # post parameters - if post_params or files: - post_params = self.prepare_post_parameters(post_params, files) - post_params = self.sanitize_for_serialization(post_params) - post_params = self.parameters_to_tuples(post_params, - collection_formats) - - # auth setting - self.update_params_for_auth(header_params, query_params, auth_settings) - - # body - if body: - body = self.sanitize_for_serialization(body) - - # request url - url = self.configuration.host + resource_path - - # perform request and return response - response_data = self.request( - method, url, query_params=query_params, headers=header_params, - post_params=post_params, body=body, - _preload_content=_preload_content, - _request_timeout=_request_timeout) - - self.last_response = response_data - - return_data = response_data - if _preload_content: - # deserialize response data - if response_type: - return_data = self.deserialize(response_data, response_type) - else: - return_data = None - - if _return_http_data_only: - return (return_data) - else: - return (return_data, response_data.status, - response_data.getheaders()) - - def sanitize_for_serialization(self, obj): - """Builds a JSON POST object. - - If obj is None, return None. - If obj is str, int, long, float, bool, return directly. - If obj is datetime.datetime, datetime.date - convert to string in iso8601 format. - If obj is list, sanitize each element in the list. - If obj is dict, return the dict. - If obj is swagger model, return the properties dict. - - :param obj: The data to serialize. - :return: The serialized form of data. - """ - if obj is None: - return None - elif isinstance(obj, self.PRIMITIVE_TYPES): - return obj - elif isinstance(obj, list): - return [self.sanitize_for_serialization(sub_obj) - for sub_obj in obj] - elif isinstance(obj, tuple): - return tuple(self.sanitize_for_serialization(sub_obj) - for sub_obj in obj) - elif isinstance(obj, (datetime.datetime, datetime.date)): - return obj.isoformat() - - if isinstance(obj, dict): - obj_dict = obj - else: - # Convert model obj to dict except - # attributes `swagger_types`, `attribute_map` - # and attributes which value is not None. - # Convert attribute name to json key in - # model definition for request. - obj_dict = {obj.attribute_map[attr]: getattr(obj, attr) - for attr, _ in six.iteritems(obj.swagger_types) - if getattr(obj, attr) is not None} - - return {key: self.sanitize_for_serialization(val) - for key, val in six.iteritems(obj_dict)} - - def deserialize(self, response, response_type): - """Deserializes response into an object. - - :param response: RESTResponse object to be deserialized. - :param response_type: class literal for - deserialized object, or string of class name. - - :return: deserialized object. - """ - # handle file downloading - # save response body into a tmp file and return the instance - if response_type == "file": - return self.__deserialize_file(response) - - # fetch data from response object - try: - data = json.loads(response.data) - except ValueError: - data = response.data - - return self.__deserialize(data, response_type) - - def __deserialize(self, data, klass): - """Deserializes dict, list, str into an object. - - :param data: dict, list or str. - :param klass: class literal, or string of class name. - - :return: object. - """ - if data is None: - return None - - if type(klass) == str: - if klass.startswith('list['): - sub_kls = re.match(r'list\[(.*)\]', klass).group(1) - return [self.__deserialize(sub_data, sub_kls) - for sub_data in data] - - if klass.startswith('dict('): - sub_kls = re.match(r'dict\(([^,]*), (.*)\)', klass).group(2) - return {k: self.__deserialize(v, sub_kls) - for k, v in six.iteritems(data)} - - # convert str to class - if klass in self.NATIVE_TYPES_MAPPING: - klass = self.NATIVE_TYPES_MAPPING[klass] - else: - klass = getattr(swagger_client.models, klass) - - if klass in self.PRIMITIVE_TYPES: - return self.__deserialize_primitive(data, klass) - elif klass == object: - return self.__deserialize_object(data) - elif klass == datetime.date: - return self.__deserialize_date(data) - elif klass == datetime.datetime: - return self.__deserialize_datatime(data) - else: - return self.__deserialize_model(data, klass) - - def call_api(self, resource_path, method, - path_params=None, query_params=None, header_params=None, - body=None, post_params=None, files=None, - response_type=None, auth_settings=None, async_req=None, - _return_http_data_only=None, collection_formats=None, - _preload_content=True, _request_timeout=None): - """Makes the HTTP request (synchronous) and returns deserialized data. - - To make an async request, set the async_req parameter. - - :param resource_path: Path to method endpoint. - :param method: Method to call. - :param path_params: Path parameters in the url. - :param query_params: Query parameters in the url. - :param header_params: Header parameters to be - placed in the request header. - :param body: Request body. - :param post_params dict: Request post form parameters, - for `application/x-www-form-urlencoded`, `multipart/form-data`. - :param auth_settings list: Auth Settings names for the request. - :param response: Response data type. - :param files dict: key -> filename, value -> filepath, - for `multipart/form-data`. - :param async_req bool: execute request asynchronously - :param _return_http_data_only: response data without head status code - and headers - :param collection_formats: dict of collection formats for path, query, - header, and post parameters. - :param _preload_content: if False, the urllib3.HTTPResponse object will - be returned without reading/decoding response - data. Default is True. - :param _request_timeout: timeout setting for this request. If one - number provided, it will be total request - timeout. It can also be a pair (tuple) of - (connection, read) timeouts. - :return: - If async_req parameter is True, - the request will be called asynchronously. - The method will return the request thread. - If parameter async_req is False or missing, - then the method will return the response directly. - """ - if not async_req: - return self.__call_api(resource_path, method, - path_params, query_params, header_params, - body, post_params, files, - response_type, auth_settings, - _return_http_data_only, collection_formats, - _preload_content, _request_timeout) - else: - thread = self.pool.apply_async(self.__call_api, (resource_path, - method, path_params, query_params, - header_params, body, - post_params, files, - response_type, auth_settings, - _return_http_data_only, - collection_formats, - _preload_content, _request_timeout)) - return thread - - def request(self, method, url, query_params=None, headers=None, - post_params=None, body=None, _preload_content=True, - _request_timeout=None): - """Makes the HTTP request using RESTClient.""" - if method == "GET": - return self.rest_client.GET(url, - query_params=query_params, - _preload_content=_preload_content, - _request_timeout=_request_timeout, - headers=headers) - elif method == "HEAD": - return self.rest_client.HEAD(url, - query_params=query_params, - _preload_content=_preload_content, - _request_timeout=_request_timeout, - headers=headers) - elif method == "OPTIONS": - return self.rest_client.OPTIONS(url, - query_params=query_params, - headers=headers, - post_params=post_params, - _preload_content=_preload_content, - _request_timeout=_request_timeout, - body=body) - elif method == "POST": - return self.rest_client.POST(url, - query_params=query_params, - headers=headers, - post_params=post_params, - _preload_content=_preload_content, - _request_timeout=_request_timeout, - body=body) - elif method == "PUT": - return self.rest_client.PUT(url, - query_params=query_params, - headers=headers, - post_params=post_params, - _preload_content=_preload_content, - _request_timeout=_request_timeout, - body=body) - elif method == "PATCH": - return self.rest_client.PATCH(url, - query_params=query_params, - headers=headers, - post_params=post_params, - _preload_content=_preload_content, - _request_timeout=_request_timeout, - body=body) - elif method == "DELETE": - return self.rest_client.DELETE(url, - query_params=query_params, - headers=headers, - _preload_content=_preload_content, - _request_timeout=_request_timeout, - body=body) - else: - raise ValueError( - "http method must be `GET`, `HEAD`, `OPTIONS`," - " `POST`, `PATCH`, `PUT` or `DELETE`." - ) - - def parameters_to_tuples(self, params, collection_formats): - """Get parameters as list of tuples, formatting collections. - - :param params: Parameters as dict or list of two-tuples - :param dict collection_formats: Parameter collection formats - :return: Parameters as list of tuples, collections formatted - """ - new_params = [] - if collection_formats is None: - collection_formats = {} - for k, v in six.iteritems(params) if isinstance(params, dict) else params: # noqa: E501 - if k in collection_formats: - collection_format = collection_formats[k] - if collection_format == 'multi': - new_params.extend((k, value) for value in v) - else: - if collection_format == 'ssv': - delimiter = ' ' - elif collection_format == 'tsv': - delimiter = '\t' - elif collection_format == 'pipes': - delimiter = '|' - else: # csv is the default - delimiter = ',' - new_params.append( - (k, delimiter.join(str(value) for value in v))) - else: - new_params.append((k, v)) - return new_params - - def prepare_post_parameters(self, post_params=None, files=None): - """Builds form parameters. - - :param post_params: Normal form parameters. - :param files: File parameters. - :return: Form parameters with files. - """ - params = [] - - if post_params: - params = post_params - - if files: - for k, v in six.iteritems(files): - if not v: - continue - file_names = v if type(v) is list else [v] - for n in file_names: - with open(n, 'rb') as f: - filename = os.path.basename(f.name) - filedata = f.read() - mimetype = (mimetypes.guess_type(filename)[0] or - 'application/octet-stream') - params.append( - tuple([k, tuple([filename, filedata, mimetype])])) - - return params - - def select_header_accept(self, accepts): - """Returns `Accept` based on an array of accepts provided. - - :param accepts: List of headers. - :return: Accept (e.g. application/json). - """ - if not accepts: - return - - accepts = [x.lower() for x in accepts] - - if 'application/json' in accepts: - return 'application/json' - else: - return ', '.join(accepts) - - def select_header_content_type(self, content_types): - """Returns `Content-Type` based on an array of content_types provided. - - :param content_types: List of content-types. - :return: Content-Type (e.g. application/json). - """ - if not content_types: - return 'application/json' - - content_types = [x.lower() for x in content_types] - - if 'application/json' in content_types or '*/*' in content_types: - return 'application/json' - else: - return content_types[0] - - def update_params_for_auth(self, headers, querys, auth_settings): - """Updates header and query params based on authentication setting. - - :param headers: Header parameters dict to be updated. - :param querys: Query parameters tuple list to be updated. - :param auth_settings: Authentication setting identifiers list. - """ - if not auth_settings: - return - - for auth in auth_settings: - auth_setting = self.configuration.auth_settings().get(auth) - if auth_setting: - if not auth_setting['value']: - continue - elif auth_setting['in'] == 'header': - headers[auth_setting['key']] = auth_setting['value'] - elif auth_setting['in'] == 'query': - querys.append((auth_setting['key'], auth_setting['value'])) - else: - raise ValueError( - 'Authentication token must be in `query` or `header`' - ) - - def __deserialize_file(self, response): - """Deserializes body to file - - Saves response body into a file in a temporary folder, - using the filename from the `Content-Disposition` header if provided. - - :param response: RESTResponse. - :return: file path. - """ - fd, path = tempfile.mkstemp(dir=self.configuration.temp_folder_path) - os.close(fd) - os.remove(path) - - content_disposition = response.getheader("Content-Disposition") - if content_disposition: - filename = re.search(r'filename=[\'"]?([^\'"\s]+)[\'"]?', - content_disposition).group(1) - path = os.path.join(os.path.dirname(path), filename) - - with open(path, "wb") as f: - f.write(response.data) - - return path - - def __deserialize_primitive(self, data, klass): - """Deserializes string to primitive type. - - :param data: str. - :param klass: class literal. - - :return: int, long, float, str, bool. - """ - try: - return klass(data) - except UnicodeEncodeError: - return six.text_type(data) - except TypeError: - return data - - def __deserialize_object(self, value): - """Return a original value. - - :return: object. - """ - return value - - def __deserialize_date(self, string): - """Deserializes string to date. - - :param string: str. - :return: date. - """ - try: - from dateutil.parser import parse - return parse(string).date() - except ImportError: - return string - except ValueError: - raise rest.ApiException( - status=0, - reason="Failed to parse `{0}` as date object".format(string) - ) - - def __deserialize_datatime(self, string): - """Deserializes string to datetime. - - The string should be in iso8601 datetime format. - - :param string: str. - :return: datetime. - """ - try: - from dateutil.parser import parse - return parse(string) - except ImportError: - return string - except ValueError: - raise rest.ApiException( - status=0, - reason=( - "Failed to parse `{0}` as datetime object" - .format(string) - ) - ) - - def __hasattr(self, object, name): - return name in object.__class__.__dict__ - - def __deserialize_model(self, data, klass): - """Deserializes list or dict to model. - - :param data: dict, list. - :param klass: class literal. - :return: model object. - """ - - if not klass.swagger_types and not self.__hasattr(klass, 'get_real_child_model'): - return data - - kwargs = {} - if klass.swagger_types is not None: - for attr, attr_type in six.iteritems(klass.swagger_types): - if (data is not None and - klass.attribute_map[attr] in data and - isinstance(data, (list, dict))): - value = data[klass.attribute_map[attr]] - kwargs[attr] = self.__deserialize(value, attr_type) - - instance = klass(**kwargs) - - if (isinstance(instance, dict) and - klass.swagger_types is not None and - isinstance(data, dict)): - for key, value in data.items(): - if key not in klass.swagger_types: - instance[key] = value - if self.__hasattr(instance, 'get_real_child_model'): - klass_name = instance.get_real_child_model(data) - if klass_name: - instance = self.__deserialize(data, klass_name) - return instance diff --git a/src/caosadvancedtools/bloxberg/swagger_client/configuration.py b/src/caosadvancedtools/bloxberg/swagger_client/configuration.py deleted file mode 100644 index 2be9f6a733a030d0dea2ab43b9e85f6ed15085d8..0000000000000000000000000000000000000000 --- a/src/caosadvancedtools/bloxberg/swagger_client/configuration.py +++ /dev/null @@ -1,244 +0,0 @@ -# coding: utf-8 - -""" - Research Object Certification - - No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) # noqa: E501 - - OpenAPI spec version: 0.2.0 - - Generated by: https://github.com/swagger-api/swagger-codegen.git -""" - -from __future__ import absolute_import - -import copy -import logging -import multiprocessing -import sys -import urllib3 - -import six -from six.moves import http_client as httplib - - -class TypeWithDefault(type): - def __init__(cls, name, bases, dct): - super(TypeWithDefault, cls).__init__(name, bases, dct) - cls._default = None - - def __call__(cls): - if cls._default is None: - cls._default = type.__call__(cls) - return copy.copy(cls._default) - - def set_default(cls, default): - cls._default = copy.copy(default) - - -class Configuration(six.with_metaclass(TypeWithDefault, object)): - """NOTE: This class is auto generated by the swagger code generator program. - - Ref: https://github.com/swagger-api/swagger-codegen - Do not edit the class manually. - """ - - def __init__(self): - """Constructor""" - # Default Base url - self.host = "https://qa.certify.bloxberg.org" - # Temp file folder for downloading files - self.temp_folder_path = None - - # Authentication Settings - # dict to store API key(s) - self.api_key = {} - # dict to store API prefix (e.g. Bearer) - self.api_key_prefix = {} - # function to refresh API key if expired - self.refresh_api_key_hook = None - # Username for HTTP basic authentication - self.username = "" - # Password for HTTP basic authentication - self.password = "" - # Logging Settings - self.logger = {} - self.logger["package_logger"] = logging.getLogger("swagger_client") - self.logger["urllib3_logger"] = logging.getLogger("urllib3") - # Log format - self.logger_format = '%(asctime)s %(levelname)s %(message)s' - # Log stream handler - self.logger_stream_handler = None - # Log file handler - self.logger_file_handler = None - # Debug file location - self.logger_file = None - # Debug switch - self.debug = False - - # SSL/TLS verification - # Set this to false to skip verifying SSL certificate when calling API - # from https server. - self.verify_ssl = True - # Set this to customize the certificate file to verify the peer. - self.ssl_ca_cert = None - # client certificate file - self.cert_file = None - # client key file - self.key_file = None - # Set this to True/False to enable/disable SSL hostname verification. - self.assert_hostname = None - - # urllib3 connection pool's maximum number of connections saved - # per pool. urllib3 uses 1 connection as default value, but this is - # not the best value when you are making a lot of possibly parallel - # requests to the same host, which is often the case here. - # cpu_count * 5 is used as default value to increase performance. - self.connection_pool_maxsize = multiprocessing.cpu_count() * 5 - - # Proxy URL - self.proxy = None - # Safe chars for path_param - self.safe_chars_for_path_param = '' - - @property - def logger_file(self): - """The logger file. - - If the logger_file is None, then add stream handler and remove file - handler. Otherwise, add file handler and remove stream handler. - - :param value: The logger_file path. - :type: str - """ - return self.__logger_file - - @logger_file.setter - def logger_file(self, value): - """The logger file. - - If the logger_file is None, then add stream handler and remove file - handler. Otherwise, add file handler and remove stream handler. - - :param value: The logger_file path. - :type: str - """ - self.__logger_file = value - if self.__logger_file: - # If set logging file, - # then add file handler and remove stream handler. - self.logger_file_handler = logging.FileHandler(self.__logger_file) - self.logger_file_handler.setFormatter(self.logger_formatter) - for _, logger in six.iteritems(self.logger): - logger.addHandler(self.logger_file_handler) - if self.logger_stream_handler: - logger.removeHandler(self.logger_stream_handler) - else: - # If not set logging file, - # then add stream handler and remove file handler. - self.logger_stream_handler = logging.StreamHandler() - self.logger_stream_handler.setFormatter(self.logger_formatter) - for _, logger in six.iteritems(self.logger): - logger.addHandler(self.logger_stream_handler) - if self.logger_file_handler: - logger.removeHandler(self.logger_file_handler) - - @property - def debug(self): - """Debug status - - :param value: The debug status, True or False. - :type: bool - """ - return self.__debug - - @debug.setter - def debug(self, value): - """Debug status - - :param value: The debug status, True or False. - :type: bool - """ - self.__debug = value - if self.__debug: - # if debug status is True, turn on debug logging - for _, logger in six.iteritems(self.logger): - logger.setLevel(logging.DEBUG) - # turn on httplib debug - httplib.HTTPConnection.debuglevel = 1 - else: - # if debug status is False, turn off debug logging, - # setting log level to default `logging.WARNING` - for _, logger in six.iteritems(self.logger): - logger.setLevel(logging.WARNING) - # turn off httplib debug - httplib.HTTPConnection.debuglevel = 0 - - @property - def logger_format(self): - """The logger format. - - The logger_formatter will be updated when sets logger_format. - - :param value: The format string. - :type: str - """ - return self.__logger_format - - @logger_format.setter - def logger_format(self, value): - """The logger format. - - The logger_formatter will be updated when sets logger_format. - - :param value: The format string. - :type: str - """ - self.__logger_format = value - self.logger_formatter = logging.Formatter(self.__logger_format) - - def get_api_key_with_prefix(self, identifier): - """Gets API key (with prefix if set). - - :param identifier: The identifier of apiKey. - :return: The token for api key authentication. - """ - if self.refresh_api_key_hook: - self.refresh_api_key_hook(self) - - key = self.api_key.get(identifier) - if key: - prefix = self.api_key_prefix.get(identifier) - if prefix: - return "%s %s" % (prefix, key) - else: - return key - - def get_basic_auth_token(self): - """Gets HTTP basic authentication header (string). - - :return: The token for basic HTTP authentication. - """ - return urllib3.util.make_headers( - basic_auth=self.username + ':' + self.password - ).get('authorization') - - def auth_settings(self): - """Gets Auth Settings dict for api client. - - :return: The Auth Settings information dict. - """ - return { - } - - def to_debug_report(self): - """Gets the essential information for debugging. - - :return: The report for debugging. - """ - return "Python SDK Debug Report:\n"\ - "OS: {env}\n"\ - "Python Version: {pyversion}\n"\ - "Version of the API: 0.2.0\n"\ - "SDK Package Version: 1.0.0".\ - format(env=sys.platform, pyversion=sys.version) diff --git a/src/caosadvancedtools/bloxberg/swagger_client/models/__init__.py b/src/caosadvancedtools/bloxberg/swagger_client/models/__init__.py deleted file mode 100644 index 55b01c66f4f68f86ea6fd8bc34e61fc534d3902f..0000000000000000000000000000000000000000 --- a/src/caosadvancedtools/bloxberg/swagger_client/models/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -# coding: utf-8 - -# flake8: noqa -""" - Research Object Certification - - No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) # noqa: E501 - - OpenAPI spec version: 0.2.0 - - Generated by: https://github.com/swagger-api/swagger-codegen.git -""" - -from __future__ import absolute_import - -# import models into model package -from swagger_client.models.batch import Batch -from swagger_client.models.controller_cert_tools_generate_pdf_json_certificate import ControllerCertToolsGeneratePdfJsonCertificate -from swagger_client.models.controller_cert_tools_generate_unsigned_certificate_json_certificate import ControllerCertToolsGenerateUnsignedCertificateJsonCertificate -from swagger_client.models.http_validation_error import HTTPValidationError -from swagger_client.models.validation_error import ValidationError diff --git a/src/caosadvancedtools/bloxberg/swagger_client/models/batch.py b/src/caosadvancedtools/bloxberg/swagger_client/models/batch.py deleted file mode 100644 index 474ca01a69a6a06c93b7e9a640695fa709890997..0000000000000000000000000000000000000000 --- a/src/caosadvancedtools/bloxberg/swagger_client/models/batch.py +++ /dev/null @@ -1,228 +0,0 @@ -# coding: utf-8 - -""" - Research Object Certification - - No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) # noqa: E501 - - OpenAPI spec version: 0.2.0 - - Generated by: https://github.com/swagger-api/swagger-codegen.git -""" - -import pprint -import re # noqa: F401 - -import six - - -class Batch(object): - """NOTE: This class is auto generated by the swagger code generator program. - - Do not edit the class manually. - """ - """ - Attributes: - swagger_types (dict): The key is attribute name - and the value is attribute type. - attribute_map (dict): The key is attribute name - and the value is json key in definition. - """ - swagger_types = { - 'public_key': 'str', - 'crid': 'list[str]', - 'crid_type': 'str', - 'enable_ipfs': 'bool', - 'metadata_json': 'str' - } - - attribute_map = { - 'public_key': 'publicKey', - 'crid': 'crid', - 'crid_type': 'cridType', - 'enable_ipfs': 'enableIPFS', - 'metadata_json': 'metadataJson' - } - - def __init__(self, public_key=None, crid=None, crid_type=None, enable_ipfs=None, metadata_json=None): # noqa: E501 - """Batch - a model defined in Swagger""" # noqa: E501 - self._public_key = None - self._crid = None - self._crid_type = None - self._enable_ipfs = None - self._metadata_json = None - self.discriminator = None - self.public_key = public_key - self.crid = crid - if crid_type is not None: - self.crid_type = crid_type - self.enable_ipfs = enable_ipfs - if metadata_json is not None: - self.metadata_json = metadata_json - - @property - def public_key(self): - """Gets the public_key of this Batch. # noqa: E501 - - Public bloxberg address where the Research Object Certificate token will be minted # noqa: E501 - - :return: The public_key of this Batch. # noqa: E501 - :rtype: str - """ - return self._public_key - - @public_key.setter - def public_key(self, public_key): - """Sets the public_key of this Batch. - - Public bloxberg address where the Research Object Certificate token will be minted # noqa: E501 - - :param public_key: The public_key of this Batch. # noqa: E501 - :type: str - """ - if public_key is None: - raise ValueError("Invalid value for `public_key`, must not be `None`") # noqa: E501 - - self._public_key = public_key - - @property - def crid(self): - """Gets the crid of this Batch. # noqa: E501 - - Cryptographic Identifier of each file you wish to certify. One certificate will be generated per hash up to a maximum of 1001 in a single request # noqa: E501 - - :return: The crid of this Batch. # noqa: E501 - :rtype: list[str] - """ - return self._crid - - @crid.setter - def crid(self, crid): - """Sets the crid of this Batch. - - Cryptographic Identifier of each file you wish to certify. One certificate will be generated per hash up to a maximum of 1001 in a single request # noqa: E501 - - :param crid: The crid of this Batch. # noqa: E501 - :type: list[str] - """ - if crid is None: - raise ValueError("Invalid value for `crid`, must not be `None`") # noqa: E501 - - self._crid = crid - - @property - def crid_type(self): - """Gets the crid_type of this Batch. # noqa: E501 - - If crid is not self-describing, provide the type of cryptographic function you used to generate the cryptographic identifier. Please use the name field from the multihash list to ensure compatibility: https://github.com/multiformats/multicodec/blob/master/table.csv # noqa: E501 - - :return: The crid_type of this Batch. # noqa: E501 - :rtype: str - """ - return self._crid_type - - @crid_type.setter - def crid_type(self, crid_type): - """Sets the crid_type of this Batch. - - If crid is not self-describing, provide the type of cryptographic function you used to generate the cryptographic identifier. Please use the name field from the multihash list to ensure compatibility: https://github.com/multiformats/multicodec/blob/master/table.csv # noqa: E501 - - :param crid_type: The crid_type of this Batch. # noqa: E501 - :type: str - """ - - self._crid_type = crid_type - - @property - def enable_ipfs(self): - """Gets the enable_ipfs of this Batch. # noqa: E501 - - EXPERIMENTAL: Set to true to enable posting certificate to IPFS. If set to false, will simply return certificates in the response. By default, this is disabled on the server due to performance and storage problems with IPFS # noqa: E501 - - :return: The enable_ipfs of this Batch. # noqa: E501 - :rtype: bool - """ - return self._enable_ipfs - - @enable_ipfs.setter - def enable_ipfs(self, enable_ipfs): - """Sets the enable_ipfs of this Batch. - - EXPERIMENTAL: Set to true to enable posting certificate to IPFS. If set to false, will simply return certificates in the response. By default, this is disabled on the server due to performance and storage problems with IPFS # noqa: E501 - - :param enable_ipfs: The enable_ipfs of this Batch. # noqa: E501 - :type: bool - """ - if enable_ipfs is None: - raise ValueError("Invalid value for `enable_ipfs`, must not be `None`") # noqa: E501 - - self._enable_ipfs = enable_ipfs - - @property - def metadata_json(self): - """Gets the metadata_json of this Batch. # noqa: E501 - - Provide optional metadata to describe the research object batch in more detail that will be included in the certificate. # noqa: E501 - - :return: The metadata_json of this Batch. # noqa: E501 - :rtype: str - """ - return self._metadata_json - - @metadata_json.setter - def metadata_json(self, metadata_json): - """Sets the metadata_json of this Batch. - - Provide optional metadata to describe the research object batch in more detail that will be included in the certificate. # noqa: E501 - - :param metadata_json: The metadata_json of this Batch. # noqa: E501 - :type: str - """ - - self._metadata_json = metadata_json - - def to_dict(self): - """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.swagger_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - if issubclass(Batch, dict): - for key, value in self.items(): - result[key] = value - - return result - - def to_str(self): - """Returns the string representation of the model""" - return pprint.pformat(self.to_dict()) - - def __repr__(self): - """For `print` and `pprint`""" - return self.to_str() - - def __eq__(self, other): - """Returns true if both objects are equal""" - if not isinstance(other, Batch): - return False - - return self.__dict__ == other.__dict__ - - def __ne__(self, other): - """Returns true if both objects are not equal""" - return not self == other diff --git a/src/caosadvancedtools/bloxberg/swagger_client/models/controller_cert_tools_generate_pdf_json_certificate.py b/src/caosadvancedtools/bloxberg/swagger_client/models/controller_cert_tools_generate_pdf_json_certificate.py deleted file mode 100644 index 8c1b50d8816b09c1a466cf7d11cee1ca605dfd3a..0000000000000000000000000000000000000000 --- a/src/caosadvancedtools/bloxberg/swagger_client/models/controller_cert_tools_generate_pdf_json_certificate.py +++ /dev/null @@ -1,380 +0,0 @@ -# coding: utf-8 - -""" - Research Object Certification - - No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) # noqa: E501 - - OpenAPI spec version: 0.2.0 - - Generated by: https://github.com/swagger-api/swagger-codegen.git -""" - -import pprint -import re # noqa: F401 - -import six - - -class ControllerCertToolsGeneratePdfJsonCertificate(object): - """NOTE: This class is auto generated by the swagger code generator program. - - Do not edit the class manually. - """ - """ - Attributes: - swagger_types (dict): The key is attribute name - and the value is attribute type. - attribute_map (dict): The key is attribute name - and the value is json key in definition. - """ - swagger_types = { - 'context': 'list[str]', - 'id': 'str', - 'type': 'list[str]', - 'issuer': 'str', - 'issuance_date': 'str', - 'credential_subject': 'object', - 'display_html': 'str', - 'crid': 'str', - 'crid_type': 'str', - 'metadata_json': 'str', - 'proof': 'object' - } - - attribute_map = { - 'context': '@context', - 'id': 'id', - 'type': 'type', - 'issuer': 'issuer', - 'issuance_date': 'issuanceDate', - 'credential_subject': 'credentialSubject', - 'display_html': 'displayHtml', - 'crid': 'crid', - 'crid_type': 'cridType', - 'metadata_json': 'metadataJson', - 'proof': 'proof' - } - - def __init__(self, context=None, id=None, type=None, issuer=None, issuance_date=None, credential_subject=None, display_html=None, crid=None, crid_type=None, metadata_json=None, proof=None): # noqa: E501 - """ControllerCertToolsGeneratePdfJsonCertificate - a model defined in Swagger""" # noqa: E501 - self._context = None - self._id = None - self._type = None - self._issuer = None - self._issuance_date = None - self._credential_subject = None - self._display_html = None - self._crid = None - self._crid_type = None - self._metadata_json = None - self._proof = None - self.discriminator = None - if context is not None: - self.context = context - self.id = id - self.type = type - self.issuer = issuer - self.issuance_date = issuance_date - self.credential_subject = credential_subject - if display_html is not None: - self.display_html = display_html - self.crid = crid - if crid_type is not None: - self.crid_type = crid_type - if metadata_json is not None: - self.metadata_json = metadata_json - self.proof = proof - - @property - def context(self): - """Gets the context of this ControllerCertToolsGeneratePdfJsonCertificate. # noqa: E501 - - Relevant JSON-LD context links in order to validate Verifiable Credentials according to their spec. # noqa: E501 - - :return: The context of this ControllerCertToolsGeneratePdfJsonCertificate. # noqa: E501 - :rtype: list[str] - """ - return self._context - - @context.setter - def context(self, context): - """Sets the context of this ControllerCertToolsGeneratePdfJsonCertificate. - - Relevant JSON-LD context links in order to validate Verifiable Credentials according to their spec. # noqa: E501 - - :param context: The context of this ControllerCertToolsGeneratePdfJsonCertificate. # noqa: E501 - :type: list[str] - """ - - self._context = context - - @property - def id(self): - """Gets the id of this ControllerCertToolsGeneratePdfJsonCertificate. # noqa: E501 - - - :return: The id of this ControllerCertToolsGeneratePdfJsonCertificate. # noqa: E501 - :rtype: str - """ - return self._id - - @id.setter - def id(self, id): - """Sets the id of this ControllerCertToolsGeneratePdfJsonCertificate. - - - :param id: The id of this ControllerCertToolsGeneratePdfJsonCertificate. # noqa: E501 - :type: str - """ - if id is None: - raise ValueError("Invalid value for `id`, must not be `None`") # noqa: E501 - - self._id = id - - @property - def type(self): - """Gets the type of this ControllerCertToolsGeneratePdfJsonCertificate. # noqa: E501 - - - :return: The type of this ControllerCertToolsGeneratePdfJsonCertificate. # noqa: E501 - :rtype: list[str] - """ - return self._type - - @type.setter - def type(self, type): - """Sets the type of this ControllerCertToolsGeneratePdfJsonCertificate. - - - :param type: The type of this ControllerCertToolsGeneratePdfJsonCertificate. # noqa: E501 - :type: list[str] - """ - if type is None: - raise ValueError("Invalid value for `type`, must not be `None`") # noqa: E501 - - self._type = type - - @property - def issuer(self): - """Gets the issuer of this ControllerCertToolsGeneratePdfJsonCertificate. # noqa: E501 - - - :return: The issuer of this ControllerCertToolsGeneratePdfJsonCertificate. # noqa: E501 - :rtype: str - """ - return self._issuer - - @issuer.setter - def issuer(self, issuer): - """Sets the issuer of this ControllerCertToolsGeneratePdfJsonCertificate. - - - :param issuer: The issuer of this ControllerCertToolsGeneratePdfJsonCertificate. # noqa: E501 - :type: str - """ - if issuer is None: - raise ValueError("Invalid value for `issuer`, must not be `None`") # noqa: E501 - - self._issuer = issuer - - @property - def issuance_date(self): - """Gets the issuance_date of this ControllerCertToolsGeneratePdfJsonCertificate. # noqa: E501 - - - :return: The issuance_date of this ControllerCertToolsGeneratePdfJsonCertificate. # noqa: E501 - :rtype: str - """ - return self._issuance_date - - @issuance_date.setter - def issuance_date(self, issuance_date): - """Sets the issuance_date of this ControllerCertToolsGeneratePdfJsonCertificate. - - - :param issuance_date: The issuance_date of this ControllerCertToolsGeneratePdfJsonCertificate. # noqa: E501 - :type: str - """ - if issuance_date is None: - raise ValueError("Invalid value for `issuance_date`, must not be `None`") # noqa: E501 - - self._issuance_date = issuance_date - - @property - def credential_subject(self): - """Gets the credential_subject of this ControllerCertToolsGeneratePdfJsonCertificate. # noqa: E501 - - - :return: The credential_subject of this ControllerCertToolsGeneratePdfJsonCertificate. # noqa: E501 - :rtype: object - """ - return self._credential_subject - - @credential_subject.setter - def credential_subject(self, credential_subject): - """Sets the credential_subject of this ControllerCertToolsGeneratePdfJsonCertificate. - - - :param credential_subject: The credential_subject of this ControllerCertToolsGeneratePdfJsonCertificate. # noqa: E501 - :type: object - """ - if credential_subject is None: - raise ValueError("Invalid value for `credential_subject`, must not be `None`") # noqa: E501 - - self._credential_subject = credential_subject - - @property - def display_html(self): - """Gets the display_html of this ControllerCertToolsGeneratePdfJsonCertificate. # noqa: E501 - - - :return: The display_html of this ControllerCertToolsGeneratePdfJsonCertificate. # noqa: E501 - :rtype: str - """ - return self._display_html - - @display_html.setter - def display_html(self, display_html): - """Sets the display_html of this ControllerCertToolsGeneratePdfJsonCertificate. - - - :param display_html: The display_html of this ControllerCertToolsGeneratePdfJsonCertificate. # noqa: E501 - :type: str - """ - - self._display_html = display_html - - @property - def crid(self): - """Gets the crid of this ControllerCertToolsGeneratePdfJsonCertificate. # noqa: E501 - - - :return: The crid of this ControllerCertToolsGeneratePdfJsonCertificate. # noqa: E501 - :rtype: str - """ - return self._crid - - @crid.setter - def crid(self, crid): - """Sets the crid of this ControllerCertToolsGeneratePdfJsonCertificate. - - - :param crid: The crid of this ControllerCertToolsGeneratePdfJsonCertificate. # noqa: E501 - :type: str - """ - if crid is None: - raise ValueError("Invalid value for `crid`, must not be `None`") # noqa: E501 - - self._crid = crid - - @property - def crid_type(self): - """Gets the crid_type of this ControllerCertToolsGeneratePdfJsonCertificate. # noqa: E501 - - - :return: The crid_type of this ControllerCertToolsGeneratePdfJsonCertificate. # noqa: E501 - :rtype: str - """ - return self._crid_type - - @crid_type.setter - def crid_type(self, crid_type): - """Sets the crid_type of this ControllerCertToolsGeneratePdfJsonCertificate. - - - :param crid_type: The crid_type of this ControllerCertToolsGeneratePdfJsonCertificate. # noqa: E501 - :type: str - """ - - self._crid_type = crid_type - - @property - def metadata_json(self): - """Gets the metadata_json of this ControllerCertToolsGeneratePdfJsonCertificate. # noqa: E501 - - - :return: The metadata_json of this ControllerCertToolsGeneratePdfJsonCertificate. # noqa: E501 - :rtype: str - """ - return self._metadata_json - - @metadata_json.setter - def metadata_json(self, metadata_json): - """Sets the metadata_json of this ControllerCertToolsGeneratePdfJsonCertificate. - - - :param metadata_json: The metadata_json of this ControllerCertToolsGeneratePdfJsonCertificate. # noqa: E501 - :type: str - """ - - self._metadata_json = metadata_json - - @property - def proof(self): - """Gets the proof of this ControllerCertToolsGeneratePdfJsonCertificate. # noqa: E501 - - - :return: The proof of this ControllerCertToolsGeneratePdfJsonCertificate. # noqa: E501 - :rtype: object - """ - return self._proof - - @proof.setter - def proof(self, proof): - """Sets the proof of this ControllerCertToolsGeneratePdfJsonCertificate. - - - :param proof: The proof of this ControllerCertToolsGeneratePdfJsonCertificate. # noqa: E501 - :type: object - """ - if proof is None: - raise ValueError("Invalid value for `proof`, must not be `None`") # noqa: E501 - - self._proof = proof - - def to_dict(self): - """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.swagger_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - if issubclass(ControllerCertToolsGeneratePdfJsonCertificate, dict): - for key, value in self.items(): - result[key] = value - - return result - - def to_str(self): - """Returns the string representation of the model""" - return pprint.pformat(self.to_dict()) - - def __repr__(self): - """For `print` and `pprint`""" - return self.to_str() - - def __eq__(self, other): - """Returns true if both objects are equal""" - if not isinstance(other, ControllerCertToolsGeneratePdfJsonCertificate): - return False - - return self.__dict__ == other.__dict__ - - def __ne__(self, other): - """Returns true if both objects are not equal""" - return not self == other diff --git a/src/caosadvancedtools/bloxberg/swagger_client/models/controller_cert_tools_generate_unsigned_certificate_json_certificate.py b/src/caosadvancedtools/bloxberg/swagger_client/models/controller_cert_tools_generate_unsigned_certificate_json_certificate.py deleted file mode 100644 index fa0da3cb0c09e384cdddbd4ce458a4baf14f4b5d..0000000000000000000000000000000000000000 --- a/src/caosadvancedtools/bloxberg/swagger_client/models/controller_cert_tools_generate_unsigned_certificate_json_certificate.py +++ /dev/null @@ -1,380 +0,0 @@ -# coding: utf-8 - -""" - Research Object Certification - - No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) # noqa: E501 - - OpenAPI spec version: 0.2.0 - - Generated by: https://github.com/swagger-api/swagger-codegen.git -""" - -import pprint -import re # noqa: F401 - -import six - - -class ControllerCertToolsGenerateUnsignedCertificateJsonCertificate(object): - """NOTE: This class is auto generated by the swagger code generator program. - - Do not edit the class manually. - """ - """ - Attributes: - swagger_types (dict): The key is attribute name - and the value is attribute type. - attribute_map (dict): The key is attribute name - and the value is json key in definition. - """ - swagger_types = { - 'context': 'list[str]', - 'id': 'str', - 'type': 'list[str]', - 'issuer': 'str', - 'issuance_date': 'str', - 'credential_subject': 'object', - 'display_html': 'str', - 'crid': 'str', - 'crid_type': 'str', - 'metadata_json': 'str', - 'proof': 'object' - } - - attribute_map = { - 'context': '@context', - 'id': 'id', - 'type': 'type', - 'issuer': 'issuer', - 'issuance_date': 'issuanceDate', - 'credential_subject': 'credentialSubject', - 'display_html': 'displayHtml', - 'crid': 'crid', - 'crid_type': 'cridType', - 'metadata_json': 'metadataJson', - 'proof': 'proof' - } - - def __init__(self, context=None, id=None, type=None, issuer=None, issuance_date=None, credential_subject=None, display_html=None, crid=None, crid_type=None, metadata_json=None, proof=None): # noqa: E501 - """ControllerCertToolsGenerateUnsignedCertificateJsonCertificate - a model defined in Swagger""" # noqa: E501 - self._context = None - self._id = None - self._type = None - self._issuer = None - self._issuance_date = None - self._credential_subject = None - self._display_html = None - self._crid = None - self._crid_type = None - self._metadata_json = None - self._proof = None - self.discriminator = None - if context is not None: - self.context = context - self.id = id - self.type = type - self.issuer = issuer - self.issuance_date = issuance_date - self.credential_subject = credential_subject - if display_html is not None: - self.display_html = display_html - self.crid = crid - if crid_type is not None: - self.crid_type = crid_type - if metadata_json is not None: - self.metadata_json = metadata_json - self.proof = proof - - @property - def context(self): - """Gets the context of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. # noqa: E501 - - Relevant JSON-LD context links in order to validate Verifiable Credentials according to their spec. # noqa: E501 - - :return: The context of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. # noqa: E501 - :rtype: list[str] - """ - return self._context - - @context.setter - def context(self, context): - """Sets the context of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. - - Relevant JSON-LD context links in order to validate Verifiable Credentials according to their spec. # noqa: E501 - - :param context: The context of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. # noqa: E501 - :type: list[str] - """ - - self._context = context - - @property - def id(self): - """Gets the id of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. # noqa: E501 - - - :return: The id of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. # noqa: E501 - :rtype: str - """ - return self._id - - @id.setter - def id(self, id): - """Sets the id of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. - - - :param id: The id of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. # noqa: E501 - :type: str - """ - if id is None: - raise ValueError("Invalid value for `id`, must not be `None`") # noqa: E501 - - self._id = id - - @property - def type(self): - """Gets the type of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. # noqa: E501 - - - :return: The type of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. # noqa: E501 - :rtype: list[str] - """ - return self._type - - @type.setter - def type(self, type): - """Sets the type of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. - - - :param type: The type of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. # noqa: E501 - :type: list[str] - """ - if type is None: - raise ValueError("Invalid value for `type`, must not be `None`") # noqa: E501 - - self._type = type - - @property - def issuer(self): - """Gets the issuer of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. # noqa: E501 - - - :return: The issuer of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. # noqa: E501 - :rtype: str - """ - return self._issuer - - @issuer.setter - def issuer(self, issuer): - """Sets the issuer of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. - - - :param issuer: The issuer of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. # noqa: E501 - :type: str - """ - if issuer is None: - raise ValueError("Invalid value for `issuer`, must not be `None`") # noqa: E501 - - self._issuer = issuer - - @property - def issuance_date(self): - """Gets the issuance_date of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. # noqa: E501 - - - :return: The issuance_date of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. # noqa: E501 - :rtype: str - """ - return self._issuance_date - - @issuance_date.setter - def issuance_date(self, issuance_date): - """Sets the issuance_date of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. - - - :param issuance_date: The issuance_date of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. # noqa: E501 - :type: str - """ - if issuance_date is None: - raise ValueError("Invalid value for `issuance_date`, must not be `None`") # noqa: E501 - - self._issuance_date = issuance_date - - @property - def credential_subject(self): - """Gets the credential_subject of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. # noqa: E501 - - - :return: The credential_subject of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. # noqa: E501 - :rtype: object - """ - return self._credential_subject - - @credential_subject.setter - def credential_subject(self, credential_subject): - """Sets the credential_subject of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. - - - :param credential_subject: The credential_subject of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. # noqa: E501 - :type: object - """ - if credential_subject is None: - raise ValueError("Invalid value for `credential_subject`, must not be `None`") # noqa: E501 - - self._credential_subject = credential_subject - - @property - def display_html(self): - """Gets the display_html of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. # noqa: E501 - - - :return: The display_html of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. # noqa: E501 - :rtype: str - """ - return self._display_html - - @display_html.setter - def display_html(self, display_html): - """Sets the display_html of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. - - - :param display_html: The display_html of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. # noqa: E501 - :type: str - """ - - self._display_html = display_html - - @property - def crid(self): - """Gets the crid of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. # noqa: E501 - - - :return: The crid of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. # noqa: E501 - :rtype: str - """ - return self._crid - - @crid.setter - def crid(self, crid): - """Sets the crid of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. - - - :param crid: The crid of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. # noqa: E501 - :type: str - """ - if crid is None: - raise ValueError("Invalid value for `crid`, must not be `None`") # noqa: E501 - - self._crid = crid - - @property - def crid_type(self): - """Gets the crid_type of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. # noqa: E501 - - - :return: The crid_type of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. # noqa: E501 - :rtype: str - """ - return self._crid_type - - @crid_type.setter - def crid_type(self, crid_type): - """Sets the crid_type of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. - - - :param crid_type: The crid_type of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. # noqa: E501 - :type: str - """ - - self._crid_type = crid_type - - @property - def metadata_json(self): - """Gets the metadata_json of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. # noqa: E501 - - - :return: The metadata_json of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. # noqa: E501 - :rtype: str - """ - return self._metadata_json - - @metadata_json.setter - def metadata_json(self, metadata_json): - """Sets the metadata_json of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. - - - :param metadata_json: The metadata_json of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. # noqa: E501 - :type: str - """ - - self._metadata_json = metadata_json - - @property - def proof(self): - """Gets the proof of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. # noqa: E501 - - - :return: The proof of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. # noqa: E501 - :rtype: object - """ - return self._proof - - @proof.setter - def proof(self, proof): - """Sets the proof of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. - - - :param proof: The proof of this ControllerCertToolsGenerateUnsignedCertificateJsonCertificate. # noqa: E501 - :type: object - """ - if proof is None: - raise ValueError("Invalid value for `proof`, must not be `None`") # noqa: E501 - - self._proof = proof - - def to_dict(self): - """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.swagger_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - if issubclass(ControllerCertToolsGenerateUnsignedCertificateJsonCertificate, dict): - for key, value in self.items(): - result[key] = value - - return result - - def to_str(self): - """Returns the string representation of the model""" - return pprint.pformat(self.to_dict()) - - def __repr__(self): - """For `print` and `pprint`""" - return self.to_str() - - def __eq__(self, other): - """Returns true if both objects are equal""" - if not isinstance(other, ControllerCertToolsGenerateUnsignedCertificateJsonCertificate): - return False - - return self.__dict__ == other.__dict__ - - def __ne__(self, other): - """Returns true if both objects are not equal""" - return not self == other diff --git a/src/caosadvancedtools/bloxberg/swagger_client/models/http_validation_error.py b/src/caosadvancedtools/bloxberg/swagger_client/models/http_validation_error.py deleted file mode 100644 index 67c23fba87467a7888bff82fc7f11e9d90e15f15..0000000000000000000000000000000000000000 --- a/src/caosadvancedtools/bloxberg/swagger_client/models/http_validation_error.py +++ /dev/null @@ -1,111 +0,0 @@ -# coding: utf-8 - -""" - Research Object Certification - - No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) # noqa: E501 - - OpenAPI spec version: 0.2.0 - - Generated by: https://github.com/swagger-api/swagger-codegen.git -""" - -import pprint -import re # noqa: F401 - -import six - - -class HTTPValidationError(object): - """NOTE: This class is auto generated by the swagger code generator program. - - Do not edit the class manually. - """ - """ - Attributes: - swagger_types (dict): The key is attribute name - and the value is attribute type. - attribute_map (dict): The key is attribute name - and the value is json key in definition. - """ - swagger_types = { - 'detail': 'list[ValidationError]' - } - - attribute_map = { - 'detail': 'detail' - } - - def __init__(self, detail=None): # noqa: E501 - """HTTPValidationError - a model defined in Swagger""" # noqa: E501 - self._detail = None - self.discriminator = None - if detail is not None: - self.detail = detail - - @property - def detail(self): - """Gets the detail of this HTTPValidationError. # noqa: E501 - - - :return: The detail of this HTTPValidationError. # noqa: E501 - :rtype: list[ValidationError] - """ - return self._detail - - @detail.setter - def detail(self, detail): - """Sets the detail of this HTTPValidationError. - - - :param detail: The detail of this HTTPValidationError. # noqa: E501 - :type: list[ValidationError] - """ - - self._detail = detail - - def to_dict(self): - """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.swagger_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - if issubclass(HTTPValidationError, dict): - for key, value in self.items(): - result[key] = value - - return result - - def to_str(self): - """Returns the string representation of the model""" - return pprint.pformat(self.to_dict()) - - def __repr__(self): - """For `print` and `pprint`""" - return self.to_str() - - def __eq__(self, other): - """Returns true if both objects are equal""" - if not isinstance(other, HTTPValidationError): - return False - - return self.__dict__ == other.__dict__ - - def __ne__(self, other): - """Returns true if both objects are not equal""" - return not self == other diff --git a/src/caosadvancedtools/bloxberg/swagger_client/models/validation_error.py b/src/caosadvancedtools/bloxberg/swagger_client/models/validation_error.py deleted file mode 100644 index 96d1e23734698efbdad8423c33012473e9aac03b..0000000000000000000000000000000000000000 --- a/src/caosadvancedtools/bloxberg/swagger_client/models/validation_error.py +++ /dev/null @@ -1,166 +0,0 @@ -# coding: utf-8 - -""" - Research Object Certification - - No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) # noqa: E501 - - OpenAPI spec version: 0.2.0 - - Generated by: https://github.com/swagger-api/swagger-codegen.git -""" - -import pprint -import re # noqa: F401 - -import six - - -class ValidationError(object): - """NOTE: This class is auto generated by the swagger code generator program. - - Do not edit the class manually. - """ - """ - Attributes: - swagger_types (dict): The key is attribute name - and the value is attribute type. - attribute_map (dict): The key is attribute name - and the value is json key in definition. - """ - swagger_types = { - 'loc': 'list[str]', - 'msg': 'str', - 'type': 'str' - } - - attribute_map = { - 'loc': 'loc', - 'msg': 'msg', - 'type': 'type' - } - - def __init__(self, loc=None, msg=None, type=None): # noqa: E501 - """ValidationError - a model defined in Swagger""" # noqa: E501 - self._loc = None - self._msg = None - self._type = None - self.discriminator = None - self.loc = loc - self.msg = msg - self.type = type - - @property - def loc(self): - """Gets the loc of this ValidationError. # noqa: E501 - - - :return: The loc of this ValidationError. # noqa: E501 - :rtype: list[str] - """ - return self._loc - - @loc.setter - def loc(self, loc): - """Sets the loc of this ValidationError. - - - :param loc: The loc of this ValidationError. # noqa: E501 - :type: list[str] - """ - if loc is None: - raise ValueError("Invalid value for `loc`, must not be `None`") # noqa: E501 - - self._loc = loc - - @property - def msg(self): - """Gets the msg of this ValidationError. # noqa: E501 - - - :return: The msg of this ValidationError. # noqa: E501 - :rtype: str - """ - return self._msg - - @msg.setter - def msg(self, msg): - """Sets the msg of this ValidationError. - - - :param msg: The msg of this ValidationError. # noqa: E501 - :type: str - """ - if msg is None: - raise ValueError("Invalid value for `msg`, must not be `None`") # noqa: E501 - - self._msg = msg - - @property - def type(self): - """Gets the type of this ValidationError. # noqa: E501 - - - :return: The type of this ValidationError. # noqa: E501 - :rtype: str - """ - return self._type - - @type.setter - def type(self, type): - """Sets the type of this ValidationError. - - - :param type: The type of this ValidationError. # noqa: E501 - :type: str - """ - if type is None: - raise ValueError("Invalid value for `type`, must not be `None`") # noqa: E501 - - self._type = type - - def to_dict(self): - """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.swagger_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - if issubclass(ValidationError, dict): - for key, value in self.items(): - result[key] = value - - return result - - def to_str(self): - """Returns the string representation of the model""" - return pprint.pformat(self.to_dict()) - - def __repr__(self): - """For `print` and `pprint`""" - return self.to_str() - - def __eq__(self, other): - """Returns true if both objects are equal""" - if not isinstance(other, ValidationError): - return False - - return self.__dict__ == other.__dict__ - - def __ne__(self, other): - """Returns true if both objects are not equal""" - return not self == other diff --git a/src/caosadvancedtools/bloxberg/swagger_client/rest.py b/src/caosadvancedtools/bloxberg/swagger_client/rest.py deleted file mode 100644 index c42e720c284832da70996e0eb885f6ffdcbb52d2..0000000000000000000000000000000000000000 --- a/src/caosadvancedtools/bloxberg/swagger_client/rest.py +++ /dev/null @@ -1,322 +0,0 @@ -# coding: utf-8 - -""" - Research Object Certification - - No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) # noqa: E501 - - OpenAPI spec version: 0.2.0 - - Generated by: https://github.com/swagger-api/swagger-codegen.git -""" - -from __future__ import absolute_import - -import io -import json -import logging -import re -import ssl - -import certifi -# python 2 and python 3 compatibility library -import six -from six.moves.urllib.parse import urlencode - -try: - import urllib3 -except ImportError: - raise ImportError('Swagger python client requires urllib3.') - - -logger = logging.getLogger(__name__) - - -class RESTResponse(io.IOBase): - - def __init__(self, resp): - self.urllib3_response = resp - self.status = resp.status - self.reason = resp.reason - self.data = resp.data - - def getheaders(self): - """Returns a dictionary of the response headers.""" - return self.urllib3_response.getheaders() - - def getheader(self, name, default=None): - """Returns a given response header.""" - return self.urllib3_response.getheader(name, default) - - -class RESTClientObject(object): - - def __init__(self, configuration, pools_size=4, maxsize=None): - # urllib3.PoolManager will pass all kw parameters to connectionpool - # https://github.com/shazow/urllib3/blob/f9409436f83aeb79fbaf090181cd81b784f1b8ce/urllib3/poolmanager.py#L75 # noqa: E501 - # https://github.com/shazow/urllib3/blob/f9409436f83aeb79fbaf090181cd81b784f1b8ce/urllib3/connectionpool.py#L680 # noqa: E501 - # maxsize is the number of requests to host that are allowed in parallel # noqa: E501 - # Custom SSL certificates and client certificates: http://urllib3.readthedocs.io/en/latest/advanced-usage.html # noqa: E501 - - # cert_reqs - if configuration.verify_ssl: - cert_reqs = ssl.CERT_REQUIRED - else: - cert_reqs = ssl.CERT_NONE - - # ca_certs - if configuration.ssl_ca_cert: - ca_certs = configuration.ssl_ca_cert - else: - # if not set certificate file, use Mozilla's root certificates. - ca_certs = certifi.where() - - addition_pool_args = {} - if configuration.assert_hostname is not None: - addition_pool_args['assert_hostname'] = configuration.assert_hostname # noqa: E501 - - if maxsize is None: - if configuration.connection_pool_maxsize is not None: - maxsize = configuration.connection_pool_maxsize - else: - maxsize = 4 - - # https pool manager - if configuration.proxy: - self.pool_manager = urllib3.ProxyManager( - num_pools=pools_size, - maxsize=maxsize, - cert_reqs=cert_reqs, - ca_certs=ca_certs, - cert_file=configuration.cert_file, - key_file=configuration.key_file, - proxy_url=configuration.proxy, - **addition_pool_args - ) - else: - self.pool_manager = urllib3.PoolManager( - num_pools=pools_size, - maxsize=maxsize, - cert_reqs=cert_reqs, - ca_certs=ca_certs, - cert_file=configuration.cert_file, - key_file=configuration.key_file, - **addition_pool_args - ) - - def request(self, method, url, query_params=None, headers=None, - body=None, post_params=None, _preload_content=True, - _request_timeout=None): - """Perform requests. - - :param method: http request method - :param url: http request url - :param query_params: query parameters in the url - :param headers: http request headers - :param body: request json body, for `application/json` - :param post_params: request post parameters, - `application/x-www-form-urlencoded` - and `multipart/form-data` - :param _preload_content: if False, the urllib3.HTTPResponse object will - be returned without reading/decoding response - data. Default is True. - :param _request_timeout: timeout setting for this request. If one - number provided, it will be total request - timeout. It can also be a pair (tuple) of - (connection, read) timeouts. - """ - method = method.upper() - assert method in ['GET', 'HEAD', 'DELETE', 'POST', 'PUT', - 'PATCH', 'OPTIONS'] - - if post_params and body: - raise ValueError( - "body parameter cannot be used with post_params parameter." - ) - - post_params = post_params or {} - headers = headers or {} - - timeout = None - if _request_timeout: - if isinstance(_request_timeout, (int, ) if six.PY3 else (int, long)): # noqa: E501,F821 - timeout = urllib3.Timeout(total=_request_timeout) - elif (isinstance(_request_timeout, tuple) and - len(_request_timeout) == 2): - timeout = urllib3.Timeout( - connect=_request_timeout[0], read=_request_timeout[1]) - - if 'Content-Type' not in headers: - headers['Content-Type'] = 'application/json' - - try: - # For `POST`, `PUT`, `PATCH`, `OPTIONS`, `DELETE` - if method in ['POST', 'PUT', 'PATCH', 'OPTIONS', 'DELETE']: - if query_params: - url += '?' + urlencode(query_params) - if re.search('json', headers['Content-Type'], re.IGNORECASE): - request_body = '{}' - if body is not None: - request_body = json.dumps(body) - r = self.pool_manager.request( - method, url, - body=request_body, - preload_content=_preload_content, - timeout=timeout, - headers=headers) - elif headers['Content-Type'] == 'application/x-www-form-urlencoded': # noqa: E501 - r = self.pool_manager.request( - method, url, - fields=post_params, - encode_multipart=False, - preload_content=_preload_content, - timeout=timeout, - headers=headers) - elif headers['Content-Type'] == 'multipart/form-data': - # must del headers['Content-Type'], or the correct - # Content-Type which generated by urllib3 will be - # overwritten. - del headers['Content-Type'] - r = self.pool_manager.request( - method, url, - fields=post_params, - encode_multipart=True, - preload_content=_preload_content, - timeout=timeout, - headers=headers) - # Pass a `string` parameter directly in the body to support - # other content types than Json when `body` argument is - # provided in serialized form - elif isinstance(body, str): - request_body = body - r = self.pool_manager.request( - method, url, - body=request_body, - preload_content=_preload_content, - timeout=timeout, - headers=headers) - else: - # Cannot generate the request from given parameters - msg = """Cannot prepare a request message for provided - arguments. Please check that your arguments match - declared content type.""" - raise ApiException(status=0, reason=msg) - # For `GET`, `HEAD` - else: - r = self.pool_manager.request(method, url, - fields=query_params, - preload_content=_preload_content, - timeout=timeout, - headers=headers) - except urllib3.exceptions.SSLError as e: - msg = "{0}\n{1}".format(type(e).__name__, str(e)) - raise ApiException(status=0, reason=msg) - - if _preload_content: - r = RESTResponse(r) - - # In the python 3, the response.data is bytes. - # we need to decode it to string. - if six.PY3: - r.data = r.data.decode('utf8') - - # log response body - logger.debug("response body: %s", r.data) - - if not 200 <= r.status <= 299: - raise ApiException(http_resp=r) - - return r - - def GET(self, url, headers=None, query_params=None, _preload_content=True, - _request_timeout=None): - return self.request("GET", url, - headers=headers, - _preload_content=_preload_content, - _request_timeout=_request_timeout, - query_params=query_params) - - def HEAD(self, url, headers=None, query_params=None, _preload_content=True, - _request_timeout=None): - return self.request("HEAD", url, - headers=headers, - _preload_content=_preload_content, - _request_timeout=_request_timeout, - query_params=query_params) - - def OPTIONS(self, url, headers=None, query_params=None, post_params=None, - body=None, _preload_content=True, _request_timeout=None): - return self.request("OPTIONS", url, - headers=headers, - query_params=query_params, - post_params=post_params, - _preload_content=_preload_content, - _request_timeout=_request_timeout, - body=body) - - def DELETE(self, url, headers=None, query_params=None, body=None, - _preload_content=True, _request_timeout=None): - return self.request("DELETE", url, - headers=headers, - query_params=query_params, - _preload_content=_preload_content, - _request_timeout=_request_timeout, - body=body) - - def POST(self, url, headers=None, query_params=None, post_params=None, - body=None, _preload_content=True, _request_timeout=None): - return self.request("POST", url, - headers=headers, - query_params=query_params, - post_params=post_params, - _preload_content=_preload_content, - _request_timeout=_request_timeout, - body=body) - - def PUT(self, url, headers=None, query_params=None, post_params=None, - body=None, _preload_content=True, _request_timeout=None): - return self.request("PUT", url, - headers=headers, - query_params=query_params, - post_params=post_params, - _preload_content=_preload_content, - _request_timeout=_request_timeout, - body=body) - - def PATCH(self, url, headers=None, query_params=None, post_params=None, - body=None, _preload_content=True, _request_timeout=None): - return self.request("PATCH", url, - headers=headers, - query_params=query_params, - post_params=post_params, - _preload_content=_preload_content, - _request_timeout=_request_timeout, - body=body) - - -class ApiException(Exception): - - def __init__(self, status=None, reason=None, http_resp=None): - if http_resp: - self.status = http_resp.status - self.reason = http_resp.reason - self.body = http_resp.data - self.headers = http_resp.getheaders() - else: - self.status = status - self.reason = reason - self.body = None - self.headers = None - - def __str__(self): - """Custom error messages for exception""" - error_message = "({0})\n"\ - "Reason: {1}\n".format(self.status, self.reason) - if self.headers: - error_message += "HTTP response headers: {0}\n".format( - self.headers) - - if self.body: - error_message += "HTTP response body: {0}\n".format(self.body) - - return error_message diff --git a/src/caosadvancedtools/cache.py b/src/caosadvancedtools/cache.py index bf1287ba35d9c0af28d440db56e38173d38fcacf..5fc1ec3c22fbee0096a9167ea35e0bc59bfb0665 100644 --- a/src/caosadvancedtools/cache.py +++ b/src/caosadvancedtools/cache.py @@ -2,7 +2,7 @@ # encoding: utf-8 # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2020 Indiscale GmbH <info@indiscale.com> # Copyright (C) 2020 Henrik tom Wörden <h.tomwoerden@indiscale.com> @@ -33,7 +33,7 @@ from abc import ABC, abstractmethod from copy import deepcopy from hashlib import sha256 -import caosdb as db +import linkahead as db from lxml import etree @@ -94,7 +94,6 @@ class AbstractCache(ABC): Increase this variable, when changes to the cache tables are made. """ - pass @abstractmethod def create_cache(self): @@ -102,14 +101,12 @@ class AbstractCache(ABC): Provide an overloaded function here that creates the cache in the most recent version. """ - pass @abstractmethod def get_default_file_name(self): """ Supply a default file name for the cache here. """ - pass def check_cache(self): """ @@ -192,9 +189,6 @@ class IdentifiableCache(AbstractCache): def get_default_file_name(self): return "caosdb_identifiable_cache.db" - def __init__(self, db_file=None, force_creation=False): - super().__init__(db_file, force_creation) - def create_cache(self): """ Create a new SQLITE cache file in self.db_file. @@ -338,7 +332,7 @@ class UpdateCache(AbstractCache): return 3 def get_default_file_name(self): - return "/tmp/crawler_update_cache.db" + return os.path.join(tempfile.gettempdir(), "crawler_update_cache.db") @staticmethod def get_previous_version(cont): diff --git a/src/caosadvancedtools/cfood.py b/src/caosadvancedtools/cfood.py index 588476bd624f7e24a5e0f49380fb1e66f5bd1b17..0eb826321d9889c6d8fcc09f6208bb56b9d3066e 100644 --- a/src/caosadvancedtools/cfood.py +++ b/src/caosadvancedtools/cfood.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # encoding: utf-8 # -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2018 Research Group Biomedical Physics, # Max-Planck-Institute for Dynamics and Self-Organization Göttingen @@ -23,9 +23,9 @@ # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <https://www.gnu.org/licenses/>. -""" Defines how something that shall be inserted into CaosDB is treated. +""" Defines how something that shall be inserted into LinkAhead is treated. -CaosDB can automatically be filled with Records based on some structure, a file +LinkAhead can automatically be filled with Records based on some structure, a file structure, a table or similar. The Crawler will iterate over the respective items and test for each item @@ -33,9 +33,9 @@ whether a CFood class exists that matches the file path, i.e. whether CFood class wants to treat that pariticular item. If one does, it is instanciated to treat the match. This occurs in basically three steps: -1. Create a list of identifiables, i.e. unique representation of CaosDB Records +1. Create a list of identifiables, i.e. unique representation of LinkAhead Records (such as an experiment belonging to a project and a date/time). -2. The identifiables are either found in CaosDB or they are created. +2. The identifiables are either found in LinkAhead or they are created. 3. The identifiables are update based on the date in the file structure. """ @@ -45,14 +45,18 @@ import warnings from abc import ABCMeta, abstractmethod from datetime import datetime -import caosdb as db -from caosdb.common.models import Entity -from caosdb.exceptions import (BadQueryError, EmptyUniqueQueryError, - QueryNotUniqueError, TransactionError) +import linkahead as db +from linkahead.exceptions import (BadQueryError, EmptyUniqueQueryError, + QueryNotUniqueError) from .datamodel_problems import DataModelProblems from .guard import global_guard as guard +# The pylint warnings triggered in this file are ignored, as this code is +# assumed to be deprecated in the near future. Should this change, they need +# to be reevaluated. + + ENTITIES = {} PROPERTIES = {} RECORDS = {} @@ -65,7 +69,7 @@ logger = logging.getLogger(__name__) def get_entity(name): """ Returns the entity with a given name, preferably from a local cache. - If the local cache does not contain the entity, retrieve it from CaosDB. + If the local cache does not contain the entity, retrieve it from LinkAhead. """ if name not in ENTITIES: @@ -81,7 +85,7 @@ def get_property(name): cache. If the local cache does not contain the record type, try to - retrieve it from CaosDB. If it does not exist, see whether it + retrieve it from LinkAhead. If it does not exist, see whether it could be a record type used as a property. """ @@ -103,7 +107,7 @@ def get_record(name): """Returns the record with a given name, preferably from a local cache. If the local cache does not contain the record, try to retrieve it - from CaosDB. + from LinkAhead. """ @@ -120,7 +124,7 @@ def get_recordtype(name): cache. If the local cache does not contain the record type, try to - retrieve it from CaosDB. If it does not exist, add it to the data + retrieve it from LinkAhead. If it does not exist, add it to the data model problems """ @@ -140,7 +144,7 @@ def get_recordtype(name): class FileGuide(object): def access(self, path): """ should be replaced by a function that adds - a prefix to paths to allow to access caosdb files locally + a prefix to paths to allow to access LinkAhead files locally This default just returns the unchanged path. """ @@ -184,7 +188,7 @@ class AbstractCFood(object, metaclass=ABCMeta): """ @classmethod - def match_item(cls, item): + def match_item(cls, item): # pylint: disable=unused-argument """ Matches an item found by the crawler against this class. Returns True if the item shall be treated by this class, i.e. if this class matches the item. @@ -209,7 +213,6 @@ class AbstractCFood(object, metaclass=ABCMeta): To be overwritten by subclasses """ - pass def attach(self, item): self.attached_items.append(item) @@ -217,7 +220,7 @@ class AbstractCFood(object, metaclass=ABCMeta): # TODO looking for should `attach` the files itsself. This would allow to # group them right away and makes it unnecessary to check matches later # again. - def looking_for(self, item): + def looking_for(self, item): # pylint: disable=unused-argument """ returns True if item can be added to this CFood. @@ -353,7 +356,7 @@ class AbstractFileCFood(AbstractCFood): raise NotImplementedError() @classmethod - def match_item(cls, path): + def match_item(cls, path): # pylint: disable=arguments-renamed """ Matches the regular expression of this class against file names Parameters @@ -367,7 +370,7 @@ class AbstractFileCFood(AbstractCFood): # TODO looking for should `attach` the files itsself. This would allow to # group them right away and makes it unnecessary to check matches later # again. - def looking_for(self, crawled_file): + def looking_for(self, crawled_file): # pylint: disable=arguments-renamed """ returns True if crawled_file can be added to this CFood. @@ -569,6 +572,7 @@ def assure_parents_are(entity, parents, to_be_updated=None, the new parents and the old ones are discarded. Note that parent matching occurs based on names. + If a parent does not have a name, a ValueError is raised. If the list to_be_updated is supplied, the entity is added to the list in order to indicate, that the entity `entity` should be updated. @@ -583,7 +587,7 @@ def assure_parents_are(entity, parents, to_be_updated=None, for i, e in enumerate(parents): if isinstance(e, db.Entity): if e.name is None: - raise Exception("Entity should have name") + raise ValueError("Entity should have name") else: parents[i] = db.Entity(name=e) @@ -690,7 +694,7 @@ def assure_has_property(entity, name, value, to_be_updated=None, try: compare_time = datetime.fromisoformat(el.value) - except ValueError: + except ValueError as e: # special case of wrong iso format # time zone tmp = el.value.split("+") @@ -708,7 +712,7 @@ def assure_has_property(entity, name, value, to_be_updated=None, ms = '.' + tmp[1] + '0'*(6-len(tmp[1])) else: raise ValueError( - "invalid millisecond format in {}".format(el.value)) + "invalid millisecond format in {}".format(el.value)) from e else: ms = "" tmp = tmp[0] + ms + tz_str @@ -746,7 +750,7 @@ def assure_has_property(entity, name, value, to_be_updated=None, def assure_property_is(entity, name, value, datatype=None, to_be_updated=None, - force=False): + force=False): # pylint: disable=unused-argument """ Checks whether `entity` has a Property `name` with the given value. diff --git a/src/caosadvancedtools/cfoods/__init__.py b/src/caosadvancedtools/cfoods/__init__.py index 30ce05add09a223c2f65dbe187a6cfb1768d7a22..6936568adb417bafa36f28bfd47be3aebd23c214 100644 --- a/src/caosadvancedtools/cfoods/__init__.py +++ b/src/caosadvancedtools/cfoods/__init__.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2020 IndiScale GmbH <www.indiscale.com> # Copyright (C) 2020 Daniel Hornung <d.hornung@indiscale.com> diff --git a/src/caosadvancedtools/cfoods/h5.py b/src/caosadvancedtools/cfoods/h5.py index dfd6f2905c955c1b4e493da1f2cbf45583ee68dc..3b3b56881df6280cc850441b71fc95ce931dfb03 100644 --- a/src/caosadvancedtools/cfoods/h5.py +++ b/src/caosadvancedtools/cfoods/h5.py @@ -34,7 +34,7 @@ Properties. from copy import deepcopy -import caosdb as db +import linkahead as db import h5py import numpy as np from caosadvancedtools.cfood import fileguide @@ -45,7 +45,7 @@ from ..structure_mapping import (EntityMapping, collect_existing_structure, def h5_attr_to_property(val): - """ returns the value and datatype of a CaosDB Property for the given value + """ returns the value and datatype of a LinkAhead Property for the given value 1d arrays are converted to lists @@ -168,7 +168,7 @@ class H5CFood(AbstractFileCFood): self.to_be_inserted = db.Container() self.insert_missing_structure(self.structure) - # TODO this is a workaround due to the fact that the caosdb library + # TODO this is a workaround due to the fact that the linkahead library # changes the objects in the Container if it is inserted. The graph # structure is flattened. I.e. references to other entity objects are # replaced with their IDs. However this code depends on this graph. diff --git a/src/caosadvancedtools/collect_datamodel.py b/src/caosadvancedtools/collect_datamodel.py index 806d15333cac7f745ce2fb82a02e0214ad2b6616..bb69a03d4475c8af21f69fd5d9ffd3ac4adb1f2f 100644 --- a/src/caosadvancedtools/collect_datamodel.py +++ b/src/caosadvancedtools/collect_datamodel.py @@ -2,7 +2,7 @@ # encoding: utf-8 # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2018 Research Group Biomedical Physics, # Max-Planck-Institute for Dynamics and Self-Organization Göttingen @@ -25,8 +25,8 @@ import argparse import os -import caosdb as db -from caosdb.apiutils import retrieve_entities_with_ids +import linkahead as db +from linkahead.apiutils import retrieve_entities_with_ids from export_related import export @@ -62,9 +62,9 @@ def store(directory, xml=False): rts, ps = get_dm() os.makedirs(directory, exist_ok=True) - with open(os.path.join(directory, "recordtypes.txt"), "w") as fi: + with open(os.path.join(directory, "recordtypes.txt"), "w", encoding="utf-8") as fi: fi.write(",".join([el[1] for el in rts])) - with open(os.path.join(directory, "properties.txt"), "w") as fi: + with open(os.path.join(directory, "properties.txt"), "w", encoding="utf-8") as fi: fi.write(",".join([el[1] for el in ps])) if xml: @@ -75,10 +75,10 @@ def store(directory, xml=False): def load_dm(directory): - with open(os.path.join(directory, "recordtypes.txt"), "r") as fi: + with open(os.path.join(directory, "recordtypes.txt"), "r", encoding="utf-8") as fi: text = fi.read() rts = [el.strip() for el in text.split(",")] - with open(os.path.join(directory, "properties.txt"), "r") as fi: + with open(os.path.join(directory, "properties.txt"), "r", encoding="utf-8") as fi: text = fi.read() ps = [el.strip() for el in text.split(",")] @@ -112,7 +112,7 @@ def compare(directory): print("{} is missing in the existing properties".format(p)) -if __name__ == "__main__": +def main(): p = get_parser() args = p.parse_args() @@ -121,3 +121,7 @@ if __name__ == "__main__": if args.compare: compare(args.compare) + + +if __name__ == "__main__": + main() diff --git a/src/caosadvancedtools/converter/__init__.py b/src/caosadvancedtools/converter/__init__.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/caosadvancedtools/converter/labfolder_api.py b/src/caosadvancedtools/converter/labfolder_api.py deleted file mode 100644 index cf57c0155a3b3970834abb2fc1058215ef7ecba8..0000000000000000000000000000000000000000 --- a/src/caosadvancedtools/converter/labfolder_api.py +++ /dev/null @@ -1,164 +0,0 @@ -#!/usr/bin/env python3 -# -# This file is a part of the CaosDB Project. -# -# Copyright (c) 2020 IndiScale GmbH -# Copyright (c) 2020 Daniel Hornung <d.hornung@indiscale.com> -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see <https://www.gnu.org/licenses/>. -# - -""" Imports data from labfolder via api """ - -import json -import os -import time - -import html2text - -import caosdb as db -from labfolder.connection import configure_connection # pylint: disable=import-error - - -class Importer(object): - def __init__(self): - self.connection = configure_connection() - self.projects = self.connection.retrieve_projects() - self.entries = self.connection.retrieve_entries() - - def create_project(self, project): - dbproject = db.Record(name=project['title']) - dbproject.add_parent(name="Project") - dbproject.add_property(name="projectId", value=project['id']) - # crawler.cached_find_identifiables([dbproject]) - - return dbproject - - def get_entries(self, project_id): - return [ent for ent in self.entries if ent["project_id"] == project_id] - - def treat_project(self, project): - cont = db.Container() - dbproject = self.create_project(project) - cont.append(dbproject) - - for entry in self.get_entries(project["id"]): - recs = self.create_entry(entry, dbproject) - cont.extend(recs) - - print(cont) - cont.insert(unique=False) - # import IPython - # IPython.embed() - - def import_data(self): - for project in self.projects: - self.treat_project(project) - - def add_property_from_data_element(self, dbrecord, element): - - if element['type'] == "DATA_ELEMENT_GROUP": - for c in element["children"]: - self.add_property_from_data_element(dbrecord, c) - elif element['type'] == "SINGLE_DATA_ELEMENT": - - # if quant is not None: - # quant = quant.strip(": ") - # title = title+" - "+quant - res = db.execute_query("FIND PROPERTY '{}'".format(element['title'])) - - if len(res) == 0: - p = db.Property(name=element['title'], unit=element['unit'], datatype=db.DOUBLE) - try: - p.insert() - except db.exceptions.TransactionError as e: - print(e) - - return - val = element['value'] - try: - val = float(val) - except (ValueError, TypeError): - print("Value is no float!!!", val) - - return - dbrecord.add_property(name=element['title'], value=val, unit=element['unit']) - elif element['type'] == "DESCRIPTIVE_DATA_ELEMENT": - res = db.execute_query("FIND PROPERTY '{}'".format(element['title'])) - - if len(res) == 0: - p = db.Property(name=element['title'], datatype=db.TEXT) - p.insert() - dbrecord.add_property(name=element['title'], - value=element['description']) - - def create_element(self, element_id, el_type, dbrecord): - print(element_id, el_type) - - if el_type == "IMAGE": - el_type = "FILE" - elif el_type == "DATA_ELEMENT": - el_type = "DATA" - - try: - element = self.connection.retrieve_element(element_id, el_type=el_type) - except BaseException: - print("Could not retrieve: ", element_id) - - return - - if el_type == "TEXT": - dbrecord.add_property( - name="textElement", - value=html2text.html2text(element["content"])) - elif el_type == "FILE": - local_file = self.connection.download_file(element_id) - f = db.File(name=element["file_name"], - path=os.path.join("labfolder", str(time.time()), - element["file_name"]), - file=local_file) - f.insert(unique=False) - dbrecord.add_property(name="associatedFile", value=f) - - elif el_type == "DATA": - for subel in element["data_elements"]: - self.add_property_from_data_element(dbrecord=dbrecord, - element=subel) - elif el_type == "TABLE": - print(element) - - def create_entry(self, entry, dbproject): - cont = db.Container() - dbrecord = db.Record(name=entry["title"]) - dbrecord.add_parent(name="LabbookEntry") - dbrecord.add_property(name="Project", value=dbproject) - dbrecord.add_property(name="entryId", value=entry['id']) - # crawler.cached_find_identifiables([dbrecord]) - - # TODO resolve id - # person = get_author_from_entry(entry) - # dbrecord.add_property(name="responsible", value=person) - - for element in entry["elements"]: - - print(json.dumps(element, sort_keys=True, indent=4)) - self.create_element(element["id"], element["type"], dbrecord) - # If all text field would have the class dd_text_entry the - # following would be sufficient: - # if 'dd_text_entry' in block['class']: - # instead we check whether an editor field exists. - - cont.extend([dbrecord]) - - return cont diff --git a/src/caosadvancedtools/converter/labfolder_export.py b/src/caosadvancedtools/converter/labfolder_export.py deleted file mode 100644 index 6e282218b6d451749ad3070693d38299663f1bee..0000000000000000000000000000000000000000 --- a/src/caosadvancedtools/converter/labfolder_export.py +++ /dev/null @@ -1,228 +0,0 @@ -#!/usr/bin/env python3 -# -# This file is a part of the CaosDB Project. -# -# Copyright (c) 2020 IndiScale GmbH -# Copyright (c) 2020 Daniel Hornung <d.hornung@indiscale.com> -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see <https://www.gnu.org/licenses/>. -# - -""" Imports labfolder exports """ - -import os - -from bs4 import BeautifulSoup - -import caosdb as db - -RERUN = False -# crawler = Crawler() - -print(""" -WARNING: This is an ALPHA version. Parsing of the by labfolder exported data -might not work correctly! There might be missing elements! Check the result -carefully before inserting it. -""") - - -def create_project(project): - dbproject = db.Record(name=project.attrs['data-name']) - dbproject.add_parent(name="Project") - dbproject.add_property(name="projectId", value=project.attrs['data-id']) - # crawler.cached_find_identifiables([dbproject]) - - return dbproject - - -def get_author_from_entry(entry): - person = db.Record() - person.add_parent(name="Person") - resp = entry.find_all(attrs={'class': 'author_name'}) - - for name in ["firstname", "lastname"]: - person.add_property( - name=name, - value=resp[0].find_all(attrs={'class': 'author_'+name})[0].getText()) - # crawler.cached_find_identifiables([person]) - - return person - - -def val_or_none(stuff): - if len(stuff) == 0: - return None - - return stuff[0].getText() - - -def add_property_from_data_element(dbrecord, element): - unit = val_or_none(element.find_all(attrs={'class': 'element-unit'})) - title = val_or_none(element.find_all(attrs={'class': 'element-title'})) - quant = val_or_none(element.find_all(attrs={'class': 'element-quantity'})) - val = val_or_none(element.find_all(attrs={'class': 'element-value'})) - - print("tit", title) - print("qu", quant) - if quant is not None: - quant = quant.strip(": ") - title = title+" - "+quant - res = db.execute_query("FIND PROPERTY '{}'".format(title)) - if len(res) == 0: - p = db.Property(name=title, unit=unit, datatype=db.DOUBLE) - p.insert() - try: - val = float(val) - except TypeError: - print("Value is no float!!!", val) - return - dbrecord.add_property(name=title, value=val, unit=unit) - - -def create_file(name, filename, root): - local_path = os.path.join(root, filename) - local_path = os.path.normpath(local_path) - if not os.path.exists(local_path): - raise ValueError("FILE DOES NOT EXIST: ", local_path) - f = db.File(path=local_path, file=local_path, name=name) - return f - - -def create_entry(entry, dbproject, root): - cont = db.Container() - dbrecord = db.Record() - dbrecord.add_parent(name="LabbookEntry") - dbrecord.add_property(name="Project", value=dbproject) - dbrecord.add_property(name="entryId", value=entry.attrs['data-id']) - # crawler.cached_find_identifiables([dbrecord]) - - person = get_author_from_entry(entry) - dbrecord.add_property(name="responsible", value=person) - - for block in entry.find_all(attrs={'class': 'dd_entry_cell'}): - # If all text field would have the class dd_text_entry the - # following would be sufficient: - # if 'dd_text_entry' in block['class']: - # instead we check whether an editor field exists. - editor = block.find_all(attrs={'class': 'redactor_editor'}) - - if len(editor) > 0: - dbrecord.add_property(name="textElement", value=editor[0].getText()) - - continue - - download = block.find_all( - attrs={'class': 'dd_entry_cell_file_download'}) - - if len(download) > 0: - name = ((download[0].parent).attrs['data-filename']).strip('"') - if name == "blank.png": - continue - if len(download[0].find_all("img")) > 0: - filename = download[0].find_all("img")[0].attrs['src'] - elif len(download[0].find_all("a")) > 0: - filename = download[0].find_all("a")[0].attrs['href'] - else: - raise ValueError("could not get filename") - print(name) - print(filename) - f = create_file(name, filename, root) - if RERUN: - f.retrieve() - else: - f.insert() - dbrecord.add_property(name="associatedFile", value=f) - cont.append(f) - - continue - - elements = block.find_all( - attrs={'class': 'data-element-display'}) - - if len(elements) > 0: - for el in elements: - add_property_from_data_element(dbrecord=dbrecord, element=el) - - continue - - tables = block.find_all( - attrs={'class': 'table-el-container'}) - - if len(tables) > 0: - name = (tables[0]).find_all( - attrs={'class': 'table-el-filename'} - )[0].getText().strip() - f = create_file(name, name, root) - if RERUN: - f.retrieve() - else: - f.insert() - dbrecord.add_property(name="table", value=f) - cont.append(f) - - continue - - empty = block.find_all( - attrs={'class': 'dd_entry_empty_element'}) - - if len(tables) > 0: - print("\n\nempty") - - continue - - cont.extend([dbrecord, person]) - - return cont - - -def treat_project(path): - with open(os.path.join(path, "index.html")) as fp: - tree = BeautifulSoup(fp, features="lxml") - - cont = db.Container() - project = tree.find_all(id="eln_project_content") - - if len(project) == 0: - return - else: - project = project[0] - dbproject = create_project(project) - cont.append(dbproject) - - for entry in project.find_all(lambda x: x.has_attr('data-id')): - recs = create_entry(entry, dbproject, path) - cont.extend(recs) - - print(cont) - cont.insert() - # import IPython - # IPython.embed() - - -def import_data(folder): - """imports the data of a labfolder export""" - - if not os.path.exists(folder): - raise ValueError("folder does not exist") - - projects_folder = os.path.join(folder, "projects") - - if not os.path.exists(projects_folder): - raise ValueError("folder does not contain a projects folder") - - for root, dirs, files in os.walk(projects_folder): - print(root, dirs, files) - - if "index.html" in files: - treat_project(root) diff --git a/src/caosadvancedtools/crawler.py b/src/caosadvancedtools/crawler.py index fc3b260b4ae26c608b40f26e4b80192fdbd0e00d..7b66440ffb0659fd76e012e812deae2b0055d55a 100644 --- a/src/caosadvancedtools/crawler.py +++ b/src/caosadvancedtools/crawler.py @@ -2,7 +2,7 @@ # encoding: utf-8 # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2018 Research Group Biomedical Physics, # Max-Planck-Institute for Dynamics and Self-Organization Göttingen @@ -25,30 +25,29 @@ # # ** end header # -""" Crawls a file structure and inserts Records into CaosDB based on what is +""" Crawls a file structure and inserts Records into LinkAhead based on what is found. -CaosDB can automatically be filled with Records based on some file structure. +LinkAhead can automatically be filled with Records based on some file structure. The Crawler will iterate over the files and test for each file whether a CFood exists that matches the file path. If one does, it is instanciated to treat the match. This occurs in basically three steps: -1. create a list of identifiables, i.e. unique representation of CaosDB Records +1. create a list of identifiables, i.e. unique representation of LinkAhead Records (such as an experiment belonging to a project and a date/time) -2. the identifiables are either found in CaosDB or they are created. +2. the identifiables are either found in LinkAhead or they are created. 3. the identifiables are update based on the date in the file structure """ import logging import os -import subprocess import traceback import uuid from datetime import datetime from sqlite3 import IntegrityError -import caosdb as db -from caosdb.exceptions import BadQueryError +import linkahead as db +from linkahead.exceptions import BadQueryError from .cache import IdentifiableCache, UpdateCache, get_pretty_xml from .cfood import RowCFood, add_files, get_ids_for_entities_with_names @@ -60,6 +59,11 @@ from .serverside.helper import send_mail as main_send_mail from .suppressKnown import SuppressKnown from .utils import create_entity_link +# The pylint warnings triggered in this file are ignored, as this code is +# assumed to be deprecated in the near future. Should this change, they need +# to be reevaluated. + + logger = logging.getLogger(__name__) @@ -67,9 +71,9 @@ def separated(text): return "-"*60 + "\n" + text -def apply_list_of_updates(to_be_updated, update_flags={}, +def apply_list_of_updates(to_be_updated, update_flags=None, update_cache=None, run_id=None): - """Updates the `to_be_updated` Container, i.e., pushes the changes to CaosDB + """Updates the `to_be_updated` Container, i.e., pushes the changes to LinkAhead after removing possible duplicates. If a chace is provided, uauthorized updates can be cached for further authorization. @@ -78,7 +82,7 @@ def apply_list_of_updates(to_be_updated, update_flags={}, to_be_updated : db.Container Container with the entities that will be updated. update_flags : dict, optional - Dictionary of CaosDB server flags that will be used for the + Dictionary of LinkAhead server flags that will be used for the update. Default is an empty dict. update_cache : UpdateCache or None, optional Cache in which the intended updates will be stored so they can be @@ -87,6 +91,8 @@ def apply_list_of_updates(to_be_updated, update_flags={}, Id with which the pending updates are cached. Only meaningful if `update_cache` is provided. Default is None. """ + if update_flags is None: + update_flags = {} if len(to_be_updated) == 0: return @@ -132,7 +138,7 @@ def apply_list_of_updates(to_be_updated, update_flags={}, ) logger.debug(traceback.format_exc()) logger.debug(e) - except Exception as e: + except Exception as e: # pylint: disable=broad-exception-caught DataModelProblems.evaluate_exception(e) @@ -147,7 +153,7 @@ class Crawler(object): The Crawler will use those CFoods when crawling. use_cache : bool, optional Whether to use caching (not re-inserting probably existing - objects into CaosDB), defaults to False. + objects into LinkAhead), defaults to False. abort_on_exception : if true, exceptions are raise. Otherwise the crawler continues if an exception occurs. interactive : boolean, optional @@ -169,6 +175,7 @@ class Crawler(object): self.abort_on_exception = abort_on_exception self.update_cache = UpdateCache() self.filterKnown = SuppressKnown() + self.run_id = None advancedtoolslogger = logging.getLogger("caosadvancedtools") # TODO this seems to be a bad idea. What if the handler was not added @@ -220,7 +227,7 @@ class Crawler(object): new_cont = db.Container.from_xml(new) ids = [] tmp = db.Container() - update_incomplete = False + update_incomplete = False # pylint: disable=unused-variable # remove duplicate entities for el in new_cont: if el.id not in ids: @@ -229,13 +236,13 @@ class Crawler(object): else: update_incomplete = True new_cont = tmp - if new_cont[0].version: + if new_cont[0].version: # pylint: disable=no-member valids = db.Container() nonvalids = db.Container() for ent in new_cont: remote_ent = db.Entity(id=ent.id).retrieve() - if ent.version == remote_ent.version: + if ent.version == remote_ent.version: # pylint: disable=no-member valids.append(ent) else: update_incomplete = True @@ -271,7 +278,7 @@ class Crawler(object): """ This is the first phase of the crawl. It collects all cfoods that shall be processed. The second phase is iterating over cfoods and updating - CaosDB. This separate first step is necessary in order to allow a + LinkAhead. This separate first step is necessary in order to allow a single cfood being influenced by multiple crawled items. E.g. the FileCrawler can have a single cfood treat multiple files. @@ -317,10 +324,10 @@ class Crawler(object): logger.debug(e) # TODO: Generally: in which cases should exceptions be raised? When is # errors_occured set to True? The expected behavior must be documented. - except Exception as e: + except Exception as e: # pylint: disable=broad-exception-caught try: DataModelProblems.evaluate_exception(e) - except BaseException: + except Exception: # pylint: disable=broad-exception-caught pass logger.debug("Failed during execution of {}!".format( Cfood.__name__)) @@ -349,13 +356,13 @@ class Crawler(object): logger.info("Cannot access {}. However, it might be needed for" " the correct execution".format(e.filename)) remove_cfoods.append(cfood) - except Exception as e: + except Exception as e: # pylint: disable=broad-exception-caught try: DataModelProblems.evaluate_exception(e) - except BaseException: + except Exception: # pylint: disable=broad-exception-caught pass logger.debug("Failed during execution of {}!".format( - Cfood.__name__)) + cfood.__name__)) logger.debug(traceback.format_exc()) logger.debug(e) remove_cfoods.append(cfood) @@ -442,10 +449,10 @@ class Crawler(object): except DataInconsistencyError as e: logger.debug(traceback.format_exc()) logger.debug(e) - except Exception as e: + except Exception as e: # pylint: disable=broad-exception-caught try: DataModelProblems.evaluate_exception(e) - except Exception: + except Exception: # pylint: disable=broad-exception-caught pass logger.info("Failed during execution of {}!".format( cfood.__class__.__name__)) @@ -488,8 +495,8 @@ ____________________\n""".format(i+1, len(pending_changes)) + str(el[3])) logger.error(err_msg) logger.error('Crawler finished with Datamodel Errors') elif errors_occured: - msg = "There were fatal errors during execution, please " - "contact the system administrator!" + msg = ("There were fatal errors during execution, please contact " + "the system administrator!") if self.debug_file: msg += "\nPlease provide the following path:\n{}".format( @@ -512,16 +519,16 @@ ____________________\n""".format(i+1, len(pending_changes)) + str(el[3])) Parameters: ----------- - changes: The CaosDB entities in the version after the update. + changes: The LinkAhead entities in the version after the update. path: the path defining the subtree that is crawled """ from xml.sax.saxutils import escape - caosdb_config = db.configuration.get_config() - if ("advancedtools" in caosdb_config and "crawler.customcssfile" in - caosdb_config["advancedtools"]): - cssfile = caosdb_config["advancedtools"]["crawler.customcssfile"] + linkahead_config = db.configuration.get_config() + if ("advancedtools" in linkahead_config and "crawler.customcssfile" in + linkahead_config["advancedtools"]): + cssfile = linkahead_config["advancedtools"]["crawler.customcssfile"] else: cssfile = None # TODO move path related stuff to sss_helper @@ -584,11 +591,11 @@ ____________________\n""".format(i+1, len(pending_changes)) + str(el[3])) </script> </body> </html> -""".format(url=caosdb_config["Connection"]["url"], +""".format(url=linkahead_config["Connection"]["url"], rid=run_id, changes=escape("\n".join(changes)), customcssfile='<link rel="stylesheet" href="{url}/webinterface/css/{customcssfile}"/>'.format( - url=caosdb_config["Connection"]["url"], customcssfile=cssfile) if cssfile else "", + url=linkahead_config["Connection"]["url"], customcssfile=cssfile) if cssfile else "", path=path) if "SHARED_DIR" in os.environ: @@ -600,7 +607,7 @@ ____________________\n""".format(i+1, len(pending_changes)) + str(el[3])) randname = os.path.basename(os.path.abspath(directory)) filepath = os.path.abspath(os.path.join(directory, filename)) filename = os.path.join(randname, filename) - with open(filepath, "w") as f: + with open(filepath, "w", encoding="utf-8") as f: f.write(form) return filename @@ -611,11 +618,11 @@ ____________________\n""".format(i+1, len(pending_changes)) + str(el[3])) Parameters: ----------- - changes: The CaosDB entities in the version after the update. + changes: The LinkAhead entities in the version after the update. filename: path to the html site that allow the authorization """ - caosdb_config = db.configuration.get_config() + linkahead_config = db.configuration.get_config() text = """Dear Curator, there where changes that need your authorization. Please check the following carefully and if the changes are ok, click on the following link: @@ -623,12 +630,12 @@ carefully and if the changes are ok, click on the following link: {url}/Shared/{filename} {changes} - """.format(url=caosdb_config["Connection"]["url"], + """.format(url=linkahead_config["Connection"]["url"], filename=filename, changes="\n".join(changes)) try: - fro = caosdb_config["advancedtools"]["crawler.from_mail"] - to = caosdb_config["advancedtools"]["crawler.to_mail"] + fro = linkahead_config["advancedtools"]["crawler.from_mail"] + to = linkahead_config["advancedtools"]["crawler.to_mail"] except KeyError: logger.error("Server Configuration is missing a setting for " "sending mails. The administrator should check " @@ -646,11 +653,11 @@ carefully and if the changes are ok, click on the following link: @staticmethod def find_or_insert_identifiables(identifiables): """ Sets the ids of identifiables (that do not have already an id from the - cache) based on searching CaosDB and retrieves those entities. + cache) based on searching LinkAhead and retrieves those entities. The remaining entities (those which can not be retrieved) have no - correspondence in CaosDB and are thus inserted. + correspondence in LinkAhead and are thus inserted. """ - # looking for matching entities in CaosDB when there is no valid id + # looking for matching entities in LinkAhead when there is no valid id # i.e. there was none set from a cache existing = [] @@ -680,7 +687,7 @@ carefully and if the changes are ok, click on the following link: guard.safe_insert(missing, unique=False, flags={"force-missing-obligatory": "ignore"}) inserted.append(ent) - except Exception as e: + except Exception as e: # pylint: disable=broad-exception-caught DataModelProblems.evaluate_exception(e) if len(existing) > 0: info = "Identified the following existing entities:\n" @@ -699,7 +706,7 @@ carefully and if the changes are ok, click on the following link: else: logger.debug("Did not insert any new entities") - logger.debug("Retrieving entities from CaosDB...") + logger.debug("Retrieving entities from LinkAhead...") identifiables.retrieve(unique=True, raise_exception_on_error=False) @staticmethod @@ -735,7 +742,7 @@ carefully and if the changes are ok, click on the following link: @staticmethod def find_existing(entity): - """searches for an entity that matches the identifiable in CaosDB + """searches for an entity that matches the identifiable in LinkAhead Characteristics of the identifiable like, properties, name or id are used for the match. diff --git a/src/caosadvancedtools/datainconsistency.py b/src/caosadvancedtools/datainconsistency.py index 3af8b5a2c0b73746185306a94b987a0800acb899..9931dd685374716107b179f08653f6424153fc78 100644 --- a/src/caosadvancedtools/datainconsistency.py +++ b/src/caosadvancedtools/datainconsistency.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # encoding: utf-8 # -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2020 Indiscale GmbH <info@indiscale.com> # Copyright (C) 2020 Henrik tom Wörden <h.tomwoerden@indiscale.com> diff --git a/src/caosadvancedtools/datamodel_problems.py b/src/caosadvancedtools/datamodel_problems.py index df5b7e56dfcc939e2eabf6454cb6e81b22a37727..d14a384bdd0f16aed82d359346a331aa17334465 100644 --- a/src/caosadvancedtools/datamodel_problems.py +++ b/src/caosadvancedtools/datamodel_problems.py @@ -2,7 +2,7 @@ # encoding: utf-8 # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2020 Indiscale GmbH <info@indiscale.com> # Copyright (C) 2020 Florian Sprckelsen <f.spreckelsen@indiscale.com> @@ -27,10 +27,10 @@ be inserted by hand or gueesed from possible exceptions when inserting or updating entities with missing parents and/or properties. """ -from caosdb.exceptions import (EntityDoesNotExistError, - TransactionError, - UnqualifiedParentsError, - UnqualifiedPropertiesError) +from linkahead.exceptions import (EntityDoesNotExistError, + TransactionError, + UnqualifiedParentsError, + UnqualifiedPropertiesError) class DataModelProblems(object): diff --git a/src/caosadvancedtools/example_cfood.py b/src/caosadvancedtools/example_cfood.py index 2e395d5c3030508087e25a7156d35c8954d223d7..43a558fdd1f1de134d5194dac23e902ca0070bab 100644 --- a/src/caosadvancedtools/example_cfood.py +++ b/src/caosadvancedtools/example_cfood.py @@ -2,7 +2,7 @@ # encoding: utf-8 # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2018 Research Group Biomedical Physics, # Max-Planck-Institute for Dynamics and Self-Organization Göttingen @@ -20,7 +20,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <https://www.gnu.org/licenses/>. -import caosdb as db +import linkahead as db from .cfood import AbstractFileCFood, assure_has_property @@ -31,6 +31,10 @@ class ExampleCFood(AbstractFileCFood): return (r".*/(?P<species>[^/]+)/" r"(?P<date>\d{4}-\d{2}-\d{2})/README.md") + def __init__(self, crawled_path, *args, **kwargs): + super().__init__(crawled_path, *args, **kwargs) + self.experiment = None + def create_identifiables(self): self.experiment = db.Record() self.experiment.add_parent(name="Experiment") diff --git a/src/caosadvancedtools/export_related.py b/src/caosadvancedtools/export_related.py index 7ae3a4dbba65faed551f75a1627eb504a3275f48..c7f25c90a3cf68a4b427eeaa2db61e1ec5d161ef 100755 --- a/src/caosadvancedtools/export_related.py +++ b/src/caosadvancedtools/export_related.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2020 IndiScale GmbH, Henrik tom Wörden # @@ -24,7 +24,7 @@ """ This file allows to create an xml representation of a complete dataset. Using the given entity all related entities are collected and saved in a way -that the data can be imported in another CaosDB instance. +that the data can be imported in another LinkAhead instance. Files that are smaller than 1MB are saved in a downloads folder and can be imported along with the entities themselves. @@ -32,9 +32,9 @@ imported along with the entities themselves. import argparse import os -import caosdb as db -from caosdb.apiutils import apply_to_ids, retrieve_entities_with_ids -from caosdb.common.datatype import get_id_of_datatype, is_reference +import linkahead as db +from linkahead.apiutils import apply_to_ids, retrieve_entities_with_ids +from linkahead.common.datatype import get_id_of_datatype, is_reference from lxml import etree @@ -118,7 +118,7 @@ def export(cont, directory="."): try: el.download(target) print("Downloaded:", target) - except BaseException: + except Exception: # pylint: disable=broad-exception-caught print("Failed download of:", target) invert_ids(cont) @@ -128,7 +128,7 @@ def export(cont, directory="."): xml = etree.tounicode(cont.to_xml( local_serialization=True), pretty_print=True) - with open(os.path.join(directory, "caosdb_data.xml"), "w") as fi: + with open(os.path.join(directory, "linkahead_data.xml"), "w", encoding="utf-8") as fi: fi.write(xml) @@ -149,8 +149,12 @@ def defineParser(): return parser -if __name__ == "__main__": +def main(): parser = defineParser() args = parser.parse_args() export_related_to(args.id, directory=args.directory) + + +if __name__ == "__main__": + main() diff --git a/src/caosadvancedtools/guard.py b/src/caosadvancedtools/guard.py index aa37448def63a356ff6e3b89327e34dbe4c510be..efda79eded09e0efc4687d58a413357c41086ced 100644 --- a/src/caosadvancedtools/guard.py +++ b/src/caosadvancedtools/guard.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # encoding: utf-8 # -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2020 Henrik tom Wörden # @@ -18,7 +18,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <https://www.gnu.org/licenses/>. -import caosdb as db +import linkahead as db RETRIEVE = 0 INSERT = 1 diff --git a/src/caosadvancedtools/import_from_xml.py b/src/caosadvancedtools/import_from_xml.py index 9d0e03f649db771147915740cabf201fae910760..7eeafa671a8aaa5469aa4c05ca685ecf937bf687 100755 --- a/src/caosadvancedtools/import_from_xml.py +++ b/src/caosadvancedtools/import_from_xml.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2020 IndiScale GmbH, Henrik tom Wörden # @@ -31,15 +31,15 @@ import argparse import os from tempfile import NamedTemporaryFile -import caosdb as db -from caosdb.apiutils import apply_to_ids +import linkahead as db +from linkahead.apiutils import apply_to_ids from caosadvancedtools.models.data_model import DataModel def create_dummy_file(text="Please ask the administrator for this file."): tmpfile = NamedTemporaryFile(delete=False) tmpfile.close() - with open(tmpfile.name, "w") as tm: + with open(tmpfile.name, "w", encoding="utf-8") as tm: tm.write(text) return tmpfile.name @@ -51,7 +51,7 @@ def import_xml(filename, rerun=False, interactive=True): rerun: boolean; if true, files are not inserted as paths would conflict. """ cont = db.Container() - with open(filename) as fi: + with open(filename, encoding="utf-8") as fi: cont = cont.from_xml(fi.read()) tmpfile = create_dummy_file() @@ -63,7 +63,7 @@ def import_xml(filename, rerun=False, interactive=True): for el in cont: if isinstance(el, db.File): - el._checksum = None + el._checksum = None # pylint: disable=protected-access target = os.path.join("downloads", el.path[1:]) if os.path.exists(target): @@ -94,7 +94,7 @@ def import_xml(filename, rerun=False, interactive=True): if not rerun: for _, el in enumerate(files.values()): - r = el.insert(unique=False) + el.insert(unique=False) else: for _, el in enumerate(files.values()): el.id = None @@ -122,8 +122,12 @@ def defineParser(): return parser -if __name__ == "__main__": +def main(): parser = defineParser() args = parser.parse_args() import_xml(args.file, args.rerun) + + +if __name__ == "__main__": + main() diff --git a/src/caosadvancedtools/json_schema_exporter.py b/src/caosadvancedtools/json_schema_exporter.py index c4c6de164aede0ce2e35b2f47fc30275552066b5..7a92eaad8aeb55ae5c34e529de4848ce4a12b0f9 100644 --- a/src/caosadvancedtools/json_schema_exporter.py +++ b/src/caosadvancedtools/json_schema_exporter.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # encoding: utf-8 # -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2023 Indiscale GmbH <info@indiscale.com> # Copyright (C) 2023 Florian Spreckelsen <f.spreckelsen@indiscale.com> @@ -58,8 +58,9 @@ from collections import OrderedDict from typing import Any, Dict, Iterable, List, Optional, Sequence, Tuple, Union import linkahead as db -from linkahead.cached import cached_query, cache_clear +from linkahead.cached import cache_clear, cached_query from linkahead.common.datatype import get_list_datatype, is_list_datatype + from .models.data_model import DataModel @@ -322,6 +323,10 @@ ui_schema : dict rt = results[0] else: rt = db.Entity() + + if isinstance(rt, str): + raise NotImplementedError("Behavior is not implemented when _no_remote == True and datatype is given as a string.") + subschema, ui_schema = self._make_segment_from_recordtype(rt) if prop.is_reference(): if prop.name: @@ -431,6 +436,7 @@ ui_schema : dict } } """ + schema: OrderedDict[str, Any] = OrderedDict({ "type": "object" }) diff --git a/src/caosadvancedtools/loadFiles.py b/src/caosadvancedtools/loadFiles.py index 77872d1dfe896688e54285551ba2e4eb9a02af99..f29bdd9e27c480d01313bc6c74553a5b6f3bebbf 100755 --- a/src/caosadvancedtools/loadFiles.py +++ b/src/caosadvancedtools/loadFiles.py @@ -2,7 +2,7 @@ # encoding: utf-8 # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2018 Research Group Biomedical Physics, # Max-Planck-Institute for Dynamics and Self-Organization Göttingen @@ -23,6 +23,18 @@ # ** end header # +"""Utilities to make the LinkAhead server aware of files. + +Installation of `caosadvancedtools` also creates an executable script ``linkahead-loadfiles`` which +calls the `loadpath` function. Get the full help with ``linkahead-loadfiles --help``. In short, +that script tells the LinkAhead server to create `FILE` entities for existing files in one branch of +the directory tree. It is necessary that this directory is already visible for the server (for +example because it is defined as ``extroot`` in the LinkAhead profile). + +""" + +from __future__ import annotations + import argparse import logging import os @@ -31,44 +43,77 @@ import sys import re from argparse import ArgumentParser from tempfile import NamedTemporaryFile +from typing import Union -import shutil -import caosdb as db +import linkahead as db logger = logging.getLogger(__name__) timeout_fallback = 20 -def convert_size(size): +def convert_size(size: int): + """Convert `size` from bytes to a human-readable file size in KB, + MB, ... + + """ if (size == 0): return '0B' size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB") - i = int(math.floor(math.log(size, 1000))) - p = math.pow(1000, i) + index = int(math.floor(math.log(size, 1000))) + p = math.pow(1000, index) s = round(size / p, 2) - return '%s %s' % (s, size_name[i]) + return f"{s} {size_name[index]}" -def combine_ignore_files(caosdbignore, localignore, dirname=None): - """appends the contents of localignore to caosdbignore and saves the result - and returns the name +def combine_ignore_files(caosdbignore: str, localignore: str, dirname=None) -> str: + """Append the contents of localignore to caosdbignore, save the result, + and return the name. + + Parameters + ---------- + caosdbignore : str + Path to parent level caosdbignore file + localignore : str + Path to current working directory's local caosdbignore. + dirname : str, optional + The path of the directory to which the temporary combined file + is written. If None is given, `NamedTemporaryFile`'s default + is used. Default is None. + + Returns + ------- + name : str + Name of the temporary combined caosdbignore file. """ tmp = NamedTemporaryFile(delete=False, mode="w", dir=dirname, prefix=".caosdbignore") - with open(caosdbignore, "r") as base: + with open(caosdbignore, "r", encoding="utf-8") as base: tmp.write(base.read()) - with open(localignore, "r") as local: + with open(localignore, "r", encoding="utf-8") as local: tmp.write(local.read()) tmp.close() return tmp.name -def compile_file_list(caosdbignore, localpath): - """creates a list of files that contain all files under localpath except - those excluded by caosdbignore +def compile_file_list(caosdbignore: str, localpath: str) -> list[str]: + """Create a list of files that contain all files under localpath except + those excluded by caosdbignore. + + Parameters + ---------- + caosdbignore : str + Path of caosdbignore file + localpath : str + Path of the directory from which the file list will be compiled. + + Returns + ------- + file_list : list[str] + List of files in `localpath` after appling the ignore rules + from `caosdbignore`. """ @@ -76,11 +121,11 @@ def compile_file_list(caosdbignore, localpath): matches = parse_gitignore(caosdbignore) current_ignore = caosdbignore non_ignored_files = [] - ignore_files = [] - for root, dirs, files in os.walk(localpath): + ignore_files: list[tuple[str, str]] = [] + for root, _, files in os.walk(localpath): # remove local ignore files that do no longer apply to the current subtree (branch switch) while len(ignore_files) > 0 and not root.startswith(ignore_files[-1][0]): - shutil.os.remove(ignore_files[-1][1]) + os.remove(ignore_files[-1][1]) ignore_files.pop() # use the global one if there are no more local ones @@ -110,10 +155,28 @@ def compile_file_list(caosdbignore, localpath): return non_ignored_files -def create_re_for_file_list(files, localroot, remoteroot): - """creates a regular expression that matches file paths contained in the - files argument and all parent directories. The prefix localroot is replaced - by the prefix remoteroot. +def create_re_for_file_list(files: list[str], localroot: str, remoteroot: str) -> str: + """Create a regular expression that matches file paths contained + in the `files` argument and all parent directories. The prefix + `localroot is replaced by the prefix `remoteroot`. + + Parameters + ---------- + files : list[str] + List of file paths to be converted to a regular expression. + localroot : str + Prefix (of the local directory root) to be removed from the + paths in `files`. + remoteroot : str + Prefix (of the LinkAhead filesystem's directory root) to be + prepended to the file paths after the removal of the + `localroot` prefix. + + Returns + ------- + regexp : str + Regular expression that matches all file paths from `files` + adapted for the remote directory root. """ regexp = "" @@ -128,8 +191,46 @@ def create_re_for_file_list(files, localroot, remoteroot): return "^("+regexp[1:]+")$" -def loadpath(path, include, exclude, prefix, dryrun, forceAllowSymlinks, caosdbignore=None, - localpath=None): +def loadpath(path: str, include: Union[str, None], exclude: Union[str, None], prefix: str, + dryrun: bool, forceAllowSymlinks: bool, caosdbignore: Union[str, None] = None, + localpath: Union[str, None] = None): + """Make all files in `path` available to the LinkAhead server as FILE entities. + + Notes + ----- + Run ``linkahead-loadfiles --help`` for more information and examples. + + Parameters + ---------- + path : str + Path to the directory the files of which are to be made + available as seen by the linkahead server (i.e., the path from + within the Docker container in a typical LinkAhead Control + setup.) + include : str or None + Regular expression matching the files that will be + included. If None, all files are matched. This is ignored if a + `caosdbignore` is provided. + exclude : str or None + Regular expression matching files that are to be included. + prefix : str + The prefix under which the files are to be inserted into + LinkAhead's file system. + dryrun : bool + Whether a dryrun should be performed. + forceAllowSymlinks : bool + Whether symlinks in the `path` to be inserted should be + processed. + caosdbignore : str, optional + Path to a caosdbignore file that defines which files shall be + included and which do not. The syntax is the same as in a + gitignore file. You must also provide the `localpath` option + since the check is done locally. If this is given, any + `include` is ignored. + localpath : str, optional + Path of `path` on the local machine. Only needed in combination with a + ``caosdbignore`` file since that is processed locally. + """ if caosdbignore: # create list of files and create regular expression for small chunks @@ -182,7 +283,11 @@ def loadpath(path, include, exclude, prefix, dryrun, forceAllowSymlinks, caosdbi def main(argv=None): - '''Command line options.''' + """Run `loadpath` with the arguments specified on the command + line, extended by the optional `argv` parameter. See ``--help`` + for more information. + + """ if argv is None: argv = sys.argv @@ -191,7 +296,7 @@ def main(argv=None): # Setup argument parser parser = ArgumentParser(description=""" -Make files that the LinkAhead server can see available als FILE entities. +Make files that the LinkAhead server can see available as FILE entities. In a typical scenario where LinkAhead runs in a Docker container and a host directory `mydir` is mounted as an extroot with name `myext`, loadfiles could be called like this: @@ -270,9 +375,7 @@ exclude is given preference over include. logger.addHandler(logging.StreamHandler(stream=sys.stdout)) logger.setLevel(logging.INFO) - con = db.get_connection() - con.timeout = float(args.timeout) - con._login() + db.configure_connection(timeout=float(args.timeout)) loadpath( path=args.path, diff --git a/src/caosadvancedtools/models/data_model.py b/src/caosadvancedtools/models/data_model.py index 266414893bcdf1ab45ee1345fc549e15f4a66250..16f5702abf015aff62123e411e5eda5c4e14361a 100644 --- a/src/caosadvancedtools/models/data_model.py +++ b/src/caosadvancedtools/models/data_model.py @@ -1,7 +1,7 @@ # encoding: utf-8 # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2018 Research Group Biomedical Physics, # Max-Planck-Institute for Dynamics and Self-Organization Göttingen @@ -23,18 +23,14 @@ # ** end header # from copy import deepcopy -# TODO(fspreck) for backwards compatibility with Python < 3.9 but this is -# actually -# [deprecated](https://docs.python.org/3/library/typing.html#typing.List), so -# remove this, when we drop support for old Python versions. -from typing import List +from typing import Optional import linkahead as db import linkahead.common.models as models from linkahead.apiutils import compare_entities, describe_diff, merge_entities -CAOSDB_INTERNAL_PROPERTIES = [ +LINKAHEAD_INTERNAL_PROPERTIES = [ "description", "name", "unit", @@ -44,19 +40,19 @@ CAOSDB_INTERNAL_PROPERTIES = [ class DataModel(dict): """Provides tools for managing a data model. - When constructing a data model the CaosDB representation can easily be + When constructing a data model the LinkAhead representation can easily be created using the classes RecordType and Propery, storing them in a - Container and inserting it in CaoSDB. However, this has one drawback: You + Container and inserting it in LinkAhead. However, this has one drawback: You cannot simply change someting and update the container. The container will insist on having valid ids for all contained Entities. This class allows you to define your model as easily but also provides you with a method (`sync_data_model`) that will sync with the data model in an - existing CaosDB instance. + existing LinkAhead instance. This is possible because entities, defined in this model, are identified - with entities in CaosDB using names. I.e. a RecordType "Experiment" in this - model will update an existing RecordType with name "Experiment" in CaosDB. + with entities in LinkAhead using names. I.e. a RecordType "Experiment" in this + model will update an existing RecordType with name "Experiment" in LinkAhead. Thus, be carefull not to change existing Entities that were created for a different purpose (e.g. someone else's experiment). @@ -85,14 +81,14 @@ class DataModel(dict): def append(self, entity: db.Entity): self[entity.name] = entity - def extend(self, entities: List[db.Entity]): + def extend(self, entities: list[db.Entity]): for entity in entities: self.append(entity) def sync_data_model(self, noquestion: bool = False, verbose: bool = True): - """Synchronize this DataModel with a CaosDB instance. + """Synchronize this DataModel with a LinkAhead instance. - Updates existing entities from the CaosDB instance and inserts + Updates existing entities from the LinkAhead instance and inserts non-existing entities into the instance. Note: This allows to easily overwrite changes that were made to an existing data model. Use this function with care and double check its effect. @@ -111,6 +107,7 @@ class DataModel(dict): existing_entities = db.Container().extend( DataModel.entities_without( self.values(), [e.name.lower() for e in non_existing_entities])) + self.sync_ids_by_name(tmp_exist) if len(non_existing_entities) > 0: @@ -138,15 +135,17 @@ class DataModel(dict): any_change = False for ent in existing_entities: - if ent.name in CAOSDB_INTERNAL_PROPERTIES: + if ent.name in LINKAHEAD_INTERNAL_PROPERTIES: # Workaround for the usage of internal properties like name # in via the extern keyword: ref = db.Property(name=ent.name).retrieve() else: query = db.Query(f"FIND ENTITY with id={ent.id}") ref = query.execute(unique=True) - diff = (describe_diff(*compare_entities(ent, ref - ), name=ent.name)) + diff = (describe_diff(*compare_entities(ent, ref), + name=ent.name, + label_e0="version from the yaml file", + label_e1="version from LinkAhead")) if diff != "": if verbose: @@ -169,12 +168,12 @@ class DataModel(dict): @staticmethod def get_existing_entities(entities): """ Return a list with those entities of the supplied iterable that - exist in the CaosDB instance. + exist in the LinkAhead instance. Args ---- entities : iterable - The entities to be retrieved. This object will not be moidified. + The entities to be retrieved. This object will not be modified. Raises ------ @@ -248,7 +247,7 @@ class DataModel(dict): for par in entity.get_parents(): if par.name.lower() == valid_e.name.lower(): - par._wrap(valid_e) + par.id = valid_e.id def collect_entities(self): """ Collects all entities: explicitly defined RecordTypes and @@ -264,7 +263,8 @@ class DataModel(dict): return list(all_ents.values()) - def get_deep(self, name: str, visited_props: dict = None, visited_parents: set = None): + def get_deep(self, name: str, visited_props: Optional[dict] = None, + visited_parents: Optional[set] = None): """Attempt to resolve references for the given ``name``. The returned entity has all the properties it inherits from its ancestry and all properties @@ -293,7 +293,7 @@ class DataModel(dict): if parent.name in visited_parents: continue visited_parents.add(parent.name) - parent_importance = importances.get(parent._flags.get("inheritance"), 999) + parent_importance = importances.get(parent.flags.get("inheritance"), 999) if parent.name in self: deep_parent = self.get_deep(parent.name, # visited_props=visited_props, visited_parents=visited_parents @@ -302,7 +302,7 @@ class DataModel(dict): for prop in deep_parent.properties: importance = importances[deep_parent.get_importance(prop.name)] if (importance <= parent_importance - and prop.name not in [prop.name for prop in entity.properties]): + and prop.name not in [p.name for p in entity.properties]): entity.add_property(prop) else: print(f"Referenced parent \"{parent.name}\" not found in data model.") diff --git a/src/caosadvancedtools/models/parser.py b/src/caosadvancedtools/models/parser.py index 175f2f7fbfc5408e70e37740d7ae0506d547c628..407346179fe0190fd9e259ab63b14c61461bd1c1 100644 --- a/src/caosadvancedtools/models/parser.py +++ b/src/caosadvancedtools/models/parser.py @@ -1,1022 +1,1059 @@ -# This file is a part of the CaosDB Project. -# -# Copyright (C) 2023 IndiScale GmbH <info@indiscale.com> -# Copyright (C) 2022 Florian Spreckelsen <f.spreckelsen@indiscale.com> -# Copyright (C) 2023 Daniel Hornung <d.hornung@indiscale.com> -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see <https://www.gnu.org/licenses/>. - -""" -This module (and script) provides methods to read a DataModel from a YAML file. - -If a file name is passed to parse_model_from_yaml it is parsed and a DataModel -is created. The yaml file needs to be structured in a certain way which will be -described in the following. - -The file should only contain a dictionary. The keys are the names of -RecordTypes or Properties. The values are again dictionaries describing the -entities. This information can be defined via the keys listed in KEYWORDS. -Notably, properties can be given in a dictionary under the xxxx_properties keys -and will be added with the respective importance. These properties can be -RecordTypes or Properties and can be defined right there. -Every Property or RecordType only needs to be defined once anywhere. When it is -not defined, simply the name can be supplied with no value. -Parents can be provided under the 'inherit_from_xxxx' keywords. The value needs -to be a list with the names. Here, NO NEW entities can be defined. -""" -import argparse -import json -import jsonref -import re -import sys -import yaml - -from typing import List, Optional -from warnings import warn - -import jsonschema -import linkahead as db - -from linkahead.common.datatype import get_list_datatype -from .data_model import CAOSDB_INTERNAL_PROPERTIES, DataModel - -# Keywords which are allowed in data model descriptions. -KEYWORDS = ["importance", - "datatype", # for example TEXT, INTEGER or REFERENCE - "unit", - "description", - "recommended_properties", - "obligatory_properties", - "suggested_properties", - "inherit_from_recommended", - "inherit_from_suggested", - "inherit_from_obligatory", - "role", - "value", - ] - -# TODO: check whether it's really ignored -# These KEYWORDS are not forbidden as properties, but merely ignored. -KEYWORDS_IGNORED = [ - "unit", -] - -JSON_SCHEMA_ATOMIC_TYPES = [ - "string", - "boolean", - "integer", - "number", - "null" -] - - -# Taken from https://stackoverflow.com/a/53647080, CC-BY-SA, 2018 by -# https://stackoverflow.com/users/2572431/augurar - - -class SafeLineLoader(yaml.SafeLoader): - """Load a line and keep meta-information. - - Note that this will add a `__line__` element to all the dicts. - """ - - def construct_mapping(self, node, deep=False): - """Overwritung the parent method.""" - mapping = super().construct_mapping(node, deep=deep) - # Add 1 so line numbering starts at 1 - mapping['__line__'] = node.start_mark.line + 1 - - return mapping -# End of https://stackoverflow.com/a/53647080 - - -class TwiceDefinedException(Exception): - def __init__(self, name): - super().__init__("The Entity '{}' was defined multiple times!".format( - name)) - - -class YamlDefinitionError(RuntimeError): - def __init__(self, line, template=None): - if not template: - template = "Error in YAML definition in line {}." - super().__init__(template.format(line)) - - -class JsonSchemaDefinitionError(RuntimeError): - # @author Florian Spreckelsen - # @date 2022-02-17 - # @review Daniel Hornung 2022-02-18 - def __init__(self, msg): - super().__init__(msg) - - -def parse_model_from_yaml(filename, existing_model: Optional[dict] = None, debug: bool = False): - """Parse a data model from a YAML file. - -This is a convenience function if the Parser object is not needed, it calls -``Parser.parse_model_from_yaml(...)`` internally. - - -Parameters ----------- - -existing_model : dict, optional - An existing model to which the created model shall be added. - -debug : bool, optional - If True, turn on miscellaneous debugging. Default is False. - """ - parser = Parser(debug=debug) - - return parser.parse_model_from_yaml(filename, existing_model=existing_model) - - -def parse_model_from_string(string, existing_model: Optional[dict] = None, debug: bool = False): - """Parse a data model from a YAML string - -This is a convenience function if the Parser object is not needed, it calls -``Parser.parse_model_from_string(...)`` internally. - -Parameters ----------- - -existing_model : dict, optional - An existing model to which the created model shall be added. - -debug : bool, optional - If True, turn on miscellaneous debugging. Default is False. - """ - parser = Parser(debug=debug) - - return parser.parse_model_from_string(string, existing_model=existing_model) - - -def parse_model_from_json_schema( - filename: str, - top_level_recordtype: bool = True, - types_for_missing_array_items: dict = {}, - ignore_unspecified_array_items: bool = False, - existing_model: Optional[dict] = None -): - """Return a datamodel parsed from a json schema definition. - - Parameters - ---------- - - filename : str - The path of the json schema file that is to be parsed - - top_level_recordtype : bool, optional - Whether there is a record type defined at the top level of the - schema. Default is true. - - types_for_missing_array_items : dict, optional - dictionary containing fall-back types for json entries with `type: - array` but without `items` specification. Default is an empty dict. - - ignore_unspecified_array_items : bool, optional - Whether to ignore `type: array` entries the type of which is not - specified by their `items` property or given in - `types_for_missing_array_items`. An error is raised if they are not - ignored. Default is False. - - existing_model : dict, optional - An existing model to which the created model shall be added. Not implemented yet. - - Returns - ------- - - out : Datamodel - The datamodel generated from the input schema which then can be used for - synchronizing with CaosDB. - - Note - ---- - This is an experimental feature, see ``JsonSchemaParser`` for information - about the limitations of the current implementation. - - """ - if existing_model is not None: - raise NotImplementedError("Adding to an existing model is not implemented yet.") - - # @author Florian Spreckelsen - # @date 2022-02-17 - # @review Timm Fitschen 2023-05-25 - parser = JsonSchemaParser(types_for_missing_array_items, ignore_unspecified_array_items) - - return parser.parse_model_from_json_schema(filename, top_level_recordtype) - - -class Parser(object): - def __init__(self, debug: bool = False): - """Initialize an empty parser object and initialize the dictionary of entities and the list of - treated elements. - -Parameters ----------- - -debug : bool, optional - If True, turn on miscellaneous debugging. Default is False. - - """ - self.model = {} - self.treated = [] - self.debug = debug - - def parse_model_from_yaml(self, filename, existing_model: Optional[dict] = None): - """Create and return a data model from the given file. - - Parameters - ---------- - filename : str - The path to the YAML file. - - existing_model : dict, optional - An existing model to which the created model shall be added. - - Returns - ------- - out : data_model.DataModel - The created DataModel - """ - with open(filename, 'r') as outfile: - ymlmodel = yaml.load(outfile, Loader=SafeLineLoader) - - return self._create_model_from_dict(ymlmodel, existing_model=existing_model) - - def parse_model_from_string(self, string, existing_model: Optional[dict] = None): - """Create and return a data model from the given YAML string. - - Parameters - ---------- - string : str - The YAML string. - - existing_model : dict, optional - An existing model to which the created model shall be added. - - Returns - ------- - out : data_model.DataModel - The created DataModel - """ - ymlmodel = yaml.load(string, Loader=SafeLineLoader) - - return self._create_model_from_dict(ymlmodel, existing_model=existing_model) - - def _create_model_from_dict(self, ymlmodel, existing_model: Optional[dict] = None): - """Create and return a data model out of the YAML dict `ymlmodel`. - - Parameters - ---------- - ymlmodel : dict - The dictionary parsed from a YAML file. - - existing_model : dict, optional - An existing model to which the created model shall be added. - - Returns - ------- - out : data_model.DataModel - The created DataModel - """ - - if not isinstance(ymlmodel, dict): - raise ValueError("Yaml file should only contain one dictionary!") - - if existing_model is not None: - self.model.update(existing_model) - - # Extern keyword: - # The extern keyword can be used to include Properties and RecordTypes - # from existing CaosDB datamodels into the current model. - # Any name included in the list specified by the extern keyword - # will be used in queries to retrieve a property or (if no property exists) - # a record type with the name of the element. - # The retrieved entity will be added to the model. - # If no entity with that name is found an exception is raised. - - if "extern" not in ymlmodel: - ymlmodel["extern"] = [] - - for name in ymlmodel["extern"]: - if name in CAOSDB_INTERNAL_PROPERTIES: - self.model[name] = db.Property(name=name).retrieve() - continue - for role in ("Property", "RecordType", "Record", "File"): - if db.execute_query("COUNT {} \"{}\"".format(role, name)) > 0: - self.model[name] = db.execute_query( - f"FIND {role} WITH name=\"{name}\"", unique=True) - break - else: - raise Exception("Did not find {}".format(name)) - - ymlmodel.pop("extern") - - # add all names to ymlmodel; initialize properties - - for name, entity in ymlmodel.items(): - self._add_entity_to_model(name, entity) - # initialize recordtypes - self._set_recordtypes() - self._check_and_convert_datatypes() - - for name, entity in ymlmodel.items(): - try: - self._treat_entity(name, entity, line=ymlmodel["__line__"]) - except ValueError as err: - err_str = err.args[0].replace("invalid keyword:", - f"invalid keyword in line {entity['__line__']}:", 1) - raise ValueError(err_str, *err.args[1:]) from err - - return DataModel(self.model.values()) - - @staticmethod - def _stringify(name, context=None): - """Make a string out of `name`. - - Warnings are emitted for difficult values of `name`. - - Parameters - ---------- - name : - The value to be converted to a string. - - context : obj - Will be printed in the case of warnings. - - Returns - ------- - out : str - If `name` was a string, return it. Else return str(`name`). - """ - - if name is None: - print("WARNING: Name of this context is None: {}".format(context), - file=sys.stderr) - - if not isinstance(name, str): - name = str(name) - - return name - - def _add_entity_to_model(self, name, definition): - """ adds names of Properties and RecordTypes to the model dictionary - - Properties are also initialized. - - name is the key of the yaml element and definition the value. - """ - - if name == "__line__": - return - name = self._stringify(name) - - if name not in self.model: - self.model[name] = None - - if definition is None: - return - - if (self.model[name] is None and isinstance(definition, dict) - # is it a property - and "datatype" in definition - # but not simply an RT of the model - and not (get_list_datatype(definition["datatype"]) == name and - get_list_datatype(definition["datatype"]) in self.model)): - - # and create the new property - self.model[name] = db.Property(name=name, - datatype=definition["datatype"]) - elif (self.model[name] is None and isinstance(definition, dict) - and "role" in definition): - if definition["role"] == "RecordType": - self.model[name] = db.RecordType(name=name) - elif definition["role"] == "Record": - self.model[name] = db.Record(name=name) - elif definition["role"] == "File": - # TODO(fspreck) Implement files at some later point in time - raise NotImplementedError( - "The definition of file objects is not yet implemented.") - - # self.model[name] = db.File(name=name) - elif definition["role"] == "Property": - self.model[name] = db.Property(name=name) - else: - raise RuntimeError("Unknown role {} in definition of entity.".format( - definition["role"])) - - # for setting values of properties directly: - if not isinstance(definition, dict): - return - - # add other definitions recursively - for prop_type in ["recommended_properties", - "suggested_properties", "obligatory_properties"]: - - if prop_type in definition: - # Empty property mapping should be allowed. - - if definition[prop_type] is None: - definition[prop_type] = {} - try: - for n, e in definition[prop_type].items(): - if n == "__line__": - continue - self._add_entity_to_model(n, e) - except AttributeError as ate: - if ate.args[0].endswith("'items'"): - line = definition["__line__"] - - if isinstance(definition[prop_type], list): - line = definition[prop_type][0]["__line__"] - raise YamlDefinitionError(line) from None - raise - - if self.debug and self.model[name] is not None: - self.model[name].__line__ = definition["__line__"] - - def _add_to_recordtype(self, ent_name, props, importance): - """Add properties to a RecordType. - - Parameters - ---------- - ent_name : str - The name of the entity to which the properties shall be added. - - props : dict [str -> dict or :doc:`Entity`] - The properties, indexed by their names. Properties may be given as :doc:`Entity` objects - or as dictionaries. - - importance - The importance as used in :doc:`Entity.add_property`. - - Returns - ------- - None - - """ - - for n, e in props.items(): - if n in KEYWORDS: - if n in KEYWORDS_IGNORED: - continue - raise YamlDefinitionError("Unexpected keyword in line {}: {}".format( - props["__line__"], n)) - - if n == "__line__": - continue - n = self._stringify(n) - - if isinstance(e, dict): - if "datatype" in e and get_list_datatype(e["datatype"]) is not None: - # Reuse the existing datatype for lists. - datatype = db.LIST(get_list_datatype(e["datatype"])) - else: - # Ignore a possible e["datatype"] here if it's not a list - # since it has been treated in the definition of the - # property (entity) already - datatype = None - if "value" in e: - value = e["value"] - else: - value = None - - else: - value = e - datatype = None - - self.model[ent_name].add_property(name=n, - value=value, - importance=importance, - datatype=datatype) - - def _inherit(self, name, prop, inheritance): - if not isinstance(prop, list): - if isinstance(prop, str): - raise YamlDefinitionError( - f"Parents must be a list but is given as string: {name} > {prop}") - raise YamlDefinitionError("Parents must be a list, error in line {}".format( - prop["__line__"])) - - for pname in prop: - if not isinstance(pname, str): - raise ValueError("Only provide the names of parents.") - self.model[name].add_parent(name=pname, inheritance=inheritance) - - def _treat_entity(self, name, definition, line=None): - """Parse the definition and the information to the entity.""" - - if name == "__line__": - return - name = self._stringify(name) - - try: - if definition is None: - return - - # for setting values of properties directly: - if not isinstance(definition, dict): - return - - # These definition items must be handled even for list props. - for prop_name, prop in definition.items(): - if prop_name == "description": - self.model[name].description = prop - - # For lists, everything else is not needed at this level. - if ("datatype" in definition and definition["datatype"].startswith("LIST")): - return - - if name in self.treated: - raise TwiceDefinedException(name) - - for prop_name, prop in definition.items(): - if prop_name == "__line__": - continue - line = definition["__line__"] - - if prop_name == "unit": - self.model[name].unit = prop - - elif prop_name == "value": - self.model[name].value = prop - - elif prop_name == "description": - # Handled above - continue - - elif prop_name == "recommended_properties": - self._add_to_recordtype( - name, prop, importance=db.RECOMMENDED) - - for n, e in prop.items(): - self._treat_entity(n, e) - - elif prop_name == "obligatory_properties": - self._add_to_recordtype( - name, prop, importance=db.OBLIGATORY) - - for n, e in prop.items(): - self._treat_entity(n, e) - - elif prop_name == "suggested_properties": - self._add_to_recordtype( - name, prop, importance=db.SUGGESTED) - - for n, e in prop.items(): - self._treat_entity(n, e) - - # datatype is already set - elif prop_name == "datatype": - continue - - # role has already been used - elif prop_name == "role": - continue - - elif prop_name == "inherit_from_obligatory": - self._inherit(name, prop, db.OBLIGATORY) - elif prop_name == "inherit_from_recommended": - self._inherit(name, prop, db.RECOMMENDED) - elif prop_name == "inherit_from_suggested": - self._inherit(name, prop, db.SUGGESTED) - - else: - raise ValueError("invalid keyword: {}".format(prop_name)) - except AttributeError as ate: - if ate.args[0].endswith("'items'"): - raise YamlDefinitionError(line) from None - except Exception as e: - print("Error in treating: "+name) - raise e - self.treated.append(name) - - def _check_and_convert_datatypes(self): - """ checks if datatype is valid. - datatype of properties is simply initialized with string. Here, we - iterate over properties and check whether it is a base datatype of a - name that was defined in the model (or extern part) - - the string representations are replaced with caosdb objects - - """ - - for key, value in self.model.items(): - - if isinstance(value, db.Property): - dtype = value.datatype - is_list = False - - if get_list_datatype(dtype) is not None: - dtype = get_list_datatype(dtype) - is_list = True - - dtype_name = dtype - if not isinstance(dtype_name, str): - dtype_name = dtype.name - - if dtype_name in self.model: - if is_list: - value.datatype = db.LIST(self.model[dtype_name]) - else: - value.datatype = self.model[dtype_name] - - continue - - if dtype in [db.DOUBLE, - db.REFERENCE, - db.TEXT, - db.DATETIME, - db.INTEGER, - db.FILE, - db.BOOLEAN]: - - if is_list: - value.datatype = db.LIST(db.__getattribute__( # pylint: disable=no-member - dtype)) - else: - value.datatype = db.__getattribute__( # pylint: disable=no-member - dtype) - - continue - - raise ValueError("Property {} has an unknown datatype: {}".format( - value.name, dtype_name)) - - def _set_recordtypes(self): - """ properties are defined in first iteration; set remaining as RTs """ - - for key, value in self.model.items(): - if value is None: - self.model[key] = db.RecordType(name=key) - - -class JsonSchemaParser(Parser): - """Extends the yaml parser to read in datamodels defined in a json schema. - - **EXPERIMENTAL:** While this class can already be used to create data models - from basic json schemas, there are the following limitations and missing - features: - - * Due to limitations of json-schema itself, we currently do not support - inheritance in the imported data models - * The same goes for suggested properties of RecordTypes - * Already defined RecordTypes and (scalar) Properties can't be re-used as - list properties - * Reference properties that are different from the referenced RT. (Although - this is possible for list of references) - * Values - * Roles - * The extern keyword from the yaml parser - - """ - # @author Florian Spreckelsen - # @date 2022-02-17 - # @review Timm Fitschen 2023-05-25 - - def __init__(self, types_for_missing_array_items={}, ignore_unspecified_array_items=False): - super().__init__() - self.types_for_missing_array_items = types_for_missing_array_items - self.ignore_unspecified_array_items = ignore_unspecified_array_items - - def parse_model_from_json_schema(self, filename: str, top_level_recordtype: bool = True): - """Return a datamodel created from the definition in the json schema in - `filename`. - - Parameters - ---------- - filename : str - The path to the json-schema file containing the datamodel definition - top_level_recordtype : bool, optional - Whether there is a record type defined at the top level of the - schema. Default is true. - - Returns - ------- - out : data_model.DataModel - The created DataModel - """ - # @author Florian Spreckelsen - # @date 2022-02-17 - # @review Timm Fitschen 2023-05-25 - with open(filename, 'r') as schema_file: - model_dict = jsonref.load(schema_file) - - return self._create_model_from_dict(model_dict, top_level_recordtype=top_level_recordtype) - - def _create_model_from_dict(self, model_dict: [dict, List[dict]], top_level_recordtype: bool = True): - """Parse a dictionary and return the Datamodel created from it. - - The dictionary was typically created from the model definition in a json schema file. - - Parameters - ---------- - model_dict : dict or list[dict] - One or several dictionaries read in from a json-schema file - top_level_recordtype : bool, optional - Whether there is a record type defined at the top level of the - schema. Default is true. - - Returns - ------- - our : data_model.DataModel - The datamodel defined in `model_dict` - """ - # @review Timm Fitschen 2023-05-25 - if isinstance(model_dict, dict): - model_dict = [model_dict] - - for ii, elt in enumerate(model_dict): - try: - jsonschema.Draft202012Validator.check_schema(elt) - except jsonschema.SchemaError as err: - key = elt["title"] if "title" in elt else f"element {ii}" - raise JsonSchemaDefinitionError( - f"Json Schema error in {key}:\n{str(err)}") from err - - if top_level_recordtype: - if "title" not in elt: - raise JsonSchemaDefinitionError( - f"Object {ii+1} is lacking the `title` key word") - if "type" not in elt: - raise JsonSchemaDefinitionError( - f"Object {ii+1} is lacking the `type` key word") - # Check if this is a valid Json Schema - name = self._stringify(elt["title"], context=elt) - self._treat_element(elt, name) - elif "properties" in elt or "patternProperties" in elt: - # No top-level type but there are entities - if "properties" in elt: - for key, prop in elt["properties"].items(): - name = self._get_name_from_property(key, prop) - self._treat_element(prop, name) - if "patternProperties" in elt: - # See also treatment in ``_treat_record_type``. Since here, - # there is no top-level RT we use the prefix `__Pattern`, - # i.e., the resulting Record Types will be called - # `__PatternElement`. - self._treat_pattern_properties( - elt["patternProperties"], name_prefix="__Pattern") - else: - # Neither RecordType itself, nor further properties in schema, - # so nothing to do here. Maybe add something in the future. - continue - - return DataModel(self.model.values()) - - def _get_name_from_property(self, key: str, prop: dict): - # @review Timm Fitschen 2023-05-25 - if "title" in prop: - name = self._stringify(prop["title"]) - else: - name = self._stringify(key) - - return name - - def _get_atomic_datatype(self, elt): - # @review Timm Fitschen 2023-05-25 - if elt["type"] == "string": - if "format" in elt and elt["format"] in ["date", "date-time"]: - return db.DATETIME - else: - return db.TEXT - elif elt["type"] == "integer": - return db.INTEGER - elif elt["type"] == "number": - return db.DOUBLE - elif elt["type"] == "boolean": - return db.BOOLEAN - elif elt["type"] == "null": - # This could be any datatype since a valid json will never have a - # value in a null property. We use TEXT for convenience. - return db.TEXT - else: - raise JsonSchemaDefinitionError(f"Unkown atomic type in {elt}.") - - def _treat_element(self, elt: dict, name: str): - # @review Timm Fitschen 2023-05-25 - force_list = False - if name in self.model: - return self.model[name], force_list - if "type" not in elt: - # Each element must have a specific type - raise JsonSchemaDefinitionError( - f"`type` is missing in element {name}.") - if name == "name": - # This is identified with the CaosDB name property as long as the - # type is correct. - if not elt["type"] == "string" and "string" not in elt["type"]: - raise JsonSchemaDefinitionError( - "The 'name' property must be string-typed, otherwise it cannot " - "be identified with CaosDB's name property." - ) - return None, force_list - # LinkAhead suports null for all types, so in the very special case of - # `"type": ["null", "<other_type>"]`, only consider the other type: - if isinstance(elt["type"], list) and len(elt["type"]) == 2 and "null" in elt["type"]: - elt["type"].remove("null") - elt["type"] = elt["type"][0] - if "enum" in elt: - ent = self._treat_enum(elt, name) - elif elt["type"] in JSON_SCHEMA_ATOMIC_TYPES: - ent = db.Property( - name=name, datatype=self._get_atomic_datatype(elt)) - elif elt["type"] == "object": - ent = self._treat_record_type(elt, name) - elif elt["type"] == "array": - ent, force_list = self._treat_list(elt, name) - else: - raise NotImplementedError( - f"Cannot parse items of type '{elt['type']}' (yet).") - if "description" in elt and ent.description is None: - # There is a description and it hasn't been set by another - # treat_something function - ent.description = elt["description"] - - if ent is not None: - self.model[name] = ent - return ent, force_list - - def _treat_record_type(self, elt: dict, name: str): - # @review Timm Fitschen 2023-05-25 - rt = db.RecordType(name=name) - if "required" in elt: - required = elt["required"] - else: - required = [] - if "properties" in elt: - for key, prop in elt["properties"].items(): - name = self._get_name_from_property(key, prop) - prop_ent, force_list = self._treat_element(prop, name) - if prop_ent is None: - # Nothing to be appended since the property has to be - # treated specially. - continue - importance = db.OBLIGATORY if key in required else db.RECOMMENDED - if not force_list: - rt.add_property(prop_ent, importance=importance) - else: - # Special case of rt used as a list property - rt.add_property(prop_ent, importance=importance, - datatype=db.LIST(prop_ent)) - - if "patternProperties" in elt: - - pattern_property_rts = self._treat_pattern_properties( - elt["patternProperties"], name_prefix=name) - for ppr in pattern_property_rts: - # add reference to pattern property type. These can never be - # obligatory since pattern properties cannot be required in the - # original schema (since their actual names are not known a - # priori). - rt.add_property(ppr) - - if "description" in elt: - rt.description = elt["description"] - return rt - - def _treat_enum(self, elt: dict, name: str): - # @review Timm Fitschen 2022-02-30 - if "type" in elt and elt["type"] == "integer": - raise NotImplementedError( - "Integer-enums are not allowd until " - "https://gitlab.indiscale.com/caosdb/src/caosdb-server/-/issues/224 " - "has been fixed." - ) - rt = db.RecordType(name=name) - for enum_elt in elt["enum"]: - rec = db.Record(name=self._stringify(enum_elt)) - rec.add_parent(rt) - self.model[enum_elt] = rec - - return rt - - def _treat_list(self, elt: dict, name: str): - # @review Timm Fitschen 2023-05-25 - - if "items" not in elt and name not in self.types_for_missing_array_items: - if self.ignore_unspecified_array_items: - return None, False - raise JsonSchemaDefinitionError( - f"The definition of the list items is missing in {elt}.") - if "items" in elt: - items = elt["items"] - if "enum" in items: - return self._treat_enum(items, name), True - if items["type"] in JSON_SCHEMA_ATOMIC_TYPES: - datatype = db.LIST(self._get_atomic_datatype(items)) - return db.Property(name=name, datatype=datatype), False - if items["type"] == "object": - if "title" not in items or self._stringify(items["title"]) == name: - # Property is RecordType - return self._treat_record_type(items, name), True - else: - # List property will be an entity of its own with a name - # different from the referenced RT - ref_rt = self._treat_record_type( - items, self._stringify(items["title"])) - self.model[ref_rt.name] = ref_rt - return db.Property(name=name, datatype=db.LIST(ref_rt)), False - else: - # Use predefined type: - datatype = db.LIST(self.types_for_missing_array_items[name]) - return db.Property(name=name, datatype=datatype), False - - def _get_pattern_prop(self): - # @review Timm Fitschen 2023-05-25 - if "__pattern_property_pattern_property" in self.model: - return self.model["__pattern_property_pattern_property"] - pp = db.Property(name="__matched_pattern", datatype=db.TEXT) - self.model["__pattern_property_pattern_property"] = pp - return pp - - def _treat_pattern_properties(self, pattern_elements, name_prefix=""): - """Special Treatment for pattern properties: A RecordType is created for - each pattern property. In case of a `type: object` PatternProperty, the - remaining properties of the JSON entry are appended to the new - RecordType; in case of an atomic type PatternProperty, a single value - Property is added to the RecordType. - - Raises - ------ - NotImplementedError - In case of patternProperties with non-object, non-atomic type, e.g., - array. - - """ - # @review Timm Fitschen 2023-05-25 - num_patterns = len(pattern_elements) - pattern_prop = self._get_pattern_prop() - returns = [] - for ii, (key, element) in enumerate(pattern_elements.items()): - if "title" not in element: - name_suffix = f"_{ii+1}" if num_patterns > 1 else "" - name = name_prefix + "Entry" + name_suffix - else: - name = element["title"] - if element["type"] == "object": - # simple, is already an object, so can be treated like any other - # record type. - pattern_type = self._treat_record_type(element, name) - elif element["type"] in JSON_SCHEMA_ATOMIC_TYPES: - # create a property that stores the actual value of the pattern - # property. - propname = f"{name}_value" - prop = db.Property(name=propname, datatype=self._get_atomic_datatype(element)) - self.model[propname] = prop - pattern_type = db.RecordType(name=name) - pattern_type.add_property(prop) - else: - raise NotImplementedError( - "Pattern properties are currently only supported for types " + - ", ".join(JSON_SCHEMA_ATOMIC_TYPES) + ", and object.") - - # Add pattern property and description - pattern_type.add_property(pattern_prop, importance=db.OBLIGATORY) - if pattern_type.description: - pattern_type.description += f"\n\npattern: {key}" - else: - pattern_type.description = f"pattern: {key}" - - self.model[name] = pattern_type - returns.append(pattern_type) - - return returns - - -if __name__ == "__main__": - parser = argparse.ArgumentParser(description=__doc__, - formatter_class=argparse.RawTextHelpFormatter) - parser.add_argument("data_model", - help="Path name of the data model file (yaml or json) to be used.") - parser.add_argument("--sync", action="store_true", - help="Whether or not to sync the data model with the server.") - parser.add_argument("--noquestion", action="store_true", - help="Whether or not to ask questions during synchronization.") - parser.add_argument("--print", action="store_true", - help="Whether or not to print the data model.") - - args = parser.parse_args() - if args.data_model.endswith(".json"): - model = parse_model_from_json_schema(args.data_model) - elif args.data_model.endswith(".yml") or args.data_model.endswith(".yaml"): - model = parse_model_from_yaml(args.data_model) - else: - raise RuntimeError(f"Unknown file ending of data model: {args.data_model}") - if args.print: - print(model) - if args.sync: - model.sync_data_model(noquestion=args.noquestion) +# This file is a part of the LinkAhead project. +# +# Copyright (C) 2023 IndiScale GmbH <info@indiscale.com> +# Copyright (C) 2022 Florian Spreckelsen <f.spreckelsen@indiscale.com> +# Copyright (C) 2023 Daniel Hornung <d.hornung@indiscale.com> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +""" +This module (and script) provides methods to read a DataModel from a YAML file. + +If a file name is passed to parse_model_from_yaml it is parsed and a DataModel +is created. The yaml file needs to be structured in a certain way which will be +described in the following. + +The file should only contain a dictionary. The keys are the names of +RecordTypes or Properties. The values are again dictionaries describing the +entities. This information can be defined via the keys listed in KEYWORDS. +Notably, properties can be given in a dictionary under the xxxx_properties keys +and will be added with the respective importance. These properties can be +RecordTypes or Properties and can be defined right there. +Every Property or RecordType only needs to be defined once anywhere. When it is +not defined, simply the name can be supplied with no value. +Parents can be provided under the 'inherit_from_xxxx' keywords. The value needs +to be a list with the names. Here, NO NEW entities can be defined. +""" +import argparse +import sys +from typing import List, Optional, Union + +import jsonref +import jsonschema +import linkahead as db +import yaml +from linkahead.common.datatype import get_list_datatype + +from .data_model import LINKAHEAD_INTERNAL_PROPERTIES, DataModel + +# Keywords which are allowed in data model descriptions. +KEYWORDS = ["importance", + "datatype", # for example TEXT, INTEGER or REFERENCE + "unit", + "description", + "recommended_properties", + "obligatory_properties", + "suggested_properties", + "inherit_from_recommended", + "inherit_from_suggested", + "inherit_from_obligatory", + "role", + "value", + ] + +# TODO: check whether it's really ignored +# These KEYWORDS are not forbidden as properties, but merely ignored. +KEYWORDS_IGNORED = [ + "unit", +] + +JSON_SCHEMA_ATOMIC_TYPES = [ + "string", + "boolean", + "integer", + "number", + "null" +] + + +# Taken from https://stackoverflow.com/a/53647080, CC-BY-SA, 2018 by +# https://stackoverflow.com/users/2572431/augurar + + +class SafeLineLoader(yaml.SafeLoader): + """Load a line and keep meta-information. + + Note that this will add a `__line__` element to all the dicts. + """ + + def construct_mapping(self, node, deep=False): + """Overwritung the parent method.""" + mapping = super().construct_mapping(node, deep=deep) + # Add 1 so line numbering starts at 1 + mapping['__line__'] = node.start_mark.line + 1 + + return mapping +# End of https://stackoverflow.com/a/53647080 + + +class TwiceDefinedException(Exception): + def __init__(self, name): + super().__init__("The Entity '{}' was defined multiple times!".format( + name)) + + +class YamlDefinitionError(RuntimeError): + def __init__(self, line, template=None): + if not template: + template = "Error in YAML definition in line {}." + super().__init__(template.format(line)) + + +class JsonSchemaDefinitionError(RuntimeError): + # @author Florian Spreckelsen + # @date 2022-02-17 + # @review Daniel Hornung 2022-02-18 + def __init__(self, msg): + super().__init__(msg) + + +def parse_model_from_yaml(filename, existing_model: Optional[dict] = None, debug: bool = False): + """Parse a data model from a YAML file. + +This is a convenience function if the Parser object is not needed, it calls +``Parser.parse_model_from_yaml(...)`` internally. + + +Parameters +---------- + +existing_model : dict, optional + An existing model to which the created model shall be added. + +debug : bool, optional + If True, turn on miscellaneous debugging. Default is False. + """ + parser = Parser(debug=debug) + + return parser.parse_model_from_yaml(filename, existing_model=existing_model) + + +def parse_model_from_string(string, existing_model: Optional[dict] = None, debug: bool = False): + """Parse a data model from a YAML string + +This is a convenience function if the Parser object is not needed, it calls +``Parser.parse_model_from_string(...)`` internally. + +Parameters +---------- + +existing_model : dict, optional + An existing model to which the created model shall be added. + +debug : bool, optional + If True, turn on miscellaneous debugging. Default is False. + """ + parser = Parser(debug=debug) + + return parser.parse_model_from_string(string, existing_model=existing_model) + + +def parse_model_from_json_schema( + filename: str, + top_level_recordtype: bool = True, + types_for_missing_array_items: Optional[dict] = None, + ignore_unspecified_array_items: bool = False, + existing_model: Optional[dict] = None +): + """Return a datamodel parsed from a json schema definition. + + Parameters + ---------- + + filename : str + The path of the json schema file that is to be parsed + + top_level_recordtype : bool, optional + Whether there is a record type defined at the top level of the + schema. Default is true. + + types_for_missing_array_items : dict, optional + dictionary containing fall-back types for json entries with `type: + array` but without `items` specification. Default is an empty dict. + + ignore_unspecified_array_items : bool, optional + Whether to ignore `type: array` entries the type of which is not + specified by their `items` property or given in + `types_for_missing_array_items`. An error is raised if they are not + ignored. Default is False. + + existing_model : dict, optional + An existing model to which the created model shall be added. Not implemented yet. + + Returns + ------- + + out : Datamodel + The datamodel generated from the input schema which then can be used for + synchronizing with LinkAhead. + + Note + ---- + This is an experimental feature, see ``JsonSchemaParser`` for information + about the limitations of the current implementation. + + """ + if types_for_missing_array_items is None: + types_for_missing_array_items = {} + + if existing_model is not None: + raise NotImplementedError("Adding to an existing model is not implemented yet.") + + # @author Florian Spreckelsen + # @date 2022-02-17 + # @review Timm Fitschen 2023-05-25 + parser = JsonSchemaParser(types_for_missing_array_items, ignore_unspecified_array_items) + + return parser.parse_model_from_json_schema(filename, top_level_recordtype) + + +class Parser(object): + def __init__(self, debug: bool = False): + """Initialize an empty parser object and initialize the dictionary of entities and the list of + treated elements. + +Parameters +---------- + +debug : bool, optional + If True, turn on miscellaneous debugging. Default is False. + + """ + self.model = {} + self.treated = [] + self.debug = debug + + def parse_model_from_yaml(self, filename, existing_model: Optional[dict] = None): + """Create and return a data model from the given file. + + Parameters + ---------- + filename : str + The path to the YAML file. + + existing_model : dict, optional + An existing model to which the created model shall be added. + + Returns + ------- + out : data_model.DataModel + The created DataModel + """ + with open(filename, 'r', encoding="utf-8") as outfile: + ymlmodel = yaml.load(outfile, Loader=SafeLineLoader) + + return self._create_model_from_dict(ymlmodel, existing_model=existing_model) + + def parse_model_from_string(self, string, existing_model: Optional[dict] = None): + """Create and return a data model from the given YAML string. + + Parameters + ---------- + string : str + The YAML string. + + existing_model : dict, optional + An existing model to which the created model shall be added. + + Returns + ------- + out : data_model.DataModel + The created DataModel + """ + ymlmodel = yaml.load(string, Loader=SafeLineLoader) + + return self._create_model_from_dict(ymlmodel, existing_model=existing_model) + + def _create_model_from_dict(self, ymlmodel, existing_model: Optional[dict] = None): + """Create and return a data model out of the YAML dict `ymlmodel`. + + Parameters + ---------- + ymlmodel : dict + The dictionary parsed from a YAML file. + + existing_model : dict, optional + An existing model to which the created model shall be added. + + Raises + ------ + ValueError + If model_dict is not a dict, model_dict["extern"] contains an + unknown entry, or there is an unknown entry in model_dict. + + Returns + ------- + out : data_model.DataModel + The created DataModel + """ + + if not isinstance(ymlmodel, dict): + raise ValueError("Yaml file should only contain one dictionary!") + + if existing_model is not None: + self.model.update(existing_model) + + # Extern keyword: + # The extern keyword can be used to include Properties and RecordTypes + # from existing LinkAhead datamodels into the current model. + # Any name included in the list specified by the extern keyword + # will be used in queries to retrieve a property or (if no property exists) + # a record type with the name of the element. + # The retrieved entity will be added to the model. + # If no entity with that name is found an exception is raised. + + if "extern" not in ymlmodel: + ymlmodel["extern"] = [] + + for name in ymlmodel["extern"]: + if name in LINKAHEAD_INTERNAL_PROPERTIES: + self.model[name] = db.Property(name=name).retrieve() + continue + for role in ("Property", "RecordType", "Record", "File"): + if db.execute_query("COUNT {} \"{}\"".format(role, name)) > 0: + self.model[name] = db.execute_query( + f"FIND {role} WITH name=\"{name}\"", unique=True) + break + else: + raise ValueError("Did not find {}".format(name)) + + ymlmodel.pop("extern") + + # add all names to ymlmodel; initialize properties + + for name, entity in ymlmodel.items(): + self._add_entity_to_model(name, entity) + # initialize recordtypes + self._set_recordtypes() + self._check_and_convert_datatypes() + + for name, entity in ymlmodel.items(): + try: + self._treat_entity(name, entity, line=ymlmodel["__line__"]) + except ValueError as err: + err_str = err.args[0].replace("invalid keyword:", + f"invalid keyword in line {entity['__line__']}:", 1) + raise ValueError(err_str, *err.args[1:]) from err + +# Update properties that are part of record types: +# e.g. add their datatypes, units etc.. +# Otherwise comparison of existing models and the parsed model become difficult. + for name, ent in self.model.items(): + if not isinstance(ent, db.RecordType): + continue + props = ent.get_properties() + for prop in props: + if prop.name in self.model: + model_prop = self.model[prop.name] + # The information must be missing, we don't want to overwrite it accidentally: + if prop.datatype is None: + if isinstance(model_prop, db.RecordType): + prop.datatype = model_prop.name + else: + prop.datatype = model_prop.datatype + # TODO: Data type overwrite is allowed here (because + # of lists), but this might change in the future. + # elif prop.datatype != model_prop.datatype: + # raise RuntimeError("datatype must not be set, here. This is probably a bug.") + if prop.unit is None: + # No unit for plain reference properties + if not isinstance(model_prop, db.RecordType): + prop.unit = model_prop.unit + if prop.description is None: + prop.description = model_prop.description + + return DataModel(self.model.values()) + + @staticmethod + def _stringify(name, context=None): + """Make a string out of `name`. + + Warnings are emitted for difficult values of `name`. + + Parameters + ---------- + name : + The value to be converted to a string. + + context : obj + Will be printed in the case of warnings. + + Returns + ------- + out : str + If `name` was a string, return it. Else return str(`name`). + """ + + if name is None: + print("WARNING: Name of this context is None: {}".format(context), + file=sys.stderr) + + if not isinstance(name, str): + name = str(name) + + return name + + def _add_entity_to_model(self, name, definition): + """ adds names of Properties and RecordTypes to the model dictionary + + Properties are also initialized. + + name is the key of the yaml element and definition the value. + """ + + if name == "__line__": + return + name = self._stringify(name) + + if name not in self.model: + self.model[name] = None + + if definition is None: + return + + if (self.model[name] is None and isinstance(definition, dict) + # is it a property + and "datatype" in definition + # but not simply an RT of the model + and not (get_list_datatype(definition["datatype"]) == name and + get_list_datatype(definition["datatype"]) in self.model)): + + # and create the new property + self.model[name] = db.Property(name=name, + datatype=definition["datatype"]) + elif (self.model[name] is None and isinstance(definition, dict) + and "role" in definition): + if definition["role"] == "RecordType": + self.model[name] = db.RecordType(name=name) + elif definition["role"] == "Record": + self.model[name] = db.Record(name=name) + elif definition["role"] == "File": + # TODO(fspreck) Implement files at some later point in time + raise NotImplementedError( + "The definition of file objects is not yet implemented.") + + # self.model[name] = db.File(name=name) + elif definition["role"] == "Property": + self.model[name] = db.Property(name=name) + else: + raise RuntimeError("Unknown role {} in definition of entity.".format( + definition["role"])) + + # for setting values of properties directly: + if not isinstance(definition, dict): + return + + # add other definitions recursively + for prop_type in ["recommended_properties", + "suggested_properties", "obligatory_properties"]: + + if prop_type in definition: + # Empty property mapping should be allowed. + + if definition[prop_type] is None: + definition[prop_type] = {} + try: + for n, e in definition[prop_type].items(): + if n == "__line__": + continue + self._add_entity_to_model(n, e) + except AttributeError as ate: + if ate.args[0].endswith("'items'"): + line = definition["__line__"] + + if isinstance(definition[prop_type], list): + line = definition[prop_type][0]["__line__"] + raise YamlDefinitionError(line) from None + raise + + if self.debug and self.model[name] is not None: + self.model[name].__line__ = definition["__line__"] + + def _add_to_recordtype(self, ent_name, props, importance): + """Add properties to a RecordType. + + Parameters + ---------- + ent_name : str + The name of the entity to which the properties shall be added. + + props : dict [str -> dict or :doc:`Entity`] + The properties, indexed by their names. Properties may be given as :doc:`Entity` objects + or as dictionaries. + + importance + The importance as used in :doc:`Entity.add_property`. + + Returns + ------- + None + + """ + + for n, e in props.items(): + + if n in KEYWORDS: + if n in KEYWORDS_IGNORED: + continue + raise YamlDefinitionError("Unexpected keyword in line {}: {}".format( + props["__line__"], n)) + + if n == "__line__": + continue + n = self._stringify(n) + + if isinstance(e, dict): + if "datatype" in e and get_list_datatype(e["datatype"]) is not None: + # Reuse the existing datatype for lists. + datatype = db.LIST(get_list_datatype(e["datatype"])) + else: + # Ignore a possible e["datatype"] here if it's not a list + # since it has been treated in the definition of the + # property (entity) already + datatype = None + if "value" in e: + value = e["value"] + else: + value = None + + else: + value = e + datatype = None + + self.model[ent_name].add_property(name=n, + value=value, + importance=importance, + datatype=datatype) + + def _inherit(self, name, prop, inheritance): + if not isinstance(prop, list): + if isinstance(prop, str): + raise YamlDefinitionError( + f"Parents must be a list but is given as string: {name} > {prop}") + raise YamlDefinitionError("Parents must be a list, error in line {}".format( + prop["__line__"])) + + for pname in prop: + if not isinstance(pname, str): + raise ValueError("Only provide the names of parents.") + self.model[name].add_parent(name=pname, inheritance=inheritance) + + def _treat_entity(self, name, definition, line=None): + """Parse the definition and the information to the entity.""" + + if name == "__line__": + return + name = self._stringify(name) + + try: + if definition is None: + return + + # for setting values of properties directly: + if not isinstance(definition, dict): + return + + # These definition items must be handled even for list props. + for prop_name, prop in definition.items(): + if prop_name == "description": + self.model[name].description = prop + + # For lists, everything else is not needed at this level. + if ("datatype" in definition and definition["datatype"].startswith("LIST")): + return + + if name in self.treated: + raise TwiceDefinedException(name) + + # for reducing a little bit of code duplication: + importance_dict = { + "recommended_properties": db.RECOMMENDED, + "obligatory_properties": db.OBLIGATORY, + "suggested_properties": db.SUGGESTED + } + + for prop_name, prop in definition.items(): + if prop_name == "__line__": + continue + line = definition["__line__"] + + if prop_name == "unit": + self.model[name].unit = prop + + elif prop_name == "value": + self.model[name].value = prop + + elif prop_name == "description": + # Handled above + continue + + elif prop_name in importance_dict: + for imp_name, imp_val in importance_dict.items(): + if prop_name == imp_name: + self._add_to_recordtype( + name, prop, importance=imp_val) + + for n, e in prop.items(): + self._treat_entity(n, e) + + # datatype is already set + elif prop_name == "datatype": + continue + + # role has already been used + elif prop_name == "role": + continue + + elif prop_name == "inherit_from_obligatory": + self._inherit(name, prop, db.OBLIGATORY) + elif prop_name == "inherit_from_recommended": + self._inherit(name, prop, db.RECOMMENDED) + elif prop_name == "inherit_from_suggested": + self._inherit(name, prop, db.SUGGESTED) + + else: + raise ValueError("invalid keyword: {}".format(prop_name)) + except AttributeError as ate: + if ate.args[0].endswith("'items'"): + raise YamlDefinitionError(line) from None + except Exception as e: + print("Error in treating: "+name) + raise e + self.treated.append(name) + + def _check_and_convert_datatypes(self): + """ checks if datatype is valid. + datatype of properties is simply initialized with string. Here, we + iterate over properties and check whether it is a base datatype of a + name that was defined in the model (or extern part) + + the string representations are replaced with linkahead objects + + """ + + for _, value in self.model.items(): + + if isinstance(value, db.Property): + dtype = value.datatype + is_list = False + + if get_list_datatype(dtype) is not None: + dtype = get_list_datatype(dtype) + is_list = True + + dtype_name = dtype + if not isinstance(dtype_name, str): + dtype_name = dtype.name + + if dtype_name in self.model: + if is_list: + value.datatype = db.LIST(self.model[dtype_name]) + else: + value.datatype = self.model[dtype_name] + + continue + + if dtype in [db.DOUBLE, + db.REFERENCE, + db.TEXT, + db.DATETIME, + db.INTEGER, + db.FILE, + db.BOOLEAN]: + + if is_list: + value.datatype = db.LIST(db.__getattribute__( # pylint: disable=no-member + dtype)) + else: + value.datatype = db.__getattribute__( # pylint: disable=no-member + dtype) + + continue + + raise ValueError("Property {} has an unknown datatype: {}".format( + value.name, dtype_name)) + + def _set_recordtypes(self): + """ properties are defined in first iteration; set remaining as RTs """ + + for key, value in self.model.items(): + if value is None: + self.model[key] = db.RecordType(name=key) + + +class JsonSchemaParser(Parser): + """Extends the yaml parser to read in datamodels defined in a json schema. + + **EXPERIMENTAL:** While this class can already be used to create data models + from basic json schemas, there are the following limitations and missing + features: + + * Due to limitations of json-schema itself, we currently do not support + inheritance in the imported data models + * The same goes for suggested properties of RecordTypes + * Already defined RecordTypes and (scalar) Properties can't be re-used as + list properties + * Reference properties that are different from the referenced RT. (Although + this is possible for list of references) + * Values + * Roles + * The extern keyword from the yaml parser + + """ + # @author Florian Spreckelsen + # @date 2022-02-17 + # @review Timm Fitschen 2023-05-25 + + def __init__(self, types_for_missing_array_items=None, + ignore_unspecified_array_items=False): + super().__init__() + if types_for_missing_array_items is None: + types_for_missing_array_items = {} + self.types_for_missing_array_items = types_for_missing_array_items + self.ignore_unspecified_array_items = ignore_unspecified_array_items + + def parse_model_from_json_schema(self, filename: str, top_level_recordtype: bool = True): + """Return a datamodel created from the definition in the json schema in + `filename`. + + Parameters + ---------- + filename : str + The path to the json-schema file containing the datamodel definition + top_level_recordtype : bool, optional + Whether there is a record type defined at the top level of the + schema. Default is true. + + Returns + ------- + out : data_model.DataModel + The created DataModel + """ + # @author Florian Spreckelsen + # @date 2022-02-17 + # @review Timm Fitschen 2023-05-25 + with open(filename, 'r', encoding="utf-8") as schema_file: + model_dict = jsonref.load(schema_file) + + return self._create_model_from_dict(model_dict, top_level_recordtype=top_level_recordtype) + + # ToDo: Fix https://gitlab.indiscale.com/caosdb/src/caosdb-advanced-user-tools/-/issues/139 + # and remove pylint disable + def _create_model_from_dict(self, model_dict: Union[dict, List[dict]], top_level_recordtype: bool = True): # pylint: disable=arguments-renamed + """Parse a dictionary and return the Datamodel created from it. + + The dictionary was typically created from the model definition in a json schema file. + + Parameters + ---------- + model_dict : dict or list[dict] + One or several dictionaries read in from a json-schema file + top_level_recordtype : bool, optional + Whether there is a record type defined at the top level of the + schema. Default is true. + + Returns + ------- + our : data_model.DataModel + The datamodel defined in `model_dict` + """ + # @review Timm Fitschen 2023-05-25 + if isinstance(model_dict, dict): + model_dict = [model_dict] + + for ii, elt in enumerate(model_dict): + try: + jsonschema.Draft202012Validator.check_schema(elt) + except jsonschema.SchemaError as err: + key = elt["title"] if "title" in elt else f"element {ii}" + raise JsonSchemaDefinitionError( + f"Json Schema error in {key}:\n{str(err)}") from err + + if top_level_recordtype: + if "title" not in elt: + raise JsonSchemaDefinitionError( + f"Object {ii+1} is lacking the `title` key word") + if "type" not in elt: + raise JsonSchemaDefinitionError( + f"Object {ii+1} is lacking the `type` key word") + # Check if this is a valid Json Schema + name = self._stringify(elt["title"], context=elt) + self._treat_element(elt, name) + elif "properties" in elt or "patternProperties" in elt: + # No top-level type but there are entities + if "properties" in elt: + for key, prop in elt["properties"].items(): + name = self._get_name_from_property(key, prop) + self._treat_element(prop, name) + if "patternProperties" in elt: + # See also treatment in ``_treat_record_type``. Since here, + # there is no top-level RT we use the prefix `__Pattern`, + # i.e., the resulting Record Types will be called + # `__PatternElement`. + self._treat_pattern_properties( + elt["patternProperties"], name_prefix="__Pattern") + else: + # Neither RecordType itself, nor further properties in schema, + # so nothing to do here. Maybe add something in the future. + continue + + return DataModel(self.model.values()) + + def _get_name_from_property(self, key: str, prop: dict): + # @review Timm Fitschen 2023-05-25 + if "title" in prop: + name = self._stringify(prop["title"]) + else: + name = self._stringify(key) + + return name + + def _get_atomic_datatype(self, elt): + # @review Timm Fitschen 2023-05-25 + if elt["type"] == "string": + if "format" in elt and elt["format"] in ["date", "date-time"]: + return db.DATETIME + else: + return db.TEXT + elif elt["type"] == "integer": + return db.INTEGER + elif elt["type"] == "number": + return db.DOUBLE + elif elt["type"] == "boolean": + return db.BOOLEAN + elif elt["type"] == "null": + # This could be any datatype since a valid json will never have a + # value in a null property. We use TEXT for convenience. + return db.TEXT + else: + raise JsonSchemaDefinitionError(f"Unkown atomic type in {elt}.") + + def _treat_element(self, elt: dict, name: str): + # @review Timm Fitschen 2023-05-25 + force_list = False + if name in self.model: + return self.model[name], force_list + if "type" not in elt: + # Each element must have a specific type + raise JsonSchemaDefinitionError( + f"`type` is missing in element {name}.") + if name == "name": + # This is identified with the LinkAhead name property as long as the + # type is correct. + if not elt["type"] == "string" and "string" not in elt["type"]: + raise JsonSchemaDefinitionError( + "The 'name' property must be string-typed, otherwise it cannot " + "be identified with LinkAhead's name property." + ) + return None, force_list + # LinkAhead suports null for all types, so in the very special case of + # `"type": ["null", "<other_type>"]`, only consider the other type: + if isinstance(elt["type"], list) and len(elt["type"]) == 2 and "null" in elt["type"]: + elt["type"].remove("null") + elt["type"] = elt["type"][0] + if "enum" in elt: + ent = self._treat_enum(elt, name) + elif elt["type"] in JSON_SCHEMA_ATOMIC_TYPES: + ent = db.Property( + name=name, datatype=self._get_atomic_datatype(elt)) + elif elt["type"] == "object": + ent = self._treat_record_type(elt, name) + elif elt["type"] == "array": + ent, force_list = self._treat_list(elt, name) + else: + raise NotImplementedError( + f"Cannot parse items of type '{elt['type']}' (yet).") + if "description" in elt and ent.description is None: + # There is a description and it hasn't been set by another + # treat_something function + ent.description = elt["description"] + + if ent is not None: + self.model[name] = ent + return ent, force_list + + def _treat_record_type(self, elt: dict, name: str): + # @review Timm Fitschen 2023-05-25 + rt = db.RecordType(name=name) + if "required" in elt: + required = elt["required"] + else: + required = [] + if "properties" in elt: + for key, prop in elt["properties"].items(): + name = self._get_name_from_property(key, prop) + prop_ent, force_list = self._treat_element(prop, name) + if prop_ent is None: + # Nothing to be appended since the property has to be + # treated specially. + continue + importance = db.OBLIGATORY if key in required else db.RECOMMENDED + if not force_list: + rt.add_property(prop_ent, importance=importance) + else: + # Special case of rt used as a list property + rt.add_property(prop_ent, importance=importance, + datatype=db.LIST(prop_ent)) + + if "patternProperties" in elt: + + pattern_property_rts = self._treat_pattern_properties( + elt["patternProperties"], name_prefix=name) + for ppr in pattern_property_rts: + # add reference to pattern property type. These can never be + # obligatory since pattern properties cannot be required in the + # original schema (since their actual names are not known a + # priori). + rt.add_property(ppr) + + if "description" in elt: + rt.description = elt["description"] + return rt + + def _treat_enum(self, elt: dict, name: str): + # @review Timm Fitschen 2022-02-30 + if "type" in elt and elt["type"] == "integer": + raise NotImplementedError( + "Integer-enums are not allowd until " + "https://gitlab.indiscale.com/caosdb/src/caosdb-server/-/issues/224 " + "has been fixed." + ) + rt = db.RecordType(name=name) + for enum_elt in elt["enum"]: + rec = db.Record(name=self._stringify(enum_elt)) + rec.add_parent(rt) + self.model[enum_elt] = rec + + return rt + + def _treat_list(self, elt: dict, name: str): + # @review Timm Fitschen 2023-05-25 + + if "items" not in elt and name not in self.types_for_missing_array_items: + if self.ignore_unspecified_array_items: + return None, False + raise JsonSchemaDefinitionError( + f"The definition of the list items is missing in {elt}.") + if "items" in elt: + items = elt["items"] + if "enum" in items: + return self._treat_enum(items, name), True + if items["type"] in JSON_SCHEMA_ATOMIC_TYPES: + datatype = db.LIST(self._get_atomic_datatype(items)) + return db.Property(name=name, datatype=datatype), False + if items["type"] == "object": + if "title" not in items or self._stringify(items["title"]) == name: + # Property is RecordType + return self._treat_record_type(items, name), True + else: + # List property will be an entity of its own with a name + # different from the referenced RT + ref_rt = self._treat_record_type( + items, self._stringify(items["title"])) + self.model[ref_rt.name] = ref_rt + return db.Property(name=name, datatype=db.LIST(ref_rt)), False + else: + # Use predefined type: + datatype = db.LIST(self.types_for_missing_array_items[name]) + return db.Property(name=name, datatype=datatype), False + + def _get_pattern_prop(self): + # @review Timm Fitschen 2023-05-25 + if "__pattern_property_pattern_property" in self.model: + return self.model["__pattern_property_pattern_property"] + pp = db.Property(name="__matched_pattern", datatype=db.TEXT) + self.model["__pattern_property_pattern_property"] = pp + return pp + + def _treat_pattern_properties(self, pattern_elements, name_prefix=""): + """Special Treatment for pattern properties: A RecordType is created for + each pattern property. In case of a `type: object` PatternProperty, the + remaining properties of the JSON entry are appended to the new + RecordType; in case of an atomic type PatternProperty, a single value + Property is added to the RecordType. + + Raises + ------ + NotImplementedError + In case of patternProperties with non-object, non-atomic type, e.g., + array. + + """ + # @review Timm Fitschen 2023-05-25 + num_patterns = len(pattern_elements) + pattern_prop = self._get_pattern_prop() + returns = [] + for ii, (key, element) in enumerate(pattern_elements.items()): + if "title" not in element: + name_suffix = f"_{ii+1}" if num_patterns > 1 else "" + name = name_prefix + "Entry" + name_suffix + else: + name = element["title"] + if element["type"] == "object": + # simple, is already an object, so can be treated like any other + # record type. + pattern_type = self._treat_record_type(element, name) + elif element["type"] in JSON_SCHEMA_ATOMIC_TYPES: + # create a property that stores the actual value of the pattern + # property. + propname = f"{name}_value" + prop = db.Property(name=propname, datatype=self._get_atomic_datatype(element)) + self.model[propname] = prop + pattern_type = db.RecordType(name=name) + pattern_type.add_property(prop) + else: + raise NotImplementedError( + "Pattern properties are currently only supported for types " + + ", ".join(JSON_SCHEMA_ATOMIC_TYPES) + ", and object.") + + # Add pattern property and description + pattern_type.add_property(pattern_prop, importance=db.OBLIGATORY) + if pattern_type.description: + pattern_type.description += f"\n\npattern: {key}" + else: + pattern_type.description = f"pattern: {key}" + + self.model[name] = pattern_type + returns.append(pattern_type) + + return returns + + +def main(): + parser = argparse.ArgumentParser(description=__doc__, + formatter_class=argparse.RawTextHelpFormatter) + parser.add_argument("data_model", + help="Path name of the data model file (yaml or json) to be used.") + parser.add_argument("--sync", action="store_true", + help="Whether or not to sync the data model with the server.") + parser.add_argument("--noquestion", action="store_true", + help="Whether or not to ask questions during synchronization.") + parser.add_argument("--print", action="store_true", + help="Whether or not to print the data model.") + + args = parser.parse_args() + if args.data_model.endswith(".json"): + model = parse_model_from_json_schema(args.data_model) + elif args.data_model.endswith(".yml") or args.data_model.endswith(".yaml"): + model = parse_model_from_yaml(args.data_model) + else: + raise RuntimeError(f"Unknown file ending of data model: {args.data_model}") + if args.print: + print(model) + if args.sync: + model.sync_data_model(noquestion=args.noquestion) + + +if __name__ == "__main__": + main() diff --git a/src/caosadvancedtools/pandoc_header_tools.py b/src/caosadvancedtools/pandoc_header_tools.py index e746a26ac19c00de4ee7785399ef98478472340c..88cdbc19ffa8d5dd724be0e1042fb2a42094c7dc 100644 --- a/src/caosadvancedtools/pandoc_header_tools.py +++ b/src/caosadvancedtools/pandoc_header_tools.py @@ -6,7 +6,7 @@ # A. Schlemmer, 04/2019 # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # Copyright (C) 2018 Research Group Biomedical Physics, # Max-Planck-Institute for Dynamics and Self-Organization Göttingen @@ -30,10 +30,7 @@ # D. Hornung 2019-02 # T. Fitschen 2019-02 -import argparse -import glob import os -import re import yaml @@ -71,31 +68,30 @@ description: """ -def get_header(filename, add_header=False): - """Open an md file identified by filename and read out the yaml -header. +def get_header(filename, add_header_to_file=False): + """Open an md file identified by filename and read out the yaml header. -filename can also be a folder. In this case folder/README.md will be used for -getting the header. + filename can also be a folder. In this case folder/README.md will be used + for getting the header. -If a header is found a tuple is returned: (first yaml header line index, last+1 -yaml header line index, header) + If a header is found a tuple is returned: (first yaml header line index, + last+1 yaml header line index, header) -Otherwise, if `add_header` is True, a header is added and the function is called -again. + Otherwise, if `add_header_to_file` is True, a header is added and the + function is called again. -The header is normalized in the following way: + The header is normalized in the following way: -- If the value to a key is a string, a list with that string as only element is - returned. + - If the value to a key is a string, a list with that string as only + element is returned. -From https://pandoc.org/MANUAL.html: - -A YAML metadata block is a valid YAML object, delimited by a line of three -hyphens (---) at the top and a line of three hyphens (---) or three dots (...) -at the bottom. A YAML metadata block may occur anywhere in the document, but if -it is not at the beginning, it must be preceded by a blank line. + From https://pandoc.org/MANUAL.html: + A YAML metadata block is a valid YAML object, delimited by a line of three + hyphens (---) at the top and a line of three hyphens (---) or three + dots (...) at the bottom. A YAML metadata block may occur anywhere in the + document, but if it is not at the beginning, it must be preceded by a blank + line. """ if os.path.isdir(filename): @@ -106,16 +102,14 @@ it is not at the beginning, it must be preceded by a blank line. if not os.path.exists(filename): raise MetadataFileMissing(filename) - with open(filename) as f: + with open(filename, encoding="utf-8") as f: textlines = f.readlines() state = 0 - found_0 = -1 found_1 = -1 found_2 = -1 for i, line in enumerate(textlines): if len(line) == 1 and state in {-1, 0}: - found_0 = i state = 0 continue if line.rstrip() == "---" and state == 0: @@ -144,14 +138,14 @@ it is not at the beginning, it must be preceded by a blank line. try: yaml_part = yaml.load("\n".join(headerlines), Loader=yaml.BaseLoader) except yaml.scanner.ScannerError as e: - raise ParseErrorsInHeader(filename, e) + raise ParseErrorsInHeader(filename, e) from e # except yaml.error.MarkedYAMLError as e: # raise NoValidHeader(filename) if not isinstance(yaml_part, dict): raise NoValidHeader(filename) return (found_1, found_2, clean_header(yaml_part)) - if not add_header: + if not add_header_to_file: raise NoValidHeader(filename) else: print("Adding header in: {fn}".format(fn=filename)) @@ -171,7 +165,7 @@ def save_header(filename, header_data): if os.path.isdir(filename): filename = os.path.join(filename, "README.md") - with open(filename) as f: + with open(filename, encoding="utf-8") as f: textlines = f.readlines() while textlines[header_data[0]] != "...\n": @@ -184,7 +178,7 @@ def save_header(filename, header_data): default_flow_style=False, allow_unicode=True)) - with open(filename, "w") as f: + with open(filename, "w", encoding="utf-8") as f: f.writelines(textlines) @@ -202,7 +196,7 @@ def add_header(filename, header_dict=None): filename = os.path.join(filename, "README.md") if os.path.exists(filename): - with open(filename) as f: + with open(filename, encoding="utf-8") as f: textlines = f.readlines() else: textlines = "" @@ -214,7 +208,7 @@ def add_header(filename, header_dict=None): default_flow_style=False, allow_unicode=True) + "...\n" - with open(filename, "w") as f: + with open(filename, "w", encoding="utf-8") as f: f.write(localheader) f.writelines(textlines) diff --git a/src/caosadvancedtools/read_md_header.py b/src/caosadvancedtools/read_md_header.py index ece81c403af7ca65fb48ebd457fdded8544413e8..cc3e2152a38536fedbc538661cdcf7f086ae5501 100644 --- a/src/caosadvancedtools/read_md_header.py +++ b/src/caosadvancedtools/read_md_header.py @@ -2,7 +2,7 @@ # encoding: utf-8 # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) # A. Schlemmer, 01/2019 @@ -34,7 +34,7 @@ def get_header(fn): # import os # import re -# import caosdb as db +# import linkahead as db # import yaml # from .cfood import AbstractCFood, get_entity diff --git a/src/caosadvancedtools/scifolder/analysis_cfood.py b/src/caosadvancedtools/scifolder/analysis_cfood.py index adce7225649ddf80852588d1cb78d045c04db1d3..0216f53468e87e2a91a2427a2cbbd5c2be392eab 100644 --- a/src/caosadvancedtools/scifolder/analysis_cfood.py +++ b/src/caosadvancedtools/scifolder/analysis_cfood.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <https://www.gnu.org/licenses/>. -import caosdb as db +import linkahead as db from caosadvancedtools.cfood import (AbstractFileCFood, assure_has_property, assure_object_is_in_list, @@ -51,7 +51,7 @@ class AnalysisCFood(AbstractFileCFood, WithREADME): @staticmethod def name_beautifier(name): """ a function that can be used to rename the project. I.e. if - the project in CaosDB shall be named differently than in the folder + the project in LinkAhead shall be named differently than in the folder structure. Use discouraged. """ diff --git a/src/caosadvancedtools/scifolder/experiment_cfood.py b/src/caosadvancedtools/scifolder/experiment_cfood.py index 83329863433d302e16744a781a3b599fe0bb11f5..b19b29242909a6f447da2903cb6e2040121b4e53 100644 --- a/src/caosadvancedtools/scifolder/experiment_cfood.py +++ b/src/caosadvancedtools/scifolder/experiment_cfood.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <https://www.gnu.org/licenses/>. -import caosdb as db +import linkahead as db from caosadvancedtools.cfood import (AbstractFileCFood, assure_has_property, assure_object_is_in_list, diff --git a/src/caosadvancedtools/scifolder/publication_cfood.py b/src/caosadvancedtools/scifolder/publication_cfood.py index 68e345aca1bd650b4da784f4741866683bd4f04a..61e0a0ef0d63cf2d7eb43dd9ca90a2138324babf 100644 --- a/src/caosadvancedtools/scifolder/publication_cfood.py +++ b/src/caosadvancedtools/scifolder/publication_cfood.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <https://www.gnu.org/licenses/>. -import caosdb as db +import linkahead as db from caosadvancedtools.cfood import (AbstractFileCFood, assure_object_is_in_list, fileguide, ) diff --git a/src/caosadvancedtools/scifolder/result_table_cfood.py b/src/caosadvancedtools/scifolder/result_table_cfood.py index e32cd0bd1efe77d5be4583c8bae764a677e33fc4..fec2903953d0f5479d89531c0e3f8f7e88073f84 100644 --- a/src/caosadvancedtools/scifolder/result_table_cfood.py +++ b/src/caosadvancedtools/scifolder/result_table_cfood.py @@ -18,7 +18,7 @@ import re -import caosdb as db +import linkahead as db import pandas as pd from caosadvancedtools.cfood import (AbstractFileCFood, ) diff --git a/src/caosadvancedtools/scifolder/simulation_cfood.py b/src/caosadvancedtools/scifolder/simulation_cfood.py index f8f3d07e30b81e42591ce0c4698c0f47164f2b90..5127cbfd071a8232f6721a5d1a108144a50eaa12 100644 --- a/src/caosadvancedtools/scifolder/simulation_cfood.py +++ b/src/caosadvancedtools/scifolder/simulation_cfood.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <https://www.gnu.org/licenses/>. -import caosdb as db +import linkahead as db from caosadvancedtools.cfood import (AbstractFileCFood, assure_has_property, assure_object_is_in_list, diff --git a/src/caosadvancedtools/scifolder/software_cfood.py b/src/caosadvancedtools/scifolder/software_cfood.py index d91817f10a278b91f7c52aa1a0674b1a2daa0394..589112c567541a9fe19a630b552750e561b0ac5c 100644 --- a/src/caosadvancedtools/scifolder/software_cfood.py +++ b/src/caosadvancedtools/scifolder/software_cfood.py @@ -17,7 +17,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <https://www.gnu.org/licenses/>. -import caosdb as db +import linkahead as db from caosadvancedtools.cfood import (AbstractFileCFood, assure_has_property, assure_name_is, assure_object_is_in_list, diff --git a/src/caosadvancedtools/scifolder/utils.py b/src/caosadvancedtools/scifolder/utils.py index cbf87c4b802c829f34f4368c3605ce05fa42cfb2..8e832c10fc9227365535314ce4cc2cdf6d49b212 100644 --- a/src/caosadvancedtools/scifolder/utils.py +++ b/src/caosadvancedtools/scifolder/utils.py @@ -21,7 +21,7 @@ import logging import os from itertools import chain -import caosdb as db +import linkahead as db import pandas as pd from caosadvancedtools.cfood import assure_object_is_in_list, fileguide from caosadvancedtools.utils import (find_records_that_reference_ids, diff --git a/src/caosadvancedtools/scifolder/withreadme.py b/src/caosadvancedtools/scifolder/withreadme.py index d8388e1d28bd23e1804c2f747a47f4ea97d265b0..faab94cbafb18e1b28e7fc71f1d30eba7325e6f1 100644 --- a/src/caosadvancedtools/scifolder/withreadme.py +++ b/src/caosadvancedtools/scifolder/withreadme.py @@ -22,7 +22,7 @@ import logging import os from dataclasses import dataclass -import caosdb as db +import linkahead as db from caosadvancedtools.cfood import (assure_has_description, assure_has_parent, assure_object_is_in_list, fileguide) from caosadvancedtools.read_md_header import get_header as get_md_header @@ -156,8 +156,8 @@ class WithREADME(object): for f in sublist] if len(flat_list) == 0: - LOGGER.warn("ATTENTION: the field {} does not reference any " - "known files".format(field.key)) + LOGGER.warning(f"ATTENTION: the field {field.key} does not" + " reference any known files") self.attached_filenames.extend(flat_list) # pylint: disable=no-member diff --git a/src/caosadvancedtools/serverside/examples/example_script.py b/src/caosadvancedtools/serverside/examples/example_script.py index d97d2d0d1f936b1c12e857d38fce043f0b514340..fe9bbaa7b417f99cec58d3747402b5c99b957582 100755 --- a/src/caosadvancedtools/serverside/examples/example_script.py +++ b/src/caosadvancedtools/serverside/examples/example_script.py @@ -2,7 +2,7 @@ # encoding: utf-8 # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2021 Indiscale GmbH <info@indiscale.com> # Copyright (C) 2021 Henrik tom Wörden <h.tomwoerden@indiscale.com> @@ -45,7 +45,7 @@ import sys from argparse import RawTextHelpFormatter from datetime import datetime -import caosdb as db +import linkahead as db import matplotlib.pyplot as plt import numpy as np from caosadvancedtools.cfood import assure_property_is @@ -68,18 +68,18 @@ def send_mail(changes: [db.Entity], receipient: str): Parameters: ----------- - changes: The CaosDB entities in the version after the update. + changes: The LinkAhead entities in the version after the update. receipient: The person who shall receive the mail. """ - caosdb_config = db.configuration.get_config() + linkahead_config = db.configuration.get_config() text = """Dear Curator, The following changes where done automatically. {changes} """.format(changes="\n".join(changes)) try: - fro = caosdb_config["advancedtools"]["automated_updates.from_mail"] + fro = linkahead_config["advancedtools"]["automated_updates.from_mail"] except KeyError: logger.error("Server Configuration is missing a setting for " "sending mails. The administrator should check " diff --git a/src/caosadvancedtools/serverside/generic_analysis.py b/src/caosadvancedtools/serverside/generic_analysis.py index 7c7b26cc3ddb19ff54710f04debe3c0a48f35b82..e32e02d000be51eb84a25648dbbc4c97756f4a39 100644 --- a/src/caosadvancedtools/serverside/generic_analysis.py +++ b/src/caosadvancedtools/serverside/generic_analysis.py @@ -87,8 +87,8 @@ import logging import os import sys -import caosdb as db -from caosdb.utils.server_side_scripting import run_server_side_script +import linkahead as db +from linkahead.utils.server_side_scripting import run_server_side_script logger = logging.getLogger(__name__) diff --git a/src/caosadvancedtools/serverside/helper.py b/src/caosadvancedtools/serverside/helper.py index b7289c7ffd1d67ebd9862aa5f92cd41ccc62d706..ec8083ab5a045bbe7db747f8bf7799cac3352d04 100644 --- a/src/caosadvancedtools/serverside/helper.py +++ b/src/caosadvancedtools/serverside/helper.py @@ -30,7 +30,7 @@ import sys from email import message, policy, utils from tempfile import NamedTemporaryFile -import caosdb as db +import linkahead as db def wrap_bootstrap_alert(text, kind): @@ -165,7 +165,7 @@ def recordtype_is_child_of(rt, parent): Parameters ---------- - rt : caosdb.Entity + rt : linkahead.Entity The child RecordType. parent : str or int The parent's name or id. @@ -193,7 +193,7 @@ def init_data_model(entities): Parameters ---------- - entities : iterable of caosdb.Entity + entities : iterable of linkahead.Entity The data model entities which are to be checked for existence. Raises @@ -339,7 +339,7 @@ def send_mail(from_addr, to, subject, body, cc=None, bcc=None, send_mail_bin=None): """ Send an email via the configured send_mail client. - The relevant options in the pycaosdb.ini are: + The relevant options in the pylinkahead.ini are: [Misc] sendmail = ... @@ -365,8 +365,8 @@ def send_mail(from_addr, to, subject, body, cc=None, bcc=None, ------ subprocess.CalledProcessError If the sendmail client returned with a non-zero code. - caosdb.ConfigurationException - If the caosdb configuration has no `Misc.sendmail` configured while the + linkahead.ConfigurationException + If the linkahead configuration has no `Misc.sendmail` configured while the `send_mail_bin` parameter is None. """ @@ -389,14 +389,14 @@ def send_mail(from_addr, to, subject, body, cc=None, bcc=None, if send_mail_bin is not None: sendmail = send_mail_bin else: - caosdb_config = db.configuration.get_config() + linkahead_config = db.configuration.get_config() - if "Misc" not in caosdb_config or "sendmail" not in caosdb_config["Misc"]: + if "Misc" not in linkahead_config or "sendmail" not in linkahead_config["Misc"]: err_msg = ("No sendmail executable configured. " "Please configure `Misc.sendmail` " - "in your pycaosdb.ini.") + "in your pylinkahead.ini.") raise db.ConfigurationError(err_msg) - sendmail = caosdb_config["Misc"]["sendmail"] + sendmail = linkahead_config["Misc"]["sendmail"] # construct sendmail command # options explained (from `man sendmail`): @@ -438,7 +438,7 @@ def get_file_via_download(ent, logger=logging.getLogger(__name__)): try: # TODO remove the following treatment of size=0 when the # following issue is resolved: - # https://gitlab.com/caosdb/caosdb-server/-/issues/107 + # https://gitlab.com/linkahead/linkahead-server/-/issues/107 if ent.size > 0: val_file = ent.download() @@ -450,7 +450,7 @@ def get_file_via_download(ent, logger=logging.getLogger(__name__)): logger.error("The checksum of the downloaded file with id={} did not " "match.".format(ent.id)) raise e - except db.CaosDBException as e: + except db.LinkAheadException as e: logger.error("Cannot download the file with id={}.".format(ent.id)) raise e diff --git a/src/caosadvancedtools/structure_mapping.py b/src/caosadvancedtools/structure_mapping.py index 50e57ac4d84f2034fbdb6da6c7159f450a993c3a..aba47058cb992587089ac9af3559ca9981aa96f9 100644 --- a/src/caosadvancedtools/structure_mapping.py +++ b/src/caosadvancedtools/structure_mapping.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2021 IndiScale GmbH <www.indiscale.com> # Copyright (C) 2021 Henrik tom Wörden <h.tomwoerden@indiscale.com> @@ -18,13 +18,17 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <https://www.gnu.org/licenses/>. -import caosdb as db -from caosdb.apiutils import resolve_reference -from caosdb.common.utils import uuid +import linkahead as db +from linkahead.apiutils import resolve_reference +from linkahead.common.utils import uuid from .cfood import (assure_has_description, assure_has_parent, assure_property_is) +# The pylint warnings triggered in this file are ignored, as this code is +# assumed to be deprecated in the near future. Should this change, they need +# to be reevaluated. + class EntityMapping(object): """ @@ -39,9 +43,9 @@ class EntityMapping(object): self.to_target = {} def add(self, target, existing): - if target._cuid is None: - target._cuid = str(uuid()) - self.to_existing[str(target._cuid)] = existing + if target.cuid is None: + target._cuid = str(uuid()) # pylint: disable=protected-access + self.to_existing[str(target.cuid)] = existing self.to_target[existing.id] = target @@ -103,11 +107,11 @@ def update_structure(em, updating: db.Container, target_structure: db.Record): A record which may have references to other records. Must be a DAG. """ - if target_structure._cuid in em.to_existing: + if target_structure.cuid in em.to_existing: update_matched_entity(em, updating, target_structure, - em.to_existing[target_structure._cuid]) + em.to_existing[target_structure.cuid]) for prop in target_structure.get_properties(): if prop.is_reference(server_retrieval=True): @@ -134,8 +138,8 @@ def update_matched_entity(em, updating, target_record, existing_record): # check for remaining property types if isinstance(prop.value, db.Entity): - if prop.value._cuid in em.to_existing: - value = em.to_existing[prop.value._cuid].id + if prop.value.cuid in em.to_existing: + value = em.to_existing[prop.value.cuid].id else: value = prop.value.id else: diff --git a/src/caosadvancedtools/suppressKnown.py b/src/caosadvancedtools/suppressKnown.py index 1b31de7e9d8f1fdce35a135d558dd5ceea3bca2a..aada4ef64df6a496c4d1c30006cca23bd3e329c8 100644 --- a/src/caosadvancedtools/suppressKnown.py +++ b/src/caosadvancedtools/suppressKnown.py @@ -28,6 +28,7 @@ class SuppressKnown(logging.Filter): """ def __init__(self, db_file=None): + super().__init__() if db_file: self.db_file = db_file else: diff --git a/src/caosadvancedtools/table_converter.py b/src/caosadvancedtools/table_converter.py index 7d1097e13a0780a7656a18c71bf7f408df5c69c5..19e6d85f01a38708a8fc0ad4e7b714e05e4630bd 100644 --- a/src/caosadvancedtools/table_converter.py +++ b/src/caosadvancedtools/table_converter.py @@ -2,7 +2,7 @@ # encoding: utf-8 # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2019 Henrik tom Wörden # @@ -24,8 +24,7 @@ import argparse import re import sys -import caosdb as db -import numpy as np +import linkahead as db import pandas as pd @@ -74,7 +73,7 @@ def from_table(spreadsheet, recordtype): """ parses a pandas DataFrame to a list of records """ records = db.Container() - for idx, row in spreadsheet.iterrows(): + for _, row in spreadsheet.iterrows(): rec = db.Record() rec.add_parent(name=recordtype) @@ -99,8 +98,7 @@ def from_table(spreadsheet, recordtype): return records -if __name__ == "__main__": - +def main(): p = argparse.ArgumentParser() p.add_argument("-f", "--filename", help="The excel filename") p.add_argument("--auth-token") @@ -111,3 +109,7 @@ if __name__ == "__main__": recordtype = "Experiment" from_tsv(arg.filename, recordtype) + + +if __name__ == "__main__": + main() diff --git a/src/caosadvancedtools/table_export.py b/src/caosadvancedtools/table_export.py index eabb10754bdb93859dcc6ef3d3ff0838fa6ff6d4..32191530fed0eaadbc52bee7ba41ec64fb148df3 100644 --- a/src/caosadvancedtools/table_export.py +++ b/src/caosadvancedtools/table_export.py @@ -2,7 +2,7 @@ # encoding: utf-8 # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2020 Indiscale GmbH <info@indiscale.com> # Copyright (C) 2020 Florian Sprecklelsen <f.spreckelsen@indiscale.com> @@ -22,7 +22,7 @@ # # ** end header # -"""Collect optional and mandatory data from CaosDB records and prepare +"""Collect optional and mandatory data from LinkAhead records and prepare them for an export as a table, e.g., for the export to metadata repositories. @@ -31,7 +31,7 @@ from inspect import signature import json import logging -import caosdb as db +import linkahead as db FIND_FUNCTION = "find_func" QUERY = "query" @@ -39,7 +39,7 @@ QUERY = "query" logger = logging.getLogger(__name__) -class TableExportError(db.CaosDBException): +class TableExportError(db.LinkAheadException): """Error that is raised in case of failing export, e.g., because of missing mandatory entries. @@ -123,12 +123,12 @@ class BaseTableExporter(object): self.export_dict = export_dict else: try: - with open(export_dict) as tmp: + with open(export_dict, encoding="utf-8") as tmp: self.export_dict = json.load(tmp) - except BaseException: + except Exception as e: raise ValueError( "export_dict must be either a dictionary" - " or the path to a json file.") + " or the path to a json file.") from e self.record = record self._check_sanity_of_export_dict() self.raise_error_if_missing = raise_error_if_missing @@ -159,7 +159,7 @@ class BaseTableExporter(object): logger.debug(exc) errmssg = "Empty or invalid query '{}' for entry {}".format( q, e) - raise TableExportError(errmssg) + raise TableExportError(errmssg) from exc if val is not None: self.info[e] = val @@ -172,7 +172,7 @@ class BaseTableExporter(object): self.info[e] = val else: self._append_missing(e, d) - except Exception as exc: + except Exception as exc: # pylint: disable=broad-exception-caught self._append_missing(e, d) logger.error(exc) # last resort: check if record has e as property: @@ -189,7 +189,7 @@ class BaseTableExporter(object): errmssg += ", nor does record {} have a property of that name".format( self.record.id) errmssg += "." - raise TableExportError(errmssg) + raise TableExportError(errmssg) from exc if self.missing: errmssg = "The following mandatory entries are missing:\n" diff --git a/src/caosadvancedtools/table_importer.py b/src/caosadvancedtools/table_importer.py index cd1b206f7ebbe7730692a3a6a7137e4aa467a5eb..c2cb0250579cff20a6f7088065a7e9b22bb64ec6 100755 --- a/src/caosadvancedtools/table_importer.py +++ b/src/caosadvancedtools/table_importer.py @@ -110,8 +110,7 @@ def date_converter(val, fmt="%Y-%m-%d"): return datetime_converter(val, fmt=fmt).date() -def incomplete_date_converter(val, fmts={"%Y-%m-%d": "%Y-%m-%d", - "%Y-%m": "%Y-%m", "%Y": "%Y"}): +def incomplete_date_converter(val, fmts=None): """ if the value is already a datetime, it is returned otherwise it converts it using format string @@ -124,6 +123,8 @@ def incomplete_date_converter(val, fmts={"%Y-%m-%d": "%Y-%m-%d", keys are the formats into which the input value is tried to be converted, values are the possible input formats. """ + if fmts is None: + fmts = {"%Y-%m-%d": "%Y-%m-%d", "%Y-%m": "%Y-%m", "%Y": "%Y"} for to, fro in fmts.items(): try: @@ -496,7 +497,7 @@ class XLSImporter(TableImporter): str(e)), extra={'identifier': str(filename), 'category': "inconsistency"}) - raise DataInconsistencyError(*e.args) + raise DataInconsistencyError(*e.args) from e if len(xls_file.sheet_names) > 1: # Multiple sheets is the default now. Only show in debug @@ -514,7 +515,7 @@ class XLSImporter(TableImporter): "Cannot parse {}.\n{}".format(filename, e), extra={'identifier': str(filename), 'category': "inconsistency"}) - raise DataInconsistencyError(*e.args) + raise DataInconsistencyError(*e.args) from e df = self.check_dataframe(df, filename) @@ -536,7 +537,7 @@ class CSVImporter(TableImporter): "Cannot parse {}.\n{}".format(filename, ve), extra={'identifier': str(filename), 'category': "inconsistency"}) - raise DataInconsistencyError(*ve.args) + raise DataInconsistencyError(*ve.args) from ve except TypeError as te: # Iterate through the columns and rows to identify # problematic cells with wrong types. @@ -576,7 +577,7 @@ class CSVImporter(TableImporter): for err in error_list: msg += f" * column \"{err[0]}\": Expected \"{err[1]}\" but found \"{err[2]}\".\n" msg += '\n' - raise DataInconsistencyError(msg) + raise DataInconsistencyError(msg) from te df = self.check_dataframe(df, filename) @@ -584,5 +585,5 @@ class CSVImporter(TableImporter): class TSVImporter(CSVImporter): - def read_file(self, filename, **kwargs): + def read_file(self, filename, **kwargs): # pylint: disable=arguments-differ return super().read_file(filename, sep="\t", **kwargs) diff --git a/src/caosadvancedtools/table_json_conversion/convert.py b/src/caosadvancedtools/table_json_conversion/convert.py index 09882f963fd976583d4acbc8f2dd3b67ef510ac8..4b02fa46a8e7a2426118cd987e5d84f906e2dfdb 100644 --- a/src/caosadvancedtools/table_json_conversion/convert.py +++ b/src/caosadvancedtools/table_json_conversion/convert.py @@ -25,10 +25,11 @@ from __future__ import annotations import datetime import itertools import sys +import textwrap from functools import reduce from operator import getitem from types import SimpleNamespace -from typing import Any, BinaryIO, Callable, TextIO, Union +from typing import Any, BinaryIO, Callable, TextIO, Union, Optional from warnings import warn import jsonschema @@ -46,6 +47,105 @@ def _strict_bool(value: Any) -> bool: raise TypeError(f"Not a good boolean: {repr(value)}") +def _column_id_to_chars(num): + """Converts a column id (zero based) to the corresponding string + representation, e.g. 0 -> 'A', 97 -> 'CT'""" + if num < 0: + return "" + return _column_id_to_chars(int(num / 26) - 1) + chr(int(num % 26) + 65) + + +def _format_exception_table(exceptions: list[tuple], worksheet_title: str, + column_names: Optional[Union[dict, list]] = None, + max_line_length: int = 120) -> str: + """ + Given a list of tuples containing a row and column number as well as an + exception in that order, and the title of the current worksheet, returns + a formatted table of the exceptions. + + Optionally takes a dict of column names, if given a header will be + generated for each column and exceptions will be clustered by column. + + Default line length is 120 and can be overwritten by max_line_length. + + Params + ------ + exceptions: list of tuples containing row, column, and exception + Data to be formatted + worksheet_title: str + Name of the current worksheet + column_names: dict or list, optional + column_names[column_num] should return the name of + column column_names. + If given, exceptions will be clustered by column. + max_line_length: int, default=120 + Soft cap for the line length of the resulting table + + Return + ------ + string_rep: str + Table containing the given exceptions + """ + max_line_length -= 40 # Estimate of Field + Type space use + + headers = {"loc": "Location", "type": "Error Type", "mess": ["Message"]} + lengths = {key: len(headers[key]) for key in headers} + new_data = [] + + current_column = None + exceptions.sort(key=lambda tup: tup[1]) + for row_i, col_i, excep in exceptions: + if column_names is not None: + # Add a line with information about the current column + if current_column != col_i: + current_column = col_i + new_data.append({ + "loc": f"\nErrors in column '{column_names[col_i]}':", + "type": "", "mess": [""] + }) + # Setup for current Exception + curr_err_data: Any = {} + new_data.append(curr_err_data) + # Get field + if isinstance(row_i, int): + curr_err_data["loc"] = f"Cell {_column_id_to_chars(col_i)}{row_i + 1}" + else: + curr_err_data["loc"] = f"Column {_column_id_to_chars(col_i)}" + lengths["loc"] = max(lengths["loc"], len(curr_err_data["loc"])) + # Add error code + curr_err_data["type"] = type(excep).__name__ + lengths["type"] = max(lengths["type"], len(curr_err_data["type"])) + # Format message - split into lines + lines = str(excep).split('\n') + new_lines = [] + for line in lines: + new_lines += textwrap.wrap(line, max_line_length, break_long_words=False) + for line in new_lines: + lengths["mess"] = max(lengths["mess"], len(line)) + if new_lines == []: + new_lines = [""] + curr_err_data["mess"] = new_lines + + # Generate underline for each header + dividers = {key: '–' * l for key, l in lengths.items()} + dividers["mess"] = [dividers["mess"]] + # Fill with spaces for alignment + string_rep = f"There were errors during the validation of worksheet '{worksheet_title}':\n\n" + for curr_err_data in [headers, dividers] + new_data: + string_rep += ' {loc: <{fill}} '.format(loc=curr_err_data["loc"], + fill=lengths["loc"]) + string_rep += ' {typ: <{fill}} '.format(typ=curr_err_data["type"], + fill=lengths["type"]) + # Fill for the messages is set to 0, if we want another column or align + # right we need to use lengths["mess"] + string_rep += ' {mes: <{fill}}\n'.format(mes=curr_err_data["mess"][0], fill=0) + for line in curr_err_data["mess"][1:]: + # Front padding for lines without location and error type + string_rep += ' ' * (lengths["loc"] + lengths["type"] + 6) + string_rep += ' {mes: <{fill}}\n'.format(mes=line, fill=0) + return string_rep + + class ForeignError(KeyError): def __init__(self, *args, definitions: list, message: str = ""): super().__init__(message, *args) @@ -55,10 +155,9 @@ class ForeignError(KeyError): class XLSXConverter: """Class for conversion from XLSX to JSON. -For a detailed description of the required formatting of the XLSX files, see ``specs.md`` in the -documentation. + For a detailed description of the required formatting of the XLSX files, see ``specs.md`` in the + documentation. """ - PARSER: dict[str, Callable] = { "string": str, "number": float, @@ -69,49 +168,165 @@ documentation. def __init__(self, xlsx: Union[str, BinaryIO], schema: Union[dict, str, TextIO], strict: bool = False): """ -Parameters ----------- -xlsx: Union[str, BinaryIO] - Path to the XLSX file or opened file object. + Parameters + ---------- + xlsx: Union[str, BinaryIO] + Path to the XLSX file or opened file object. -schema: Union[dict, str, TextIO] - Schema for validation of XLSX content. + schema: Union[dict, str, TextIO] + Schema for validation of XLSX content. -strict: bool, optional - If True, fail faster. -""" + strict: bool, optional + If True, fail faster. + """ self._workbook = load_workbook(xlsx) self._schema = read_or_dict(schema) self._defining_path_index = xlsx_utils.get_defining_paths(self._workbook) + self._check_path_validity() self._check_columns(fail_fast=strict) self._handled_sheets: set[str] = set() self._result: dict = {} self._errors: dict = {} + def _check_path_validity(self): + """ + Method to check the workbook paths for completeness and correctness, + and raises a jsonschema.ValidationError containing information on all + faulty paths if any are found. + + If this method does not raise an error, this does not mean the workbook + is formatted correctly, only that the contained paths are complete and + can be found in the schema. + """ + # Setup + error_message = ["There were errors during path validation:"] + only_warnings = True + for sheetname in self._workbook.sheetnames: + sheet = self._workbook[sheetname] + error_message.append(f"\nIn sheet {sheetname}:") + + # Collect path information and filter out information column + row_i_col_type = xlsx_utils.get_column_type_row_index(sheet) + path_rows = xlsx_utils.get_path_rows(sheet) + paths = [] + for col_i, col in enumerate(sheet.iter_cols()): + col_type = col[row_i_col_type].value + path = [col[row_i].value for row_i in path_rows + if col[row_i].value not in [None, '']] + if col_type == 'COL_TYPE': + continue + paths.append((col_type, path, col_i, col)) + + # Check paths + for col_type, path, col_i, col in paths: + # No column type set + if col_type in [None, '']: + if len(path) == 0: # Likely a comment column + # Check whether the column has any visible content + content_in_column = False + for cell in col: + visible_content = ''.join(str(cell.value)).split() + if cell.value is not None and visible_content != '': + content_in_column = True + # If yes - might be an error but is not forbidden, so warn + if content_in_column: + m = (f"Warning:\tIn column {_column_id_to_chars(col_i)} " + f"there is no column metadata set. This column " + f"will be ignored during parsing.") + error_message.append(m) + continue + else: # Path is set but no column type + only_warnings = False + m = (f"ERROR:\t\tIn column {_column_id_to_chars(col_i)} " + f"the column type is missing.") + error_message.append(m) + # No continue - even if column type is missing, we can check path + if len(path) == 0: # Column type is set but no path + only_warnings = False + m = (f"ERROR:\t\tIn column {_column_id_to_chars(col_i)} " + f"the path is missing.") + error_message.append(m) + continue + # Check path is in schema + try: + subschema = xlsx_utils.get_subschema(path, self._schema) + schema_type = subschema.get('type', None) + if schema_type is None and 'enum' in subschema: + schema_type = 'enum' + if schema_type is None and 'anyOf' in subschema: + schema_type = 'anyOf' + if schema_type == 'array': # Check item type instead + schema_type = subschema.get('items', {}).get('type', None) + if schema_type in ['object', 'array', None]: + m = (f"Warning:\tIn column {_column_id_to_chars(col_i)} " + f"the path may be incomplete.") + error_message.append(m) + except KeyError as e: + only_warnings = False + m = (f"ERROR:\t\tIn column {_column_id_to_chars(col_i)} " + f"parsing of the path '{'.'.join(path)}' fails " + f"on the path component {str(e)}.\n\t\t\t" + f"This likely means the path is incomplete or not " + f"present in the schema.") + error_message.append(m) + + # Cleanup if no errors were found + if error_message[-1] == f"\nIn sheet {sheetname}:": + error_message.pop(-1) + + # Determine whether error / warning / nothing should be raised + if error_message == ["There were errors during path validation:"]: + return + error_message = '\n'.join(error_message) + if only_warnings: + warn(error_message) + else: + raise jsonschema.ValidationError(error_message) + def to_dict(self, validate: bool = False, collect_errors: bool = True) -> dict: """Convert the xlsx contents to a dict. -Parameters ----------- -validate: bool, optional - If True, validate the result against the schema. + Parameters + ---------- + validate: bool, optional + If True, validate the result against the schema. -collect_errors: bool, optional - If True, do not fail at the first error, but try to collect as many errors as possible. After an - Exception is raised, the errors can be collected with ``get_errors()`` and printed with - ``get_error_str()``. + collect_errors: bool, optional + If True, do not fail at the first error, but try to collect as many errors as possible. After an + Exception is raised, the errors can be collected with ``get_errors()`` and printed with + ``get_error_str()``. -Returns -------- -out: dict - A dict representing the JSON with the extracted data. + Returns + ------- + out: dict + A dict representing the JSON with the extracted data. """ self._handled_sheets = set() self._result = {} self._errors = {} - for sheetname in self._workbook.sheetnames: - if sheetname not in self._handled_sheets: - self._handle_sheet(self._workbook[sheetname], fail_later=collect_errors) + if not collect_errors: + for sheetname in self._workbook.sheetnames: + if sheetname not in self._handled_sheets: + self._handle_sheet(self._workbook[sheetname], fail_later=collect_errors) + else: + # Collect errors from converting + exceptions = [] + for sheetname in self._workbook.sheetnames: + if sheetname not in self._handled_sheets: + try: + self._handle_sheet(self._workbook[sheetname], fail_later=collect_errors) + except jsonschema.ValidationError as e: + exceptions.append(e) + # do not collect errors from sheet again + self._handled_sheets.add(sheetname) + if len(exceptions) == 1: + raise exceptions[0] + elif len(exceptions) > 1: + mess = "There were errors during the validation of several worksheets:\n\n" + mess += '\n\n'.join([str(e).replace("There were errors during the validation of worksheet", + "In worksheet") + for e in exceptions]) + raise jsonschema.ValidationError(mess) if validate: jsonschema.validate(self._result, self._schema) if self._errors: @@ -147,8 +362,11 @@ out: dict parents[xlsx_utils.p2s(col.path[:-1])] = col.path[:-1] col_paths.append(col.path) for path in parents.values(): - subschema = xlsx_utils.get_subschema(path, self._schema) - + try: + subschema = xlsx_utils.get_subschema(path, self._schema) + except KeyError as kerr: + kerr.args = (sheetname, *kerr.args) + raise # Unfortunately, there are a lot of special cases to handle here. if subschema.get("type") == "array": subschema = subschema["items"] @@ -177,24 +395,28 @@ out: dict def _handle_sheet(self, sheet: Worksheet, fail_later: bool = False) -> None: """Add the contents of the sheet to the result (stored in ``self._result``). -Each row in the sheet corresponds to one entry in an array in the result. Which array exactly is -defined by the sheet's "proper name" and the content of the foreign columns. + Each row in the sheet corresponds to one entry in an array in the result. Which array exactly is + defined by the sheet's "proper name" and the content of the foreign columns. -Look at ``xlsx_utils.get_path_position`` for the specification of the "proper name". + Look at ``xlsx_utils.get_path_position`` for the specification of the "proper name". -Parameters ----------- -fail_later: bool, optional - If True, do not fail with unresolvable foreign definitions, but collect all errors. -""" + Parameters + ---------- + fail_later: bool, optional + If True, do not fail with unresolvable foreign definitions, but collect all errors. + """ row_type_column = xlsx_utils.get_row_type_column_index(sheet) foreign_columns = xlsx_utils.get_foreign_key_columns(sheet) foreign_column_paths = {col.index: col.path for col in foreign_columns.values()} data_columns = xlsx_utils.get_data_columns(sheet) data_column_paths = {col.index: col.path for col in data_columns.values()} # Parent path, insert in correct order. - parent, proper_name = xlsx_utils.get_path_position(sheet) + try: + parent, proper_name = xlsx_utils.get_path_position(sheet) + except UnboundLocalError as e: + raise jsonschema.ValidationError(f"Malformed metadata: Cannot parse " + f"paths in worksheet '{sheet.title}'.") from e if parent: parent_sheetname = xlsx_utils.get_worksheet_for_path(parent, self._defining_path_index) if parent_sheetname not in self._handled_sheets: @@ -206,8 +428,10 @@ fail_later: bool, optional # # - data: The actual data of this entry, a dict. # entries: dict[str, list[SimpleNamespace]] = {} + exceptions = [] + col_names = {} for row_idx, row in enumerate(sheet.iter_rows(values_only=True)): - # Skip non-data rows. + # Skip non-data rows if row[row_type_column] is not None: continue foreign_repr = "" @@ -220,24 +444,34 @@ fail_later: bool, optional foreign.append(foreign_column_paths[col_idx] + [value]) continue - if col_idx in data_column_paths: - path = data_column_paths[col_idx] - if self._is_multiple_choice(path): - real_value = path.pop() # Last component is the enum value, insert above - # set up list - try: - _set_in_nested(mydict=data, path=path, value=[], prefix=parent, skip=1) - except ValueError as err: - if not str(err).startswith("There is already some value at"): - raise - if not xlsx_utils.parse_multiple_choice(value): - continue - _set_in_nested(mydict=data, path=path, value=real_value, prefix=parent, - skip=1, append_to_list=True) + try: + if col_idx in data_column_paths: + path = data_column_paths[col_idx] + col_names[col_idx] = '.'.join(path) + if self._is_multiple_choice(path): + real_value = path.pop() # Last component is the enum value, insert above + # set up list + try: + _set_in_nested(mydict=data, path=path, value=[], prefix=parent, skip=1) + except ValueError as err: + if not str(err).startswith("There is already some value at"): + raise + if not xlsx_utils.parse_multiple_choice(value): + continue + _set_in_nested(mydict=data, path=path, value=real_value, prefix=parent, + skip=1, append_to_list=True) + else: + value = self._validate_and_convert(value, path) + _set_in_nested(mydict=data, path=path, value=value, prefix=parent, skip=1) + continue + except (ValueError, KeyError, jsonschema.ValidationError) as e: + # Append error for entire column only once + if isinstance(e, KeyError) and 'column' in str(e): + if len([err for ri, ci, err in exceptions + if ci == col_idx and isinstance(err, KeyError)]) == 0: + exceptions.append((None, col_idx, e)) else: - value = self._validate_and_convert(value, path) - _set_in_nested(mydict=data, path=path, value=value, prefix=parent, skip=1) - continue + exceptions.append((row_idx, col_idx, e)) try: # Find current position in tree @@ -251,6 +485,12 @@ fail_later: bool, optional if not fail_later: raise self._errors[(sheet.title, row_idx)] = kerr.definitions + + if exceptions: + exception_table = _format_exception_table(exceptions, sheet.title, + col_names) + raise jsonschema.ValidationError(exception_table) + self._handled_sheets.add(sheet.title) def _is_multiple_choice(self, path: list[str]) -> bool: @@ -267,9 +507,9 @@ fail_later: bool, optional def _get_parent_dict(self, parent_path: list[str], foreign: list[list]) -> dict: """Return the dict into which values can be inserted. -This method returns, from the current result-in-making, the entry at ``parent_path`` which matches -the values given in the ``foreign`` specification. -""" + This method returns, from the current result-in-making, the entry at ``parent_path`` which matches + the values given in the ``foreign`` specification. + """ foreign_groups = _group_foreign_paths(foreign, common=parent_path) current_object = self._result @@ -296,9 +536,9 @@ the values given in the ``foreign`` specification. def _validate_and_convert(self, value: Any, path: list[str]): """Apply some basic validation and conversion steps. -This includes: -- Validation against the type given in the schema -- List typed values are split at semicolons and validated individually + This includes: + - Validation against the type given in the schema + - List typed values are split at semicolons and validated individually """ if value is None: return value @@ -309,20 +549,21 @@ This includes: if isinstance(value, str) and ";" in value: values = [self.PARSER[array_type](v) for v in value.split(";")] return values - try: - # special case: datetime or date - if ("anyOf" in subschema): - if isinstance(value, datetime.datetime) and ( - {'type': 'string', 'format': 'date-time'} in subschema["anyOf"]): - return value - if isinstance(value, datetime.date) and ( - {'type': 'string', 'format': 'date'} in subschema["anyOf"]): - return value - jsonschema.validate(value, subschema) - except jsonschema.ValidationError as verr: - print(verr) - print(path) - raise + # special case: datetime or date + if ("anyOf" in subschema): + if isinstance(value, datetime.datetime) and ( + {'type': 'string', 'format': 'date-time'} in subschema["anyOf"]): + return value + if isinstance(value, datetime.date) and ( + {'type': 'string', 'format': 'date'} in subschema["anyOf"]): + return value + # booleans might be retrieved as an integer or formula + if subschema.get('type') == 'boolean': + if value == 0 or isinstance(value, str) and '=false()' == value.lower(): + value = False + if value == 1 or isinstance(value, str) and '=true()' == value.lower(): + value = True + jsonschema.validate(value, subschema) # Finally: convert to target type return self.PARSER[subschema.get("type", "string")](value) @@ -340,29 +581,29 @@ This includes: def _group_foreign_paths(foreign: list[list], common: list[str]) -> list[SimpleNamespace]: """Group the foreign keys by their base paths. -Parameters ----------- -foreign: list[list] - A list of foreign definitions, consisting of path components, property and possibly value. - -common: list[list[str]] - A common path which defines the final target of the foreign definitions. This helps to understand - where the ``foreign`` paths shall be split. - -Returns -------- -out: list[dict[str, list[list]]] - - A list of foreign path segments, grouped by their common segments. Each element is a namespace - with detailed information of all those elements which form the group. The namespace has the - following attributes: - - - ``path``: The full path to this path segment. This is always the previous segment's ``path`` - plus this segment's ``subpath``. - - ``stringpath``: The stringified ``path``, might be useful for comparison or sorting. - - ``subpath``: The path, relative from the previous segment. - - ``definitions``: A list of the foreign definitions for this segment, but stripped of the - ``path`` components. + Parameters + ---------- + foreign: list[list] + A list of foreign definitions, consisting of path components, property and possibly value. + + common: list[list[str]] + A common path which defines the final target of the foreign definitions. This helps to understand + where the ``foreign`` paths shall be split. + + Returns + ------- + out: list[dict[str, list[list]]] + + A list of foreign path segments, grouped by their common segments. Each element is a namespace + with detailed information of all those elements which form the group. The namespace has the + following attributes: + + - ``path``: The full path to this path segment. This is always the previous segment's ``path`` + plus this segment's ``subpath``. + - ``stringpath``: The stringified ``path``, might be useful for comparison or sorting. + - ``subpath``: The path, relative from the previous segment. + - ``definitions``: A list of the foreign definitions for this segment, but stripped of the + ``path`` components. """ # Build a simple dict first, without subpath. results = {} @@ -392,9 +633,6 @@ out: list[dict[str, list[list]]] last_level = len(elem.path) resultlist.append(elem) - # from IPython import embed - # embed() - if last_level != len(common): raise ValueError("Foreign keys must cover the complete `common` depth.") return resultlist @@ -405,31 +643,31 @@ def _set_in_nested(mydict: dict, path: list, value: Any, prefix: list = [], skip overwrite: bool = False, append_to_list: bool = False) -> dict: """Set a value in a nested dict. -Parameters ----------- -mydict: dict - The dict into which the ``value`` shall be inserted. -path: list - A list of keys, denoting the location of the value. -value - The value which shall be set inside the dict. -prefix: list - A list of keys which shall be removed from ``path``. A KeyError is raised if ``path`` does not - start with the elements of ``prefix``. -skip: int = 0 - Remove this many additional levels from the path, *after* removing the prefix. -overwrite: bool = False - If True, allow overwriting existing content. Otherwise, attempting to overwrite existing values - leads to an exception. -append_to_list: bool = False - If True, assume that the element at ``path`` is a list and append the value to it. If the list - does not exist, create it. If there is a non-list at ``path`` already, overwrite it with a new - list, if ``overwrite`` is True, otherwise raise a ValueError. - -Returns -------- -mydict: dict - The same dictionary that was given as a parameter, but modified. + Parameters + ---------- + mydict: dict + The dict into which the ``value`` shall be inserted. + path: list + A list of keys, denoting the location of the value. + value + The value which shall be set inside the dict. + prefix: list + A list of keys which shall be removed from ``path``. A KeyError is raised if ``path`` does not + start with the elements of ``prefix``. + skip: int = 0 + Remove this many additional levels from the path, *after* removing the prefix. + overwrite: bool = False + If True, allow overwriting existing content. Otherwise, attempting to overwrite existing values + leads to an exception. + append_to_list: bool = False + If True, assume that the element at ``path`` is a list and append the value to it. If the list + does not exist, create it. If there is a non-list at ``path`` already, overwrite it with a new + list, if ``overwrite`` is True, otherwise raise a ValueError. + + Returns + ------- + mydict: dict + The same dictionary that was given as a parameter, but modified. """ for idx, el in enumerate(prefix): if path[idx] != el: @@ -469,29 +707,35 @@ mydict: dict return mydict +# ToDo: Fix https://gitlab.indiscale.com/caosdb/src/caosdb-advanced-user-tools/-/issues/138 +# and remove pylint disable def to_dict(xlsx: Union[str, BinaryIO], schema: Union[dict, str, TextIO], - validate: bool = None, strict: bool = False) -> dict: + validate: Optional[bool] = None, strict: bool = False) -> dict: """Convert the xlsx contents to a dict, it must follow a schema. -Parameters ----------- -xlsx: Union[str, BinaryIO] - Path to the XLSX file or opened file object. + Parameters + ---------- + xlsx: Union[str, BinaryIO] + Path to the XLSX file or opened file object. -schema: Union[dict, str, TextIO] - Schema for validation of XLSX content. + schema: Union[dict, str, TextIO] + Schema for validation of XLSX content. -validate: bool, optional - If True, validate the result against the schema. + validate: bool, optional + If True, validate the result against the schema. -strict: bool, optional - If True, fail faster. + strict: bool, optional + If True, fail faster. -Returns -------- -out: dict - A dict representing the JSON with the extracted data. + Returns + ------- + out: dict + A dict representing the JSON with the extracted data. """ + if validate: + raise NotImplementedError( + "For input validation implement " + "https://gitlab.indiscale.com/caosdb/src/caosdb-advanced-user-tools/-/issues/138") converter = XLSXConverter(xlsx, schema, strict=strict) return converter.to_dict() diff --git a/src/caosadvancedtools/table_json_conversion/xlsx_utils.py b/src/caosadvancedtools/table_json_conversion/xlsx_utils.py index 5002f3ac7fe4bd78accffe0697cd7ecc7273dc27..7770e3ecd372aa0bfb149659dc6397e3b675ff87 100644 --- a/src/caosadvancedtools/table_json_conversion/xlsx_utils.py +++ b/src/caosadvancedtools/table_json_conversion/xlsx_utils.py @@ -68,22 +68,22 @@ class RowType(Enum): def array_schema_from_model_schema(model_schema: dict) -> dict: """Convert a *data model* schema to a *data array* schema. -Practically, this means that the top level properties are converted into lists. In a simplified -notation, this can be expressed as: - -``array_schema = { elem: [elem typed data...] for elem in model_schema }`` - -Parameters ----------- -model_schema: dict - The schema description of the data model. Must be a json schema *object*, with a number of - *object* typed properties. - -Returns -------- -array_schema: dict - A corresponding json schema, where the properties are arrays with the types of the input's - top-level properties. + Practically, this means that the top level properties are converted into lists. In a simplified + notation, this can be expressed as: + + ``array_schema = { elem: [elem typed data...] for elem in model_schema }`` + + Parameters + ---------- + model_schema: dict + The schema description of the data model. Must be a json schema *object*, with a number of + *object* typed properties. + + Returns + ------- + array_schema: dict + A corresponding json schema, where the properties are arrays with the types of the input's + top-level properties. """ assert model_schema["type"] == "object" result = deepcopy(model_schema) @@ -100,30 +100,30 @@ array_schema: dict def get_defining_paths(workbook: Workbook) -> dict[str, list[list[str]]]: """For all sheets in ``workbook``, list the paths which they define. -A sheet is said to define a path, if it has data columns for properties inside that path. For -example, consider the following worksheet: - -| `COL_TYPE` | `SCALAR` | `SCALAR` | `LIST` | `SCALAR` | -| `PATH` | `Training` | `Training` | `Training` | `Training` | -| `PATH` | `url` | `date` | `subjects` | `supervisor` | -| `PATH` | | | | `email` | -|------------|----------------|---------------|--------------|--------------------| -| | example.com/mp | 2024-02-27 | Math;Physics | steve@example.com | -| | example.com/m | 2024-02-27 | Math | stella@example.com | - -This worksheet defines properties for the paths `["Training"]` and `["Training", "supervisor"]`, and -thus these two path lists would be returned for the key with this sheet's sheetname. - -Parameters ----------- -workbook: Workbook - The workbook to analyze. - -Returns -------- -out: dict[str, list[list[str]] - A dict with worksheet names as keys and lists of paths (represented as string lists) as values. -""" + A sheet is said to define a path, if it has data columns for properties inside that path. For + example, consider the following worksheet: + + | `COL_TYPE` | `SCALAR` | `SCALAR` | `LIST` | `SCALAR` | + | `PATH` | `Training` | `Training` | `Training` | `Training` | + | `PATH` | `url` | `date` | `subjects` | `supervisor` | + | `PATH` | | | | `email` | + |------------|----------------|---------------|--------------|--------------------| + | | example.com/mp | 2024-02-27 | Math;Physics | steve@example.com | + | | example.com/m | 2024-02-27 | Math | stella@example.com | + + This worksheet defines properties for the paths `["Training"]` and `["Training", "supervisor"]`, and + thus these two path lists would be returned for the key with this sheet's sheetname. + + Parameters + ---------- + workbook: Workbook + The workbook to analyze. + + Returns + ------- + out: dict[str, list[list[str]] + A dict with worksheet names as keys and lists of paths (represented as string lists) as values. + """ result: dict[str, list[list[str]]] = {} for sheet in workbook.worksheets: paths = [] @@ -140,11 +140,11 @@ out: dict[str, list[list[str]] def get_data_columns(sheet: Worksheet) -> dict[str, SimpleNamespace]: """Return the data paths of the worksheet. -Returns -------- -out: dict[str, SimpleNamespace] - The keys are the stringified paths. The values are SimpleNamespace objects with ``index``, - ``path`` and ``column`` attributes. + Returns + ------- + out: dict[str, SimpleNamespace] + The keys are the stringified paths. The values are SimpleNamespace objects with ``index``, + ``path`` and ``column`` attributes. """ column_types = _get_column_types(sheet) path_rows = get_path_rows(sheet) @@ -171,11 +171,11 @@ out: dict[str, SimpleNamespace] def get_foreign_key_columns(sheet: Worksheet) -> dict[str, SimpleNamespace]: """Return the foreign keys of the worksheet. -Returns -------- -out: dict[str, SimpleNamespace] - The keys are the stringified paths. The values are SimpleNamespace objects with ``index``, - ``path`` and ``column`` attributes. + Returns + ------- + out: dict[str, SimpleNamespace] + The keys are the stringified paths. The values are SimpleNamespace objects with ``index``, + ``path`` and ``column`` attributes. """ column_types = _get_column_types(sheet) path_rows = get_path_rows(sheet) @@ -198,20 +198,20 @@ out: dict[str, SimpleNamespace] def get_path_position(sheet: Worksheet) -> tuple[list[str], str]: """Return a path which represents the parent element, and the sheet's "proper name". -For top-level sheets / entries (those without foreign columns), the path is an empty list. + For top-level sheets / entries (those without foreign columns), the path is an empty list. -A sheet's "proper name" is detected from the data column paths: it is the first component after the -parent components. + A sheet's "proper name" is detected from the data column paths: it is the first component after the + parent components. -Returns -------- -parent: list[str] - Path to the parent element. Note that there may be list elements on the path which are **not** - represented in this return value. + Returns + ------- + parent: list[str] + Path to the parent element. Note that there may be list elements on the path which are **not** + represented in this return value. -proper_name: str - The "proper name" of this sheet. This defines an array where all the data lives, relative to the - parent path. + proper_name: str + The "proper name" of this sheet. This defines an array where all the data lives, relative to the + parent path. """ # Parent element: longest common path shared among any foreign column and all the data columns parent: list[str] = [] @@ -258,6 +258,16 @@ def get_row_type_column_index(sheet: Worksheet): raise ValueError("The column which defines row types (COL_TYPE, PATH, ...) is missing") +def get_column_type_row_index(sheet: Worksheet): + """Return the row index (0-indexed) of the row which defines the column types. + """ + for row in sheet.rows: + for cell in row: + if cell.value == RowType.COL_TYPE.name: + return cell.row - 1 + raise ValueError("The column which defines row types (COL_TYPE, SCALAR, ...) is missing") + + def get_subschema(path: list[str], schema: dict) -> dict: """Return the sub schema at ``path``.""" if path: @@ -285,7 +295,7 @@ def is_exploded_sheet(sheet: Worksheet) -> bool: """Return True if this is a an "exploded" sheet. An exploded sheet is a sheet whose data entries are LIST valued properties of entries in another - sheet. A sheet is detected as exploded iff it has FOREIGN columns. + sheet. A sheet is detected as exploded if and only if it has FOREIGN columns. """ column_types = _get_column_types(sheet) return ColumnType.FOREIGN.name in column_types.values() @@ -308,22 +318,22 @@ def p2s(path: list[str]) -> str: def parse_multiple_choice(value: Any) -> bool: """Interpret ``value`` as a multiple choice input. -*Truthy* values are: -- The boolean ``True``. -- The number "1". -- The (case-insensitive) strings ``true``, ``wahr``, ``x``, ``√``, ``yes``, ``ja``, ``y``, ``j``. - -*Falsy* values are: -- The boolean ``False``. -- ``None``, empty strings, lists, dicts. -- The number "0". -- The (case-insensitive) strings ``false``, ``falsch``, ``-``, ``no``, ``nein``, ``n``. -- Everything else. - -Returns -------- -out: bool - The interpretation result of ``value``. + *Truthy* values are: + - The boolean ``True``. + - The number "1". + - The (case-insensitive) strings ``true``, ``wahr``, ``x``, ``√``, ``yes``, ``ja``, ``y``, ``j``. + + *Falsy* values are: + - The boolean ``False``. + - ``None``, empty strings, lists, dicts. + - The number "0". + - The (case-insensitive) strings ``false``, ``falsch``, ``-``, ``no``, ``nein``, ``n``. + - Everything else. + + Returns + ------- + out: bool + The interpretation result of ``value``. """ # Non-string cases first: # pylint: disable-next=too-many-boolean-expressions @@ -349,7 +359,7 @@ out: bool def read_or_dict(data: Union[dict, str, TextIO]) -> dict: """If data is a json file name or input stream, read data from there. -If it is a dict already, just return it.""" + If it is a dict already, just return it.""" if isinstance(data, dict): return data diff --git a/src/caosadvancedtools/utils.py b/src/caosadvancedtools/utils.py index 05000a34fd27162837ecfe316b20af42b1156c45..f64900c04e8f1d126a7299662a2b529aa9f027b8 100644 --- a/src/caosadvancedtools/utils.py +++ b/src/caosadvancedtools/utils.py @@ -2,7 +2,7 @@ # encoding: utf-8 # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> # Copyright (C) 2020 Henrik tom Wörden <h.tomwoerden@indiscale.com> @@ -25,17 +25,15 @@ import logging import os -import pathlib -import caosdb as db -from caosdb.exceptions import TransactionError +import linkahead as db +from linkahead.exceptions import TransactionError, BadQueryError logger = logging.getLogger(__name__) -def set_log_level(level): - logger = logging.getLogger(__name__) - logger.setLevel(level=logging.DEBUG) +def set_log_level(level=logging.DEBUG): + logger.setLevel(level=level) def replace_path_prefix(path, old_prefix, new_prefix): @@ -234,9 +232,8 @@ def find_records_that_reference_ids(referenced_ids, rt="", step_size=50): [str(el) for el in subset])) exps = db.execute_query(q_string) record_ids.update([exp.id for exp in exps]) - except Exception as e: + except (TransactionError, BadQueryError) as e: print(e) - pass index += step_size diff --git a/src/caosadvancedtools/webui_formatter.py b/src/caosadvancedtools/webui_formatter.py index c3c5381d96e86a2698cc16d1bf1a2726566dcd7b..43ebbe061cccc2aec2c12f9193731017bad5e156 100644 --- a/src/caosadvancedtools/webui_formatter.py +++ b/src/caosadvancedtools/webui_formatter.py @@ -92,4 +92,4 @@ class WebUI_Formatter(logging.Formatter): return wrap_bootstrap_alert("<b>CRITICAL ERROR:</b> " + text, kind="danger") else: - raise Exception("unknown level") + raise RuntimeError("unknown level") diff --git a/src/doc/Makefile b/src/doc/Makefile index 7a1bec105f4b0fe1d70cabd7e3cf5f1ceff93bee..2df1aff867758c005fcd2357f0238cb60d3c2174 100644 --- a/src/doc/Makefile +++ b/src/doc/Makefile @@ -1,5 +1,5 @@ # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> # Copyright (C) 2020 Daniel Hornung <d.hornung@indiscale.com> diff --git a/src/doc/conf.py b/src/doc/conf.py index 0fc4ff0811cf4b845e5978b553e7760ac3000637..12495069ff28f300ed1595f6617d37934151ada3 100644 --- a/src/doc/conf.py +++ b/src/doc/conf.py @@ -23,13 +23,13 @@ import sphinx_rtd_theme # -- Project information ----------------------------------------------------- project = 'caosadvancedtools' -copyright = '2023, IndiScale GmbH' +copyright = '2025, IndiScale GmbH' author = 'Daniel Hornung' # The short X.Y version -version = '0.12.0' +version = '0.13.0' # The full version, including alpha/beta/rc tags -release = '0.12.0' +release = '0.13.0' # -- General configuration --------------------------------------------------- @@ -201,6 +201,4 @@ autodoc_default_options = { 'undoc-members': None, } autodoc_mock_imports = [ - "caosadvancedtools.bloxberg", - "labfolder", ] diff --git a/src/doc/crawler.rst b/src/doc/crawler.rst index d7b351bb3132cefed8920f977b345dc32e4db819..3323631e174f07169dae9c4e323299af3160a541 100644 --- a/src/doc/crawler.rst +++ b/src/doc/crawler.rst @@ -241,7 +241,7 @@ Let’s look at the following Example: >>> # Example CFood >>> from caosadvancedtools.cfood import AbstractFileCFood, assure_has_property - >>> import caosdb as db + >>> import linkahead as db >>> >>> class ExampleCFood(AbstractFileCFood): ... @staticmethod diff --git a/src/doc/table-json-conversion/specs.rst b/src/doc/table-json-conversion/specs.rst index c98eddc1180f552f1d2389b1bb57979e93550ab8..62c75a7055a4f2f07441a036e14b5fd5fe9b9256 100644 --- a/src/doc/table-json-conversion/specs.rst +++ b/src/doc/table-json-conversion/specs.rst @@ -181,7 +181,7 @@ a. Properties with primitive data types "date": "2023-06-15", "url": "www.indiscale.com/next", "duration": 2.5, - "participants": None, + "participants": null, "remote": true } ] diff --git a/src/doc/utilities.rst b/src/doc/utilities.rst index 4d520ae2d4b7a9bbd81171ba002c4f736223713a..f80460f32f9c5493206183427627a7fc7d5d13ba 100644 --- a/src/doc/utilities.rst +++ b/src/doc/utilities.rst @@ -35,3 +35,30 @@ behavior can be changed by initializing the ``TableImporter`` with :py:class:`~caosadvancedtools.datainconsistency.DataInconsistencyError` is raised when an empty field is encountered in a column with an non-nullable integer datatype. + +The loadfiles module and executable +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +For making files available to the LinkAhead server as File entities +(see also the server's `file server +<https://docs.indiscale.com/caosdb-server/specification/Fileserver.html>`_ +documentation), the LinkAhead Advanced User tools provide the +:py:mod:`~caosadvancedtools.loadFiles` module and a +``linkahead-loadfiles`` executable. Both operate on a path as seen by +the LinkAhead server (i.e., a path within the Docker container in the +typical LinkAhead Control setup) and can be further specified to +exclude or exclude specific files. In the typical setup, where a +directory is mounted as an *extroot* into the Docker container by +LinkAhead control, running + +.. code-block:: sh + + linkahead-loadfiles /opt/caosdb/mnt/extroot + +makes all files available. Execute + +.. code-block:: sh + + linkahead-loadfiles --help + +for more information and examples. diff --git a/tox.ini b/tox.ini index a7e06bf51f1f4cad2a2c695e44d3a4d09020b2a3..786a10547668e7c3a66ad0cbc8eb9606253bd213 100644 --- a/tox.ini +++ b/tox.ini @@ -1,18 +1,12 @@ [tox] -envlist=py38, py39, py310, py311, py312, py313 +envlist = py39, py310, py311, py312, py313 skip_missing_interpreters = true [testenv] -deps=nose - pandas +deps = git+https://gitlab.indiscale.com/caosdb/src/caosdb-pylib.git@dev - pytest - pytest-cov - gitignore-parser - openpyxl >= 3.0.7 - xlrd == 1.2 - h5py -commands=py.test --cov=caosadvancedtools --cov-report=html:.tox/cov_html -vv {posargs} +extras = test +commands = py.test --cov=caosadvancedtools --cov-report=html:.tox/cov_html -vv {posargs} [flake8] max-line-length=100 diff --git a/unittests/create_filetree.py b/unittests/create_filetree.py index f80b9681163859027bb8f8c7cd6b1387bf2d378d..bbd7783cd15331956b1aeaf80074e1a631dedd24 100644 --- a/unittests/create_filetree.py +++ b/unittests/create_filetree.py @@ -2,7 +2,7 @@ # encoding: utf-8 # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2018 Research Group Biomedical Physics, # Max-Planck-Institute for Dynamics and Self-Organization Göttingen diff --git a/unittests/example_labfolder_data/projects.html b/unittests/example_labfolder_data/projects.html deleted file mode 100644 index 6aafb8e237fe06d0655a165f860e3cecc661e8a4..0000000000000000000000000000000000000000 --- a/unittests/example_labfolder_data/projects.html +++ /dev/null @@ -1,138 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> - <meta name="apple-mobile-web-app-capable" content="yes"> - <meta name="apple-mobile-web-app-status-bar-style" - content="black-translucent"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - - <title>Projects</title> - - <link rel="shortcut icon" type="image/x-icon" - href="static/img/favicon2.ico"/> - - <script - src="static/js/jquery-1.8.2.min.js" - type="text/javascript"></script> - - <script src="static/js/tree.js" - type="text/javascript"></script> - - - <!-- This must be the first labfolder JS file included --> - <script - src="static/js/labfolder-global.js?13fcc6eeb30608bb104f4b234c2fa3fd86699ffe" - type="text/javascript"></script> - - <link rel="stylesheet" type="text/css" - href="static/css/eln_layout.css"/> - - - <link rel="stylesheet" type="text/css" - href="static/css/pixel_icon.css"/> - - <link rel="stylesheet" type="text/css" - href="static/css/tree.css"/> - - <link rel="stylesheet" type="text/css" - href="static/css/notebook.css"/> - -</head> -<body> -<div class="body_bg"></div> -<div class="eln_header eln_row"> - <div class="headerbar_top"> - <a href="/eln/"><span class="logo-img"></span></a> - <header> - <span aria-hidden="true" class="manage_s-img"></span> Projects - </header> - <nav> - <div class="nav_top"> - <ul> - <li><a href="templates.html"> - <button class="header_btn "> - <span class="desk-img"></span> - <p>Templates</p> - </button> - </a></li> - </ul> - </div> - </nav> - </div> -</div> -<div class="action_bar clearfix"></div> -<div id="data_element" data-viewname="WORKSPACE_INDEX"></div> -<div id="eln_main_content" - class="eln_main_content eln_row eln_scroll-y"> - <div class="eln_main_content_box projects-list"> - <div class="headers"> - <div class="owner">Owner</div> - <div class="update">Last Modified</div> - <div class="created">Created</div> - </div> - <div class="tree_my_eln_projects tree_top_level" data-treeid="eln_projects"> - <a id="treeline_eln_projects_0_0" - data-groupid="0" - data-objectid="0" - data-ownerid="{{ownerId}}" - class="treeline is_folder ui-droppable is_closed_folder"> - <span class="updateTS"></span> - <span class="folder_up-img"></span> - <span class="name">My private projects</span> - <span class="details"> - <span class="box-owner"> - <label>Owner:</label> - - -</span> -<span class="box-last-update"> - <label>Last update:</label> - -</span> - - </span> - </a> - <div class="treeline_children"style="overflow: hidden; display: none;"><a id="treeline_eln_projects" data-id="118217" data-parentId="0" data-userId="30003" data-groupId="0" data-name="Example project" data-folder="false" data-template="false" data-createTS="22.10.2019 15:49" data-hidden="false" data-shareable="false" data-owner-profilePictureHash="null" data-owner-tutorial="1" data-owner-zoneId="Europe/Berlin" data-owner-id="30003" data-owner-firstname="max" data-owner-lastname="muster" data-owner-email="max.muster@posteo.de" data-numberOfBlocks="4" data-lastEditedTS="28.01.2020 10:12" data-adminUserIds="[]" data-adminOrOwner="true" class="treeline is_item ui-draggable" href="./projects/My private projects_0/118217_Example%20project/index.html"> - <span class="updateTS">22.10.2019 15:49</span> - <span class="project_s-img"></span> - <span class="name">Example project</span> - <span class="details"> - <span class="box-owner"> - <label>Owner:</label> - max - muster -</span> -<span class="box-last-update"> - <label>Last update:</label> - 28.01.2020 10:12 -</span> - - </span> -</a> -<div class="treeline_children"style="overflow: hidden; display: none;"></div> -<a id="treeline_eln_projects" data-id="118224" data-parentId="0" data-userId="30003" data-groupId="0" data-name="subproj 1" data-folder="false" data-template="false" data-createTS="22.10.2019 16:49" data-hidden="false" data-shareable="false" data-owner-profilePictureHash="null" data-owner-tutorial="1" data-owner-zoneId="Europe/Berlin" data-owner-id="30003" data-owner-firstname="max" data-owner-lastname="muster" data-owner-email="max.muster@posteo.de" data-numberOfBlocks="0" data-lastEditedTS="22.10.2019 16:49" data-adminUserIds="[]" data-adminOrOwner="true" class="treeline is_item ui-draggable" href="./projects/My private projects_0/118224_subproj%201/index.html"> - <span class="updateTS">22.10.2019 16:49</span> - <span class="project_s-img"></span> - <span class="name">subproj 1</span> - <span class="details"> - <span class="box-owner"> - <label>Owner:</label> - max - muster -</span> -<span class="box-last-update"> - <label>Last update:</label> - 22.10.2019 16:49 -</span> - - </span> -</a> -<div class="treeline_children"style="overflow: hidden; display: none;"></div> -</div> -</div> - - </div> -</div> -</body> -</html> diff --git a/unittests/example_labfolder_data/projects/My private projects_0/118217_Example project/click_on_extract_4624688_10.xlsx b/unittests/example_labfolder_data/projects/My private projects_0/118217_Example project/click_on_extract_4624688_10.xlsx deleted file mode 100644 index 81ad1fa3196ba4235ce116dc408ba5ad0379cc5e..0000000000000000000000000000000000000000 Binary files a/unittests/example_labfolder_data/projects/My private projects_0/118217_Example project/click_on_extract_4624688_10.xlsx and /dev/null differ diff --git a/unittests/example_labfolder_data/projects/My private projects_0/118217_Example project/click_on_preview_4624688_9.docx b/unittests/example_labfolder_data/projects/My private projects_0/118217_Example project/click_on_preview_4624688_9.docx deleted file mode 100644 index 5b07c13c7997239ff51c78839e90bf34a98482d9..0000000000000000000000000000000000000000 Binary files a/unittests/example_labfolder_data/projects/My private projects_0/118217_Example project/click_on_preview_4624688_9.docx and /dev/null differ diff --git a/unittests/example_labfolder_data/projects/My private projects_0/118217_Example project/click_on_view_4624688_8.pdf b/unittests/example_labfolder_data/projects/My private projects_0/118217_Example project/click_on_view_4624688_8.pdf deleted file mode 100644 index 211d0f4b9c8b61ee87b4d276d2da0460f187935e..0000000000000000000000000000000000000000 Binary files a/unittests/example_labfolder_data/projects/My private projects_0/118217_Example project/click_on_view_4624688_8.pdf and /dev/null differ diff --git a/unittests/example_labfolder_data/projects/My private projects_0/118217_Example project/image_945829_4624688_image_element.png b/unittests/example_labfolder_data/projects/My private projects_0/118217_Example project/image_945829_4624688_image_element.png deleted file mode 100644 index 7a57e0e322072c8d8914dd0453761e3f0e519b24..0000000000000000000000000000000000000000 Binary files a/unittests/example_labfolder_data/projects/My private projects_0/118217_Example project/image_945829_4624688_image_element.png and /dev/null differ diff --git a/unittests/example_labfolder_data/projects/My private projects_0/118217_Example project/image_946047_4625717_blank.png b/unittests/example_labfolder_data/projects/My private projects_0/118217_Example project/image_946047_4625717_blank.png deleted file mode 100644 index 1939e07a484248d5b92ebae2fd50056a492ccad9..0000000000000000000000000000000000000000 Binary files a/unittests/example_labfolder_data/projects/My private projects_0/118217_Example project/image_946047_4625717_blank.png and /dev/null differ diff --git a/unittests/example_labfolder_data/projects/My private projects_0/118217_Example project/index.html b/unittests/example_labfolder_data/projects/My private projects_0/118217_Example project/index.html deleted file mode 100644 index 2450911f0bdd411558192ef36fa25310efea436a..0000000000000000000000000000000000000000 --- a/unittests/example_labfolder_data/projects/My private projects_0/118217_Example project/index.html +++ /dev/null @@ -1,1788 +0,0 @@ -<html> -<head> - <style type="text/css"> - @charset "UTF-8"; - [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak, .ng-hide:not(.ng-hide-animate) { - display: none !important; - } - - ng\:form { - display: block; - } - </style> - - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> - <meta name="apple-mobile-web-app-capable" content="yes"> - <meta name="apple-mobile-web-app-status-bar-style" - content="black-translucent"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - - - <title>Notebook</title> - - - <link rel="shortcut icon" type="image/x-icon" - href="../../../static/img/favicon2.ico"> - - <script src="../../../static/js/jquery-1.8.2.min.js" - type="text/javascript"></script> - <style type="text/css"></style> - - - <!-- This must be the first labfolder JS file included --> - <script - src="../../../static/js/labfolder-global.js?no-build-number" - type="text/javascript"></script> - - <link rel="stylesheet" type="text/css" - href="../../../static/css/export-table-element.css"> - <link rel="stylesheet" type="text/css" - href="../../../static/css/jquery-ui.css"> - - <link rel="stylesheet" type="text/css" - href="../../../static/css/data-elements.css?no-build-number"> - <link rel="stylesheet" type="text/css" - href="../../../static/css/combined.css?no-build-number"> - <link rel="stylesheet" type="text/css" - href="../../../static/css/export-entry-footer.css"> - <link rel="stylesheet" type="text/css" - href="../../../static/css/redactor.css"/> - - <script type="text/javascript"> - function getTemplateText(className) { - return $("#jsTemplate_jsText").find(".jstext_" + className).text(); - } - - $(document).ready(function () { - // expand tags and custom dates container on hover - $(".entry_menu_less").hover( - function () { - if (!$(this).children(":first").hasClass("entry_name_menu")) { - $(this).addClass('entry_menu_more'); - $(this).children(":first").addClass('show_list_more'); - if ($(this).children(":first").hasClass("entry_tags")) { - $(".entry_tags").css("height", "auto"); - } - } - }, - function () { - if (!$(this).children(":first").hasClass("entry_name_menu")) { - $(this).removeClass('entry_menu_more'); - $(this).children(":first").removeClass('show_list_more'); - if ($(this).children(":first").hasClass("entry_tags")) { - $(".entry_tags").css("height", "100%"); - } - } - } - ); - - //selects the table sheet according to click - $(".sheet_tab").click(function () { - if ($(this).hasClass('selected') === false) { - var previous = $(this).siblings(".selected"); - var previousElementId = previous.data("elementid"); - var previousSheetIndex = previous.data("sheetidx"); - previous.removeClass("selected"); - - var targetElementId = $(this).data("elementid"); - var targetSheetIndex = $(this).data("sheetidx"); - $(this).addClass("selected"); - - $("#table_" + targetElementId + "_" + targetSheetIndex).css("display", "block"); - $("#table_" + previousElementId + "_" + previousSheetIndex).css("display", "none"); - } - }); - }); - </script> - - <script src="../../../static/js/jquery-ui.js" - type="text/javascript"></script> -</head> - -<body> -<div class="body_bg"></div> -<div id="global_data"></div> -<div class="eln_header eln_row"> - <div class="headerbar_top"> - <a href="/eln/"><span class="logo-img"></span></a> - <header> - <span class="notebook_s-img"></span> Notebook - </header> - <nav> - <div class="nav_top"> - <ul> - <li><a href="../../../projects.html"> - <button class="header_btn "> - <span class="desk-img"></span> - <p>Projects</p> - </button> - </a></li> - <li><a href="../../../templates.html"> - <button class="header_btn "> - <span class="desk-img"></span> - <p>Templates</p> - </button> - </a></li> - </ul> - </div> - </nav> - </div> - - -</div> -<div class="ng-scope"> - <div class="action_bar clearfix ng-scope"> - <div class="plus_btn_wrap"> - <div class="plus_btn_hover"> - <div class="add_dropdown more_options_menu" style="display: none;"> - <ul> - </ul> - </div> - </div> - </div> - <div class="action_menu_wrap"> - <div class="filter_wrap list_horizontal"></div> - </div> - </div> - <div id="eln_project_content" - class="eln_project_content eln_row eln_scroll-y ng-scope" data-id="118217" data-parentId="0" data-userId="30003" data-groupId="0" data-name="Example project" data-folder="false" data-template="false" data-createTS="22.10.2019 15:49" data-hidden="false" data-shareable="false" data-owner-profilePictureHash="null" data-owner-tutorial="1" data-owner-zoneId="Europe/Berlin" data-owner-id="30003" data-owner-firstname="max" data-owner-lastname="muster" data-owner-email="max.muster@posteo.de" data-numberOfBlocks="4" data-lastEditedTS="28.01.2020 10:12" data-adminUserIds="[]" data-adminOrOwner="true" > - <div id="epb_container"><div data-id="4624688"data-blockId="4624662"data-elnProjectId="118217"data-sourceId="0"data-userAction="8"data-groupId="0"data-hidden="false"data-readOnly="false"data-versionTS="22.10.2019 17:49"data-createTS="22.10.2019 17:49"data-signHash="null"data-signHashDescription=""data-signHashVersion="null"data-signTS="null"data-witnessTS="null"data-title="Example entry"data-blockNumber="1"data-totalBlocksInProject="4"data-projectName="Example project"data-projectReferenceId="null"data-signBiometricsDocId="null"data-witnessBiometricsDocId="null"data-referenced="false"> - <div class="epb_header_container"> - <div class="epb_header clearfix" style="display: block;"> - - <div class="entry_container"> - <header class="entry_header"> - <div class="entry_author"> - <figure> - <span class="avatar-img"></span> - <img ng-src=""> - </figure> - - <div class="author_name"> - <div class="author_firstname ng-binding">max</div> - <div class="author_lastname ng-binding">muster</div> - </div> - </div> - <div class="entry_menu_less entry_title_wrap ng-scope"> - <div class="entry_name_menu has_tooltip"> - <ul> - <li> - <div style="display:block">Entry 1/4:</div> - <div>In Project:</div> - </li> - <li> - <div style="display:block" class="entry_title ng-binding">Example entry</div> - <div>Example project</div> - </li> - </ul> - </div> - <div class="entry_menu_options"> - </div> - <div class="entry_dropdown entry_name"> - <div class="close_entry_menu"> - <span class="cancel_entry_title close_box-img"></span> - </div> - <ul> - <li><label>Entry name</label> <input - class="entry_name_input ng-pristine ng-untouched ng-valid" - type="text" data-title="" value=""></li> - <li><label>located in project</label> <select - class="ng-pristine ng-untouched ng-valid"> - <option - value="0">tableproject - </option> - <option value="1" selected="selected">a project</option> - </select></li> - <li> - <div class="save_entry_menu"> - <span class="cancel_dropdown cancel_entry_title grey_link" - ng-click="cancel()">cancel</span> - <button class="save_entry_title btn_on_grey" ng-click="save()">save</button> - </div> - </li> - </ul> - </div> - </div> - - <div class="entry_menus"> - <ul> - <li class="entry_menu_less ng-scope" - ng-controller="EntryDateController"> - <div class="entry_menu_list has_tooltip" - ng-class="{true: '', false: 'has_tooltip'}[entry.readOnly]"> - <ul> - <li><span>created:</span> <span class="ng-binding">22.10.2019 17:49</span> - </li> - <li><span>modified</span> <span class="ng-binding">22.10.2019 17:49</span> - </li> - <!-- ngRepeat: date in currentDates | orderBy:predicate --> - <li> - <span>due date</span> - <span class=\"ng-binding\">22.10.2019</span> -</li> -<li> - <span>my date</span> - <span class=\"ng-binding\">22.10.2019</span> -</li> - - </ul> - </div> - <div class="entry_menu_options"> - </div> - <div class="entry_dropdown" - ng-mouseenter="activateElement($event)"> - <div class="close_entry_menu"> - <span class="close_box-img" ng-click="cancel()"></span> - </div> - <ul class="entry_dates"> - <li><label>Dates</label></li> - <li> - <div class="date_key"> - <input type="text" value="created" disabled=""> - </div> - <div class="date_value"> - <input type="text" ng-value="parseDate(entry.createTS)" - disabled="" value="18.02.2015"> - </div> - </li> - <li> - <div class="date_key"> - <input type="text" value="modified" disabled=""> - </div> - <div class="date_value"> - <input type="text" ng-value="parseDate(entry.versionTS)" - disabled="" value="18.02.2015"> - </div> - </li> - <!-- ngRepeat: date in currentDates | orderBy:predicate --> - <li style="overflow: visible;"> - <div class="date_key"> - - <div class="selectize-control single ng-valid" - ng-keyup="updateInput($select.search)" - reset-search-input="false" ng-model="dateKeyInput.selected" - theme="selectize" style="min-width: 120px;"> - <div class="selectize-input" - ng-class="{'focus': $select.open, 'disabled': $select.disabled, 'selectize-focus' : $select.focus}" - ng-click="$select.activate()"> - <div - ng-hide="$select.searchEnabled && ($select.open || $select.isEmpty())" - class="ui-select-match ng-hide" ng-transclude="" - placeholder="Custom date" - ng-keydown="inputKeydown($event)"> - <span class="ng-binding ng-scope"></span> - </div> - <input type="text" autocomplete="off" tabindex="-1" - class="ui-select-search ui-select-toggle ng-pristine ng-untouched ng-valid" - ng-click="$select.toggle($event)" - placeholder="Custom date" ng-model="$select.search" - ng-hide="!$select.searchEnabled || ($select.selected && !$select.open)" - ng-disabled="$select.disabled"> - </div> - <div ng-show="$select.open" - class="ui-select-choices selectize-dropdown single ng-scope ng-hide" - repeat="date in availableDates | filter: $select.search"> - <div - class="ui-select-choices-content selectize-dropdown-content"> - <div class="ui-select-choices-group optgroup"> - <div ng-show="$select.isGrouped" - class="ui-select-choices-group-label optgroup-header ng-binding ng-hide"></div> - <!-- ngRepeat: date in $select.items --> - <div class="ui-select-choices-row ng-scope" - ng-class="{active: $select.isActive(this), disabled: $select.isDisabled(this)}" - ng-repeat="date in $select.items" - ng-mouseenter="$select.setActiveItem(date)" - ng-click="$select.select(date)"> - <div class="option ui-select-choices-row-inner" - data-selectable="" uis-transclude-append=""> - <span ng-bind-html="date | highlight: $select.search" - class="ng-binding ng-scope">due date</span> - </div> - </div> - <!-- end ngRepeat: date in $select.items --> - <div class="ui-select-choices-row ng-scope" - ng-class="{active: $select.isActive(this), disabled: $select.isDisabled(this)}" - ng-repeat="date in $select.items" - ng-mouseenter="$select.setActiveItem(date)" - ng-click="$select.select(date)"> - <div class="option ui-select-choices-row-inner" - data-selectable="" uis-transclude-append=""> - <span ng-bind-html="date | highlight: $select.search" - class="ng-binding ng-scope">my date</span> - </div> - </div> - <!-- end ngRepeat: date in $select.items --> - </div> - </div> - </div> - <input ng-disabled="$select.disabled" - class="ui-select-focusser ui-select-offscreen ng-scope" - type="text" aria-haspopup="true" role="button"> - </div> - </div> - - <div class="date_value"> - <input type="text" - class="entry_datepicker date_input ng-pristine ng-untouched ng-valid" - ng-model="dateValueInput" ng-keydown="inputKeydown($event)"> - </div> - </li> - </ul> - <div class="save_entry_menu"> - <span class="cancel_dropdown grey_link" ng-click="cancel()">cancel</span> - <button class="btn_on_grey" ng-click="save()">save</button> - </div> - </div> - </li> - <li class="entry_menu_less ng-scope" - ng-controller="EntryTagsController"> - <div class="entry_tags has_tooltip" - ng-class="{true: '', false: 'has_tooltip'}[entry.readOnly]"> - <span>demo</span><span>example</span><span>entry</span> - </div> - <div class="entry_menu_options"> - </div> - <div class="entry_dropdown"> - <div class="close_entry_menu"> - <span class="close_box-img" ng-click="cancel()"></span> - </div> - <label>Create new tags by using commas</label> - <div class="token_input token_input_width"></div> - <div class="tags_input entry_tags_input" ng-click="focusInput()"> - - <!-- ngRepeat: tag in currentTokens --> - - <textarea class="token_input ng-pristine ng-untouched ng-valid" - ng-model="tagInput" ng-keydown="inputKeydown($event)"></textarea> - </div> - - <!-- <div class="save_entry_menu"> - <span class="cancel_dropdown grey_link" ng-click="cancel()">cancel</span> - <button class="btn_on_grey" ng-click='fromViewModel()'>fromViewModel</button> - </div> --> - <h3 class="all_tags">All tags</h3> - <div class="tag_data_wrap"> - <div class="tag_register"> - <ul> - <li> - <ul class="my_tags"> - <!-- ngRepeat: token in filteredValues = (availableTokens | filter:tagInput) --> - <li - ng-repeat="token in filteredValues = (availableTokens | filter:tagInput)" - class="ng-scope"><span - class="existing_tag ng-binding" - ng-class="{disabled: added(token), selected_tag: inputSelected(token)}" - ng-click="add(token)">demo</span></li> - <!-- end ngRepeat: token in filteredValues = (availableTokens | filter:tagInput) --> - <li - ng-repeat="token in filteredValues = (availableTokens | filter:tagInput)" - class="ng-scope"><span - class="existing_tag ng-binding" - ng-class="{disabled: added(token), selected_tag: inputSelected(token)}" - ng-click="add(token)">Entry</span></li> - <!-- end ngRepeat: token in filteredValues = (availableTokens | filter:tagInput) --> - <li - ng-repeat="token in filteredValues = (availableTokens | filter:tagInput)" - class="ng-scope"><span - class="existing_tag ng-binding" - ng-class="{disabled: added(token), selected_tag: inputSelected(token)}" - ng-click="add(token)">example</span></li> - <!-- end ngRepeat: token in filteredValues = (availableTokens | filter:tagInput) --> - </ul> - </li> - </ul> - </div> - </div> - </div> - </li> - <li> - <div class="entry_options"> - <ul> - </ul> - </div> - </li> - </ul> - </div> - </header> - <div class="entry_toolbar"></div> - </div> - <div class="clear"></div> - </div> -</div> - - <div class="epb_content_wrap"> - <div class="epb_content_container"> - <div class="hdrop ui-droppable"></div> - <div class="dd_entry_table"> - <div class="dd_entry_table"> - <div class="dd_entry_row"> - <div class="dd_entry_cell ui-draggable dd_text_entry"> - <div class="dd_entry_cell_wrapper" > - <div class="button_wrapper"></div> - <div class="dd_entry_cell_content redactor_editor"> - <p><p style="text-align: center;text-align: center;"><span style="color: rgb(61, 142, 185);"><strong>Use the buttons above to add text, tables, handwritten sketches, files, or data elements.</strong></span></p></p> -</div> - - </div> - </div> - </div> -</div> -<div class="dd_entry_table"> - <div class="dd_entry_row"> - <div class="dd_entry_cell ui-draggable dd_text_entry"> - <div class="dd_entry_cell_wrapper" > - <div class="button_wrapper"></div> - <div class="dd_entry_cell_content redactor_editor"> - <p><p style="text-align: center;text-align: center;"><strong><span style="font-size: 24px;">I am a text block</span></strong>.</p><p><br /></p><p style="text-align: justify;text-align: justify;">You can capture all your notes in me immediately after creating an entry. Use all the tools in the editor to style your texts, add numbered and bulleted lists, insert simple tables, and use special characters.</p><p style="text-align: justify;text-align: justify;"><br /></p><p style="text-align: justify;text-align: justify;">Look at this example:</p><p style="text-align: justify;text-align: justify;"><br /></p><h2 style="text-align: justify;text-align: justify;"><strong><span style="color: rgb(51, 51, 51);">Cloning plasmid for inducible mCherry-Wt1</span></strong></h2><table style="width: 100%;"><tbody><tr><td style="background-color: rgb(239, 239, 239);width: 33.3333%;"><strong>Primer</strong></td><td style="background-color: rgb(239, 239, 239);width: 33.3333%;"><strong>Sequence (5' -3')</strong></td><td style="background-color: rgb(239, 239, 239);width: 33.3333%;"><strong>Melting temperature (T<sub>m</sub>)</strong></td></tr><tr><td style="width: 33.3333%;">Fwd pSV40 Kan/Neo</td><td style="width: 33.3333%;">gtc ttc aag aat tcc tca gaa gaa ctc gtc aag<br /></td><td style="width: 33.3333%;">56 °C<br /></td></tr><tr><td style="width: 33.3333%;">Rev pSV40 Kan/Neo</td><td style="width: 33.3333%;">tga tag gga gta aac gag gtg cac tct cag tac<br /></td><td style="width: 33.3333%;">55 °C<br /></td></tr><tr><td style="width: 33.3333%;">Fwd IRES</td><td style="width: 33.3333%;">cct ttc gtc ttc aag gat atc cgg ccc ggt tgt ggc cat a<br /></td><td style="width: 33.3333%;">56 °C<br /></td></tr><tr><td style="width: 33.3333%;">Rev IRES</td><td style="width: 33.3333%;">cga gtt ctt ctg acg gcc ggc ccc tct ccc t<br /></td><td style="width: 33.3333%;">52 °C<br /></td></tr><tr><td style="width: 33.3333%;">Fwd PolyA Tet-ON 3G</td><td style="width: 33.3333%;">cga gtt ctt ctg acg gcc ggc ccc tct ccc t<br /></td><td style="width: 33.3333%;">53 °C<br /></td></tr><tr><td style="width: 33.3333%;">Rev PolyA Tet-ON 3G</td><td style="width: 33.3333%;">a caa ccg ggc cgg ata tgt cta gac tgg aca aga g<br /></td><td style="width: 33.3333%;">58 °C<br /></td></tr></tbody></table><p style="text-align: justify;text-align: justify;"><br /></p></p> -</div> - - </div> - </div> - </div> -</div> -<div class="dd_entry_table"> - <div class="dd_entry_row"> - <div class="dd_entry_cell ui-draggable dd_text_entry"> - <div class="dd_entry_cell_wrapper" data-imageOriginalDocId="945829" data-imageLayerDocId="null" data-zoomLevel="50" data-blockVersionId="4624688" data-filename="image_element.png" data-elementNumber="7" > - <div class="button_wrapper"></div> - <div class="dd_entry_cell_file_download"> - <i>image_element.png</i> - <br> - <div class="dd_entry_cell_content"> - <img class="imageOriginal" src="image_945829_4624688_image_element.png" width="50%"> - </div> -</div> - - </div> - </div> - </div> -</div> -<div class="dd_entry_table"> - <div class="dd_entry_row"> - <div class="dd_entry_cell ui-draggable dd_text_entry"> - <div class="dd_entry_cell_wrapper" > - <div class="button_wrapper"></div> - <div class="dd_entry_cell_content redactor_editor"> - <p><p style="text-align: center;text-align: center;"><span style="font-size: 24px;"><strong>Table Element</strong></span></p><p style="text-align: center;text-align: center;">You can record your data with the Table Element below to later perform operations, do calculations, or create charts.</p></p> -</div> - - </div> - </div> - </div> -</div> -<div class="dd_entry_table"> - <div class="dd_entry_row"> - <div class="dd_entry_cell ui-draggable dd_text_entry"> - <div class="dd_entry_cell_wrapper" {{elementMeta1}}> - <div class="button_wrapper"></div> - <div class="dd_entry_cell_content table-el-container"> - <div> - <div class="table-el-info"> - Your labfolder table is available for visualization as the following Excel file: - </div> - <div class="table-el-download"> - <a href="labfolder_table_4624688_11.xlsx"> - <svg class="table-el-icon" viewBox="0 0 475.1 402.5"> - <title>icon-table</title> - <path d="M461.7,14C452.7,5,442,0.5,429.4,0.5H45.7C33.1,0.5,22.4,5,13.4,14C4.5,22.9,0,33.7,0,46.2v310.6 c0,12.6,4.5,23.3,13.4,32.3c8.9,8.9,19.7,13.4,32.3,13.4h383.7c12.6,0,23.3-4.5,32.3-13.4c8.9-9,13.4-19.7,13.4-32.3V46.2 C475.1,33.7,470.6,22.9,461.7,14z M146.2,356.9c0,2.7-0.9,4.9-2.6,6.6c-1.7,1.7-3.9,2.6-6.6,2.6H45.7c-2.7,0-4.9-0.9-6.6-2.6 c-1.7-1.7-2.6-3.9-2.6-6.6V302c0-2.7,0.9-4.9,2.6-6.6c1.7-1.7,3.9-2.6,6.6-2.6H137c2.7,0,4.9,0.9,6.6,2.6c1.7,1.7,2.6,3.9,2.6,6.6 L146.2,356.9L146.2,356.9z M146.2,247.2c0,2.7-0.9,4.9-2.6,6.6c-1.7,1.7-3.9,2.6-6.6,2.6H45.7c-2.7,0-4.9-0.9-6.6-2.6 c-1.7-1.7-2.6-3.9-2.6-6.6v-54.8c0-2.7,0.9-4.9,2.6-6.6c1.7-1.7,3.9-2.6,6.6-2.6H137c2.7,0,4.9,0.9,6.6,2.6 c1.7,1.7,2.6,3.9,2.6,6.6L146.2,247.2L146.2,247.2z M146.2,137.6c0,2.7-0.9,4.9-2.6,6.6c-1.7,1.7-3.9,2.6-6.6,2.6H45.7 c-2.7,0-4.9-0.9-6.6-2.6c-1.7-1.7-2.6-3.9-2.6-6.6V82.8c0-2.7,0.9-4.9,2.6-6.6c1.7-1.7,3.9-2.6,6.6-2.6H137c2.7,0,4.9,0.9,6.6,2.6 c1.7,1.7,2.6,3.9,2.6,6.6L146.2,137.6L146.2,137.6z M292.4,356.9c0,2.7-0.9,4.9-2.6,6.6c-1.7,1.7-3.9,2.6-6.6,2.6h-91.4 c-2.7,0-4.9-0.9-6.6-2.6c-1.7-1.7-2.6-3.9-2.6-6.6V302c0-2.7,0.9-4.9,2.6-6.6c1.7-1.7,3.9-2.6,6.6-2.6h91.4c2.7,0,4.9,0.9,6.6,2.6 c1.7,1.7,2.6,3.9,2.6,6.6L292.4,356.9L292.4,356.9L292.4,356.9z M292.4,247.2c0,2.7-0.9,4.9-2.6,6.6c-1.7,1.7-3.9,2.6-6.6,2.6 h-91.4c-2.7,0-4.9-0.9-6.6-2.6c-1.7-1.7-2.6-3.9-2.6-6.6v-54.8c0-2.7,0.9-4.9,2.6-6.6c1.7-1.7,3.9-2.6,6.6-2.6h91.4 c2.7,0,4.9,0.9,6.6,2.6c1.7,1.7,2.6,3.9,2.6,6.6L292.4,247.2L292.4,247.2z M292.4,137.6c0,2.7-0.9,4.9-2.6,6.6 c-1.7,1.7-3.9,2.6-6.6,2.6h-91.4c-2.7,0-4.9-0.9-6.6-2.6c-1.7-1.7-2.6-3.9-2.6-6.6V82.8c0-2.7,0.9-4.9,2.6-6.6 c1.7-1.7,3.9-2.6,6.6-2.6h91.4c2.7,0,4.9,0.9,6.6,2.6c1.7,1.7,2.6,3.9,2.6,6.6L292.4,137.6L292.4,137.6z M438.5,356.9 c0,2.7-0.9,4.9-2.6,6.6c-1.7,1.7-3.9,2.6-6.6,2.6H338c-2.7,0-4.9-0.9-6.6-2.6c-1.7-1.7-2.6-3.9-2.6-6.6V302c0-2.7,0.8-4.9,2.6-6.6 c1.7-1.7,3.9-2.6,6.6-2.6h91.4c2.7,0,4.9,0.9,6.6,2.6c1.7,1.7,2.6,3.9,2.6,6.6V356.9z M438.5,247.2c0,2.7-0.9,4.9-2.6,6.6 c-1.7,1.7-3.9,2.6-6.6,2.6H338c-2.7,0-4.9-0.9-6.6-2.6c-1.7-1.7-2.6-3.9-2.6-6.6v-54.8c0-2.7,0.8-4.9,2.6-6.6 c1.7-1.7,3.9-2.6,6.6-2.6h91.4c2.7,0,4.9,0.9,6.6,2.6c1.7,1.7,2.6,3.9,2.6,6.6V247.2z M438.5,137.6c0,2.7-0.9,4.9-2.6,6.6 c-1.7,1.7-3.9,2.6-6.6,2.6H338c-2.7,0-4.9-0.9-6.6-2.6c-1.7-1.7-2.6-3.9-2.6-6.6V82.8c0-2.7,0.8-4.9,2.6-6.6 c1.7-1.7,3.9-2.6,6.6-2.6h91.4c2.7,0,4.9,0.9,6.6,2.6c1.7,1.7,2.6,3.9,2.6,6.6V137.6z"/> - </svg> - <div class="table-el-filename"> - labfolder_table_4624688_11.xlsx - </div> - </a> - </div> - </div> -</div> - - </div> - </div> - </div> -</div> -<div class="dd_entry_table"> - <div class="dd_entry_row"> - <div class="dd_entry_cell" data-width="50" - style="width: 50%;"> - <div class="dd_entry_cell_wrapper" ><div class="dd_entry_cell_content redactor_editor"> - <p><p><span style="font-size: 24px;"><strong>File Elements</strong></span></p><p><br /></p><p>You can upload and directly view PDF files in labfolder. See the example one on the right side. >></p></p> -</div> -</div> - </div> - <div class="dd_entry_cell"> - <div class="dd_entry_cell_wrapper" data-blockId="4624688" data-elementNumber="8" data-filename="click_on_view.pdf" data-fileSize="67.7 KB" data-fileDocId="945830" data-fileExists="true" ><div class="dd_entry_cell_file_download"> - <div class="file_icon"> - <div class="file_extension">pdf</div> - <span class="icon-file"></span> - </div> - <div class="file_details"> - <div class="file_name">click_on_view.pdf</div> - <div class="file_size_link"> - 67.7 KB <a href="click_on_view_4624688_8.pdf" - target="_blank"> Download </a> - </div> - </div> -</div> -</div> - </div> - </div> -</div> -<div class="dd_entry_table"> - <div class="dd_entry_row"> - <div class="dd_entry_cell ui-draggable dd_text_entry"> - <div class="dd_entry_cell_wrapper" > - <div class="button_wrapper"></div> - <div class="dd_entry_cell_content redactor_editor"> - <p>Check out the Microsoft Word® and Excel® support. After uploading a file you can do the following: <ul> <li><strong>Preview:</strong> Shows you a preview to see the content of the file.</li> <li><strong>Extract: </strong>All content from a file will be extracted and added to the entry.</li> <li><strong>Download: </strong>You can always download a file, which you uploaded to labfolder.</li> </ul></p> -</div> - - </div> - </div> - </div> -</div> -<div class="dd_entry_table"> - <div class="dd_entry_row"> - <div class="dd_entry_cell" data-width="50" - style="width: 50%;"> - <div class="dd_entry_cell_wrapper" data-blockId="4624688" data-elementNumber="9" data-filename="click_on_preview.docx" data-fileSize="66.8 KB" data-fileDocId="945831" data-fileExists="true" ><div class="dd_entry_cell_file_download"> - <div class="file_icon"> - <div class="file_extension">docx</div> - <span class="icon-file"></span> - </div> - <div class="file_details"> - <div class="file_name">click_on_preview.docx</div> - <div class="file_size_link"> - 66.8 KB <a href="click_on_preview_4624688_9.docx" - target="_blank"> Download </a> - </div> - </div> -</div> -</div> - </div> - <div class="dd_entry_cell"> - <div class="dd_entry_cell_wrapper" data-blockId="4624688" data-elementNumber="10" data-filename="click_on_extract.xlsx" data-fileSize="20.8 KB" data-fileDocId="945832" data-fileExists="true" ><div class="dd_entry_cell_file_download"> - <div class="file_icon"> - <div class="file_extension">xlsx</div> - <span class="icon-file"></span> - </div> - <div class="file_details"> - <div class="file_name">click_on_extract.xlsx</div> - <div class="file_size_link"> - 20.8 KB <a href="click_on_extract_4624688_10.xlsx" - target="_blank"> Download </a> - </div> - </div> -</div> -</div> - </div> - </div> -</div> -<div class="dd_entry_table"> - <div class="dd_entry_row"> - <div class="dd_entry_cell" data-width="53" - style="width: 53%;"> - <div class="dd_entry_cell_wrapper" ><div class="dd_entry_cell_content redactor_editor"> - <p><p><span style="font-size: 24px;"><strong>Data Element</strong></span></p><p><br /></p><p>The Data Element (DE) can be found in the entry toolbar next to the <em>Text</em>, <em>Table</em>, <em>Sketch</em> and <em>Upload</em> functions. You have these possibilities when working on the DE:</p><p><br /></p><ul><li>Insert a <em>Numerical Data Element</em> for quantitative experimental parameters.</li><li>Insert a <em>Descriptive Data Element</em> to document parameters with qualitative data.</li><li>Insert a <em>Data Group</em> with several experimental parameters.</li><li>Insert an item from your Material Database, referenced here as a <em>Material Element</em>.</li></ul><p><br /></p><p>Explore the example to the right. >></p></p> -</div> -</div> - </div> - <div class="dd_entry_cell"> - <div class="dd_entry_cell_wrapper" ><div class="notebook-element-content data-elements-container data-elements"> - <html><head></head><body><div class="data-element-wrap data-group-wrap"> - <svg class="data-element-icon data-group-icon" viewbox="0 0 67 64"> - <title>icon-vf-group-filled</title> - <path d="M32.119 39.613c0-0.238-0.119-0.476-0.357-0.595s-0.476-0.119-0.595 0l-12.372 7.138c-0.714 0.357-1.071 1.071-1.071 1.903v14.394c0 0.238 0.119 0.476 0.357 0.595s0.476 0.119 0.595 0l11.896-6.9c0.952-0.595 1.546-1.546 1.546-2.617v-13.918z"></path> - <path d="M0.952 39.019c-0.238-0.119-0.476-0.119-0.595 0-0.238 0.119-0.357 0.357-0.357 0.595v0 13.799c0 1.071 0.595 2.141 1.546 2.617l11.896 6.9c0.238 0.119 0.476 0.119 0.595 0 0.238-0.119 0.357-0.357 0.357-0.595v-14.275c0-0.714-0.357-1.428-1.071-1.903l-12.372-7.138z"></path> - <path d="M29.502 36.996c0.238-0.119 0.357-0.357 0.357-0.595s-0.119-0.476-0.357-0.595v0l-11.896-6.9c-0.952-0.595-2.141-0.595-3.093 0l-11.896 6.9c-0.238 0.119-0.357 0.357-0.357 0.595s0.119 0.476 0.357 0.595l12.372 7.138c0.714 0.357 1.428 0.357 2.141 0l12.372-7.138z"></path> - <path d="M49.487 11.063c0-0.238-0.119-0.476-0.357-0.595s-0.476-0.119-0.595 0l-12.372 7.138c-0.714 0.357-1.071 1.071-1.071 1.903v14.394c0 0.238 0.119 0.476 0.357 0.595s0.476 0.119 0.595 0l11.896-6.9c0.952-0.595 1.546-1.546 1.546-2.617v-13.918z"></path> - <path d="M19.39 10.587c-0.238-0.119-0.476-0.119-0.595 0-0.238 0.119-0.357 0.357-0.357 0.595v0 13.799c0 1.071 0.595 2.141 1.546 2.617l11.896 6.9c0.238 0.119 0.476 0.119 0.595 0 0.238-0.119 0.357-0.357 0.357-0.595v-14.394c0-0.714-0.357-1.427-1.071-1.903l-12.372-7.019z"></path> - <path d="M46.87 8.565c0.238-0.119 0.357-0.357 0.357-0.595s-0.119-0.476-0.357-0.595v0l-11.896-6.9c-0.952-0.595-2.141-0.595-3.093 0l-11.896 6.9c-0.238 0.119-0.357 0.357-0.357 0.595s0.119 0.476 0.357 0.595l12.372 7.138c0.714 0.357 1.428 0.357 2.141 0l12.372-7.138z"></path> - <path d="M66.498 40.327c0-0.238-0.119-0.476-0.357-0.595s-0.476-0.119-0.595 0l-12.372 7.138c-0.714 0.357-1.071 1.071-1.071 1.903v14.394c0 0.238 0.119 0.476 0.357 0.595s0.476 0.119 0.595 0l11.896-6.9c0.952-0.595 1.546-1.546 1.546-2.617v-13.918z"></path> - <path d="M35.331 39.851c-0.238-0.119-0.476-0.119-0.595 0-0.238 0.119-0.357 0.357-0.357 0.595v0 13.799c0 1.071 0.595 2.141 1.546 2.617l11.896 6.9c0 0 0 0 0 0 0.238 0.119 0.476 0.119 0.595 0 0.238-0.119 0.357-0.357 0.357-0.595v-14.394c0-0.714-0.357-1.428-1.071-1.903l-12.372-7.019z"></path> - <path d="M64 37.71c0.238-0.119 0.357-0.357 0.357-0.595s-0.119-0.476-0.357-0.595c0 0 0 0 0 0l-11.896-6.9c-0.952-0.595-2.141-0.595-3.093 0l-11.896 6.9c-0.238 0.119-0.357 0.357-0.357 0.595s0.119 0.476 0.357 0.595l12.372 7.138c0.714 0.357 1.428 0.357 2.141 0l12.372-7.138z"></path> - </svg> - - <div class="data-group-content display-mode"> - <div class="data-element-wrap data-group-header"> - <div class="data-element-display data-group-display"> - <span class="element-title">PCR reaction pSV40-Tet3G-TRE3G-mCherry</span> - </div> - </div> - - <div class="data-group-children"> - <div class="data-element-wrap single-element-wrap"> - <svg class="data-element-icon single-element-icon" viewbox="0 0 67 64"> - <title>icon-vf-filled</title> - <path d="M59.413 20.587c0-0.427-0.213-0.853-0.64-1.067-0.32-0.213-0.853-0.213-1.173 0l-22.827 13.227c-1.173 0.747-1.92 2.027-1.92 3.413v26.453c0 0.427 0.213 0.853 0.64 1.067 0.32 0.213 0.853 0.213 1.173 0l21.867-12.8c1.707-1.067 2.88-2.88 2.88-4.907v-25.387z"></path> - <path d="M2.027 19.52c-0.32-0.213-0.853-0.213-1.173 0s-0.64 0.64-0.64 1.067v0 25.387c0 2.027 1.067 3.947 2.88 4.907l21.973 12.693c0 0 0 0 0 0 0.32 0.213 0.853 0.213 1.173 0s0.64-0.64 0.64-1.067v-26.347c0-1.387-0.747-2.667-1.92-3.413l-22.933-13.227z"></path> - <path d="M54.72 15.787c0.32-0.213 0.64-0.64 0.64-1.067s-0.213-0.853-0.64-1.067c0 0 0 0 0 0l-22.080-12.587c-1.707-1.067-3.947-1.067-5.653 0l-21.973 12.693c-0.32 0.213-0.64 0.64-0.64 1.067s0.213 0.853 0.64 1.067l22.827 13.227c1.173 0.747 2.667 0.747 3.947 0l22.933-13.333z"></path> - </svg> - - <div class="data-element-display single-element-display"> - <span class="element-title ">5X In-Fusion HD Enzyme Premix</span> - <span class="element-quantity">: Volume: </span> - <span class="element-value ">2 </span> - <span class="element-unit">µL</span> - </div> -</div> -<div class="data-element-wrap single-element-wrap"> - <svg class="data-element-icon single-element-icon" viewbox="0 0 67 64"> - <title>icon-vf-filled</title> - <path d="M59.413 20.587c0-0.427-0.213-0.853-0.64-1.067-0.32-0.213-0.853-0.213-1.173 0l-22.827 13.227c-1.173 0.747-1.92 2.027-1.92 3.413v26.453c0 0.427 0.213 0.853 0.64 1.067 0.32 0.213 0.853 0.213 1.173 0l21.867-12.8c1.707-1.067 2.88-2.88 2.88-4.907v-25.387z"></path> - <path d="M2.027 19.52c-0.32-0.213-0.853-0.213-1.173 0s-0.64 0.64-0.64 1.067v0 25.387c0 2.027 1.067 3.947 2.88 4.907l21.973 12.693c0 0 0 0 0 0 0.32 0.213 0.853 0.213 1.173 0s0.64-0.64 0.64-1.067v-26.347c0-1.387-0.747-2.667-1.92-3.413l-22.933-13.227z"></path> - <path d="M54.72 15.787c0.32-0.213 0.64-0.64 0.64-1.067s-0.213-0.853-0.64-1.067c0 0 0 0 0 0l-22.080-12.587c-1.707-1.067-3.947-1.067-5.653 0l-21.973 12.693c-0.32 0.213-0.64 0.64-0.64 1.067s0.213 0.853 0.64 1.067l22.827 13.227c1.173 0.747 2.667 0.747 3.947 0l22.933-13.333z"></path> - </svg> - - <div class="data-element-display single-element-display"> - <span class="element-title ">Linearized pSV40 vector</span> - <span class="element-quantity">: Volume: </span> - <span class="element-value ">7 </span> - <span class="element-unit">µL</span> - </div> -</div> -<div class="data-element-wrap single-element-wrap"> - <svg class="data-element-icon single-element-icon" viewbox="0 0 67 64"> - <title>icon-vf-filled</title> - <path d="M59.413 20.587c0-0.427-0.213-0.853-0.64-1.067-0.32-0.213-0.853-0.213-1.173 0l-22.827 13.227c-1.173 0.747-1.92 2.027-1.92 3.413v26.453c0 0.427 0.213 0.853 0.64 1.067 0.32 0.213 0.853 0.213 1.173 0l21.867-12.8c1.707-1.067 2.88-2.88 2.88-4.907v-25.387z"></path> - <path d="M2.027 19.52c-0.32-0.213-0.853-0.213-1.173 0s-0.64 0.64-0.64 1.067v0 25.387c0 2.027 1.067 3.947 2.88 4.907l21.973 12.693c0 0 0 0 0 0 0.32 0.213 0.853 0.213 1.173 0s0.64-0.64 0.64-1.067v-26.347c0-1.387-0.747-2.667-1.92-3.413l-22.933-13.227z"></path> - <path d="M54.72 15.787c0.32-0.213 0.64-0.64 0.64-1.067s-0.213-0.853-0.64-1.067c0 0 0 0 0 0l-22.080-12.587c-1.707-1.067-3.947-1.067-5.653 0l-21.973 12.693c-0.32 0.213-0.64 0.64-0.64 1.067s0.213 0.853 0.64 1.067l22.827 13.227c1.173 0.747 2.667 0.747 3.947 0l22.933-13.333z"></path> - </svg> - - <div class="data-element-display single-element-display"> - <span class="element-title ">Purified PCR fragment</span> - <span class="element-quantity">: Volume: </span> - <span class="element-value ">8 </span> - <span class="element-unit">µL</span> - </div> -</div> -<div class="data-element-wrap single-element-wrap"> - <svg class="data-element-icon single-element-icon" viewbox="0 0 67 64"> - <title>icon-vf-filled</title> - <path d="M59.413 20.587c0-0.427-0.213-0.853-0.64-1.067-0.32-0.213-0.853-0.213-1.173 0l-22.827 13.227c-1.173 0.747-1.92 2.027-1.92 3.413v26.453c0 0.427 0.213 0.853 0.64 1.067 0.32 0.213 0.853 0.213 1.173 0l21.867-12.8c1.707-1.067 2.88-2.88 2.88-4.907v-25.387z"></path> - <path d="M2.027 19.52c-0.32-0.213-0.853-0.213-1.173 0s-0.64 0.64-0.64 1.067v0 25.387c0 2.027 1.067 3.947 2.88 4.907l21.973 12.693c0 0 0 0 0 0 0.32 0.213 0.853 0.213 1.173 0s0.64-0.64 0.64-1.067v-26.347c0-1.387-0.747-2.667-1.92-3.413l-22.933-13.227z"></path> - <path d="M54.72 15.787c0.32-0.213 0.64-0.64 0.64-1.067s-0.213-0.853-0.64-1.067c0 0 0 0 0 0l-22.080-12.587c-1.707-1.067-3.947-1.067-5.653 0l-21.973 12.693c-0.32 0.213-0.64 0.64-0.64 1.067s0.213 0.853 0.64 1.067l22.827 13.227c1.173 0.747 2.667 0.747 3.947 0l22.933-13.333z"></path> - </svg> - - <div class="data-element-display single-element-display"> - <span class="element-title ">dH2O (as needed)</span> - <span class="element-quantity">: Volume: </span> - <span class="element-value ">8 </span> - <span class="element-unit">µL</span> - </div> -</div> - - </div> - </div> -</div> -</body></html><html><head></head><body><div class="data-element-wrap descriptive-element-wrap"> - <svg class="data-element-icon descriptive-element-icon" viewbox="0 0 64 64"> - <title>icon-dde</title> - <path d="M62.080 48.96h-60.16c-1.088 0-1.92 0.832-1.92 1.92v11.2c0 1.088 0.832 1.92 1.92 1.92h60.16c1.088 0 1.92-0.832 1.92-1.92v-11.2c0-1.024-0.832-1.92-1.92-1.92z"></path> - <path d="M62.080 24.192h-60.16c-1.088 0-1.92 0.832-1.92 1.92v11.2c0 1.088 0.832 1.92 1.92 1.92h60.16c1.088 0 1.92-0.832 1.92-1.92v-11.2c0-1.088-0.832-1.92-1.92-1.92z"></path> - <path d="M37.504 0h-35.584c-1.088 0-1.92 0.832-1.92 1.92v11.2c0 1.088 0.832 1.92 1.92 1.92h35.584c1.088 0 1.92-0.832 1.92-1.92v-11.2c0-1.088-0.832-1.92-1.92-1.92z"></path> - </svg> - - <div class="data-element-display descriptive-element-display"> - <span class="element-title">Human Monocytes: </span> - <span class="element-description ">Prepared</span> - </div> -</div> -</body></html> -</div> -</div> - </div> - </div> -</div> - - </div> - </div> -</div> - - -</div><div data-id="4625717"data-blockId="4625197"data-elnProjectId="118217"data-sourceId="0"data-userAction="5"data-groupId="0"data-hidden="false"data-readOnly="false"data-versionTS="22.10.2019 20:01"data-createTS="22.10.2019 18:47"data-signHash="null"data-signHashDescription=""data-signHashVersion="null"data-signTS="null"data-witnessTS="null"data-title="null"data-blockNumber="2"data-totalBlocksInProject="4"data-projectName="Example project"data-projectReferenceId="null"data-signBiometricsDocId="null"data-witnessBiometricsDocId="null"data-referenced="false"> - <div class="epb_header_container"> - <div class="epb_header clearfix" style="display: block;"> - - <div class="entry_container"> - <header class="entry_header"> - <div class="entry_author"> - <figure> - <span class="avatar-img"></span> - <img ng-src=""> - </figure> - - <div class="author_name"> - <div class="author_firstname ng-binding">max</div> - <div class="author_lastname ng-binding">muster</div> - </div> - </div> - <div class="entry_menu_less entry_title_wrap ng-scope"> - <div class="entry_name_menu has_tooltip"> - <ul> - <li> - <div style="display:block">Entry 2/4:</div> - <div>In Project:</div> - </li> - <li> - <div style="display:block" class="entry_title ng-binding"><em>No entry title yet</em></div> - <div>Example project</div> - </li> - </ul> - </div> - <div class="entry_menu_options"> - </div> - <div class="entry_dropdown entry_name"> - <div class="close_entry_menu"> - <span class="cancel_entry_title close_box-img"></span> - </div> - <ul> - <li><label>Entry name</label> <input - class="entry_name_input ng-pristine ng-untouched ng-valid" - type="text" data-title="" value=""></li> - <li><label>located in project</label> <select - class="ng-pristine ng-untouched ng-valid"> - <option - value="0">tableproject - </option> - <option value="1" selected="selected">a project</option> - </select></li> - <li> - <div class="save_entry_menu"> - <span class="cancel_dropdown cancel_entry_title grey_link" - ng-click="cancel()">cancel</span> - <button class="save_entry_title btn_on_grey" ng-click="save()">save</button> - </div> - </li> - </ul> - </div> - </div> - - <div class="entry_menus"> - <ul> - <li class="entry_menu_less ng-scope" - ng-controller="EntryDateController"> - <div class="entry_menu_list has_tooltip" - ng-class="{true: '', false: 'has_tooltip'}[entry.readOnly]"> - <ul> - <li><span>created:</span> <span class="ng-binding">22.10.2019 18:47</span> - </li> - <li><span>modified</span> <span class="ng-binding">22.10.2019 20:01</span> - </li> - <!-- ngRepeat: date in currentDates | orderBy:predicate --> - - </ul> - </div> - <div class="entry_menu_options"> - </div> - <div class="entry_dropdown" - ng-mouseenter="activateElement($event)"> - <div class="close_entry_menu"> - <span class="close_box-img" ng-click="cancel()"></span> - </div> - <ul class="entry_dates"> - <li><label>Dates</label></li> - <li> - <div class="date_key"> - <input type="text" value="created" disabled=""> - </div> - <div class="date_value"> - <input type="text" ng-value="parseDate(entry.createTS)" - disabled="" value="18.02.2015"> - </div> - </li> - <li> - <div class="date_key"> - <input type="text" value="modified" disabled=""> - </div> - <div class="date_value"> - <input type="text" ng-value="parseDate(entry.versionTS)" - disabled="" value="18.02.2015"> - </div> - </li> - <!-- ngRepeat: date in currentDates | orderBy:predicate --> - <li style="overflow: visible;"> - <div class="date_key"> - - <div class="selectize-control single ng-valid" - ng-keyup="updateInput($select.search)" - reset-search-input="false" ng-model="dateKeyInput.selected" - theme="selectize" style="min-width: 120px;"> - <div class="selectize-input" - ng-class="{'focus': $select.open, 'disabled': $select.disabled, 'selectize-focus' : $select.focus}" - ng-click="$select.activate()"> - <div - ng-hide="$select.searchEnabled && ($select.open || $select.isEmpty())" - class="ui-select-match ng-hide" ng-transclude="" - placeholder="Custom date" - ng-keydown="inputKeydown($event)"> - <span class="ng-binding ng-scope"></span> - </div> - <input type="text" autocomplete="off" tabindex="-1" - class="ui-select-search ui-select-toggle ng-pristine ng-untouched ng-valid" - ng-click="$select.toggle($event)" - placeholder="Custom date" ng-model="$select.search" - ng-hide="!$select.searchEnabled || ($select.selected && !$select.open)" - ng-disabled="$select.disabled"> - </div> - <div ng-show="$select.open" - class="ui-select-choices selectize-dropdown single ng-scope ng-hide" - repeat="date in availableDates | filter: $select.search"> - <div - class="ui-select-choices-content selectize-dropdown-content"> - <div class="ui-select-choices-group optgroup"> - <div ng-show="$select.isGrouped" - class="ui-select-choices-group-label optgroup-header ng-binding ng-hide"></div> - <!-- ngRepeat: date in $select.items --> - <div class="ui-select-choices-row ng-scope" - ng-class="{active: $select.isActive(this), disabled: $select.isDisabled(this)}" - ng-repeat="date in $select.items" - ng-mouseenter="$select.setActiveItem(date)" - ng-click="$select.select(date)"> - <div class="option ui-select-choices-row-inner" - data-selectable="" uis-transclude-append=""> - <span ng-bind-html="date | highlight: $select.search" - class="ng-binding ng-scope">due date</span> - </div> - </div> - <!-- end ngRepeat: date in $select.items --> - <div class="ui-select-choices-row ng-scope" - ng-class="{active: $select.isActive(this), disabled: $select.isDisabled(this)}" - ng-repeat="date in $select.items" - ng-mouseenter="$select.setActiveItem(date)" - ng-click="$select.select(date)"> - <div class="option ui-select-choices-row-inner" - data-selectable="" uis-transclude-append=""> - <span ng-bind-html="date | highlight: $select.search" - class="ng-binding ng-scope">my date</span> - </div> - </div> - <!-- end ngRepeat: date in $select.items --> - </div> - </div> - </div> - <input ng-disabled="$select.disabled" - class="ui-select-focusser ui-select-offscreen ng-scope" - type="text" aria-haspopup="true" role="button"> - </div> - </div> - - <div class="date_value"> - <input type="text" - class="entry_datepicker date_input ng-pristine ng-untouched ng-valid" - ng-model="dateValueInput" ng-keydown="inputKeydown($event)"> - </div> - </li> - </ul> - <div class="save_entry_menu"> - <span class="cancel_dropdown grey_link" ng-click="cancel()">cancel</span> - <button class="btn_on_grey" ng-click="save()">save</button> - </div> - </div> - </li> - <li class="entry_menu_less ng-scope" - ng-controller="EntryTagsController"> - <div class="entry_tags has_tooltip" - ng-class="{true: '', false: 'has_tooltip'}[entry.readOnly]"> - <i>No tags associated</i> - </div> - <div class="entry_menu_options"> - </div> - <div class="entry_dropdown"> - <div class="close_entry_menu"> - <span class="close_box-img" ng-click="cancel()"></span> - </div> - <label>Create new tags by using commas</label> - <div class="token_input token_input_width"></div> - <div class="tags_input entry_tags_input" ng-click="focusInput()"> - - <!-- ngRepeat: tag in currentTokens --> - - <textarea class="token_input ng-pristine ng-untouched ng-valid" - ng-model="tagInput" ng-keydown="inputKeydown($event)"></textarea> - </div> - - <!-- <div class="save_entry_menu"> - <span class="cancel_dropdown grey_link" ng-click="cancel()">cancel</span> - <button class="btn_on_grey" ng-click='fromViewModel()'>fromViewModel</button> - </div> --> - <h3 class="all_tags">All tags</h3> - <div class="tag_data_wrap"> - <div class="tag_register"> - <ul> - <li> - <ul class="my_tags"> - <!-- ngRepeat: token in filteredValues = (availableTokens | filter:tagInput) --> - <li - ng-repeat="token in filteredValues = (availableTokens | filter:tagInput)" - class="ng-scope"><span - class="existing_tag ng-binding" - ng-class="{disabled: added(token), selected_tag: inputSelected(token)}" - ng-click="add(token)">demo</span></li> - <!-- end ngRepeat: token in filteredValues = (availableTokens | filter:tagInput) --> - <li - ng-repeat="token in filteredValues = (availableTokens | filter:tagInput)" - class="ng-scope"><span - class="existing_tag ng-binding" - ng-class="{disabled: added(token), selected_tag: inputSelected(token)}" - ng-click="add(token)">Entry</span></li> - <!-- end ngRepeat: token in filteredValues = (availableTokens | filter:tagInput) --> - <li - ng-repeat="token in filteredValues = (availableTokens | filter:tagInput)" - class="ng-scope"><span - class="existing_tag ng-binding" - ng-class="{disabled: added(token), selected_tag: inputSelected(token)}" - ng-click="add(token)">example</span></li> - <!-- end ngRepeat: token in filteredValues = (availableTokens | filter:tagInput) --> - </ul> - </li> - </ul> - </div> - </div> - </div> - </li> - <li> - <div class="entry_options"> - <ul> - </ul> - </div> - </li> - </ul> - </div> - </header> - <div class="entry_toolbar"></div> - </div> - <div class="clear"></div> - </div> -</div> - - <div class="epb_content_wrap"> - <div class="epb_content_container"> - <div class="hdrop ui-droppable"></div> - <div class="dd_entry_table"> - <div class="dd_entry_table"> - <div class="dd_entry_row"> - <div class="dd_entry_cell ui-draggable dd_text_entry"> - <div class="dd_entry_cell_wrapper" > - <div class="button_wrapper"></div> - <div class="dd_entry_cell_content redactor_editor"> - <p><h1>bcvncbvn</h1></p> -</div> - - </div> - </div> - </div> -</div> -<div class="dd_entry_table"> - <div class="dd_entry_row"> - <div class="dd_entry_cell ui-draggable dd_text_entry"> - <div class="dd_entry_cell_wrapper" > - <div class="button_wrapper"></div> - <div class="dd_entry_empty_element"><div><i>Empty File Element</i></div></div> - </div> - </div> - </div> -</div> -<div class="dd_entry_table"> - <div class="dd_entry_row"> - <div class="dd_entry_cell ui-draggable dd_text_entry"> - <div class="dd_entry_cell_wrapper" data-imageOriginalDocId="946047" data-imageLayerDocId="946048" data-zoomLevel="50" data-blockVersionId="4625717" data-filename="blank.png" data-elementNumber="4" > - <div class="button_wrapper"></div> - <div class="dd_entry_cell_file_download"> - <i>blank.png</i> - <br> - <div class="dd_entry_cell_content"> - <img class="imageOriginal" src="image_946047_4625717_blank.png" width="50%"> - </div> -</div> - - </div> - </div> - </div> -</div> - - </div> - </div> -</div> - - -</div><div data-id="4625212"data-blockId="4625203"data-elnProjectId="118217"data-sourceId="4625184"data-userAction="24"data-groupId="0"data-hidden="false"data-readOnly="false"data-versionTS="22.10.2019 18:48"data-createTS="22.10.2019 18:48"data-signHash="null"data-signHashDescription=""data-signHashVersion="null"data-signTS="null"data-witnessTS="null"data-title="null"data-blockNumber="3"data-totalBlocksInProject="4"data-projectName="Example project"data-projectReferenceId="null"data-signBiometricsDocId="null"data-witnessBiometricsDocId="null"data-referenced="false"> - <div class="epb_header_container"> - <div class="epb_header clearfix" style="display: block;"> - - <div class="entry_container"> - <header class="entry_header"> - <div class="entry_author"> - <figure> - <span class="avatar-img"></span> - <img ng-src=""> - </figure> - - <div class="author_name"> - <div class="author_firstname ng-binding">max</div> - <div class="author_lastname ng-binding">muster</div> - </div> - </div> - <div class="entry_menu_less entry_title_wrap ng-scope"> - <div class="entry_name_menu has_tooltip"> - <ul> - <li> - <div style="display:block">Entry 3/4:</div> - <div>In Project:</div> - </li> - <li> - <div style="display:block" class="entry_title ng-binding"><em>No entry title yet</em></div> - <div>Example project</div> - </li> - </ul> - </div> - <div class="entry_menu_options"> - </div> - <div class="entry_dropdown entry_name"> - <div class="close_entry_menu"> - <span class="cancel_entry_title close_box-img"></span> - </div> - <ul> - <li><label>Entry name</label> <input - class="entry_name_input ng-pristine ng-untouched ng-valid" - type="text" data-title="" value=""></li> - <li><label>located in project</label> <select - class="ng-pristine ng-untouched ng-valid"> - <option - value="0">tableproject - </option> - <option value="1" selected="selected">a project</option> - </select></li> - <li> - <div class="save_entry_menu"> - <span class="cancel_dropdown cancel_entry_title grey_link" - ng-click="cancel()">cancel</span> - <button class="save_entry_title btn_on_grey" ng-click="save()">save</button> - </div> - </li> - </ul> - </div> - </div> - - <div class="entry_menus"> - <ul> - <li class="entry_menu_less ng-scope" - ng-controller="EntryDateController"> - <div class="entry_menu_list has_tooltip" - ng-class="{true: '', false: 'has_tooltip'}[entry.readOnly]"> - <ul> - <li><span>created:</span> <span class="ng-binding">22.10.2019 18:48</span> - </li> - <li><span>modified</span> <span class="ng-binding">22.10.2019 18:48</span> - </li> - <!-- ngRepeat: date in currentDates | orderBy:predicate --> - <li> - <span>todo</span> - <span class=\"ng-binding\">31.10.2019</span> -</li> - - </ul> - </div> - <div class="entry_menu_options"> - </div> - <div class="entry_dropdown" - ng-mouseenter="activateElement($event)"> - <div class="close_entry_menu"> - <span class="close_box-img" ng-click="cancel()"></span> - </div> - <ul class="entry_dates"> - <li><label>Dates</label></li> - <li> - <div class="date_key"> - <input type="text" value="created" disabled=""> - </div> - <div class="date_value"> - <input type="text" ng-value="parseDate(entry.createTS)" - disabled="" value="18.02.2015"> - </div> - </li> - <li> - <div class="date_key"> - <input type="text" value="modified" disabled=""> - </div> - <div class="date_value"> - <input type="text" ng-value="parseDate(entry.versionTS)" - disabled="" value="18.02.2015"> - </div> - </li> - <!-- ngRepeat: date in currentDates | orderBy:predicate --> - <li style="overflow: visible;"> - <div class="date_key"> - - <div class="selectize-control single ng-valid" - ng-keyup="updateInput($select.search)" - reset-search-input="false" ng-model="dateKeyInput.selected" - theme="selectize" style="min-width: 120px;"> - <div class="selectize-input" - ng-class="{'focus': $select.open, 'disabled': $select.disabled, 'selectize-focus' : $select.focus}" - ng-click="$select.activate()"> - <div - ng-hide="$select.searchEnabled && ($select.open || $select.isEmpty())" - class="ui-select-match ng-hide" ng-transclude="" - placeholder="Custom date" - ng-keydown="inputKeydown($event)"> - <span class="ng-binding ng-scope"></span> - </div> - <input type="text" autocomplete="off" tabindex="-1" - class="ui-select-search ui-select-toggle ng-pristine ng-untouched ng-valid" - ng-click="$select.toggle($event)" - placeholder="Custom date" ng-model="$select.search" - ng-hide="!$select.searchEnabled || ($select.selected && !$select.open)" - ng-disabled="$select.disabled"> - </div> - <div ng-show="$select.open" - class="ui-select-choices selectize-dropdown single ng-scope ng-hide" - repeat="date in availableDates | filter: $select.search"> - <div - class="ui-select-choices-content selectize-dropdown-content"> - <div class="ui-select-choices-group optgroup"> - <div ng-show="$select.isGrouped" - class="ui-select-choices-group-label optgroup-header ng-binding ng-hide"></div> - <!-- ngRepeat: date in $select.items --> - <div class="ui-select-choices-row ng-scope" - ng-class="{active: $select.isActive(this), disabled: $select.isDisabled(this)}" - ng-repeat="date in $select.items" - ng-mouseenter="$select.setActiveItem(date)" - ng-click="$select.select(date)"> - <div class="option ui-select-choices-row-inner" - data-selectable="" uis-transclude-append=""> - <span ng-bind-html="date | highlight: $select.search" - class="ng-binding ng-scope">due date</span> - </div> - </div> - <!-- end ngRepeat: date in $select.items --> - <div class="ui-select-choices-row ng-scope" - ng-class="{active: $select.isActive(this), disabled: $select.isDisabled(this)}" - ng-repeat="date in $select.items" - ng-mouseenter="$select.setActiveItem(date)" - ng-click="$select.select(date)"> - <div class="option ui-select-choices-row-inner" - data-selectable="" uis-transclude-append=""> - <span ng-bind-html="date | highlight: $select.search" - class="ng-binding ng-scope">my date</span> - </div> - </div> - <!-- end ngRepeat: date in $select.items --> - </div> - </div> - </div> - <input ng-disabled="$select.disabled" - class="ui-select-focusser ui-select-offscreen ng-scope" - type="text" aria-haspopup="true" role="button"> - </div> - </div> - - <div class="date_value"> - <input type="text" - class="entry_datepicker date_input ng-pristine ng-untouched ng-valid" - ng-model="dateValueInput" ng-keydown="inputKeydown($event)"> - </div> - </li> - </ul> - <div class="save_entry_menu"> - <span class="cancel_dropdown grey_link" ng-click="cancel()">cancel</span> - <button class="btn_on_grey" ng-click="save()">save</button> - </div> - </div> - </li> - <li class="entry_menu_less ng-scope" - ng-controller="EntryTagsController"> - <div class="entry_tags has_tooltip" - ng-class="{true: '', false: 'has_tooltip'}[entry.readOnly]"> - - </div> - <div class="entry_menu_options"> - </div> - <div class="entry_dropdown"> - <div class="close_entry_menu"> - <span class="close_box-img" ng-click="cancel()"></span> - </div> - <label>Create new tags by using commas</label> - <div class="token_input token_input_width"></div> - <div class="tags_input entry_tags_input" ng-click="focusInput()"> - - <!-- ngRepeat: tag in currentTokens --> - - <textarea class="token_input ng-pristine ng-untouched ng-valid" - ng-model="tagInput" ng-keydown="inputKeydown($event)"></textarea> - </div> - - <!-- <div class="save_entry_menu"> - <span class="cancel_dropdown grey_link" ng-click="cancel()">cancel</span> - <button class="btn_on_grey" ng-click='fromViewModel()'>fromViewModel</button> - </div> --> - <h3 class="all_tags">All tags</h3> - <div class="tag_data_wrap"> - <div class="tag_register"> - <ul> - <li> - <ul class="my_tags"> - <!-- ngRepeat: token in filteredValues = (availableTokens | filter:tagInput) --> - <li - ng-repeat="token in filteredValues = (availableTokens | filter:tagInput)" - class="ng-scope"><span - class="existing_tag ng-binding" - ng-class="{disabled: added(token), selected_tag: inputSelected(token)}" - ng-click="add(token)">demo</span></li> - <!-- end ngRepeat: token in filteredValues = (availableTokens | filter:tagInput) --> - <li - ng-repeat="token in filteredValues = (availableTokens | filter:tagInput)" - class="ng-scope"><span - class="existing_tag ng-binding" - ng-class="{disabled: added(token), selected_tag: inputSelected(token)}" - ng-click="add(token)">Entry</span></li> - <!-- end ngRepeat: token in filteredValues = (availableTokens | filter:tagInput) --> - <li - ng-repeat="token in filteredValues = (availableTokens | filter:tagInput)" - class="ng-scope"><span - class="existing_tag ng-binding" - ng-class="{disabled: added(token), selected_tag: inputSelected(token)}" - ng-click="add(token)">example</span></li> - <!-- end ngRepeat: token in filteredValues = (availableTokens | filter:tagInput) --> - </ul> - </li> - </ul> - </div> - </div> - </div> - </li> - <li> - <div class="entry_options"> - <ul> - </ul> - </div> - </li> - </ul> - </div> - </header> - <div class="entry_toolbar"></div> - </div> - <div class="clear"></div> - </div> -</div> - - <div class="epb_content_wrap"> - <div class="epb_content_container"> - <div class="hdrop ui-droppable"></div> - <div class="dd_entry_table"> - <div class="dd_entry_table"> - <div class="dd_entry_row"> - <div class="dd_entry_cell ui-draggable dd_text_entry"> - <div class="dd_entry_cell_wrapper" > - <div class="button_wrapper"></div> - <div class="dd_entry_cell_content redactor_editor"> - <p><p>Text ist hier</p></p> -</div> - - </div> - </div> - </div> -</div> -<div class="dd_entry_table"> - <div class="dd_entry_row"> - <div class="dd_entry_cell ui-draggable dd_text_entry"> - <div class="dd_entry_cell_wrapper" > - <div class="button_wrapper"></div> - <div class="notebook-element-content data-elements-container data-elements"> - <html><head></head><body><div class="data-element-wrap data-group-wrap"> - <svg class="data-element-icon data-group-icon" viewbox="0 0 67 64"> - <title>icon-vf-group-filled</title> - <path d="M32.119 39.613c0-0.238-0.119-0.476-0.357-0.595s-0.476-0.119-0.595 0l-12.372 7.138c-0.714 0.357-1.071 1.071-1.071 1.903v14.394c0 0.238 0.119 0.476 0.357 0.595s0.476 0.119 0.595 0l11.896-6.9c0.952-0.595 1.546-1.546 1.546-2.617v-13.918z"></path> - <path d="M0.952 39.019c-0.238-0.119-0.476-0.119-0.595 0-0.238 0.119-0.357 0.357-0.357 0.595v0 13.799c0 1.071 0.595 2.141 1.546 2.617l11.896 6.9c0.238 0.119 0.476 0.119 0.595 0 0.238-0.119 0.357-0.357 0.357-0.595v-14.275c0-0.714-0.357-1.428-1.071-1.903l-12.372-7.138z"></path> - <path d="M29.502 36.996c0.238-0.119 0.357-0.357 0.357-0.595s-0.119-0.476-0.357-0.595v0l-11.896-6.9c-0.952-0.595-2.141-0.595-3.093 0l-11.896 6.9c-0.238 0.119-0.357 0.357-0.357 0.595s0.119 0.476 0.357 0.595l12.372 7.138c0.714 0.357 1.428 0.357 2.141 0l12.372-7.138z"></path> - <path d="M49.487 11.063c0-0.238-0.119-0.476-0.357-0.595s-0.476-0.119-0.595 0l-12.372 7.138c-0.714 0.357-1.071 1.071-1.071 1.903v14.394c0 0.238 0.119 0.476 0.357 0.595s0.476 0.119 0.595 0l11.896-6.9c0.952-0.595 1.546-1.546 1.546-2.617v-13.918z"></path> - <path d="M19.39 10.587c-0.238-0.119-0.476-0.119-0.595 0-0.238 0.119-0.357 0.357-0.357 0.595v0 13.799c0 1.071 0.595 2.141 1.546 2.617l11.896 6.9c0.238 0.119 0.476 0.119 0.595 0 0.238-0.119 0.357-0.357 0.357-0.595v-14.394c0-0.714-0.357-1.427-1.071-1.903l-12.372-7.019z"></path> - <path d="M46.87 8.565c0.238-0.119 0.357-0.357 0.357-0.595s-0.119-0.476-0.357-0.595v0l-11.896-6.9c-0.952-0.595-2.141-0.595-3.093 0l-11.896 6.9c-0.238 0.119-0.357 0.357-0.357 0.595s0.119 0.476 0.357 0.595l12.372 7.138c0.714 0.357 1.428 0.357 2.141 0l12.372-7.138z"></path> - <path d="M66.498 40.327c0-0.238-0.119-0.476-0.357-0.595s-0.476-0.119-0.595 0l-12.372 7.138c-0.714 0.357-1.071 1.071-1.071 1.903v14.394c0 0.238 0.119 0.476 0.357 0.595s0.476 0.119 0.595 0l11.896-6.9c0.952-0.595 1.546-1.546 1.546-2.617v-13.918z"></path> - <path d="M35.331 39.851c-0.238-0.119-0.476-0.119-0.595 0-0.238 0.119-0.357 0.357-0.357 0.595v0 13.799c0 1.071 0.595 2.141 1.546 2.617l11.896 6.9c0 0 0 0 0 0 0.238 0.119 0.476 0.119 0.595 0 0.238-0.119 0.357-0.357 0.357-0.595v-14.394c0-0.714-0.357-1.428-1.071-1.903l-12.372-7.019z"></path> - <path d="M64 37.71c0.238-0.119 0.357-0.357 0.357-0.595s-0.119-0.476-0.357-0.595c0 0 0 0 0 0l-11.896-6.9c-0.952-0.595-2.141-0.595-3.093 0l-11.896 6.9c-0.238 0.119-0.357 0.357-0.357 0.595s0.119 0.476 0.357 0.595l12.372 7.138c0.714 0.357 1.428 0.357 2.141 0l12.372-7.138z"></path> - </svg> - - <div class="data-group-content display-mode"> - <div class="data-element-wrap data-group-header"> - <div class="data-element-display data-group-display"> - <span class="element-title">gruppe 1</span> - </div> - </div> - - <div class="data-group-children"> - <div class="data-element-wrap single-element-wrap"> - <svg class="data-element-icon single-element-icon" viewbox="0 0 67 64"> - <title>icon-vf-filled</title> - <path d="M59.413 20.587c0-0.427-0.213-0.853-0.64-1.067-0.32-0.213-0.853-0.213-1.173 0l-22.827 13.227c-1.173 0.747-1.92 2.027-1.92 3.413v26.453c0 0.427 0.213 0.853 0.64 1.067 0.32 0.213 0.853 0.213 1.173 0l21.867-12.8c1.707-1.067 2.88-2.88 2.88-4.907v-25.387z"></path> - <path d="M2.027 19.52c-0.32-0.213-0.853-0.213-1.173 0s-0.64 0.64-0.64 1.067v0 25.387c0 2.027 1.067 3.947 2.88 4.907l21.973 12.693c0 0 0 0 0 0 0.32 0.213 0.853 0.213 1.173 0s0.64-0.64 0.64-1.067v-26.347c0-1.387-0.747-2.667-1.92-3.413l-22.933-13.227z"></path> - <path d="M54.72 15.787c0.32-0.213 0.64-0.64 0.64-1.067s-0.213-0.853-0.64-1.067c0 0 0 0 0 0l-22.080-12.587c-1.707-1.067-3.947-1.067-5.653 0l-21.973 12.693c-0.32 0.213-0.64 0.64-0.64 1.067s0.213 0.853 0.64 1.067l22.827 13.227c1.173 0.747 2.667 0.747 3.947 0l22.933-13.333z"></path> - </svg> - - <div class="data-element-display single-element-display"> - <span class="element-title ">foo</span> - <span class="element-quantity">: Angular Momentum: </span> - <span class="element-value ">20€ </span> - <span class="element-unit">kg/m<sup>2</sup> s<sup>-1</sup></span> - </div> -</div> -<div class="data-element-wrap single-element-wrap"> - <svg class="data-element-icon single-element-icon" viewbox="0 0 67 64"> - <title>icon-vf-filled</title> - <path d="M59.413 20.587c0-0.427-0.213-0.853-0.64-1.067-0.32-0.213-0.853-0.213-1.173 0l-22.827 13.227c-1.173 0.747-1.92 2.027-1.92 3.413v26.453c0 0.427 0.213 0.853 0.64 1.067 0.32 0.213 0.853 0.213 1.173 0l21.867-12.8c1.707-1.067 2.88-2.88 2.88-4.907v-25.387z"></path> - <path d="M2.027 19.52c-0.32-0.213-0.853-0.213-1.173 0s-0.64 0.64-0.64 1.067v0 25.387c0 2.027 1.067 3.947 2.88 4.907l21.973 12.693c0 0 0 0 0 0 0.32 0.213 0.853 0.213 1.173 0s0.64-0.64 0.64-1.067v-26.347c0-1.387-0.747-2.667-1.92-3.413l-22.933-13.227z"></path> - <path d="M54.72 15.787c0.32-0.213 0.64-0.64 0.64-1.067s-0.213-0.853-0.64-1.067c0 0 0 0 0 0l-22.080-12.587c-1.707-1.067-3.947-1.067-5.653 0l-21.973 12.693c-0.32 0.213-0.64 0.64-0.64 1.067s0.213 0.853 0.64 1.067l22.827 13.227c1.173 0.747 2.667 0.747 3.947 0l22.933-13.333z"></path> - </svg> - - <div class="data-element-display single-element-display"> - <span class="element-title ">barium</span> - <span class="element-quantity">: Fugacity: </span> - <span class="element-value ">12 </span> - <span class="element-unit">Pa</span> - </div> -</div> - - </div> - </div> -</div> -</body></html><html><head></head><body><div class="data-element-wrap single-element-wrap"> - <svg class="data-element-icon single-element-icon" viewbox="0 0 67 64"> - <title>icon-vf-filled</title> - <path d="M59.413 20.587c0-0.427-0.213-0.853-0.64-1.067-0.32-0.213-0.853-0.213-1.173 0l-22.827 13.227c-1.173 0.747-1.92 2.027-1.92 3.413v26.453c0 0.427 0.213 0.853 0.64 1.067 0.32 0.213 0.853 0.213 1.173 0l21.867-12.8c1.707-1.067 2.88-2.88 2.88-4.907v-25.387z"></path> - <path d="M2.027 19.52c-0.32-0.213-0.853-0.213-1.173 0s-0.64 0.64-0.64 1.067v0 25.387c0 2.027 1.067 3.947 2.88 4.907l21.973 12.693c0 0 0 0 0 0 0.32 0.213 0.853 0.213 1.173 0s0.64-0.64 0.64-1.067v-26.347c0-1.387-0.747-2.667-1.92-3.413l-22.933-13.227z"></path> - <path d="M54.72 15.787c0.32-0.213 0.64-0.64 0.64-1.067s-0.213-0.853-0.64-1.067c0 0 0 0 0 0l-22.080-12.587c-1.707-1.067-3.947-1.067-5.653 0l-21.973 12.693c-0.32 0.213-0.64 0.64-0.64 1.067s0.213 0.853 0.64 1.067l22.827 13.227c1.173 0.747 2.667 0.747 3.947 0l22.933-13.333z"></path> - </svg> - - <div class="data-element-display single-element-display"> - <span class="element-title ">dsf</span> - <span class="element-quantity">: Electric Displacement: </span> - <span class="element-value ">8765^98x90 </span> - <span class="element-unit">C/m<sup>2</sup></span> - </div> -</div> -</body></html><html><head></head><body><div class="data-element-wrap descriptive-element-wrap"> - <svg class="data-element-icon descriptive-element-icon" viewbox="0 0 64 64"> - <title>icon-dde</title> - <path d="M62.080 48.96h-60.16c-1.088 0-1.92 0.832-1.92 1.92v11.2c0 1.088 0.832 1.92 1.92 1.92h60.16c1.088 0 1.92-0.832 1.92-1.92v-11.2c0-1.024-0.832-1.92-1.92-1.92z"></path> - <path d="M62.080 24.192h-60.16c-1.088 0-1.92 0.832-1.92 1.92v11.2c0 1.088 0.832 1.92 1.92 1.92h60.16c1.088 0 1.92-0.832 1.92-1.92v-11.2c0-1.088-0.832-1.92-1.92-1.92z"></path> - <path d="M37.504 0h-35.584c-1.088 0-1.92 0.832-1.92 1.92v11.2c0 1.088 0.832 1.92 1.92 1.92h35.584c1.088 0 1.92-0.832 1.92-1.92v-11.2c0-1.088-0.832-1.92-1.92-1.92z"></path> - </svg> - - <div class="data-element-display descriptive-element-display"> - <span class="element-title">DE name: </span> - <span class="element-description ">fdgdfghgfdhgdfhh dfghdfghdfghfgh dfghdfgd</span> - </div> -</div> -</body></html><html><head></head><body><div class="data-element-wrap data-group-wrap"> - <svg class="data-element-icon data-group-icon" viewbox="0 0 67 64"> - <title>icon-vf-group-filled</title> - <path d="M32.119 39.613c0-0.238-0.119-0.476-0.357-0.595s-0.476-0.119-0.595 0l-12.372 7.138c-0.714 0.357-1.071 1.071-1.071 1.903v14.394c0 0.238 0.119 0.476 0.357 0.595s0.476 0.119 0.595 0l11.896-6.9c0.952-0.595 1.546-1.546 1.546-2.617v-13.918z"></path> - <path d="M0.952 39.019c-0.238-0.119-0.476-0.119-0.595 0-0.238 0.119-0.357 0.357-0.357 0.595v0 13.799c0 1.071 0.595 2.141 1.546 2.617l11.896 6.9c0.238 0.119 0.476 0.119 0.595 0 0.238-0.119 0.357-0.357 0.357-0.595v-14.275c0-0.714-0.357-1.428-1.071-1.903l-12.372-7.138z"></path> - <path d="M29.502 36.996c0.238-0.119 0.357-0.357 0.357-0.595s-0.119-0.476-0.357-0.595v0l-11.896-6.9c-0.952-0.595-2.141-0.595-3.093 0l-11.896 6.9c-0.238 0.119-0.357 0.357-0.357 0.595s0.119 0.476 0.357 0.595l12.372 7.138c0.714 0.357 1.428 0.357 2.141 0l12.372-7.138z"></path> - <path d="M49.487 11.063c0-0.238-0.119-0.476-0.357-0.595s-0.476-0.119-0.595 0l-12.372 7.138c-0.714 0.357-1.071 1.071-1.071 1.903v14.394c0 0.238 0.119 0.476 0.357 0.595s0.476 0.119 0.595 0l11.896-6.9c0.952-0.595 1.546-1.546 1.546-2.617v-13.918z"></path> - <path d="M19.39 10.587c-0.238-0.119-0.476-0.119-0.595 0-0.238 0.119-0.357 0.357-0.357 0.595v0 13.799c0 1.071 0.595 2.141 1.546 2.617l11.896 6.9c0.238 0.119 0.476 0.119 0.595 0 0.238-0.119 0.357-0.357 0.357-0.595v-14.394c0-0.714-0.357-1.427-1.071-1.903l-12.372-7.019z"></path> - <path d="M46.87 8.565c0.238-0.119 0.357-0.357 0.357-0.595s-0.119-0.476-0.357-0.595v0l-11.896-6.9c-0.952-0.595-2.141-0.595-3.093 0l-11.896 6.9c-0.238 0.119-0.357 0.357-0.357 0.595s0.119 0.476 0.357 0.595l12.372 7.138c0.714 0.357 1.428 0.357 2.141 0l12.372-7.138z"></path> - <path d="M66.498 40.327c0-0.238-0.119-0.476-0.357-0.595s-0.476-0.119-0.595 0l-12.372 7.138c-0.714 0.357-1.071 1.071-1.071 1.903v14.394c0 0.238 0.119 0.476 0.357 0.595s0.476 0.119 0.595 0l11.896-6.9c0.952-0.595 1.546-1.546 1.546-2.617v-13.918z"></path> - <path d="M35.331 39.851c-0.238-0.119-0.476-0.119-0.595 0-0.238 0.119-0.357 0.357-0.357 0.595v0 13.799c0 1.071 0.595 2.141 1.546 2.617l11.896 6.9c0 0 0 0 0 0 0.238 0.119 0.476 0.119 0.595 0 0.238-0.119 0.357-0.357 0.357-0.595v-14.394c0-0.714-0.357-1.428-1.071-1.903l-12.372-7.019z"></path> - <path d="M64 37.71c0.238-0.119 0.357-0.357 0.357-0.595s-0.119-0.476-0.357-0.595c0 0 0 0 0 0l-11.896-6.9c-0.952-0.595-2.141-0.595-3.093 0l-11.896 6.9c-0.238 0.119-0.357 0.357-0.357 0.595s0.119 0.476 0.357 0.595l12.372 7.138c0.714 0.357 1.428 0.357 2.141 0l12.372-7.138z"></path> - </svg> - - <div class="data-group-content display-mode"> - <div class="data-element-wrap data-group-header"> - <div class="data-element-display data-group-display"> - <span class="element-title">gruppe 2</span> - </div> - </div> - - <div class="data-group-children"> - <div class="data-element-wrap data-group-wrap"> - <svg class="data-element-icon data-group-icon" viewbox="0 0 67 64"> - <title>icon-vf-group-filled</title> - <path d="M32.119 39.613c0-0.238-0.119-0.476-0.357-0.595s-0.476-0.119-0.595 0l-12.372 7.138c-0.714 0.357-1.071 1.071-1.071 1.903v14.394c0 0.238 0.119 0.476 0.357 0.595s0.476 0.119 0.595 0l11.896-6.9c0.952-0.595 1.546-1.546 1.546-2.617v-13.918z"></path> - <path d="M0.952 39.019c-0.238-0.119-0.476-0.119-0.595 0-0.238 0.119-0.357 0.357-0.357 0.595v0 13.799c0 1.071 0.595 2.141 1.546 2.617l11.896 6.9c0.238 0.119 0.476 0.119 0.595 0 0.238-0.119 0.357-0.357 0.357-0.595v-14.275c0-0.714-0.357-1.428-1.071-1.903l-12.372-7.138z"></path> - <path d="M29.502 36.996c0.238-0.119 0.357-0.357 0.357-0.595s-0.119-0.476-0.357-0.595v0l-11.896-6.9c-0.952-0.595-2.141-0.595-3.093 0l-11.896 6.9c-0.238 0.119-0.357 0.357-0.357 0.595s0.119 0.476 0.357 0.595l12.372 7.138c0.714 0.357 1.428 0.357 2.141 0l12.372-7.138z"></path> - <path d="M49.487 11.063c0-0.238-0.119-0.476-0.357-0.595s-0.476-0.119-0.595 0l-12.372 7.138c-0.714 0.357-1.071 1.071-1.071 1.903v14.394c0 0.238 0.119 0.476 0.357 0.595s0.476 0.119 0.595 0l11.896-6.9c0.952-0.595 1.546-1.546 1.546-2.617v-13.918z"></path> - <path d="M19.39 10.587c-0.238-0.119-0.476-0.119-0.595 0-0.238 0.119-0.357 0.357-0.357 0.595v0 13.799c0 1.071 0.595 2.141 1.546 2.617l11.896 6.9c0.238 0.119 0.476 0.119 0.595 0 0.238-0.119 0.357-0.357 0.357-0.595v-14.394c0-0.714-0.357-1.427-1.071-1.903l-12.372-7.019z"></path> - <path d="M46.87 8.565c0.238-0.119 0.357-0.357 0.357-0.595s-0.119-0.476-0.357-0.595v0l-11.896-6.9c-0.952-0.595-2.141-0.595-3.093 0l-11.896 6.9c-0.238 0.119-0.357 0.357-0.357 0.595s0.119 0.476 0.357 0.595l12.372 7.138c0.714 0.357 1.428 0.357 2.141 0l12.372-7.138z"></path> - <path d="M66.498 40.327c0-0.238-0.119-0.476-0.357-0.595s-0.476-0.119-0.595 0l-12.372 7.138c-0.714 0.357-1.071 1.071-1.071 1.903v14.394c0 0.238 0.119 0.476 0.357 0.595s0.476 0.119 0.595 0l11.896-6.9c0.952-0.595 1.546-1.546 1.546-2.617v-13.918z"></path> - <path d="M35.331 39.851c-0.238-0.119-0.476-0.119-0.595 0-0.238 0.119-0.357 0.357-0.357 0.595v0 13.799c0 1.071 0.595 2.141 1.546 2.617l11.896 6.9c0 0 0 0 0 0 0.238 0.119 0.476 0.119 0.595 0 0.238-0.119 0.357-0.357 0.357-0.595v-14.394c0-0.714-0.357-1.428-1.071-1.903l-12.372-7.019z"></path> - <path d="M64 37.71c0.238-0.119 0.357-0.357 0.357-0.595s-0.119-0.476-0.357-0.595c0 0 0 0 0 0l-11.896-6.9c-0.952-0.595-2.141-0.595-3.093 0l-11.896 6.9c-0.238 0.119-0.357 0.357-0.357 0.595s0.119 0.476 0.357 0.595l12.372 7.138c0.714 0.357 1.428 0.357 2.141 0l12.372-7.138z"></path> - </svg> - - <div class="data-group-content display-mode"> - <div class="data-element-wrap data-group-header"> - <div class="data-element-display data-group-display"> - <span class="element-title">Untergruppe 2.1</span> - </div> - </div> - - <div class="data-group-children"> - <div class="data-element-wrap descriptive-element-wrap"> - <svg class="data-element-icon descriptive-element-icon" viewbox="0 0 64 64"> - <title>icon-dde</title> - <path d="M62.080 48.96h-60.16c-1.088 0-1.92 0.832-1.92 1.92v11.2c0 1.088 0.832 1.92 1.92 1.92h60.16c1.088 0 1.92-0.832 1.92-1.92v-11.2c0-1.024-0.832-1.92-1.92-1.92z"></path> - <path d="M62.080 24.192h-60.16c-1.088 0-1.92 0.832-1.92 1.92v11.2c0 1.088 0.832 1.92 1.92 1.92h60.16c1.088 0 1.92-0.832 1.92-1.92v-11.2c0-1.088-0.832-1.92-1.92-1.92z"></path> - <path d="M37.504 0h-35.584c-1.088 0-1.92 0.832-1.92 1.92v11.2c0 1.088 0.832 1.92 1.92 1.92h35.584c1.088 0 1.92-0.832 1.92-1.92v-11.2c0-1.088-0.832-1.92-1.92-1.92z"></path> - </svg> - - <div class="data-element-display descriptive-element-display"> - <span class="element-title">DE name 2 (desc): </span> - <span class="element-description empty-value">⎵</span> - </div> -</div> -<div class="data-element-wrap single-element-wrap"> - <svg class="data-element-icon single-element-icon" viewbox="0 0 67 64"> - <title>icon-vf-filled</title> - <path d="M59.413 20.587c0-0.427-0.213-0.853-0.64-1.067-0.32-0.213-0.853-0.213-1.173 0l-22.827 13.227c-1.173 0.747-1.92 2.027-1.92 3.413v26.453c0 0.427 0.213 0.853 0.64 1.067 0.32 0.213 0.853 0.213 1.173 0l21.867-12.8c1.707-1.067 2.88-2.88 2.88-4.907v-25.387z"></path> - <path d="M2.027 19.52c-0.32-0.213-0.853-0.213-1.173 0s-0.64 0.64-0.64 1.067v0 25.387c0 2.027 1.067 3.947 2.88 4.907l21.973 12.693c0 0 0 0 0 0 0.32 0.213 0.853 0.213 1.173 0s0.64-0.64 0.64-1.067v-26.347c0-1.387-0.747-2.667-1.92-3.413l-22.933-13.227z"></path> - <path d="M54.72 15.787c0.32-0.213 0.64-0.64 0.64-1.067s-0.213-0.853-0.64-1.067c0 0 0 0 0 0l-22.080-12.587c-1.707-1.067-3.947-1.067-5.653 0l-21.973 12.693c-0.32 0.213-0.64 0.64-0.64 1.067s0.213 0.853 0.64 1.067l22.827 13.227c1.173 0.747 2.667 0.747 3.947 0l22.933-13.333z"></path> - </svg> - - <div class="data-element-display single-element-display"> - <span class="element-title ">DE 2.1.1</span> - <span class="element-quantity">: Amount of substance: </span> - <span class="element-value ">20 </span> - <span class="element-unit">mol</span> - </div> -</div> - - </div> - </div> -</div> -<div class="data-element-wrap single-element-wrap"> - <svg class="data-element-icon single-element-icon" viewbox="0 0 67 64"> - <title>icon-vf-filled</title> - <path d="M59.413 20.587c0-0.427-0.213-0.853-0.64-1.067-0.32-0.213-0.853-0.213-1.173 0l-22.827 13.227c-1.173 0.747-1.92 2.027-1.92 3.413v26.453c0 0.427 0.213 0.853 0.64 1.067 0.32 0.213 0.853 0.213 1.173 0l21.867-12.8c1.707-1.067 2.88-2.88 2.88-4.907v-25.387z"></path> - <path d="M2.027 19.52c-0.32-0.213-0.853-0.213-1.173 0s-0.64 0.64-0.64 1.067v0 25.387c0 2.027 1.067 3.947 2.88 4.907l21.973 12.693c0 0 0 0 0 0 0.32 0.213 0.853 0.213 1.173 0s0.64-0.64 0.64-1.067v-26.347c0-1.387-0.747-2.667-1.92-3.413l-22.933-13.227z"></path> - <path d="M54.72 15.787c0.32-0.213 0.64-0.64 0.64-1.067s-0.213-0.853-0.64-1.067c0 0 0 0 0 0l-22.080-12.587c-1.707-1.067-3.947-1.067-5.653 0l-21.973 12.693c-0.32 0.213-0.64 0.64-0.64 1.067s0.213 0.853 0.64 1.067l22.827 13.227c1.173 0.747 2.667 0.747 3.947 0l22.933-13.333z"></path> - </svg> - - <div class="data-element-display single-element-display"> - <span class="element-title ">DE 2.2</span> - <span class="element-quantity">: Capacitance: </span> - <span class="element-value ">876x876x87 </span> - <span class="element-unit">µF</span> - </div> -</div> - - </div> - </div> -</div> -</body></html> -</div> - - </div> - </div> - </div> -</div> -<div class="dd_entry_table"> - <div class="dd_entry_row"> - <div class="dd_entry_cell ui-draggable dd_text_entry"> - <div class="dd_entry_cell_wrapper" {{elementMeta1}}> - <div class="button_wrapper"></div> - <div class="dd_entry_cell_content table-el-container"> - <div> - <div class="table-el-info"> - Your labfolder table is available for visualization as the following Excel file: - </div> - <div class="table-el-download"> - <a href="labfolder_table_4625212_3.xlsx"> - <svg class="table-el-icon" viewBox="0 0 475.1 402.5"> - <title>icon-table</title> - <path d="M461.7,14C452.7,5,442,0.5,429.4,0.5H45.7C33.1,0.5,22.4,5,13.4,14C4.5,22.9,0,33.7,0,46.2v310.6 c0,12.6,4.5,23.3,13.4,32.3c8.9,8.9,19.7,13.4,32.3,13.4h383.7c12.6,0,23.3-4.5,32.3-13.4c8.9-9,13.4-19.7,13.4-32.3V46.2 C475.1,33.7,470.6,22.9,461.7,14z M146.2,356.9c0,2.7-0.9,4.9-2.6,6.6c-1.7,1.7-3.9,2.6-6.6,2.6H45.7c-2.7,0-4.9-0.9-6.6-2.6 c-1.7-1.7-2.6-3.9-2.6-6.6V302c0-2.7,0.9-4.9,2.6-6.6c1.7-1.7,3.9-2.6,6.6-2.6H137c2.7,0,4.9,0.9,6.6,2.6c1.7,1.7,2.6,3.9,2.6,6.6 L146.2,356.9L146.2,356.9z M146.2,247.2c0,2.7-0.9,4.9-2.6,6.6c-1.7,1.7-3.9,2.6-6.6,2.6H45.7c-2.7,0-4.9-0.9-6.6-2.6 c-1.7-1.7-2.6-3.9-2.6-6.6v-54.8c0-2.7,0.9-4.9,2.6-6.6c1.7-1.7,3.9-2.6,6.6-2.6H137c2.7,0,4.9,0.9,6.6,2.6 c1.7,1.7,2.6,3.9,2.6,6.6L146.2,247.2L146.2,247.2z M146.2,137.6c0,2.7-0.9,4.9-2.6,6.6c-1.7,1.7-3.9,2.6-6.6,2.6H45.7 c-2.7,0-4.9-0.9-6.6-2.6c-1.7-1.7-2.6-3.9-2.6-6.6V82.8c0-2.7,0.9-4.9,2.6-6.6c1.7-1.7,3.9-2.6,6.6-2.6H137c2.7,0,4.9,0.9,6.6,2.6 c1.7,1.7,2.6,3.9,2.6,6.6L146.2,137.6L146.2,137.6z M292.4,356.9c0,2.7-0.9,4.9-2.6,6.6c-1.7,1.7-3.9,2.6-6.6,2.6h-91.4 c-2.7,0-4.9-0.9-6.6-2.6c-1.7-1.7-2.6-3.9-2.6-6.6V302c0-2.7,0.9-4.9,2.6-6.6c1.7-1.7,3.9-2.6,6.6-2.6h91.4c2.7,0,4.9,0.9,6.6,2.6 c1.7,1.7,2.6,3.9,2.6,6.6L292.4,356.9L292.4,356.9L292.4,356.9z M292.4,247.2c0,2.7-0.9,4.9-2.6,6.6c-1.7,1.7-3.9,2.6-6.6,2.6 h-91.4c-2.7,0-4.9-0.9-6.6-2.6c-1.7-1.7-2.6-3.9-2.6-6.6v-54.8c0-2.7,0.9-4.9,2.6-6.6c1.7-1.7,3.9-2.6,6.6-2.6h91.4 c2.7,0,4.9,0.9,6.6,2.6c1.7,1.7,2.6,3.9,2.6,6.6L292.4,247.2L292.4,247.2z M292.4,137.6c0,2.7-0.9,4.9-2.6,6.6 c-1.7,1.7-3.9,2.6-6.6,2.6h-91.4c-2.7,0-4.9-0.9-6.6-2.6c-1.7-1.7-2.6-3.9-2.6-6.6V82.8c0-2.7,0.9-4.9,2.6-6.6 c1.7-1.7,3.9-2.6,6.6-2.6h91.4c2.7,0,4.9,0.9,6.6,2.6c1.7,1.7,2.6,3.9,2.6,6.6L292.4,137.6L292.4,137.6z M438.5,356.9 c0,2.7-0.9,4.9-2.6,6.6c-1.7,1.7-3.9,2.6-6.6,2.6H338c-2.7,0-4.9-0.9-6.6-2.6c-1.7-1.7-2.6-3.9-2.6-6.6V302c0-2.7,0.8-4.9,2.6-6.6 c1.7-1.7,3.9-2.6,6.6-2.6h91.4c2.7,0,4.9,0.9,6.6,2.6c1.7,1.7,2.6,3.9,2.6,6.6V356.9z M438.5,247.2c0,2.7-0.9,4.9-2.6,6.6 c-1.7,1.7-3.9,2.6-6.6,2.6H338c-2.7,0-4.9-0.9-6.6-2.6c-1.7-1.7-2.6-3.9-2.6-6.6v-54.8c0-2.7,0.8-4.9,2.6-6.6 c1.7-1.7,3.9-2.6,6.6-2.6h91.4c2.7,0,4.9,0.9,6.6,2.6c1.7,1.7,2.6,3.9,2.6,6.6V247.2z M438.5,137.6c0,2.7-0.9,4.9-2.6,6.6 c-1.7,1.7-3.9,2.6-6.6,2.6H338c-2.7,0-4.9-0.9-6.6-2.6c-1.7-1.7-2.6-3.9-2.6-6.6V82.8c0-2.7,0.8-4.9,2.6-6.6 c1.7-1.7,3.9-2.6,6.6-2.6h91.4c2.7,0,4.9,0.9,6.6,2.6c1.7,1.7,2.6,3.9,2.6,6.6V137.6z"/> - </svg> - <div class="table-el-filename"> - labfolder_table_4625212_3.xlsx - </div> - </a> - </div> - </div> -</div> - - </div> - </div> - </div> -</div> - - </div> - </div> -</div> - - -</div><div data-id="5026191"data-blockId="5026165"data-elnProjectId="118217"data-sourceId="4624688"data-userAction="36"data-groupId="0"data-hidden="false"data-readOnly="false"data-versionTS="28.01.2020 11:12"data-createTS="28.01.2020 11:10"data-signHash="null"data-signHashDescription=""data-signHashVersion="null"data-signTS="null"data-witnessTS="null"data-title="null"data-blockNumber="4"data-totalBlocksInProject="4"data-projectName="Example project"data-projectReferenceId="null"data-signBiometricsDocId="null"data-witnessBiometricsDocId="null"data-referenced="false"> - <div class="epb_header_container"> - <div class="epb_header clearfix" style="display: block;"> - - <div class="entry_container"> - <header class="entry_header"> - <div class="entry_author"> - <figure> - <span class="avatar-img"></span> - <img ng-src=""> - </figure> - - <div class="author_name"> - <div class="author_firstname ng-binding">max</div> - <div class="author_lastname ng-binding">muster</div> - </div> - </div> - <div class="entry_menu_less entry_title_wrap ng-scope"> - <div class="entry_name_menu has_tooltip"> - <ul> - <li> - <div style="display:block">Entry 4/4:</div> - <div>In Project:</div> - </li> - <li> - <div style="display:block" class="entry_title ng-binding"><em>No entry title yet</em></div> - <div>Example project</div> - </li> - </ul> - </div> - <div class="entry_menu_options"> - </div> - <div class="entry_dropdown entry_name"> - <div class="close_entry_menu"> - <span class="cancel_entry_title close_box-img"></span> - </div> - <ul> - <li><label>Entry name</label> <input - class="entry_name_input ng-pristine ng-untouched ng-valid" - type="text" data-title="" value=""></li> - <li><label>located in project</label> <select - class="ng-pristine ng-untouched ng-valid"> - <option - value="0">tableproject - </option> - <option value="1" selected="selected">a project</option> - </select></li> - <li> - <div class="save_entry_menu"> - <span class="cancel_dropdown cancel_entry_title grey_link" - ng-click="cancel()">cancel</span> - <button class="save_entry_title btn_on_grey" ng-click="save()">save</button> - </div> - </li> - </ul> - </div> - </div> - - <div class="entry_menus"> - <ul> - <li class="entry_menu_less ng-scope" - ng-controller="EntryDateController"> - <div class="entry_menu_list has_tooltip" - ng-class="{true: '', false: 'has_tooltip'}[entry.readOnly]"> - <ul> - <li><span>created:</span> <span class="ng-binding">28.01.2020 11:10</span> - </li> - <li><span>modified</span> <span class="ng-binding">28.01.2020 11:12</span> - </li> - <!-- ngRepeat: date in currentDates | orderBy:predicate --> - <li> - <span>due date</span> - <span class=\"ng-binding\">22.10.2019</span> -</li> -<li> - <span>my date</span> - <span class=\"ng-binding\">22.10.2019</span> -</li> - - </ul> - </div> - <div class="entry_menu_options"> - </div> - <div class="entry_dropdown" - ng-mouseenter="activateElement($event)"> - <div class="close_entry_menu"> - <span class="close_box-img" ng-click="cancel()"></span> - </div> - <ul class="entry_dates"> - <li><label>Dates</label></li> - <li> - <div class="date_key"> - <input type="text" value="created" disabled=""> - </div> - <div class="date_value"> - <input type="text" ng-value="parseDate(entry.createTS)" - disabled="" value="18.02.2015"> - </div> - </li> - <li> - <div class="date_key"> - <input type="text" value="modified" disabled=""> - </div> - <div class="date_value"> - <input type="text" ng-value="parseDate(entry.versionTS)" - disabled="" value="18.02.2015"> - </div> - </li> - <!-- ngRepeat: date in currentDates | orderBy:predicate --> - <li style="overflow: visible;"> - <div class="date_key"> - - <div class="selectize-control single ng-valid" - ng-keyup="updateInput($select.search)" - reset-search-input="false" ng-model="dateKeyInput.selected" - theme="selectize" style="min-width: 120px;"> - <div class="selectize-input" - ng-class="{'focus': $select.open, 'disabled': $select.disabled, 'selectize-focus' : $select.focus}" - ng-click="$select.activate()"> - <div - ng-hide="$select.searchEnabled && ($select.open || $select.isEmpty())" - class="ui-select-match ng-hide" ng-transclude="" - placeholder="Custom date" - ng-keydown="inputKeydown($event)"> - <span class="ng-binding ng-scope"></span> - </div> - <input type="text" autocomplete="off" tabindex="-1" - class="ui-select-search ui-select-toggle ng-pristine ng-untouched ng-valid" - ng-click="$select.toggle($event)" - placeholder="Custom date" ng-model="$select.search" - ng-hide="!$select.searchEnabled || ($select.selected && !$select.open)" - ng-disabled="$select.disabled"> - </div> - <div ng-show="$select.open" - class="ui-select-choices selectize-dropdown single ng-scope ng-hide" - repeat="date in availableDates | filter: $select.search"> - <div - class="ui-select-choices-content selectize-dropdown-content"> - <div class="ui-select-choices-group optgroup"> - <div ng-show="$select.isGrouped" - class="ui-select-choices-group-label optgroup-header ng-binding ng-hide"></div> - <!-- ngRepeat: date in $select.items --> - <div class="ui-select-choices-row ng-scope" - ng-class="{active: $select.isActive(this), disabled: $select.isDisabled(this)}" - ng-repeat="date in $select.items" - ng-mouseenter="$select.setActiveItem(date)" - ng-click="$select.select(date)"> - <div class="option ui-select-choices-row-inner" - data-selectable="" uis-transclude-append=""> - <span ng-bind-html="date | highlight: $select.search" - class="ng-binding ng-scope">due date</span> - </div> - </div> - <!-- end ngRepeat: date in $select.items --> - <div class="ui-select-choices-row ng-scope" - ng-class="{active: $select.isActive(this), disabled: $select.isDisabled(this)}" - ng-repeat="date in $select.items" - ng-mouseenter="$select.setActiveItem(date)" - ng-click="$select.select(date)"> - <div class="option ui-select-choices-row-inner" - data-selectable="" uis-transclude-append=""> - <span ng-bind-html="date | highlight: $select.search" - class="ng-binding ng-scope">my date</span> - </div> - </div> - <!-- end ngRepeat: date in $select.items --> - </div> - </div> - </div> - <input ng-disabled="$select.disabled" - class="ui-select-focusser ui-select-offscreen ng-scope" - type="text" aria-haspopup="true" role="button"> - </div> - </div> - - <div class="date_value"> - <input type="text" - class="entry_datepicker date_input ng-pristine ng-untouched ng-valid" - ng-model="dateValueInput" ng-keydown="inputKeydown($event)"> - </div> - </li> - </ul> - <div class="save_entry_menu"> - <span class="cancel_dropdown grey_link" ng-click="cancel()">cancel</span> - <button class="btn_on_grey" ng-click="save()">save</button> - </div> - </div> - </li> - <li class="entry_menu_less ng-scope" - ng-controller="EntryTagsController"> - <div class="entry_tags has_tooltip" - ng-class="{true: '', false: 'has_tooltip'}[entry.readOnly]"> - <span>demo</span><span>example</span><span>entry</span> - </div> - <div class="entry_menu_options"> - </div> - <div class="entry_dropdown"> - <div class="close_entry_menu"> - <span class="close_box-img" ng-click="cancel()"></span> - </div> - <label>Create new tags by using commas</label> - <div class="token_input token_input_width"></div> - <div class="tags_input entry_tags_input" ng-click="focusInput()"> - - <!-- ngRepeat: tag in currentTokens --> - - <textarea class="token_input ng-pristine ng-untouched ng-valid" - ng-model="tagInput" ng-keydown="inputKeydown($event)"></textarea> - </div> - - <!-- <div class="save_entry_menu"> - <span class="cancel_dropdown grey_link" ng-click="cancel()">cancel</span> - <button class="btn_on_grey" ng-click='fromViewModel()'>fromViewModel</button> - </div> --> - <h3 class="all_tags">All tags</h3> - <div class="tag_data_wrap"> - <div class="tag_register"> - <ul> - <li> - <ul class="my_tags"> - <!-- ngRepeat: token in filteredValues = (availableTokens | filter:tagInput) --> - <li - ng-repeat="token in filteredValues = (availableTokens | filter:tagInput)" - class="ng-scope"><span - class="existing_tag ng-binding" - ng-class="{disabled: added(token), selected_tag: inputSelected(token)}" - ng-click="add(token)">demo</span></li> - <!-- end ngRepeat: token in filteredValues = (availableTokens | filter:tagInput) --> - <li - ng-repeat="token in filteredValues = (availableTokens | filter:tagInput)" - class="ng-scope"><span - class="existing_tag ng-binding" - ng-class="{disabled: added(token), selected_tag: inputSelected(token)}" - ng-click="add(token)">Entry</span></li> - <!-- end ngRepeat: token in filteredValues = (availableTokens | filter:tagInput) --> - <li - ng-repeat="token in filteredValues = (availableTokens | filter:tagInput)" - class="ng-scope"><span - class="existing_tag ng-binding" - ng-class="{disabled: added(token), selected_tag: inputSelected(token)}" - ng-click="add(token)">example</span></li> - <!-- end ngRepeat: token in filteredValues = (availableTokens | filter:tagInput) --> - </ul> - </li> - </ul> - </div> - </div> - </div> - </li> - <li> - <div class="entry_options"> - <ul> - </ul> - </div> - </li> - </ul> - </div> - </header> - <div class="entry_toolbar"></div> - </div> - <div class="clear"></div> - </div> -</div> - - <div class="epb_content_wrap"> - <div class="epb_content_container"> - <div class="hdrop ui-droppable"></div> - <div class="dd_entry_table"> - - </div> - </div> -</div> - - -</div></div> - <div id="epb_newer_blocks_panel"></div> - </div> -</div> -</body> -</html> diff --git a/unittests/example_labfolder_data/projects/My private projects_0/118217_Example project/labfolder_table_4624688_11.xlsx b/unittests/example_labfolder_data/projects/My private projects_0/118217_Example project/labfolder_table_4624688_11.xlsx deleted file mode 100644 index 251f84c2f7ef25c567bef65102a16134b5d453e7..0000000000000000000000000000000000000000 Binary files a/unittests/example_labfolder_data/projects/My private projects_0/118217_Example project/labfolder_table_4624688_11.xlsx and /dev/null differ diff --git a/unittests/example_labfolder_data/projects/My private projects_0/118217_Example project/labfolder_table_4625212_3.xlsx b/unittests/example_labfolder_data/projects/My private projects_0/118217_Example project/labfolder_table_4625212_3.xlsx deleted file mode 100644 index 83d3d8119085d311ceb5a54e56c5363351aa1c0d..0000000000000000000000000000000000000000 Binary files a/unittests/example_labfolder_data/projects/My private projects_0/118217_Example project/labfolder_table_4625212_3.xlsx and /dev/null differ diff --git a/unittests/example_labfolder_data/projects/My private projects_0/118217_Example project/original_image_946047_4625717_blank.png b/unittests/example_labfolder_data/projects/My private projects_0/118217_Example project/original_image_946047_4625717_blank.png deleted file mode 100644 index 27d041f3a61aa472e57cb5447c3eb8aa364ca210..0000000000000000000000000000000000000000 Binary files a/unittests/example_labfolder_data/projects/My private projects_0/118217_Example project/original_image_946047_4625717_blank.png and /dev/null differ diff --git a/unittests/example_labfolder_data/projects/My private projects_0/118224_subproj 1/index.html b/unittests/example_labfolder_data/projects/My private projects_0/118224_subproj 1/index.html deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/unittests/example_labfolder_data/static/css/combined.css b/unittests/example_labfolder_data/static/css/combined.css deleted file mode 100644 index a2cc2529e4f8332444c5ef76256077aca321cc1c..0000000000000000000000000000000000000000 --- a/unittests/example_labfolder_data/static/css/combined.css +++ /dev/null @@ -1,10061 +0,0 @@ -/************** -* basic.css * -**************/ -/********** -* colors * -***********/ -/********** -* helper * -***********/ -.list_vertical > ul { - margin: 0; - padding: 0; -} -.list_vertical > ul li { - list-style-type: none; -} -.list_horizontal > ul { - margin: 0; - padding: 0; -} -.list_horizontal > ul > li { - list-style-type: none; - float: left; - position: relative; -} -/************* -* functions * -**************/ -/****** -* css * -******/ -body { - color: #374858; -} -.clearfix:after { - content: " "; - visibility: hidden; - display: block; - height: 0; - clear: both; -} -table.adminTable { - background-color: white; - border-collapse: collapse; -} -table.adminTable th { - font-weight: bold; - border: 1px solid black; - padding: 10px; -} -table.adminTable th .info { - font-size: 10px; - width: 120px; -} -table.adminTable td { - border: 1px solid black; - padding: 10px; -} -#percentage { - border: 1px solid black; - height: 20px; - width: 200px; - background: white; - position: relative; - text-align: center; - color: black; - font-weight: bold; - display: none; -} -#percentage div { - height: 100%; - width: 0%; - background: #33FF33; - position: absolute; - top: 0; - left: 0; -} -#percentage span { - height: 100%; - width: 100%; - position: absolute; - top: 0; - left: 0; -} -#messages { - width: 500px; - height: 300px; - overflow: scroll; -} -#buttonCancel { - margin-top: 20px; - width: 150px; - height: 30px; - display: none; -} - -/*********** -* apps.css * -************/ -/************** -* basic.css * -**************/ -/********** -* colors * -***********/ -/********** -* helper * -***********/ -.list_vertical > ul { - margin: 0; - padding: 0; -} -.list_vertical > ul li { - list-style-type: none; -} -.list_horizontal > ul { - margin: 0; - padding: 0; -} -.list_horizontal > ul > li { - list-style-type: none; - float: left; - position: relative; -} -/************* -* functions * -**************/ -/****** -* css * -******/ -body { - color: #374858; -} -.clearfix:after { - content: " "; - visibility: hidden; - display: block; - height: 0; - clear: both; -} -.app_card { - background-color: white; - border: 1px solid #bac7d4; - float: left; - height: 260px; - margin: 10px; - padding: 10px; - overflow: hidden; - text-align: center; - width: 144px; - -webkit-transition: all 0.1s ease; - -moz-transition: all 0.1s ease; - -o-transition: all 0.1s ease; - transition: all 0.1s ease; -} -.app_card:hover { - -webkit-box-shadow: 0 4px 6px rgba(55, 72, 88, 0.3); - -moz-box-shadow: 0 4px 6px rgba(55, 72, 88, 0.3); - box-shadow: 0 4px 6px rgba(55, 72, 88, 0.3); -} -.app_card_icon { - width: 100px; - height: 100px; -} -.app_card_icon:hover, -.app_card_title:hover { - cursor: pointer; -} -.app_card .app_install_button { - width: 100%; -} -.app_installed_info { - line-height: 1.4; - font-size: 13px; -} -.app_card_title { - margin-top: 5px; - margin-bottom: 5px; - font-size: 16px; - height: 44px; -} -.app_card_lastUpdate { - font-size: 12px; - line-height: 1.6; - color: #7b95ad; - margin-bottom: 20px; -} -.app_info_top_left { - float: left; - width: 200px; - padding-top: 25px; - text-align: center; -} -.app_info_top_right { - margin-left: 202px; - padding-top: 25px; -} -.app_info_icon { - border: 1px solid #CCC; - border-radius: 10px; - width: 150px; - height: 150px; -} -.app_info_top_left .app_install_button { - width: 150px; - margin-top: 15px; - margin-left: 25px; -} -.app_info_title { - margin-top: 0; - margin-bottom: 20px; - font-size: 24px; -} -.app_info_description { - line-height: 20px; - max-width: 600px; -} -.app_info_lastUpdate { - font-size: 12px; - color: #aaa; - margin-bottom: 20px; -} -.app_info_preview { - padding-top: 15px; - padding-bottom: 25px; -} -.app_info_preview_left { - float: left; - width: 175px; - padding-left: 25px; -} -.app_info_preview_right { - margin-left: 202px; -} -.app_info_preview_small { - border: 3px solid #CCC; - width: 150px; - margin-bottom: 10px; - cursor: pointer; - transition: all ease 0.3s; -} -.app_info_preview_big { - border: 3px solid #CCC; - width: 600px; - height: 350px; -} -.app_info_preview_small.selected { - border: 3px solid #69bfee; - box-shadow: 0 0 10px #69bfee; -} - -/************** -* basic.css * -**************/ -/********** -* colors * -***********/ -/********** -* helper * -***********/ -.list_vertical > ul { - margin: 0; - padding: 0; -} -.list_vertical > ul li { - list-style-type: none; -} -.list_horizontal > ul { - margin: 0; - padding: 0; -} -.list_horizontal > ul > li { - list-style-type: none; - float: left; - position: relative; -} -/************* -* functions * -**************/ -/****** -* css * -******/ -body { - color: #374858; -} -.clearfix:after { - content: " "; - visibility: hidden; - display: block; - height: 0; - clear: both; -} - -/****************************** - COMMENTS COLLECTION -*******************************/ -/************** -* basic.css * -**************/ -/********** -* colors * -***********/ -/********** -* helper * -***********/ -.list_vertical > ul { - margin: 0; - padding: 0; -} -.list_vertical > ul li { - list-style-type: none; -} -.list_horizontal > ul { - margin: 0; - padding: 0; -} -.list_horizontal > ul > li { - list-style-type: none; - float: left; - position: relative; -} -/************* -* functions * -**************/ -/****** -* css * -******/ -body { - color: #374858; -} -.clearfix:after { - content: " "; - visibility: hidden; - display: block; - height: 0; - clear: both; -} -.eln_main_content_box.comments { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - height: auto; - min-height: 400px; - margin: 0 25px 0 0; -} -#comments_header { - background: #EEE; - border-bottom: 1px solid #D6D4D5; - border-radius: 10px 10px 0 0; - display: block; - font-size: 14px; - height: 35px; - padding: 10px 0px 5px 15px; -} -#comments_content { - max-width: 900px; - padding-left: 10px; - display: block; - line-height: 18px; - position: relative; - overflow: auto; -} -.comment_pagination { - position: relative; - float: left; -} -.comment_pagination, -.comment_total, -.comment_shown { - font-size: 11px; -} -.message_pagination { - position: relative; - float: left; -} -.comment_page_change { - box-sizing: border-box; - cursor: pointer; - display: inline-block; - width: 30px; - text-align: center; - font-size: 22px; - margin: 0; - line-height: 0.6; - height: 17px; - margin-top: 4px; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; -} -.comment_page_change.disabled .disabled { - color: #5e7b97; - cursor: default; -} -.comment_empty_folder { - padding: 50px; - text-align: center; - font-size: 12px; -} -.comment_list { - font-size: 14px; -} -.comment_list table { - border-collapse: collapse; - outline: none; - table-layout: fixed; - width: 100%; -} -.comment_list table tr td:last-child { - font-size: 11px; -} -.comment_list_line { - font-size: 12px; - border-bottom: 1px solid #bac7d4; - cursor: pointer; - height: 34px; - line-height: 1.2; - white-space: nowrap; -} -.comment_list_line:hover { - background: #ecf0f3; -} -.comment_list_line:first-child:hover { - background: none; - cursor: default; -} -.comment_line_name { - white-space: nowrap; - text-overflow: ellipsis; - vertical-align: bottom; - overflow: hidden; - padding-left: 4px; -} -.comment_line_text { - overflow: hidden; - text-overflow: ellipsis; -} -.column_comment_name { - min-width: 100px; - width: 25%; -} -.column_comment_project { - min-width: 100px; - width: 25%; -} -.column_comment_content { - min-width: 100px; - width: 50%; -} -.column_comment_date { - width: 89px; -} -.table_header { - color: #7b95ad; - font-size: 12px; -} -.grey_line { - border-bottom: solid 1px #9baec0; -} -/****************************** - COMMENT SIDE VIEW -*******************************/ -.comment_block_container { - /* border-left: 1px solid #DDD; */ - display: none; - font-size: 12px; - min-height: 25px; - overflow-y: auto; - overflow-x: hidden; - position: relative; - vertical-align: top; - min-width: 250px; - width: 15%; -} -.comment_block { - border-radius: 0 0 10px 0; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - padding: 15px; - right: 0; -} -.add_comment { - display: block; - margin: 10px; - text-align: center; -} -.epb_entry_removed .comment_block_container { - display: none !important; -} -.epb_entry_removed .epb_comments_alert { - display: none !important; -} -/****************************** - COMMENT THREAD -*******************************/ -.comment_thread_box { - background: white; - border: 1px solid #bac7d4; - margin-bottom: 10px; - min-height: 40px; - padding: 5px; - position: relative; -} -.comment_thread_box:after, -.comment_thread_box:before { - right: 100%; - top: 23px; - border: solid transparent; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; -} -.comment_thread_box:after { - border-right-color: white; - border-width: 13px; - margin-top: -13px; -} -.comment_thread_box:before { - border-right-color: #c0ccd8 !important; - border-width: 15px; - margin-top: -15px; -} -.comment_thread_resolve { - cursor: pointer; - text-align: right; - margin-bottom: 10px; -} -.comment_thread_resolve span { - font-size: 8px; -} -.comment_thread_resolve:hover { - color: #4bb1d7; -} -.comment_thread_resolve.disabled { - color: #aaa; - cursor: default; -} -/****************************** - COMMENT ITEM -*******************************/ -.comment_content_wrap { - float: left; - width: 174px; -} -.comment_item { - /* border-bottom: 1px solid lighten(@dark_blue, 60%); */ - margin-bottom: 10px; - overflow: auto; -} -.comment_item:last-child { - border: 0; - padding-bottom: 20px; -} -.comment_author_picture { - border: 1px solid #bac7d4; - float: left; - margin-right: 6px; - margin-top: 2px; -} -.comment_author { - color: #3babe9; - margin-right: 3px; - font-weight: bold; -} -.comment_content, -.comment_content_resizer { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - line-height: 18px; - margin: 5px 0px 0px; - width: 174px; - white-space: pre-line; - word-wrap: break-word; -} -.comment_content.default_textfield, -.comment_content_resizer.default_textfield { - background: #FFF; - font-size: 12px; - min-height: 26px; - line-height: 18px; - margin: 2px 0 0 0; - overflow: hidden; - padding: 5px; - resize: none; - border-radius: 0; - border-color: #d9e1e8; - vertical-align: middle; -} -.comment_content.default_textfield { - height: 25px; -} -.comment_content.default_textfield:focus { - /* box-shadow: 0 0 3px #4bb1d7; */ -} -.comment_content_label { - position: relative; -} -.comment_content_label label { - position: absolute; - top: -20px; - left: 6px; - color: #9baec0; - font-style: italic; - font-family: Arial; - cursor: text; - font-size: 12px; -} -.comment_cancel { - float: right; - padding: 10px; -} -.comment_publish, -.comment_edit { - float: right; - height: 22px; - position: relative; - margin: 5px 0 0 0; -} -.comment_user_actions { - display: none; - margin: 8px 0; -} -.comment_user_actions .edit_light-img { - margin: 2px 20px 0 0; -} -.comment_timestamp { - margin-right: 23px; - line-height: 1.8; - float: left; - font-size: 10px; - color: #9baec0; -} -.comment_action { - padding: 5px; -} -.comment_content_resizer, -.comment_edit, -.comment_published.readOnly .comment_user_actions, -.comment_published.comment_editing .comment_user_actions, -.comment_published .comment_publish { - display: none; -} -.comment_editing .comment_edit, -.comment_published .comment_user_actions { - display: block; -} -.comment_editing { - padding-bottom: 35px; -} -.bottonShowComments, -.bottonHideComments { - display: none; -} -.comment_content_wrap .default_textfield { - border: 1px solid #bac7d4; -} - -/****************************** - Dashboard VIEW -*******************************/ -/************** -* basic.css * -**************/ -/********** -* colors * -***********/ -/********** -* helper * -***********/ -.list_vertical > ul { - margin: 0; - padding: 0; -} -.list_vertical > ul li { - list-style-type: none; -} -.list_horizontal > ul { - margin: 0; - padding: 0; -} -.list_horizontal > ul > li { - list-style-type: none; - float: left; - position: relative; -} -/************* -* functions * -**************/ -/****** -* css * -******/ -body { - color: #374858; -} -.clearfix:after { - content: " "; - visibility: hidden; - display: block; - height: 0; - clear: both; -} -.dashboard_item { - width: 50%; - min-width: 460px; - height: 45%; - min-height: 300px; - padding: 10px 20px 0 4px; - margin-top: 5px; - overflow: auto; - float: left; -} -.dashboard_item_menu { - background: #EEE; - border-bottom: 1px solid #D6D4D5; - display: block; - font-size: 14px; - height: 35px; - padding: 10px 0px 5px 15px; - margin: 0; - list-style-type: none; -} -.dashboard_item_menu > li { - height: 65%; - float: left; - display: block; - margin-right: 10px; - padding-right: 14px; - padding-top: 9px; - border-right: solid 1px #D6D4D5; -} -.dashboard_item h2 { - margin-top: 2px; - display: block; - font-weight: normal; -} -.dashboard_item h2 a { - color: #374858; - text-decoration: none; -} -.dashboard_item .default_button { - float: right; - margin-right: 10px; -} -.eln_main_content_box.apps { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - margin: 0 25px 0 0; - padding: 20px; - height: 95%; - overflow: auto; -} -.apps_decoration { - opacity: 0.3; - font-size: 45px; - text-align: center; - margin-top: 50px; -} -.dashboard_apps_info { - cursor: default; - font-size: 14px; -} -.dashboard_apps_tooltip { - opacity: 0; - font-size: 14px; - transition: all ease-in 0.3s; -} -.dashboard_apps_info:hover + .dashboard_apps_tooltip { - opacity: 1; -} -.create_list, -.create_item { - background: rgba(255, 255, 255, 0.6); - border: 1px solid #bac7d4; - height: 25px; - padding-left: 5px; - color: #4b6277; - margin-top: 10px; - width: 90%; - font-size: 14px; - /* .inner-shadow(-1px, -1px, 1px, 0.2); */ -} -.create_item { - margin: 0 0 10px 0; -} -.done_item_wrap .listed_item { - text-decoration: line-through; -} -.todolist_btn { - text-align: left; - color: #4b6277; - background: #f3f5f7; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #e0e6eb), color-stop(1, #f3f5f7)); - background: -ms-linear-gradient(bottom, #e0e6eb, #f3f5f7); - background: -moz-linear-gradient(center bottom, #e0e6eb 0%, #f3f5f7 100%); - background: -o-linear-gradient(#f3f5f7, #e0e6eb); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f3f5f7', endColorstr='#e0e6eb', GradientType=0); - border: 1px solid #9baec0; - width: 90%; - margin: 0 0 4px 0; - cursor: pointer; -} -.todolist_btn:hover { - opacity: 1; - -ms-filter: none; - filter: none; - outline: 0; - border: 1px solid #7b95ad; - -webkit-box-shadow: 0 0 8px rgba(255, 255, 255, 0.5); - -moz-box-shadow: 0 0 8px rgba(255, 255, 255, 0.5); - box-shadow: 0 0 8px rgba(255, 255, 255, 0.5); -} -.todolist_btn:active { - color: #4b6277; - opacity: 1; - -ms-filter: none; - filter: none; - outline: 0; - -webkit-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.2); - -moz-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.2); - box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.2); - border: 1px solid #7b95ad; - background: #cad4de; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #e0e6eb), color-stop(1, #cad4de)); - background: -ms-linear-gradient(bottom, #e0e6eb, #cad4de); - background: -moz-linear-gradient(center bottom, #e0e6eb 0%, #cad4de 100%); - background: -o-linear-gradient(#cad4de, #e0e6eb); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#cad4de', endColorstr='#e0e6eb', GradientType=0); -} -.active_todo_list { - background: white; - border: 1px solid #9baec0; - cursor: default; - position: relative; -} -.active_todo_list:hover, -.active_todo_list:active { - border: 1px solid #5e7b97; -} -.active_todo_list:after { - right: 0px; - top: 11px; - border: solid transparent; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - border-color: rgba(136, 183, 213, 0); - border-left-color: #374858; - border-width: 5px; - margin-top: -5px; -} -.todolist_collection { - width: 34%; - height: 100%; - padding-right: 3%; - display: inline-block; -} -.todolist_collection > ul { - margin: 0; - padding: 0; -} -.todolist_collection > ul li { - list-style-type: none; -} -.selected_list { - width: 65%; - min-height: 100%; - height: auto; - display: inline-block; - padding: 2% 2% 2% 5%; - vertical-align: top; - background: white; - border-radius: 3px; - border: 1px solid #9baec0; -} -.selected_list ul { - margin: 0; - padding: 0; - list-style: none; -} -.item_wrap { - margin: 3px 0; -} -.item_wrap .trash-img { - display: none; - cursor: pointer; -} -.item_wrap:hover { - background: #f3f5f7; -} -.item_wrap:hover .trash-img { - display: block; -} -.todolist_btn_wrap .trash-img { - display: none; - cursor: pointer; -} -.todolist_btn_wrap:hover .trash-img { - display: block; -} -.todolist_wrap { - padding-top: 20px; -} -.todolist_wrap label { - color: #a7b8c8; - font-size: 12px; -} -.todolist_wrap h3 { - font-weight: normal; - font-size: 14px; - margin: 0 0 10px 10px; - display: inline-block; -} -.todolist_wrap .trash-img { - margin-top: 2px; -} -.todolist_wrap input { - position: relative; - vertical-align: middle; - bottom: 1px; -} -.listed_item { - display: inline-block; -} -::-webkit-input-placeholder { - /* WebKit browsers */ - color: #9baec0; -} -:-moz-placeholder { - /* Mozilla Firefox 4 to 18 */ - color: #9baec0; - opacity: 1; -} -::-moz-placeholder { - /* Mozilla Firefox 19+ */ - color: #9baec0; - opacity: 1; -} -:-ms-input-placeholder { - /* Internet Explorer 10+ */ - color: #9baec0; -} -@media (max-width: 1380px) { - .todolist_btn { - width: 80%; - } -} -@media (max-width: 970px) { - .todolist_btn { - width: 88%; - } - .dashboard_item { - width: 100%; - } -} - -.re-deviceData { - background-image: url(/static/img/design/devices-icon.png); -} - -.re-deviceData:hover { - background-image: url(/static/img/design/devices-hover-icon.png); -} - -#devices_library .device_log { - padding: 10px; - margin: 10px; - border-bottom: 1px solid #BBB; -} - -#devices_library li { - list-style: none; -} - -#devices_library .device_line { - font-size: 14px; - line-height: 30px; - list-style: none; - width: 600px; - padding: 5px; -} - -#devices_library .device_line:hover { - background: #EDEDED; -} - -#devices_library .device_header { - font-size: 14px; - margin-bottom: 10px; -} - -.device_file, .device_data { - cursor: pointer !important; - float: right !important; - right: 0 !important; -} - -.devices_popup { - width: 750px !important; - left: 50% !important; - margin-left: -375px !important; -}/******************* -* eln_layout.css * -********************/ -/************** -* basic.css * -**************/ -/********** -* colors * -***********/ -/********** -* helper * -***********/ -.list_vertical > ul { - margin: 0; - padding: 0; -} -.list_vertical > ul li { - list-style-type: none; -} -.list_horizontal > ul { - margin: 0; - padding: 0; -} -.list_horizontal > ul > li { - list-style-type: none; - float: left; - position: relative; -} -/************* -* functions * -**************/ -/****** -* css * -******/ -body { - color: #374858; -} -.clearfix:after { - content: " "; - visibility: hidden; - display: block; - height: 0; - clear: both; -} -::selection { - background: #c5e6f8; -} -::-moz-selection { - background: #c5e6f8; -} -*, -*::before, -*::after { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -a { - cursor: pointer; -} -body { - font-size: 14px; - margin: 0; - padding: 0; - font-family: arial, sans-serif; - height: 100%; - width: 100%; -} -html { - height: 100%; -} -.body_bg { - background: #ffffff url(../img/squares.png); - height: 100%; - width: 100%; - position: fixed; - z-index: -1; - top: 33px; - left: -10px; -} -a { - text-decoration: none; - color: #1995d8; - outline: none; -} -a:hover { - text-decoration: none; -} -img { - border: 0; -} -button { - margin: 0; -} -button::-moz-focus-inner { - border: 0; -} -.clear { - clear: both; -} -.content_top_margin { - margin-top: 50px; -} -/****************************** - DEFAULT BLUE BUTTONS -*******************************/ -.default_button { - border: 1px solid #455a6e; - padding: 4px 8px; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; - color: white; - opacity: 1; - line-height: 1.2; - background: #304d69; - font-size: 14px; - -webkit-transition: all 0.1s linear; - -moz-transition: all 0.1s linear; - -o-transition: all 0.1s linear; - transition: all 0.1s linear; - -webkit-backface-visibility: hidden; - cursor: pointer; - /* background-color:#374858; */ - /* border:1px solid #ffffff; */ - /* border-radius:6px; */ - /* box-shadow:0px 0px 1px black; */ - /* -webkit-box-sizing: border-box; */ - /* -moz-box-sizing: border-box; */ - /* box-sizing: border-box; */ - /* color:#ffffff; */ - /* cursor:pointer; */ - /* display:inline-block; */ - /* float:left; */ - /* font-family:din-medi; */ - /* font-size:14px; */ - /* height:28px; */ - /* line-height:28px; */ - /* margin:0 1px 1px 0; */ - /* outline: none; */ - /* padding: 0 10px; */ - /* transition: background-color 0.2s ease, box-shadow 0.2s ease; */ -} -.default_button:hover, -.default_button:focus { - background: #375877; - -ms-filter: none; - filter: none; - outline: 0; - color: white; - text-decoration: none; -} -.default_button:active { - background: #304d69; - -ms-filter: none; - filter: none; - outline: 0; - -webkit-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.5); - -moz-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.5); - box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.5); -} -.default_button:hover { - /* background-color: #607D99; */ - /* text-decoration:none; */ -} -.default_button:active { - opacity: 1.0; - /* box-shadow:0px 0px 10px #888888; */ - /* text-decoration:none; */ -} -.default_button.disabled { - opacity: 0.5; - /* background-color:#DDD; */ - /* border:1px solid #FFF; */ - /* box-shadow:0px 0px 1px #AAA; */ - /* color:#AAA; */ - /* cursor:default; */ -} -/****************************** - DEFAULT FIELDS -*******************************/ -.default_textfield { - background-color: white; - border: 0; - -webkit-box-sizing: border-box; - /* Safari/Chrome, other WebKit */ - -moz-box-sizing: border-box; - /* Firefox, other Gecko */ - box-sizing: border-box; - /* Opera/IE 8+ */ - font-family: Arial; - color: #4b6277; - font-size: 14px; - line-height: 1.8; - font-style: normal; - font-variant: normal; - font-weight: normal; - margin: 0 5px 5px 0; - padding-left: 5px; - min-height: 30px; - transition: box-shadow ease 0.2s; -} -.textfield_on_white { - border: solid 1px #bac7d4; -} -.default_textfield:hover { - /* box-shadow: 0 0 3px #69bfee; */ -} -.default_textfield:focus { - /* border: 1px solid #69bfee; */ - /* box-shadow: 0 0 6px #69bfee; */ -} -/****************************** - DEFAULT SELECT -*******************************/ -.default_select { - background: #FFF; - border: 1px solid #d9e1e8; - color: #4b6277; - cursor: pointer; - margin: 0 0 0 10px; - padding: 4px 4px 4px 8px; -} -.dialog_wide_select { - margin: 0; - width: 100%; -} -/****************************** - DEFAULT PROFILE PICTURE -*******************************/ -img.default_profile_picture { - border: 1px solid #888; - height: 100px; - width: 100px; -} -img.default_profile_picture_small { - border: 1px solid #888; - height: 32px; - width: 32px; - margin-top: 3px; -} -/* ****************** */ -/* more_options START */ -/* ****************** */ -.more_options { - float: right; - position: relative; -} -.more_options_panel { - position: absolute; - right: 0; - z-index: 10; - display: none; - -webkit-box-shadow: 0 4px 6px rgba(55, 72, 88, 0.3); - -moz-box-shadow: 0 4px 6px rgba(55, 72, 88, 0.3); - box-shadow: 0 4px 6px rgba(55, 72, 88, 0.3); - border: 1px solid #CDCDCD; - /* border-radius: 10px; */ - background-color: #FDFDFD; -} -.more_options_panel.in_project { - top: 38px; -} -.more_options_panel.in_block { - top: 40px; -} -.more_options_item { - font-size: 12px; - /* line-height: 40px; */ - padding-left: 12px; - padding-right: 12px; - cursor: pointer; - /* border-top: 1px solid #D6D4D5; */ - transition: background ease 0.2s; -} -.more_options_item:hover { - /* background: #ededed; */ - /* color: #69bfee; */ -} -.more_options_item:first-child { - /* border-radius: 10px 10px 0 0; */ - /* border: 0; */ -} -.more_options_item:last-child { - /* border-radius: 0 0 10px 10px; */ -} -.more_options_item span { - position: absolute; - right: 0; -} -div.zoom_bar { - width: 180px; - padding: 4px 14px !important; - height: 44px; - -webkit-user-select: none; - /* Chrome all / Safari all */ - -moz-user-select: none; - /* Firefox all */ - -ms-user-select: none; - /* IE 10+ */ -} -div.zoom_bar:hover { - background: #e6ebef; -} -div.zoom_bar:hover { - color: #374858; -} -/* **************** */ -/* more_options END */ -/* **************** */ -/* ****************** */ -/* gear_button START */ -/* ****************** */ -/* ************ */ -/* layout START */ -/* ************ */ -/* generic rules */ -.eln_row { - left: 0; - right: 0; - /* overflow:hidden; */ - position: absolute; -} -.eln_scroll-x { - overflow-x: auto; -} -.eln_scroll-y { - overflow-y: scroll; -} -/* specific rules */ -.eln_header.eln_row { - position: relative; - /* height:50px; */ - /* background: #FFF; */ - /* box-shadow:0 3px 10px #BBB; */ - min-width: 800px; -} -.eln_content.eln_row { - top: 70px; - bottom: 0; - margin-left: 200px; - min-width: 600px; -} -.eln_main_title.eln_row { - top: 70px; - margin-right: 40px; - margin-left: 100px; - min-width: 436px; - overflow: visible; -} -.eln_main_content.eln_row { - top: 86px; - bottom: 0; - margin-left: 49px; - min-width: 600px; -} -.eln_folder_title.eln_row { - top: 70px; - margin-left: 100px; - min-width: 600px; - overflow: visible; -} -.eln_folder_content.eln_row { - top: 86px; - bottom: 0; - margin-left: 49px; - min-width: 640px; -} -.eln_project_title.eln_row { - top: 70px; - margin-left: 100px; - min-width: 640px; - overflow: visible; -} -.eln_project_content.eln_row { - top: 86px; - bottom: 0; - /* margin-left:100px; */ - margin-left: 29px; - min-width: 600px; -} -.eln_main_content_box { - height: auto; - min-height: 400px; - margin: 0 25px 25px 0; - background-color: white; - border-bottom: solid 1px #cad4de; - border-left: solid 1px #cad4de; - border-right: solid 1px #cad4de; - position: relative; - padding: 20px 20px 20px 135px; - color: #4b6277; -} -.eln_main_content_box .header { - display: block; - font-size: 24px; - height: 35px; -} -.eln_main_content_box .header button { - margin-right: 10px; -} -.app_wrap { - position: relative; - background: #f3f5f7; - border: solid 1px #cad4de; - -webkit-box-shadow: 0 2px 2px rgba(55, 72, 88, 0.1); - -moz-box-shadow: 0 2px 2px rgba(55, 72, 88, 0.1); - box-shadow: 0 2px 2px rgba(55, 72, 88, 0.1); - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - height: calc(95% - 15px); -} -.app_content_wrap { - max-width: 900px; - padding: 10px; - display: block; - line-height: 18px; - position: absolute; - overflow: auto; - top: 10px; - left: 0; - right: 0; - bottom: 0px; -} -.app_header { - height: 29px; - background: #cad4de; - padding: 6px; -} -.app_header > h2 { - display: block; - float: left; - font-size: 14px; - margin: 0 13px 0 0; - color: #374858; -} -.app_header .filter_dn_wrap { - top: 23px; -} -.app_header .dropdown_button { - height: 20px; -} -.app_header .dropdown_button p { - margin: 0; - float: left; -} -.app_header .dropdown_button span { - height: 4px; - width: 12px; - display: block; - float: left; - margin: 2px 0 0 4px; -} -.app_plus_btn { - width: 35px; - height: 18px; - line-height: 1; - margin-right: 2px !important; - padding: 0; -} -.get_more_apps { - height: 100%; - padding: 20px; -} -/* ********** */ -/* layout END */ -/* ********** */ -/* ****************** */ -/* action links START */ -/* ****************** */ -.action_link_submit { - background: url(/static/img/design/action/submit.png) top right no-repeat; - width: 112px; - height: 25px; - display: block; -} -.action_link_submit:hover { - background-image: url(/static/img/design/action/submit_hover.png); -} -.action_link_signout { - background: url(/static/img/design/action/signout.png); - width: 83px; - height: 24px; - display: block; - float: right; - margin: 10px 0; -} -.action_link_signout:hover { - background: url(/static/img/design/action/signout_hover.png); -} -.action_link_profile { - background: url(/static/img/design/action/profile.png); - width: 71px; - height: 24px; - display: block; - float: right; - margin: 10px 0; -} -.action_link_profile:hover { - background: url(/static/img/design/action/profile_hover.png); -} -/* **************** */ -/* action links END */ -/* **************** */ -/* ************ */ -/* header START */ -/* ************ */ -/* LOGO */ -.eln_header_logo { - float: left; - padding-top: 7px; - padding-left: 17px; -} -/* Storage icon */ -#eln_header_storage_button { - background: none repeat scroll 0 0 transparent; - border: none; - cursor: pointer; - float: right; - font-size: 14px; - margin-top: 5px; - padding: 0; - height: 27px; - width: 32px; -} -#eln_header_storage_button span { - font-size: 10px; - margin-top: 14px; - position: absolute; - text-align: center; - width: 32px; - z-index: 6; -} -#eln_header_storage_stored { - background-color: #ededed; - height: 32px; - width: 32px; -} -#eln_header_storage_mask { - position: absolute; - z-index: 5; -} -#eln_header_storage_fill { - background-color: #BDCA70; - bottom: -5px; - position: absolute; - width: 32px; - z-index: 2; -} -/* Storage drop down panel */ -#eln_header_storage_panel { - background-color: #FFFFFF; - border: 3px solid #DDDDDD; - top: 53px; - z-index: 7; -} -#eln_header_storage_info { - cursor: default; -} -#eln_header_storage_info:hover { - color: #374858; -} -#eln_header_storage_info span { - font-size: 14px; - padding-right: 10px; - text-align: right; - width: 80px; -} -/* Storage percent bar */ -#eln_header_storage_bar_container { - float: right; - padding: 12px 10px 0; -} -#eln_header_storage_bar { - border: 1px solid #888; - height: auto; - line-height: 15px; - padding: 2px; - position: relative; - width: 80px; -} -span#eln_header_storage_bar_percent { - font-size: 12px; - line-height: 12px; - padding: 0; - position: absolute; - text-align: center; - width: 80px; -} -#eln_header_storage_bar_fill { - background-color: #bdca70; - height: 10px; -} -#eln_header_name { - display: inline-block; - line-height: 40px; - text-align: center; - text-overflow: ellipsis; - overflow: hidden; - padding: 0 5px; - vertical-align: top; - white-space: nowrap; -} -#eln_header_name div { - display: inline; -} -#eln_header_actions { - margin-right: 43px; -} -#eln_header_actions_button { - -webkit-box-sizing: border-box; - /* Safari/Chrome, other WebKit */ - -moz-box-sizing: border-box; - /* Firefox, other Gecko */ - box-sizing: border-box; - /* Opera/IE 8+ */ - background: none repeat scroll 0 0 transparent; - border: none; - cursor: pointer; - float: right; - font-size: 14px; - height: 50px; - margin: 0; - padding: 5px; -} -#eln_header_storage_button:hover, -#eln_header_actions_button:hover { - cursor: pointer; - background: #ededed; - border: none; - border-radius: 0; -} -#eln_header_storage_button:active { - margin: 5px 1px 0px 0px; -} -div#eln_header_actions_button.active { - background: #ededed; - border: none; - border-radius: 0; - margin: 0; -} -#eln_header_arrow span { - font-size: 18px; -} -#eln_header_arrow { - display: inline-block; - margin-top: 8px; - padding-left: 5px; - vertical-align: top; -} -#eln_header_actions_panel { - background-color: #FFFFFF; - position: absolute; - top: 53px; - z-index: 7; -} -.eln_header_actions_item { - border-top: 1px solid #D6D4D5; - cursor: pointer; - font-size: 14px; - line-height: 40px; - padding: 0 20px; -} -.eln_header_actions_item:first-child { - border-top: 0; -} -.eln_header_actions_item span { - float: right; - font-size: 18px; - line-height: 18px; - padding-top: 12px; - text-align: center; - width: 36px; -} -.eln_header_actions_item:hover { - background: #ededed; - color: #69bfee; -} -.colorbar { - height: 4px; - background: url(/static/img/design/colorbar.png); -} -/* ************ */ -/* header END */ -/* ************ */ -/* **************** */ -/* navigation START */ -/* **************** */ -#eln_navigation { - position: fixed; - top: 70px; - width: 75px; - border-radius: 0 10px 0 0; - box-shadow: 0 3px 10px #888; - background: #FFF; - bottom: 0; - left: 0; - z-index: 2; - text-align: center; -} -#eln_navigation a { - border-bottom: 1px solid #d6d4d5; - display: block; - text-decoration: none; - padding: 10px 0; - font-size: 12px; - color: #374858; - transition: all ease 0.2s; -} -#eln_navigation a:hover { - background: #ededed; - color: #69bfee; -} -#eln_navigation a:first-child { - border-radius: 0 10px 0 0; -} -#eln_navigation span { - display: block; - font-size: 24px; - margin-bottom: 3px; -} -#eln_navigation span.icon-group { - font-size: 20px; - margin-left: 9px; -} -#eln_navigation span.icon-inventory { - margin-left: 4px; -} -#eln_navigation span.icon-template { - margin-left: 5px; -} -#eln_navigation .highlight { - color: #69bfee; -} -#eln_navigation .disabled, -#eln_navigation .disabled:hover { - color: #ccc; -} -#eln_navigation button { - border: 5px solid white; - border-radius: 10px; - color: #FFF; - cursor: pointer; - font-size: 11px; - outline: none; - width: 70px; - height: 70px; -} -#feedback_button span, -#invite_button span { - font-size: 22px; -} -#invite_button { - background-color: #bdca70; -} -#feedback_submit { - margin-right: 6px; - width: 60px; - height: 30px; - font-weight: bold; -} -#feedback_button { - background-color: #ad4e88; -} -.eln_navigation_support_buttons { - margin-top: 100px; -} -#feedback_panel { - display: none; - position: fixed; - top: -2px; - left: 0; - z-index: 102; - background: #d9e1e8; - border: 3px solid #ab48a9; - -webkit-box-shadow: 2px 6px 10px rgba(55, 72, 88, 0.3); - -moz-box-shadow: 2px 6px 10px rgba(55, 72, 88, 0.3); - box-shadow: 2px 6px 10px rgba(55, 72, 88, 0.3); -} -.feedback_title { - background: #ab48a9; - color: white; - padding: 5px; - text-align: center; - font-size: 15px; - line-height: 20px; -} -.feedback_title h4 { - display: inline-block; -} -.feedback_title img { - vertical-align: top; - margin-left: 10px; -} -.feedback_content { - padding: 10px; - width: 390px; -} -.feedback_content h4 { - font-size: 12px; -} -#feedback_panel h4 { - margin: 10px; - margin-bottom: 5px; -} -#feedback_comment { - margin: 0 10px 30px 10px; - margin-top: 0; - width: 350px; - height: 120px; -} -#feedback_submit_loader { - display: none; - margin: 8px 15px; -} -/* ************** */ -/* navigation END */ -/* ************** */ -/* ********* */ -/* EPB START */ -/* ********* */ -#epb_container { - /* padding-top: 10px; */ - /* padding-bottom: 80px; */ -} -img.imageOriginal { - border: 1px solid #DDD; - -webkit-box-sizing: border-box; - /* Safari/Chrome, other WebKit */ - -moz-box-sizing: border-box; - /* Firefox, other Gecko */ - box-sizing: border-box; - /* Opera/IE 8+ */ - transition: all linear 0.2s; -} -img.imageLayer { - left: 0; - margin-left: auto; - margin-right: auto; - position: absolute; - right: 0; - top: 0; - transition: all linear 0.2s; -} -#commentBlock { - border-radius: 10px; - cursor: pointer; - position: absolute; - right: 15px; - width: 200px; - background: #FFF; - top: 1px; -} -#epb_older_blocks_panel, -#epb_newer_blocks_panel { - text-align: center; - color: #999; - height: 30px; - line-height: 30px; - margin: 10px 0; -} -.show_more_entries { - font-size: 13px; - margin: auto; - width: 300px; - background: white; - padding: 10px; - text-align: center; - -webkit-box-shadow: 0 3px 4px rgba(55, 72, 88, 0.3); - -moz-box-shadow: 0 3px 4px rgba(55, 72, 88, 0.3); - box-shadow: 0 3px 4px rgba(55, 72, 88, 0.3); -} -.show_more_entries span { - color: #1995d8; - cursor: pointer; -} -.epb_entry { - /* background-color: white; */ - /* border: 1px solid #CCC; */ - /* border-radius: 10px; */ - display: inline-block; - /* margin-right:25px; */ - margin-bottom: 20px; -} -#epb_container { - padding-bottom: 60px; -} -#epb_container > div { - margin: 1.5em 0; -} -.epb_entry:last-child { - margin-bottom: 10px; -} -.epb_entry_removed { - border: 1px solid #F88; - box-sizing: border-box; -} -.epb_entry p { - margin: 0 !important; -} -.epb_header { - /* height: 35px; */ - /* min-width: 640px; */ - /* border-bottom: 1px solid #d6d4d5; */ - /* padding: 10px 10px 0 10px; */ - /* background-color: #ededed; */ - /* border-radius: 10px 10px 0 0; */ - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; -} -/* .epb_header_container { */ -/* height: 45px; */ -/* } */ -.epb_header_sticky { - position: fixed; - top: 86px; - z-index: 10; - transition: width ease-in 0.3s; -} -.epb_header_sticky div.action_button_text { - margin-left: 5px; -} -.epb_header_sticky div.more_options { - margin-right: 5px; -} -/*Hack for comments*/ -.epb_content_wrap { - display: table; - /* width: 100%; */ -} -.epb_show_comments .epb_content_container { - display: table-cell; - width: 85%; -} -.epb_show_comments .comment_block_container { - display: table-cell; -} -/*End of comment Hack */ -.epb_footer { - font-size: 9px; - height: auto; - margin-left: 30px; - margin-right: 45px; - position: relative; - padding: 5px; - background: #cad4de; - border-top: solid 1px white; - -webkit-box-shadow: 0 2px 2px rgba(55, 72, 88, 0.3); - -moz-box-shadow: 0 2px 2px rgba(55, 72, 88, 0.3); - box-shadow: 0 2px 2px rgba(55, 72, 88, 0.3); -} -.epb_footer_signing_infos { - display: inline-block; - text-align: left; -} -.epb_footer_witness_actions { - display: inline-block; - margin-right: 10px; -} -.epb_footer_witness_actions a { - padding-left: 10px; - line-height: 25px; -} -.epb_date { - border-right: 1px solid #d6d4d5; - margin-right: 10px; - padding-right: 10px; - padding-top: 2px; - font-size: 12px; - float: right; - text-align: right; -} -.epb_author { - border-right: 1px solid #d6d4d5; - margin-right: 10px; - padding-right: 10px; - padding-top: 2px; - padding-left: 5px; - font-size: 12px; - float: right; -} -.epb_author_picture { - border: 1px solid #d6d4d5; - float: right; - margin-top: 2px; -} -.epb_comments_alert { - /* color: #FFFFFF; */ - /* float:right; */ - /* margin-right: 5px; */ - cursor: pointer; -} -.epb_comments_count { - /* position: relative; */ - /* top: 7px; */ - /* left: 50%; */ - /* margin-left: 3px; */ - /* vertical-align: top; */ -} -.epb_header_action { - line-height: 24px; - padding-right: 15px; - padding-top: 2px; - font-size: 12px; - float: left; -} -.epb_default_slider_container { - cursor: pointer; -} -div.epb_relative_zoom { - margin-left: 2px; - font-size: 14px; - display: inline-block; - position: relative; - width: 12px; - height: 16px; - vertical-align: text-bottom; -} -div.epb_relative_zoom:hover { - /* color: #69bfee; */ -} -.epb_default_slider { - background-color: #ededed; - border: 1px solid #DDDDDD; - border-radius: 7px; - box-shadow: #B6B4A8 0 1px 7px inset; - box-sizing: border-box; - cursor: pointer; - display: inline-block; - height: 14px; - max-width: 100%; - overflow: hidden; - padding: 0; - position: relative; - width: 114px; - margin: 0 5px 0 4px; -} -.epb_default_slider_active { - background-color: #EFEFE7; - border: 1px solid #99968F; - border-radius: 6px; - box-sizing: border-box; - height: 12px; - position: relative; - width: 12px; - transition: all ease 0.2s; - left: 0; - z-index: 2; -} -.epb_default_slider_active:hover { - box-shadow: #888888 -1px -1px 3px inset; -} -.epb_default_slider_active:active { - background-color: #DDD; - box-shadow: #AAA 1px 1px 2px inset; -} -.epb_default_slider_bar { - background: #69bfee; - /* fallback */ - background: rgba(75, 177, 215, 0.5); - box-shadow: #B6B4A8 0 1px 7px inset; - box-sizing: border-box; - border-bottom-left-radius: 6px; - border-top-left-radius: 6px; - border: 0; - height: 16px; - margin-top: -14px; - padding: 0; - position: relative; - width: 0px; - transition: all ease 0.2s; - z-index: 1; -} -.epb_default_slider_zoom { - cursor: default; - display: block; - line-height: 30px; - width: 100%; - text-align: center; -} -.epb_text_save_cancel { - display: none; -} -.epb_text_save_cancel a { - padding-left: 10px; -} -.epb_file { - margin: 20px 0; -} -.epb_image { - margin: 20px 0; - position: relative; -} -.epb_image .imageLayer { - position: absolute; - top: 0; - left: 0; -} -.epb_image_zoom { - margin-top: 5px; -} -.epb_image_zoom img { - cursor: pointer; -} -.epb_image_zoom_square { - background-color: transparent; - border: 1px solid #666; - margin: 0 1px; -} -.epb_image_zoom_square_active { - background-color: #666; -} -.epb_new_panel { - background: #ededed; - border: 2px solid #CCC; - border-bottom: none; - border-radius: 5px 5px 0 0; - bottom: 0; - height: 40px; - left: 50%; - margin-left: -250px; - padding: 5px; - position: absolute; - text-align: center; - z-index: 2; -} -.epb_new_panel_middle { - background: url(/static/img/design/epb_new_panel_middle.png) repeat-x; - float: left; - height: 55px; - padding-top: 25px; -} -.epb_new_panel_left { - background: url(/static/img/design/epb_new_panel_left.png) no-repeat; - float: left; - height: 80px; - width: 30px; - position: relative; -} -.epb_new_panel_right { - background: url(/static/img/design/epb_new_panel_right.png) no-repeat; - float: left; - height: 80px; - width: 30px; -} -.epb_new_panel .default_button { - margin: 0 5px; -} -#epb_new_panel_jump_to_end { - display: none; -} -#epb_new_panel_jump_to_end div { - float: left; - font-size: 14px; - line-height: 30px; -} -.epb_entry_removed_msg_head { - display: none; - margin: 0 200px; - text-align: center; - color: #F88; - padding-top: 5px; -} -/* ******* */ -/* EPB END */ -/* ******* */ -/* ******************* */ -/* block history START */ -/* ******************* */ -.block_history_table { - border-collapse: collapse; - width: 100%; -} -tr.history_row:nth-child(odd) { - background-color: #fff; - cursor: pointer; - height: 23px; -} -tr.history_row:nth-child(even) { - background-color: #f0f0f0; - cursor: pointer; - height: 23px; -} -.block_history_table td.col1 { - padding: 3px 0 3px 5px; -} -.block_history_table td.col2 { - padding: 3px 10px 3px 10px; -} -.block_history_table td.col3 { - padding: 3px 0; -} -#block_history_navigation { - position: absolute; - width: 350px; - bottom: 0; - top: 30px; - left: 0; - overflow: auto; - border-right: 2px solid #374858; -} -#block_history_item_content { - position: absolute; - right: 0; - bottom: 0; - top: 30px; - left: 350px; - padding: 0 20px; - overflow: scroll; -} -.block_history_row_selected { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - background-color: #DDD !important; - color: #4BB1D1; -} -/* ***************** */ -/* block history END */ -/* ***************** */ -/* ************** */ -/* plupload START */ -/* ************** */ -.plupload_select { - width: 110px; - height: 24px; - margin: 0 auto; -} -.plupload_drop { - border: 2px dashed black; - width: 200px; - height: 80px; - margin: 0 auto; - background-color: #77ff66; -} -#plupload_container { - position: absolute; - top: -100px; - left: 0; - width: 100px; - height: 50px; - overflow: hidden; -} -/* ************ */ -/* plupload END */ -/* ************ */ -/* *************** */ -/* workspace START */ -/* *************** */ -.workspace_header_actions { - height: 50px; -} -.workspace_header_actions .default_button { - margin-right: 15px; -} -.workspace_header_link { - margin-right: 15px; - line-height: 36px; -} -.workspace_header_link span { - font-weight: bold; -} -/** Modified at the end of the section -.workspace_header { - background-color: #F3F3F3; - border: 1px solid #DDD; - line-height: 36px; - padding: 5px; - padding-left: 15px; -}*/ -.workspace_header_path a { - outline: none; - color: #fff; - text-decoration: none; -} -.workspace_header_path a:hover { - color: #69bfee; -} -.project_list_children { - display: none; - margin-left: 30px; -} -.project_list_head { - border: 1px solid #DDD; - border-radius: 10px; - background-color: #f3f3f3; - padding: 10px 0; - height: 12px; -} -.project_list_head .name { - margin-left: 15px; -} -.project_list_head .updateTS { - float: right; - margin-right: 15px; -} -.project_list { - min-height: 350px; - margin: 0 25px 25px 0; - background-color: #ffffff; - border-bottom: solid 1px #cad4de; - border-left: solid 1px #cad4de; - border-right: solid 1px #cad4de; - position: relative; - padding: 20px 20px 20px 135px; - -webkit-box-shadow: 0 2px 2px rgba(55, 72, 88, 0.1); - -moz-box-shadow: 0 2px 2px rgba(55, 72, 88, 0.1); - box-shadow: 0 2px 2px rgba(55, 72, 88, 0.1); -} -.project_list_line { - /* background: url(/static/icon/project40.png) no-repeat 0 -40px; */ - display: block; - outline: none; - color: #4b6277; - cursor: pointer; - text-decoration: none; - line-height: 1.2; - font-size: 14px; - padding: 5px 15px; - border: 1px solid transparent; - overflow: hidden; -} -.project_list_line > span { - color: #4b6277; - line-height: 1.2; - font-size: 14px; -} -.project_list_line:hover { - background-position: 0 0; - background: #ecf0f3; - text-decoration: none; -} -.project_list_line.is_folder { - background: url(/static/icon/folder40.png) no-repeat 0 -40px; -} -.project_list_line:hover.is_folder { - background-position: 0 0; -} -.project_list_line.is_group { - /* background: url(/static/icon/group40.png) no-repeat 0 -40px; */ -} -.project_list_line:hover.is_group { - background-position: 0 0; -} -.project_list_line img { - vertical-align: top; -} -.project_list_line .name { - font-size: 14px; -} -.project_list_line .updateTS { - font-size: 15px; - float: right; - margin-right: 15px; -} -a.order_link { - font-size: 12px; - outline: none; - color: #374858; - text-decoration: none; -} -a.order_link:hover { - color: #69bfee; -} -a.order_link_asc { - padding-right: 12px; - background: url(/static/icon/order_sign.png) no-repeat right -65px; -} -a.order_link_desc { - padding-right: 12px; - background: url(/static/icon/order_sign.png) no-repeat right -45px; -} -a.order_link_asc:hover { - padding-right: 12px; - background: url(/static/icon/order_sign.png) no-repeat right -25px; -} -a.order_link_desc:hover { - padding-right: 12px; - background: url(/static/icon/order_sign.png) no-repeat right -5px; -} -.workspace_header { - background: #374858 repeat-x 0 0; - border: 1px solid #DDD; - border-radius: 10px; - height: 35px; - line-height: 5px; - padding: 5px 10px; -} -.workspace_name { - color: #FFFFFF; - float: left; - font-size: 24px; - height: 32px; - line-height: 32px; - margin-top: 5px; - overflow: hidden; - text-overflow: ellipsis; - width: 90%; - white-space: nowrap; -} -.workspace_name a { - color: #FFF; -} -.workspace_name a:hover { - color: #69bfee; - text-decoration: none; -} -/* ************* */ -/* workspace END */ -/* ************* */ -/* ******************* */ -/* profile block START */ -/* ******************* */ -#user_settings_innovation_level_form select { - background: #ffffff; - border: 1px solid #d9e1e8; - color: #5e7b97; - cursor: pointer; - margin: 0 0 0 10px; - padding: 4px 4px 4px 8px; - outline: 0; -} -#profile_picture_edit_panel { - float: left; - margin-right: 20px; - margin-bottom: 15px; - padding-left: 5px; -} -#profile_picture_edit_panel img { - border: 1px solid #bac7d4; - margin-top: 10px; - width: 100px; - height: 100px; -} -.profile_block { - padding-left: 15px; - width: 550px; - margin-bottom: 20px; -} -.profile_block_edit { - display: block; - float: right; - margin-right: 5px; - font-size: 12px; -} -.profile_edit .placeholder_frame { - margin: 0 5px 5px 0; -} -.project_pdf_export_list { - background: #ffffff; - border: 1px solid #DDD; - height: 125px; - margin: 15px 0 30px 0; - padding: 5px; - overflow-y: scroll; -} -.project_pdf_export_list div { - line-height: 18px; - height: 18px; - overflow: hidden; -} -.pdf_range_export label { - display: block; - text-align: left; -} -/*FIND A BETTER WAY WITH last-child*/ -#profile_contact { - border: none; - padding-bottom: 0px; -} -#profile_picture_edit_link { - position: relative; -} -#profile_picture_edit_panel span { - opacity: 0; - height: 25px; - left: 0; - line-height: 25px; - position: absolute; - text-align: center; - top: 86px; - width: 100px; - -webkit-transition: all 0.3s ease; - -moz-transition: all 0.3s ease; - -o-transition: all 0.3s ease; - transition: all 0.3s ease; -} -#profile_picture_edit_panel:hover span { - background: rgba(75, 98, 119, 0.95); - opacity: 1; - color: white; -} -.profile_block_img { - display: block; -} -#updatePersonalForm .placeholder_frame { - float: none; - width: 380px; -} -.profile_block_key { - float: left; - font-weight: bold; - font-size: 12px; - height: 24px; - line-height: 24px; - margin-bottom: 10px; - width: 100px; -} -#profile_settings .profile_block_key { - padding-left: 5px; - width: 200px; -} -#profile_settings .profile_block h2 { - margin: 0 0 15px 0; -} -.edit_wrap { - width: 100%; - height: 10px; -} -.profile_block_value { - float: left; - line-height: 24px; - font-size: 12px; -} -.general_setting_item { - margin-bottom: 20px; -} -.profile_block_value input[type=text], -.profile_block_value input[type=password] { - width: 330px; -} -.profile_block_error { - color: red; - display: block; - line-height: 20px; -} -.cancel_save_panel { - float: right; - margin-right: 5px; - line-height: 36px; - margin-top: 20px; -} -.cancel_save_panel .cancel { - float: left; - padding-right: 10px; - font-size: 12px; -} -.profile_block h1 { - margin: 0; - font-size: 14px; -} -.profile_block h2 { - margin: 0 0 5px 0; - padding: 0 0 2px 4px; - color: #7b95ad; - border-bottom: 1px solid #9baec0; - font-size: 12px; - font-weight: normal; -} -.profile_show { - padding: 10px 0 2px 4px; - margin-bottom: 20px; -} -.profile_edit { - padding: 10px 0 2px 4px; - float: left; - display: block; -} -.profile_edit_personal { - width: 400px; -} -.profile_block h3 { - font-size: 12px; - margin: 10px 0; - font-weight: normal; -} -.profile_section { - min-height: 100px; - display: block; - overflow: auto; - margin-bottom: 20px; -} -.profile_prof_head { - width: 400px; -} -.profile_name_field { - width: 200px; -} -.placeholder_frame label.profile_personalEdit { - padding: 5px; -} -.profileTitle_field { - width: 200px; -} -#profile_personal .profile_show div { - display: inline; -} -/* ***************** */ -/* profile block END */ -/* ***************** */ -/* ******************** */ -/* sticky infobox START */ -/* ******************** */ -.sticky_infobox { - width: 350px; - height: 310px; - background: url(/static/img/design/sticky_infobox_big.png) 0 0 no-repeat; - padding: 50px 65px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -/* ****************** */ -/* sticky infobox END */ -/* ****************** */ -/* ************ */ -/* search START */ -/* ************ */ -.search_wrap { - padding-left: 15px; -} -.search_wrap .placeholder_frame { - height: 30px; -} -.search_wrap .placeholder_frame input { - height: 30px; -} -.search_wrap .placeholder_frame label { - padding: 4px 0 0 5px; - font-size: 14px; -} -.search_wrap .placeholder_frame button.search_button { - height: 30px; -} -.top_searchbox_form { - float: right; - position: relative; - top: 12px; - padding-right: 10px; -} -.search_result_item { - padding-bottom: 20px; - width: 560px; -} -.search_result_item_title { - text-decoration: underline; - font-size: 12px; -} -.search_result_item_title:hover { - text-decoration: underline; - color: #3b97ed; -} -.search_result_item_text { - font-size: 12px; -} -#search_result_load_more_spinner { - display: none; -} -#search_result_load_more_link { - display: none; -} -#search_result_error_message { - display: none; - color: red; -} -#search_result_num_all_results { - display: none; - color: #999; - font-size: 12px; - padding: 3px; -} -.search_result_content { - padding-top: 20px; -} -/* ********** */ -/* search END */ -/* ********** */ -.default_font { - font-family: Arial, Helvetica, Verdana, Tahoma, sans-serif; - font-size: 15px; - line-height: 1.45em; - white-space: normal; -} -#data_element { - display: none; -} - - -/**************/ -/* IE WARNING */ -/**************/ -#ie_warning { - display: none; - background-color: #E66873; - color: #FFF; - font-size: 14px; - height: 30px; - left: 50%; - line-height: 14px; - margin-left: -310px; - padding: 5px; - position: fixed; - text-align: center; - width: 550px; - z-index: 9999; -} -a#ie_warning_close { - color: #FFF; - float: right; - font-size: 12px; - cursor: pointer; -} -a#ie_warning_update { - color: #FFF; - font-size: 14px; - text-decoration: underline; -} -/****************************/ -/* admin active weeks START */ -/****************************/ -.activeWeeksTable { - border-spacing: 0; - border-collapse: collapse; - font-size: 8px; - background-color: #e5e5e5; - text-align: center; -} -.activeWeeksTable th { - border: 1px solid #374858; -} -.activeWeeksTable td { - border: 1px solid #374858; -} -.activeWeeksTable .week { - width: 20px; - height: 20px; -} -.activeWeeksTable .week.status1 { - background-color: white; -} -.activeWeeksTable .week.status2 { - background-color: #fcc; -} -.activeWeeksTable .week.status3 { - background-color: #cfc; -} -.activeWeeksTable .week.status3 { - background-color: #cfc; -} -.activeWeeksTable .premium { - background-color: #cfc; -} -/**************************/ -/* admin active weeks END */ -/**************************/ -/**************************/ -/* pdf viewer START */ -/**************************/ -#pdf_viewer { - border: 0; - display: block; - height: 100%; - width: 100%; -} -/**************************/ -/* pdf viewer END */ -/**************************/ -.activeExcelSheet { - font-weight: bold; -} -a.editor_reference { - color: #a21621; - cursor: pointer; - font-weight: bold; - text-decoration: none; -} -.pdf_checkbox_label { - line-height: 32px; - margin-left: 25px; -} -.pdf_checkbox_sublabel { - line-height: 32px; - margin-left: 45px; -} -.pdf_setting_description { - margin-left: 50px; - font-size: 12px; -} -.pdf_filename_label { - display: block; - margin: 10px 0 10px 32px; -} -/**************************/ -/* END */ -/**************************/ -#block_history_item_content .extract_preview_link, -.readOnly .extract_preview_link { - display: none; -} -.extract_preview { - overflow: auto; -} -.extract_preview_confirm { - float: right !important; - margin-right: 25px; -} -/*********************/ -/* jsTemplates START */ -/*********************/ -#jsTemplates { - display: none; -} -p.jsTemplate_dialog_title { - display: none; -} -/*******************/ -/* jsTemplates END */ -/*******************/ -/***************/ -/* popup START */ -/***************/ -.popup { - display: none; - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - z-index: 98; - -moz-opacity: .8; - opacity: 0.8; - background-color: white !important; -} -.popup_window { - display: none; - position: absolute; - z-index: 99; - background-color: white; - /* border: 2px solid #374858; */ - -webkit-box-shadow: 0 4px 10px rgba(55, 72, 88, 0.3); - -moz-box-shadow: 0 4px 10px rgba(55, 72, 88, 0.3); - box-shadow: 0 4px 10px rgba(55, 72, 88, 0.3); -} -.popup_window_default { - top: 75px; - bottom: 75px; - left: 75px; - right: 75px; -} -#my_popup_inner { - background-color: #cad4de; -} -.popup_dialog { - display: none; - position: absolute; - z-index: 99; - background-color: #cad4de; - top: 30%; - left: 50%; - width: 400px; - margin-top: -125px; - margin-left: -200px; - -webkit-box-shadow: 0 4px 10px rgba(55, 72, 88, 0.8); - -moz-box-shadow: 0 4px 10px rgba(55, 72, 88, 0.8); - box-shadow: 0 4px 10px rgba(55, 72, 88, 0.8); -} -.popup_title { - height: 30px; - line-height: 30px; - margin-top: -1px; - padding-left: 5px; - background: #304d69; - color: white; -} -.popup_title_close { - font-size: 20px; - width: 20px; - height: 20px; - text-align: center; - line-height: 20px; - float: right; - cursor: pointer; - margin: 4px; -} -.popup_title_left { - float: left; -} -.popup_title_center { - text-align: center; -} -.popup_title_center span { - display: none; -} -.popup_loading_image { - margin: 50px auto; - background: url(/static/img/ajax-loader-big.gif) no-repeat; - width: 32px; - height: 32px; -} -.popup_dialog .popup_dialog_content { - max-height: 650px; - overflow: auto; - padding: 10px; -} -.popup_dialog_cancel_save_panel { - float: right; - margin-top: 10px; - line-height: 30px; -} -.popup_dialog_cancel_save_panel .cancel { - float: left; - padding-right: 5px; - font-size: 12px; - visibility: hidden; -} -.popup_dialog_cancel_save_panel .dialog_confirm { - visibility: hidden; -} -#import_footer .dialog_confirm { - visibility: visible; -} -.popup_dialog_cancel_save_panel .default_button { - margin-left: 5px; -} -.popup_scroll_content { - position: absolute; - right: 0; - bottom: 0; - top: 30px; - left: 0; - padding: 10px; - overflow: auto; -} -.popup_list_row { - padding-bottom: 15px; - margin-bottom: 15px; - border-bottom: 1px solid #DDD; -} -.popup_list_row .default_button { - float: right; -} -.popup_list_row .deny_link { - float: right; - line-height: 36px; - font-size: 12px; - margin: 0 5px; -} -.popup_list_row_desc { - padding-top: 12px; - margin-right: 125px; -} -.popup_dialog_error { - background-color: #E66873; - color: #FFF; - display: none; - font-size: 14px; - line-height: 18px; - padding: 5px; - text-align: center; -} -.popup_dialog_loading_button { - padding: 0 10px; -} -#my_popup_content { - height: calc(100% - 29px); - overflow: auto; -} -.input_block { - margin-bottom: 20px; - word-wrap: break-word; - font-size: 12px; -} -.input_block .folder_up-img { - background-position: -738px -5px; - width: 24px; - height: 13px; -} -.tagline_hidden { - display: none; -} -.input_title { - margin: 10px 0 5px; - font-size: 12px; - color: #4b6277; -} -#my_popup_content .input_title:first-of-type { - /* margin: 0 0 5px 0; */ -} -#my_popup_content .spinner { - display: block; - margin: auto; -} -#my_popup_content textarea { - color: #4b6277; - line-height: 1.4; - font-size: 14px; - height: 150px; - resize: none; -} -/*************/ -/* popup END */ -/*************/ -/**************************/ -/* custom selectbox START */ -/**************************/ -div.lfSelectBox { - position: relative; - cursor: pointer; - background-color: white; - width: 0; - float: left; -} -div.lfSelectTitle { - border: 1px solid black; -} -div.lfSelectOptions { - position: absolute; - border: 1px solid black; - background: white; - z-index: 99; - display: none; -} -div.lfSelectOption:hover { - color: #E7E7E7; - background: #3988e5; -} -/************************/ -/* custom selectbox END */ -/************************/ -/* ************ */ -/* button START */ -/* ************ */ -a.btn, -button.btn { - background: transparent url(/static/img/button/button_right.gif) no-repeat scroll top right; - border: 0; - color: #666; - cursor: pointer; - display: block; - float: left; - font-size: 14px; - line-height: 16px; - height: 24px; - margin-right: 6px; - outline: none; - padding-right: 16px; - padding-top: 0; - text-decoration: none; -} -a.btn span, -button.btn span { - background: transparent url(/static/img/button/button_left.gif) no-repeat; - display: block; - padding: 4px 0 4px 18px; -} -a.btn img, -button.btn img { - vertical-align: top; -} -a.btn:active, -button.btn:active { - background-position: bottom right; -} -a.btn:active span, -button.btn:active span { - background-position: bottom left; - padding: 5px 0 3px 18px; -} -/* a.btn36, button.btn36 { */ -/* background-color: transparent; */ -/* border: 0; */ -/* margin: 0; */ -/* padding: 0; */ -/* color: white; */ -/* cursor: pointer; */ -/* display: block; */ -/* float: left; */ -/* font-size: 14px; */ -/* line-height: 16px; */ -/* height: 36px; */ -/* outline: none; */ -/* text-decoration: none; */ -/* font-family: 'din-medi'; */ -/* } */ -/* a.btn36 img, button.btn36 img { */ -/* vertical-align: top; */ -/* margin-right: 7px; */ -/* } */ -/* a.btn36 span, button.btn36 span { */ -/* display: block; */ -/* float: left; */ -/* } */ -/* a.btn36 span.m, button.btn36 span.m { */ -/* background: url(/static/img/button/b36_m.png) repeat-x 0 0; */ -/* height: 16px; */ -/* padding: 10px 1px 10px 1px; */ -/* } */ -/* a.btn36 span.l, button.btn36 span.l { */ -/* background: url(/static/img/button/b36_l.png) no-repeat 0 0; */ -/* width: 15px; */ -/* height: 36px; */ -/* } */ -/* a.btn36 span.r, button.btn36 span.r { */ -/* background: url(/static/img/button/b36_r.png) no-repeat 0 0; */ -/* width: 15px; */ -/* height: 36px; */ -/* } */ -/* a.btn36:hover span, button.btn36:hover span { */ -/* background-position: 0 -36px; */ -/* } */ -/* a.btn36:active span, button.btn36:active span { */ -/* background-position: 0 -72px; */ -/* } */ -/* a.btn36:active span.m, button.btn36:active span.m { */ -/* padding: 11px 0px 9px 2px; */ -/* } */ -/* ********** */ -/* button END */ -/* ********** */ -/* ************ */ -/* errors START */ -/* ************ */ -.errorBox { - border: 1px solid red; -} -.errorInput { - background-color: red; -} -.errorMessage { - color: red; -} -/* ********** */ -/* errors END */ -/* ********** */ -/* *********************** */ -/* input placeholder START */ -/* *********************** */ -.placeholder_frame { - position: relative; - float: left; -} -.placeholder_frame label { - position: absolute; - padding: 7px 0 0 5px; - top: 2px; - left: 0; - color: #9baec0; - font-style: italic; - font-family: Arial; - cursor: text; - font-size: 14px; -} -.placeholder_frame input { - padding: 5px; - margin: 0; - font-size: 14px; - line-height: 14px; - color: #4b6277; -} -.placeholder_frame button { - position: absolute; - height: 28px; - padding: 7px; - top: 0; - right: 0; -} -.placeholder_frame input.searchbox_input { - width: 250px ; - padding-right: 30px; - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; -} -.placeholder_frame.big label { - font-size: 20px; - padding: 10px 0 0 12px; -} -.placeholder_frame.big input { - padding: 10px; - padding-right: 50px; - width: 500px; - font-size: 20px; - line-height: 20px; -} -.placeholder_frame.big button { - padding: 10px; - font-size: 20px; -} -/* *********************** */ -/* input placeholder END */ -/* *********************** */ -/* ************ */ -/* inputs START */ -/* ************ */ -.input_with_padding { - padding: 3px; - width: 100%; -} -.form_around_input_with_padding { - padding-right: 5px; -} -/* ********** */ -/* inputs END */ -/* ********** */ -.aligned_radio_button { - display: -moz-inline-box; - display: inline-block; - vertical-align: middle; - line-height: 18px; - margin-bottom: 5px; -} -input { - outline: 0; -} -textarea { - outline-color: #69bfee; -} -input[type="checkbox"].default_checkbox { - position: absolute; - opacity: 0; -} -input[type="checkbox"].default_checkbox + div { - cursor: pointer; - display: inline-block; - vertical-align: middle; - width: 46px; - height: 13px; - border: 1px solid rgba(55, 72, 88, 0.47); - border-radius: 999px; - margin: 0 .5em; - background: #f9fafb; - background-image: linear-gradient(rgba(176, 205, 231, 0.2), rgba(0, 0, 0, 0)), linear-gradient(90deg, #374858, rgba(0, 0, 0, 0) 65%); - background-size: 200% 100%; - background-position: 100% 0; - background-origin: border-box; - background-clip: border-box; - overflow: hidden; - transition-duration: .3s; - transition-property: padding, width, background-position, text-indent; - box-shadow: 0 0.2em 0.4em rgba(14, 27, 37, 0.12) inset, 0 0.45em 0 0.1em rgba(45, 98, 133, 0.05) inset; - font-size: 150%; -} -input[type="checkbox"].default_checkbox:checked + div { - padding-left: 33px; - width: 46px; - background-position: 0 0; -} -input[type="checkbox"].default_checkbox + div:before { - content: 'On'; - float: left; - width: 13px; - height: 13px; - margin: -1px; - border: 1px solid rgba(55, 72, 88, 0.35); - border-radius: inherit; - background: white; - background-image: linear-gradient(#8fa1b4, transparent); - box-shadow: 0 0.1em 0.1em 0.1em rgba(255, 255, 255, 0.8) inset, 0 0 0.5em rgba(55, 72, 88, 0.3); - color: white; - text-shadow: 0 -1px 1px rgba(0, 0, 0, 0.3); - text-indent: -2.5em; -} -input[type="checkbox"].default_checkbox:active + div:before { - background-color: #eee; -} -input[type="checkbox"].default_checkbox + div:before, -input[type="checkbox"].default_checkbox + div:after { - font-size: 9px; - line-height: 12px; - font-weight: bold; - text-transform: uppercase; -} -input[type="checkbox"].default_checkbox + div:after { - content: 'Off'; - float: left; - text-indent: .5em; - color: #4b6277; - text-shadow: none; -} -/* Draggable */ -div.action_button.dragging_helper { - width: 42px; - height: 24px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - padding: 2px 10px; - background-image: url('/static/img/design/blank.png') !important; - background-color: #FFF; - border-radius: 2px; - box-shadow: 0 1px 4px #646464; - color: #69bfee; - cursor: pointer; - opacity: 0.8; - text-decoration: none; - z-index: 50; -} -a.dragging_helper { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - background-image: url('/static/img/design/blank.png') !important; - background-color: #FFF; - border-radius: 2px; - box-shadow: 1px 1px 5px #000; - color: #69bfee; - cursor: pointer; - opacity: 0.5; - padding: 10px 30px; - text-decoration: none; - z-index: 50; -} -.dialog_message_form textarea { - min-height: 150px; -} -/************* -* header css * -**************/ -.arrow_box { - position: relative; - background: white; -} -.arrow_box:after, -.arrow_box:before { - bottom: 100%; - left: 50%; - border: solid transparent; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; -} -.arrow_box:after { - border-color: rgba(0, 0, 0, 0); - border-bottom-color: white; - border-width: 5px; - margin-left: -4px; -} -.arrow_box:before { - border-color: rgba(0, 0, 0, 0); - border-bottom-color: #bac7d4; - border-width: 6px; - margin-left: -5px; -} -.headerbar_top { - width: 100%; - height: 50px; - background: white; - border-bottom: solid 1px #bac7d4; -} -.headerbar_top > header { - margin: 21px 0 0 65px; - font-weight: bold; - float: left; - position: relative; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - color: #415568; -} -.headerbar_top > header:hover .page_title { - position: absolute; - overflow: visible; - white-space: normal; - display: block; - margin-left: 21px; - z-index: 999; - background: white; - -webkit-box-shadow: 0 2px 4px rgba(55, 72, 88, 0.2); - -moz-box-shadow: 0 2px 4px rgba(55, 72, 88, 0.2); - box-shadow: 0 2px 4px rgba(55, 72, 88, 0.2); -} -.headerbar_top h1 { - font-size: 14px; - font-weight: normal; - margin: 0; -} -.headerbar_top > nav { - float: right; - height: 50px; -} -.headerbar_top a { - color: inherit; - text-decoration: none; - cursor: pointer; -} -.page_title { - white-space: nowrap; - text-overflow: ellipsis; - display: block; - overflow: hidden; - padding: 0; - background: white; - margin-left: 0; -} -.page_title a { - white-space: nowrap; -} -.nav_top { - float: left; - margin: 0 100px 0 10px; -} -.nav_top > ul { - margin: 0; - padding: 0; -} -.nav_top > ul > li { - width: 72px; - height: 49px; - margin-left: -1px; - list-style-type: none; - float: left; - position: relative; - -webkit-transition: all 0.2s ease; - -moz-transition: all 0.2s ease; - -o-transition: all 0.2s ease; - transition: all 0.2s ease; -} -.header_btn { - width: 100%; - height: 100%; - color: #4b6277; - padding: 0; - text-align: center; - font-size: 10px; - position: relative; - cursor: pointer; - background: transparent; - border-left: solid 1px transparent; - border-right: solid 1px transparent; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; - -webkit-transition: all 0.2s ease; - -moz-transition: all 0.2s ease; - -o-transition: all 0.2s ease; - transition: all 0.2s ease; -} -.header_btn span { - margin-left: auto; - margin-right: auto; - margin-top: 2px; - display: block; - float: none; -} -.header_btn p { - margin: 7px 0; -} -.header_btn:hover { - background: #f3f5f7; - -webkit-box-shadow: inset 0 1px 6px rgba(55, 72, 88, 0.1); - -moz-box-shadow: inset 0 1px 6px rgba(55, 72, 88, 0.1); - box-shadow: inset 0 1px 6px rgba(55, 72, 88, 0.1); - border-left: solid 1px #cad4de; - border-right: solid 1px #cad4de; - padding-top: 0; -} -.header_btn:active { - background: #d9e1e8; - padding-top: 0; - -webkit-box-shadow: inset 0 1px 6px rgba(55, 72, 88, 0.2); - -moz-box-shadow: inset 0 1px 6px rgba(55, 72, 88, 0.2); - box-shadow: inset 0 1px 6px rgba(55, 72, 88, 0.2); -} -.nav_top_active { - -webkit-box-shadow: inset 0 1px 6px rgba(55, 72, 88, 0.1); - -moz-box-shadow: inset 0 1px 6px rgba(55, 72, 88, 0.1); - box-shadow: inset 0 1px 6px rgba(55, 72, 88, 0.1); - background: #e0e6eb !important; - border-left: solid 1px #cad4de !important; - border-right: solid 1px #cad4de !important; -} -.manage_hover:hover .header_btn { - background: #f3f5f7; - -webkit-box-shadow: inset 0 1px 6px rgba(55, 72, 88, 0.1); - -moz-box-shadow: inset 0 1px 6px rgba(55, 72, 88, 0.1); - box-shadow: inset 0 1px 6px rgba(55, 72, 88, 0.1); - border-left: solid 1px #bac7d4; - border-right: solid 1px #bac7d4; - padding-top: 0px; -} -.manage_hover:active .header_btn { - background: #d9e1e8; - padding-top: 0px; - -webkit-box-shadow: inset 0 1px 6px rgba(55, 72, 88, 0.2); - -moz-box-shadow: inset 0 1px 6px rgba(55, 72, 88, 0.2); - box-shadow: inset 0 1px 6px rgba(55, 72, 88, 0.2); -} -.manage_dropdown { - position: absolute; - top: 49px; - left: 0; - font-size: 13px; - z-index: 999; -} -.manage_dropdown li { - width: 120px; -} -.manage_dropdown > span { - position: absolute; - top: -11px; - left: 25px; -} -.header_top_dropdown { - background: white; - display: none; - border: solid 1px #bac7d4; - border-right: solid 1px #bac7d4; - border-bottom: solid 1px #bac7d4; - -webkit-box-shadow: 0 4px 10px rgba(55, 72, 88, 0.3); - -moz-box-shadow: 0 4px 10px rgba(55, 72, 88, 0.3); - box-shadow: 0 4px 10px rgba(55, 72, 88, 0.3); - font-size: 13px; -} -.header_top_dropdown > ul { - margin: 0; - padding: 0; -} -.header_top_dropdown > ul li { - list-style-type: none; -} -.header_top_dropdown > ul { - padding: 12px 0 12px 0; -} -.header_top_dropdown > ul > li { - display: block; - text-align: left; - cursor: pointer; -} -.header_top_dropdown > ul > li > a { - padding: 8px 0 8px 12px; - display: block; -} -.header_top_dropdown > ul > li:hover { - background: #ecf0f3; -} -.bread_arrow { - font-size: 11px; -} -.options_top { - float: right; - margin: 10px 0 0 10px; - position: relative; -} -.options_top > ul { - margin: 0; - padding: 0; -} -.options_top > ul > li { - list-style-type: none; - float: left; - position: relative; -} -.options_top > ul > li { - width: 40px; - height: 50px; - margin-right: 15px; - display: block; - float: left; - font-size: 10px; - position: relative; -} -.options_top > ul > li:first-child > span { - margin-left: 10px; -} -.signout_wrap { - position: relative; - display: block; - width: 40px; - height: 32px; -} -.notes_count { - padding: 2px 2px 1px 2px; - line-height: 10px; - color: white; - background: #22a6ee; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; - position: absolute; - text-align: right; - left: 20px; - top: 0px; -} -.avatar { - border-radius: 50%; - width: 28px; - height: 28px; - background: #cad4de; - margin-top: -3px; - float: left; - -webkit-box-shadow: 0px 1px 2px rgba(55, 72, 88, 0.6); - -moz-box-shadow: 0px 1px 2px rgba(55, 72, 88, 0.6); - box-shadow: 0px 1px 2px rgba(55, 72, 88, 0.6); -} -.avatar span { - display: block; - float: none; -} -.avatar img { - border-radius: 50%; - width: 28px; - height: 28px; - position: absolute; -} -.avatar .avatar-img { - margin: 3px 0 0 4px; -} -.avatar .arrow_down_s-img { - position: absolute; - top: 12px; - right: 2px; -} -.dropdown_button { - cursor: pointer; -} -.search_dropdown { - width: 250px; - height: 51px; - padding: 10px; - position: absolute; - top: 39px; - left: -111px; - z-index: 999; -} -.search_dropdown > span { - position: absolute; - top: -11px; - left: 114px; -} -.search_dropdown input { - height: 30px; - width: 100%; - font-size: 14px; - color: #4b6277; - padding-left: 4px; - display: block; - margin: auto; - border: solid 1px #bac7d4; -} -.search_dropdown button { - position: absolute; - top: 10px; - right: 10px; - padding: 7px; - height: 30px; -} -.bell_dropdown { - position: absolute; - top: 39px; - left: -166px; - font-size: 12px; - line-height: 1.4; - z-index: 99; - max-height: 530px; - overflow-y: auto; - overflow-x: hidden; -} -.bell_dropdown > span { - position: absolute; - top: -11px; - left: 169px; -} -.bell_dropdown li { - width: 250px; - padding: 8px 0 8px 8px; -} -.bell_dropdown li span { - color: #69bfee; - font-weight: bold; -} -.bell_dropdown li article { - width: 200px; - display: inline-block; - margin-left: 10px; -} -.bell_dropdown li p { - color: #9baec0; - margin: 5px 0; -} -.bell_dropdown li:last-child { - text-align: center; - margin: 14px 0 -12px 0 !important; - background: #d9e1e8; -} -.profile_dropdown { - position: absolute; - top: 39px; - left: -70px; - font-size: 13px; - z-index: 999; - width: 120px; -} -.profile_dropdown > span { - position: absolute; - top: -11px; - left: 77px; -} -.profile_dropdown ul > li { - padding-left: 10px; -} -.profile_dropdown ul > li a { - width: 100%; -} -.med_blue_btn { - padding: 8px 17px 8px 17px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - color: white; - opacity: 1; - background: #3277b8; - font-size: 16px; - -webkit-transition: all 0.1s linear; - -moz-transition: all 0.1s linear; - -o-transition: all 0.1s linear; - transition: all 0.1s linear; - -webkit-backface-visibility: hidden; -} -.med_blue_btn:hover, -.med_blue_btn:focus { - background: #2a6398; - -ms-filter: none; - filter: none; - outline: 0; - color: white; - text-decoration: none; -} -.med_blue_btn:active { - background: #245684; - -ms-filter: none; - filter: none; - outline: 0; - -webkit-box-shadow: inset 0 3px 6px rgba(0, 0, 0, 0.4); - -moz-box-shadow: inset 0 3px 6px rgba(0, 0, 0, 0.4); - box-shadow: inset 0 3px 6px rgba(0, 0, 0, 0.4); -} -.orange_btn { - padding: 4px 17px 5px 17px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - color: #ffffff; - opacity: 1; - background: #e37900; - font-size: 20px; - -webkit-transition: all 0.1s linear; - -moz-transition: all 0.1s linear; - -o-transition: all 0.1s linear; - transition: all 0.1s linear; - -webkit-backface-visibility: hidden; -} -.upgrade_box { - position: relative; - background: #ffffff; - display: inline-block; - vertical-align: middle; - margin-right: 6px; -} -.upgrade_btn { - color: white; - background: #ff8617; - border: 0; - opacity: 1; - position: absolute; - top: 44px; - right: 40px; - border-radius: 3px; - color: white !important; - text-decoration: none; - padding: 3px 16px; - font-weight: bold; - height: 22px; - margin-top: 3px; - font-size: 14px; - display: block; -} -.upgrade_btn:hover { - background: #ffa14a; - outline: 0; -} -.upgrade_btn:active { - background: #ff8617; - outline: 0; - -webkit-box-shadow: inset 0 1px 2px rgba(55, 72, 88, 0.3); - -moz-box-shadow: inset 0 1px 2px rgba(55, 72, 88, 0.3); - box-shadow: inset 0 1px 2px rgba(55, 72, 88, 0.3); -} -.upgrade_box:after { - left: 100%; - top: 50%; - border: solid rgba(0, 0, 0, 0); - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - border-color: rgba(213, 213, 213, 0); - border-left-color: #ffffff; - border-width: 4px; - margin-top: -5px; -} -.filterbox_wrap { - position: relative; - float: left; - min-width: 100px; - width: auto; -} -.filterbox_wrap .filter_btn { - border-left: solid 1px #bac7d4; - border-right: solid 1px #bac7d4; - border-top: solid 1px #bac7d4; -} -.filterbox_task_wrap { - position: relative; - float: left; - min-width: 150px; -} -.filterbox_task_wrap .filter_btn { - border-left: solid 1px #bac7d4; - border-right: solid 1px #bac7d4; - border-top: solid 1px #bac7d4; -} -.filter_box_dropdown { - width: auto; - min-width: 100px; - padding: 10px 0; - float: left; - border: solid 1px #cad4de; - background: white; - font-size: 12px; - -webkit-box-shadow: 0 2px 4px rgba(55, 72, 88, 0.2); - -moz-box-shadow: 0 2px 4px rgba(55, 72, 88, 0.2); - box-shadow: 0 2px 4px rgba(55, 72, 88, 0.2); -} -.filter_box_dropdown > ul { - margin: 0; - padding: 0; -} -.filter_box_dropdown li { - list-style-type: none; - padding: 8px 8px 8px 8px; - cursor: pointer; -} -.filter_box_dropdown li:hover { - background: #ecf0f3; -} -.notebook_notification { - font-size: 16px; - margin: 40px auto; - width: 390px; - padding: 20px; - background: #ffffff; - -webkit-box-shadow: 0 1px 2px rgba(55, 72, 88, 0.5); - -moz-box-shadow: 0 1px 2px rgba(55, 72, 88, 0.5); - box-shadow: 0 1px 2px rgba(55, 72, 88, 0.5); -} -/********************* -* overwrite jqueryUI * -*********************/ -.ui-datepicker { - -webkit-box-shadow: 0 4px 8px rgba(55, 72, 88, 0.3); - -moz-box-shadow: 0 4px 8px rgba(55, 72, 88, 0.3); - box-shadow: 0 4px 8px rgba(55, 72, 88, 0.3); -} -.ui-corner-all, -.ui-corner-bottom, -.ui-corner-right, -.ui-corner-br { - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} -.ui-widget-header { - border: 0 /*{borderColorHeader}*/; - background: #d9e1e8; - color: #4b6277; - /*{fcHeader}*/ - font-weight: normal; -} -.ui-datepicker .ui-datepicker-prev, -.ui-datepicker .ui-datepicker-next { - border: 0; - position: absolute; - top: 0; - width: 1.8em; - height: 100%; -} -.ui-datepicker .ui-datepicker-prev:hover, -.ui-datepicker .ui-datepicker-next:hover { - border: 0; - background: #bac7d4; -} -.ui-datepicker th { - padding: .7em .3em; - text-align: center; - font-weight: normal; - color: #4b6277; - border: 0; -} -.ui-widget-content { - border: 1px solid #9baec0; - background: #ecf0f3; - color: #4b6277; -} -.ui-state-default, -.ui-widget-content .ui-state-default, -.ui-widget-header .ui-state-default { - border: 1px solid #cad4de; - background: white; - font-weight: normal /*{fwDefault}*/; -} -.ui-state-hover, -.ui-widget-content .ui-state-hover, -.ui-widget-header .ui-state-hover, -.ui-state-focus, -.ui-widget-content .ui-state-focus, -.ui-widget-header .ui-state-focus { - border: 1px solid #bac7d4 /*{borderColorHover}*/; - background: #e4eef7; - font-weight: normal /*{fwDefault}*/; - color: #4b6277; - /*{fcHover}*/ -} -.ui-state-default, -.ui-widget-content .ui-state-default, -.ui-widget-header .ui-state-default { - color: #4b6277; -} -.ui-state-hover .ui-icon, -.ui-state-focus .ui-icon { - background-image: none; -} -.ui-widget-header .ui-icon { - background-image: none; -} -.ui-icon { - overflow: visible !important; -} -.ui-icon-circle-triangle-w { - position: relative; - background: white; - display: inline-block; - height: 0; - width: 0; -} -.ui-icon-circle-triangle-w:after { - right: 100%; - top: 50%; - border: solid transparent; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - border-color: rgba(136, 183, 213, 0); - border-right-color: #4b6277; - border-width: 8px; - margin-top: -7px; -} -.ui-icon-circle-triangle-e { - position: relative; - background: white; - display: inline-block; - height: 0; - width: 0; -} -.ui-icon-circle-triangle-e:after { - left: 100%; - top: 50%; - border: solid transparent; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - border-color: rgba(136, 183, 213, 0); - border-left-color: #4b6277; - border-width: 8px; - margin-top: -7px; -} -.ui-datepicker .ui-datepicker-prev span, -.ui-datepicker .ui-datepicker-next span { - display: block; - position: absolute; - left: 50%; - margin-left: -2px; - top: 50%; - margin-top: 0px; -} -.ui-tooltip { - padding: 5px 10px; - background: #374858; - -webkit-box-shadow: 0 2px 3px rgba(55, 72, 88, 0.3); - -moz-box-shadow: 0 2px 3px rgba(55, 72, 88, 0.3); - box-shadow: 0 2px 3px rgba(55, 72, 88, 0.3); - font: normal 14px; - color: white; - border: 0; - z-index: 11; -} -.ui-tooltip:after { - bottom: 100%; - left: 13px; - border: solid transparent; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - border-color: transparent; - border-bottom-color: #374858; - border-width: 7px; - margin-left: -7px; -} -/**************** -* media queries * -****************/ -@media (max-width: 1750px) { - .headerbar_top > header { - width: 30%; - } -} -@media (max-width: 1160px) { - .group_content_block { - width: 100%; - } - .headerbar_top > header { - width: 30%; - margin: 19px 0 0 20px; - } - .eln_main_content_box, - .project_list { - padding: 20px 20px 20px 20px; - width: auto; - } - #messages_content, - #task_content, - #comments_content { - padding: 0 10px 0 10px; - } -} -@media (max-width: 1100px) { - .author_firstname, - .author_lastname { - width: 100px; - } -} -@media (max-width: 970px) { - .nav_top { - margin: 0 30px 0 10px; - } - .headerbar_top > header { - width: 200px; - } - .page_title { - margin-top: 2px; - font-size: 12px; - } - .author_firstname, - .author_lastname { - width: 66px; - } - .group_content_box { - padding: 20px; - } - .profile_block { - max-width: 550px; - width: calc(100% - 25px); - } -} -@media (max-height: 600px) { - .popup_dialog { - top: 50%; - } -} - -/****************************** - GROUP HEADER AND NAVIGATION BAR -*******************************/ -/************** -* basic.css * -**************/ -/********** -* colors * -***********/ -/********** -* helper * -***********/ -.list_vertical > ul { - margin: 0; - padding: 0; -} -.list_vertical > ul li { - list-style-type: none; -} -.list_horizontal > ul { - margin: 0; - padding: 0; -} -.list_horizontal > ul > li { - list-style-type: none; - float: left; - position: relative; -} -/************* -* functions * -**************/ -/****** -* css * -******/ -body { - color: #374858; -} -.clearfix:after { - content: " "; - visibility: hidden; - display: block; - height: 0; - clear: both; -} -.is_group .group-img { - margin-top: 1px; -} -.group_header { - background: #374858 repeat-x 0 0; - border-left: 1px solid #DDD; - border-right: 1px solid #DDD; - border-top: 1px solid #DDD; - border-radius: 10px 10px 0px 0px; - height: 35px; - line-height: 14px; - padding: 5px 10px; -} -/*.group_name{ - color: #FFFFFF; - display: block; - font-size: 24px; - height: 24px; - line-height: 24px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -}*/ -.group_tagline { - color: #FFFFFF; - display: block; - font-size: 14px; - height: 14px; - line-height: 14px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} -.group_nav { - font-size: 16px; - background-color: #FFF; - margin: 0; -} -.group_nav a { - color: #5e7b97; - border: 1px solid #D6D4D5; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - display: inline-block; - position: relative; - width: 20%; - padding: 8px 0; - text-align: center; - white-space: nowrap; - transition: all ease 0.2s; -} -.group_nav a:hover { - background: #ededed; - color: #69bfee; - text-decoration: none; -} -.group_nav .active { - color: #69bfee; - text-decoration: none; -} -.group_first_nav { - border-radius: 0px 0px 0px 10px; -} -.group_last_nav { - border-radius: 0px 0px 10px 0px; -} -.group_main_icon { - color: #FFFFFF; - display: inline-block; - float: left; - font-size: 24px; - margin-top: 5px; -} -.group_main_title { - height: 35px; -} -.group_search_form { - float: right; - margin: 2px 10px 0 0; -} -.group_search_input { - border: 1px solid #D6D4D5; - border-radius: 5px; - font-size: 14px; - padding: 5px; -} -/****************************** - GROUP CONTENT STYLES -*******************************/ -.group_content_box { - height: auto; - margin: 0 25px 25px 0; - background-color: #ffffff; - border-bottom: solid 1px #cad4de; - border-left: solid 1px #cad4de; - border-right: solid 1px #cad4de; - position: relative; - padding: 20px 20px 20px 135px; -} -.group_content_block { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - display: block; - width: 900px; - padding-left: 31px; -} -.group_content_block .tree_my_eln_projects { - max-width: 500px; -} -#group_activities { - float: left; -} -#group_about { - float: right; - width: 400px; - margin-right: 35px; -} -.group_content_header { - color: #7b95ad; - font-size: 12px; - white-space: nowrap; - padding: 0 0 2px 4px; - width: 100%; - border-bottom: 1px solid #bac7d4; - display: block; - margin-bottom: 10px; -} -.group_description { - padding-left: 4px; -} -.group_content_subheader { - display: block; - font-size: 18px; - height: 18px; - padding: 5px 0px 10px 0; - white-space: nowrap; -} -.group_header_add_search { - border-bottom: 1px solid #D6D4D5; - display: block; - font-size: 24px; - height: 35px; - padding: 10px 0px 5px 15px; -} -.group_header_add_search button { - margin-right: 10px; -} -.group_content { - display: block; - font-size: 12px; - line-height: 18px; - margin-bottom: 20px; -} -/****************************** - INDEX -*******************************/ -#group_invitations { - display: none; - font-size: 12px; - line-height: 1.4; - left: 0; - top: 25px; - padding: 10px; - position: absolute; - width: 230px; - z-index: 10; -} -#group_invitations span { - color: #69bfee; - font-weight: bold; -} -.group_invitations_options { - height: 20px; - padding: 10px 0; -} -.group_invitation_line { - padding: 6px 0 6px 0; -} -/* .group_invitation_line:last-of-type{ */ -/* border-bottom: 0 !important; */ -/* } */ -.invitation_count { - top: -2px; - padding: 1px 2px 1px 2px; - line-height: 1; - color: white; - background: #22a6ee; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; - position: relative; - text-align: right; -} -#group_show_invite { - font-size: 12px; - display: block; - position: relative; -} -.group_invite_wrap { - display: block; - float: left; - padding: 6px 0 0 0; - position: relative; -} -#group_show_invite:hover { - cursor: pointer; -} -#group_boxes { - margin-top: 10px; -} -#group_boxes label { - cursor: pointer; -} -#group_row_features, -#group_mini_features, -#group_maxi_features { - display: inline-block; - border: 1px solid transparent; -} -#group_row_features div, -#group_mini_features div, -#group_maxi_features div { - padding: 5px; - height: 20px; - border: 1px solid #DDD; - box-sizing: box-border; - line-height: 20px; - margin: 0; -} -#group_mini_features div, -#group_maxi_features div { - text-align: center; -} -#group_mini_features.active, -#group_maxi_features.active { - color: #69bfee; - border: 1px solid #69bfee; -} -tr.pair_row { - background: #DDD; -} -.group_join { - float: right; -} -button.group_join { - margin: 0; -} -button.group_join:active { - margin: 0; -} -a.group_join { - margin-right: 10px; - margin-top: 8px; -} -td.group_features { - padding: 10px; - text-align: center; -} -#group_table { - width: 100%; -} -#group_table td.features { - padding: 10px; -} -#group_table td.feature_header { - background-color: #374858; - color: #FFF; - height: 25px; - text-align: center; -} -#group_table td.mini_feature, -#group_table td.maxi_feature { - height: 20px; - text-align: center; - width: 100px; -} -#group_table td.cross { - color: #ad1c28; -} -#group_table td.check { - color: #bdca70; -} -#group_table td.mini_feature button, -#group_table td.maxi_feature button { - float: none; - text-align: center; -} -/****************************** - OVERVIEW -*******************************/ -.group_feed_date { - padding-right: 4px; - font-size: 11px; - text-align: right; - float: right; -} -.group_feed { - display: table; - margin-bottom: 15px; - padding: 0 0 6px 4px; - width: 100%; -} -.feed_line { - border-bottom: 1px solid #d9e1e8; -} -.group_feed_pic { - display: block; - float: left; - margin-right: 10px; - width: auto; -} -.group_feed_pic img { - border: 1px solid #bac7d4; -} -.group_feed_text { - display: inline-block; - vertical-align: top; -} -.group_feed_text b { - color: #3babe9; -} -.group_stats_row { - display: table-row; -} -.group_stats_elem { - display: table-cell; - font-weight: bold; - width: 10em; -} -.group_stats_num { - display: table-cell; - text-align: left; - width: 5em; -} -/****************************** - MEMBERS -*******************************/ -#group_members div.content_block { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} -#group_members a.group_treeline { - background: url("/static/img/design/t.png") repeat-y; - color: #4b6277; - cursor: pointer; - display: block; - height: 26px; - padding-left: 30px; - white-space: nowrap; - -webkit-box-sizing: border-box; - /* Safari/Chrome, other WebKit */ - -moz-box-sizing: border-box; - /* Firefox, other Gecko */ - box-sizing: border-box; - /* Opera/IE 8+ */ -} -#group_members a.group_treeline:hover { - background-color: #ecf0f3 !important; - text-decoration: none; -} -#group_members a.group_treeline span.name { - display: inline-block; - height: 26px; - line-height: 1.5; - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - width: 100%; -} -.tree_button button { - padding: 4px; - background: rgba(0, 0, 0, 0); - cursor: pointer; -} -/* #group_members .group_treeline:hover span.icon-user, */ -/* #group_members .group_treeline:hover span.icon-group, */ -/* #group_members .group_treeline:hover span.name{ */ -/* color: #69bfee; */ -/* } */ -/* #group_members a.group_treeline div.more_options_panel{ */ -/* margin-top: -5px; */ -/* } */ -.subgroup .menu_arrow-img { - position: absolute; - top: -11px !important; - left: 66px !important; -} -#group_members .more_options_panel .menu_arrow-img { - position: absolute; - top: -11px; - left: 100px; -} -#group_members a.group_treeline:last-of-type { - background: url("/static/img/design/l.png") no-repeat; - margin-top: -1px; -} -#group_members a.group_treeline div.tree_button { - float: right; - display: none; -} -#group_members a.group_treeline:hover div.tree_button { - display: inline; -} -#group_members div.group_treeline_children { - background: url("/static/img/design/straight.png") repeat-y; - padding-left: 34px; - margin-left: 0px; - box-sizing: border-box; -} -#group_members div.tree_my_eln_projects > div.group_treeline_children { - padding-left: 14px; -} -#group_members div.group_treeline_children:last-child { - background: url("/static/img/design/blank.png") repeat-y; -} -#group_members a.GROUP { - background-image: url("/static/img/design/blank.png") !important; - background-repeat: repeat-y !important; - font-size: 14px; - padding: 2px 8px 2px 4px; -} -#group_members a.GROUP span.name { - font-size: 14px; - height: 20px; - line-height: 1.5; -} -#group_members a.SUBGROUP { - padding: 2px 8px 2px 25px; -} -#group_members a.SUBGROUP span.icon-group { - font-size: 15px; - text-decoration: none; - line-height: 1.5; -} -#group_members a.SUBGROUP span.icon-group:before { - letter-spacing: 0.1em !important; -} -#group_members a.SUBGROUP span.name { - font-style: italic; -} -#group_members a.subgroup_selected { - background-color: #8ad97d !important; -} -#group_members a.MEMBER { - padding: 2px 8px 2px 25px; -} -#group_members a.MEMBER span.icon-user { - font-size: 14px; - line-height: 1; - padding-right: 2px; - text-decoration: none; -} -#group_members .droppable_group { - background-color: #e5ffe1 !important; -} -#group_members .hover_droppable_group { - background-color: #dde7ff !important; -} -/****************************** - PROJECTS -*******************************/ -.group_share_block { - display: none; -} -.group_share_member_tree { - background: white; - box-sizing: border-box; - max-height: 150px; - min-height: 70px; - overflow: auto; - padding: 10px; - margin-top: 10px; -} -.group_share_member_tree input[type=checkbox] { - vertical-align: middle; - position: relative; - bottom: 1px; -} -.group_share_member_tree a { - color: #374858; - line-height: 25px; - text-decoration: none; -} -.group_share_member_tree div.group_treeline_children { - padding-left: 15px; - margin-left: 0px; - box-sizing: border-box; -} -/****************************** - SETTINGS -*******************************/ -.group_settings { - float: right; -} -.group_settings_block { - background-color: white; - border: 1px solid #DDDDDD; - border-radius: 10px; - padding: 10px; - width: 595px; -} -.group_settings_block_key { - float: left; - font-size: 14px; - font-weight: bold; - line-height: 26px; - width: 200px; -} -.group_settings_block_value { - line-height: 26px; - font-size: 14px; - margin-left: 250px; -} -.group_settings_block_value input[type="text"], -.group_settings_block_value textarea { - width: 330px; -} -.group_settings_header h2 { - float: left; - margin: 5px 0 10px; -} -@media (max-width: 1200px) { - #group_about { - float: none; - margin-bottom: 60px; - } -} - -/**************************/ -/* i18n START */ -/**************************/ - -#i18n_translation_panel { - border: 1px solid black; - min-height: 150px; - background: #DDD; - position: fixed; - bottom: 0; - left: 75%; - right: 50px; - z-index: 10000; - font-family: 'Arial'; - padding: 10px; -} - -#i18n_translation_save_button { - width: 100%; - outline: none; - border: none; - color: #ffffff; - background: #69bfee; - height: 40px; - text-transform: uppercase; - cursor: pointer; - font-weight: bold; - transition: all ease-in 0.2s; -} - -#i18n_translation_save_button:hover { - background:#374858; -} - -#i18n_translation_save_button:active { - opacity: 0.8; - background:#374858; -} - -#i18n_translation_english_text { - padding: 15px; - display: block -} - -#i18n_translation_textarea { - padding: 10px; - width: 100%; - box-sizing: border-box; - margin-bottom: 10px; - font-size: 14px; -} - -.i18n_highlight.i18n_translation_untranslated { - color: #FF3D2B !important; -} - -.i18n_highlight.i18n_translation_translated { - color: #00AA00 !important; -} - -/**************************/ -/* i18n END */ -/**************************/@font-face { - font-family: 'LabFolderWebFont'; - src:url('../font/icons11.eot'); - src:url('../font/icons11.eot?#iefix') format('embedded-opentype'), - url('../font/icons11.svg#LabFolderWebFont') format('svg'), - url('../font/icons11.woff') format('woff'), - url('../font/icons11.ttf') format('truetype'); - font-weight: normal; - font-style: normal; -} - -/* Use the following CSS code if you want to use data attributes for inserting your icons */ -[data-icon]:before { - font-family: 'LabFolderWebFont'; - content: attr(data-icon); - speak: none; - font-weight: normal; - -webkit-font-smoothing: antialiased; -} - -/* Use the following CSS code if you want to have a class per icon */ -/* -Instead of a list of all class selectors, -you can use the generic selector below, but it's slower: -[class*="icon-"] { -*/ - -.icon-date, .icon-stop_contract, .icon-change_plan, .icon-update, .icon-add_notebook, .icon-sign, .icon-witness, .icon-checkbox, .icon-alert, .icon-speech, .icon-file, .icon-arrowhead, .icon-undo, .icon-text, .icon-selection, .icon-redo, .icon-rectangle, .icon-pencil, .icon-line, .icon-circle, .icon-asterisk, .icon-arrow, .icon-zoom_out, .icon-zoom_in, .icon-arrow_right, .icon-add_template, .icon-folder_selected, .icon-folder, .icon-add_group_notebook, .icon-add_group_folder, .icon-feedback, .icon-triangle_right, .icon-triangle_left, .icon-experiment3, .icon-add_folder, .icon-add_file, .icon-experiment2, .icon-triangle_down, .icon-sync, .icon-experiment1, .icon-edit_image, .icon-sign, .icon-search, .icon-edit, .icon-down_pdf, .icon-save, .icon-rename_proj, .icon-double_sign, .icon-double_arrow_right, .icon-remove, .icon-cross, .icon-copy, .icon-publish_to_world, .icon-publish_to_group, .icon-conf_drop, .icon-conf, .icon-print, .icon-notebook, .icon-check, .icon-back_up, .icon-template, .icon-invite_user, .icon-inventory, .icon-arrow_down, .icon-add_user, .icon-group_proj, .icon-group_folder_selected, .icon-add_text, .icon-add_proj, .icon-group_folder, .icon-group, .icon-add_notebook, .icon-forward, .icon-user_change, .icon-overview, .icon-user, .icon-add_img, .icon-drag_handle, .icon-add_protocol, .icon-save2, .icon-add_template2, .icon-add_entry, .icon-circle_arrow_down, .icon-arrow_up, .icon-expand, .icon-placeholder, .icon-dashboard, .icon-information { - font-family: 'LabFolderWebFont'; - speak: none; - font-style: normal; - font-weight: normal; - font-variant: normal; - text-transform: none; - line-height: 1; - -webkit-font-smoothing: antialiased; -} - - - -.icon-zoom_out:before { - content: "\e600"; -} -.icon-zoom_in:before { - content: "\e601"; -} -.icon-user_change:before { - content: "\e602"; -} -.icon-user:before { - content: "\e603"; -} -.icon-untitled12:before { - content: "\e604"; -} -.icon-undo:before { - content: "\e605"; -} -.icon-triangle_right:before { - content: "\e606"; -} -.icon-triangle_left:before { - content: "\e607"; -} -.icon-triangle_down:before { - content: "\e608"; -} -.icon-time:before { - content: "\e609"; -} -.icon-text:before { - content: "\e60a"; -} -.icon-template:before { - content: "\e60b"; -} -.icon-tell:before { - content: "\e60c"; -} -.icon-talk:before { - content: "\e60d"; -} -.icon-sync:before { - content: "\e60e"; -} -.icon-speech:before { - content: "\e60f"; -} -.icon-selection:before { - content: "\e610"; -} -.icon-search:before { - content: "\e611"; -} -.icon-save2:before { - content: "\e612"; -} -.icon-save:before { - content: "\e613"; -} -.icon-rename_proj:before { - content: "\e614"; -} -.icon-remove:before { - content: "\e615"; -} -.icon-redo:before { - content: "\e616"; -} -.icon-rectangle:before { - content: "\e617"; -} -.icon-raster:before { - content: "\e618"; -} -.icon-publish_to_world:before { - content: "\e619"; -} -.icon-publish_to_group:before { - content: "\e61a"; -} -.icon-print:before { - content: "\e61b"; -} -.icon-placeholder:before { - content: "\e61c"; -} -.icon-pencil:before { - content: "\e61d"; -} -.icon-overview:before { - content: "\e61e"; -} -.icon-outbox:before { - content: "\e61f"; -} -.icon-notebook:before { - content: "\e620"; -} -.icon-move_templ:before { - content: "\e621"; -} -.icon-move_folder:before { - content: "\e622"; -} -.icon-move_entr:before { - content: "\e623"; -} -.icon-man:before { - content: "\e624"; -} -.icon-lock_pen:before { - content: "\e625"; -} -.icon-line:before { - content: "\e626"; -} -.icon-invite_user:before { - content: "\e627"; -} -.icon-inventory:before { - content: "\e628"; -} -.icon-information:before { - content: "\e629"; -} -.icon-inbox:before { - content: "\e62a"; -} -.icon-group_proj:before { - content: "\e62b"; -} -.icon-group_folder_selected:before { - content: "\e62c"; -} -.icon-group_folder:before { - content: "\e62d"; -} -.icon-group:before { - content: "\e62e"; -} -.icon-forward:before { - content: "\e62f"; -} -.icon-folder_selected:before { - content: "\e630"; -} -.icon-folder:before { - content: "\e631"; -} -.icon-file:before { - content: "\e632"; -} -.icon-feedback:before { - content: "\e633"; -} -.icon-eye:before { - content: "\e634"; -} -.icon-experiment3:before { - content: "\e635"; -} -.icon-experiment2:before { - content: "\e636"; -} -.icon-experiment1:before { - content: "\e637"; -} -.icon-expand:before { - content: "\e638"; -} -.icon-edit_image:before { - content: "\e639"; -} -.icon-edit:before { - content: "\e63a"; -} -.icon-drag_handle:before { - content: "\e63b"; -} -.icon-down_pdf:before { - content: "\e63c"; -} -.icon-double_sign:before { - content: "\e63d"; -} -.icon-double_arrow_right:before { - content: "\e63e"; -} -.icon-delete_text:before { - content: "\e63f"; -} -.icon-delete_pen:before { - content: "\e640"; -} -.icon-date:before { - content: "\e641"; -} -.icon-dashboard:before { - content: "\e642"; -} -.icon-cross:before { - content: "\e643"; -} -.icon-copy:before { - content: "\e644"; -} -.icon-conf_drop:before { - content: "\e645"; -} -.icon-conf:before { - content: "\e646"; -} -.icon-clip:before { - content: "\e647"; -} -.icon-circle_arrow_down:before { - content: "\e648"; -} -.icon-circle:before { - content: "\e649"; -} -.icon-checkbox:before { - content: "\e64a"; -} -.icon-check:before { - content: "\e64b"; -} -.icon-back_up:before { - content: "\e64c"; -} -.icon-asterisk:before { - content: "\e64d"; -} -.icon-arrowhead:before { - content: "\e64e"; -} -.icon-arrow_up:before { - content: "\e64f"; -} -.icon-arrow_right:before { - content: "\e650"; -} -.icon-arrow_down:before { - content: "\e651"; -} -.icon-arrow:before { - content: "\e652"; -} -.icon-alert:before { - content: "\e653"; -} -.icon-alarm:before { - content: "\e654"; -} -.icon-add-date:before { - content: "\e655"; -} -.icon-add_user:before { - content: "\e656"; -} -.icon-add_text:before { - content: "\e657"; -} -.icon-add_template2:before { - content: "\e658"; -} -.icon-add_template:before { - content: "\e659"; -} -.icon-add_speech:before { - content: "\e65a"; -} -.icon-add_proj:before { - content: "\e65b"; -} -.icon-add_note:before { - content: "\e65c"; -} -.icon-add_label:before { - content: "\e65d"; -} -.icon-add_img:before { - content: "\e65e"; -} -.icon-add_folder:before { - content: "\e65f"; -} -.icon-add_file:before { - content: "\e660"; -} -.icon-add_entry:before { - content: "\e661"; -} -.icon-add_notebook:before { - content: "\e662"; -} -.icon-sign:before { - content: "\e663"; -} -.icon-witness:before { - content: "\e664"; -} -.icon-update:before { - content: "\e667"; -} -.icon-change_plan:before { - content: "\e665"; -} -.icon-stop_contract:before { - content: "\e666"; -} - - -/*Letter spacing grouping*/ - - -.icon-checkbox:before { - letter-spacing:0.3em; -} -.icon-speech:before { - letter-spacing:0.5em; -} -.icon-alert:before { - letter-spacing:0.3em; -} -.icon-publish_to_world:before { - letter-spacing:0.5em; -} -.icon-publish_to_group:before { - letter-spacing:0.5em; -} -.icon-invite_user:before { - letter-spacing:0.5em; -} -.icon-inventory:before { - letter-spacing: 0.5em; -} -.icon-group_proj:before { - letter-spacing: 0.5em; -} -.icon-group_folder_selected:before { - letter-spacing:0.5em; -} -.icon-group_folder:before { - letter-spacing: 0.5em; -} -.icon-group:before { - letter-spacing:0.5em; -} -.icon-copy:before{ - letter-spacing:0.5em; -} -.icon-conf_drop:before { - letter-spacing: 0em; -} -.icon-check:before { - letter-spacing:0.5em; -} -.icon-add_user:before { - letter-spacing:0.5em; -} -.icon-add_text:before { - letter-spacing:0.5em; -} -.icon-add_proj:before { - letter-spacing:0.5em; -} -.icon-add_notebook:before { - letter-spacing:0.5em; -} -.icon-add_template:before { - letter-spacing:0.5em; -} -.icon-add_img:before { - letter-spacing:0.5em; -} -.icon-add_group_proj:before { - letter-spacing:0.5em; -} -.icon-add_group_folder:before { - letter-spacing:0.5em; -} -.icon-add_folder:before { - letter-spacing:0.5em; -} -.icon-add_file:before { - letter-spacing:0.5em; -} -.icon-overview:before { - letter-spacing:0.5em; -} -.icon-add_protocol:before { - letter-spacing:0.5em; -} -.icon-add_template2:before { - letter-spacing:0.5em; -} -.icon-add_entry:before { - letter-spacing:0.5em; -} -.icon-update:before { - letter-spacing:0.5em; -} -.icon-change_plan{ - letter-spacing:0.5em; -} -.icon-stop_contract{ - letter-spacing:0.5em; -} -/**********************/ -/* image marker START */ -/**********************/ -/************** -* basic.css * -**************/ -/********** -* colors * -***********/ -/********** -* helper * -***********/ -.list_vertical > ul { - margin: 0; - padding: 0; -} -.list_vertical > ul li { - list-style-type: none; -} -.list_horizontal > ul { - margin: 0; - padding: 0; -} -.list_horizontal > ul > li { - list-style-type: none; - float: left; - position: relative; -} -/************* -* functions * -**************/ -/****** -* css * -******/ -body { - color: #374858; -} -.clearfix:after { - content: " "; - visibility: hidden; - display: block; - height: 0; - clear: both; -} -#image_marker_tools { - background: #FFF; - border: 0; - -webkit-box-shadow: 0 2px 4px rgba(55, 72, 88, 0.3); - -moz-box-shadow: 0 2px 4px rgba(55, 72, 88, 0.3); - box-shadow: 0 2px 4px rgba(55, 72, 88, 0.3); - display: block; - height: 40px; - left: 0; - position: absolute; - right: 0; - top: 30px; - z-index: 95; -} -.image_marker_btn_group { - display: inline-block; - height: 30px; - margin: 5px 10px 5px 10px; - position: relative; - vertical-align: middle; - white-space: nowrap; -} -#more_options_image_marker, -#image_marker_zoom, -#image_marker_edition { - float: right; -} -button.image_marker_button { - border-radius: 0; - background-color: #FFF; - border: 1px solid transparent; - color: #374858; - cursor: pointer; - display: inline-block; - font-size: 14px; - height: 30px; - line-height: 20px; - margin-bottom: 0; - margin-left: -1px; - padding: 4px 10px; - position: relative; - text-align: center; - vertical-align: middle; - -webkit-box-sizing: border-box; - /* Safari/Chrome, other WebKit */ - -moz-box-sizing: border-box; - /* Firefox, other Gecko */ - box-sizing: border-box; - /* Opera/IE 8+ */ -} -button.image_marker_delete_disabled, -button.image_marker_delete_disabled:hover { - color: #5e7b97 !important; - cursor: default !important; - z-index: 5; -} -button.image_marker_button:hover { - background: #f3f5f7; -} -button.image_marker_button_active { - border: 1px solid #69bfee; - z-index: 5; -} -div.image_marker_toolbar_label { - display: inline-block; - height: 30px; - padding: 0 5px; - text-align: center; -} -div.image_marker_options { - background: #FFF; - display: none; - line-height: 30px; - margin-top: 5px; - padding: 5px; - position: absolute; - z-index: 25; -} -#image_marker_toolbar_list, -#image_marker_opacity_list, -#image_marker_stroke_size_list, -#image_marker_font_size_list { - margin: 0; - padding: 0; - position: relative; - overflow: hidden; -} -li.image_marker_size_options { - border-top: none; - cursor: pointer; - display: list-item; - line-height: 15px; - list-style: none; - margin: 0; - padding: 8px 0; - text-align: center; -} -li.image_marker_size_options:hover { - background: #f3f5f7; -} -#image_marker_size_user_input input { - background: #f9fafb; - border: 1px solid #d9e1e8; - height: 25px; - -webkit-box-sizing: border-box; - /* Safari/Chrome, other WebKit */ - -moz-box-sizing: border-box; - /* Firefox, other Gecko */ - box-sizing: border-box; - /* Opera/IE 8+ */ - margin: 0 0 5px; - outline: none; - text-align: center; - width: 50px; -} -#image_marker_size_drop_down { - -webkit-box-sizing: border-box; - /* Safari/Chrome, other WebKit */ - -moz-box-sizing: border-box; - /* Firefox, other Gecko */ - box-sizing: border-box; - /* Opera/IE 8+ */ - background: none repeat scroll 0 0 #FFFFFF; - -webkit-box-shadow: 0 2px 4px rgba(55, 72, 88, 0.3); - -moz-box-shadow: 0 2px 4px rgba(55, 72, 88, 0.3); - box-shadow: 0 2px 4px rgba(55, 72, 88, 0.3); - margin-left: -2px; - position: absolute; - width: 60px; - z-index: 1010; -} -#image_marker_stroke_color_box { - background: #F00; - border: 1px solid #AAA; - display: inline-block; - height: 20px; - width: 20px; -} -#image_marker_stroke_empty_box { - height: 14px; - margin: 3px; - width: 14px; -} -div.image_marker_options.image_marker_stroke_color_options { - left: 65px; -} -#image_marker_stroke_color_list { - list-style-type: none; - width: 100px; - padding: 0; - margin: 0; - z-index: 99; -} -li.image_marker_stroke_color_options { - float: left; - margin: 0; -} -li.image_marker_stroke_color_options a { - background: url(/static/img/transparent_bg.png); - display: block; - width: 20px; - height: 20px; - text-decoration: none; - text-indent: -100000px; - outline: 0; - border: none; - -webkit-box-sizing: border-box; - /* Safari/Chrome, other WebKit */ - -moz-box-sizing: border-box; - /* Firefox, other Gecko */ - box-sizing: border-box; - /* Opera/IE 8+ */ -} -#image_marker_fill_color_box { - background: url('/static/img/transparent_color.png'); - border: 1px solid #9baec0; - display: inline-block; - height: 20px; - width: 20px; -} -div.image_marker_options.image_marker_fill_color_options { - left: 65px; -} -#image_marker_fill_color_list { - list-style-type: none; - width: 100px; - padding: 0; - margin: 0; - z-index: 99; -} -li.image_marker_fill_color_options { - float: left; - margin: 0; -} -li.image_marker_fill_color_options a { - display: block; - width: 20px; - height: 20px; - text-decoration: none; - text-indent: -100000px; - outline: 0; - border: none; -} -li.image_marker_opacity_options { - border: 1px solid #5e7b97; - border-top: none; - cursor: pointer; - display: list-item; - line-height: 15px; - list-style: none; - margin: 0; - padding: 5px 0; - text-align: center; -} -li.image_marker_opacity_options:first-of-type { - border-top: 1px solid #5e7b97; -} -li.image_marker_opacity_options:hover { - color: #69bfee; -} -#image_marker_opacity_drop_down { - -webkit-box-sizing: border-box; - /* Safari/Chrome, other WebKit */ - -moz-box-sizing: border-box; - /* Firefox, other Gecko */ - box-sizing: border-box; - /* Opera/IE 8+ */ - background: none repeat scroll 0 0 #FFFFFF; - box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15); - position: absolute; - right: 0; - width: 60px; - z-index: 1010; -} -li.image_marker_toolbar_options { - border-top: none; - cursor: pointer; - display: list-item; - line-height: 15px; - list-style: none; - margin: 0; - padding: 8px; - text-align: left; -} -li.image_marker_toolbar_options:hover { - background: #f9fafb; -} -#image_marker_toolbar_drop_down { - -webkit-box-sizing: border-box; - /* Safari/Chrome, other WebKit */ - -moz-box-sizing: border-box; - /* Firefox, other Gecko */ - box-sizing: border-box; - /* Opera/IE 8+ */ - background: #e6ebef; - box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15); - top: 30px; - padding: 10px 0 10px 0; - position: absolute; - right: 0; - z-index: 1010; -} -#image_marker_toolbar_drop_down:after { - top: -11px; - right: 16px; - border: solid rgba(0, 0, 0, 0); - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - border-color: rgba(136, 183, 213, 0); - border-bottom-color: #e9edf1; - border-width: 7px; - margin-left: -3px; -} -.image_marker_options button.image_marker_button { - display: block; - width: 60px; - margin-top: -1px; -} -.image_marker_toolbar_label span { - vertical-align: middle; -} -/* .image_marker_settings{ */ -/* position:absolute; */ -/* background:#FFF; */ -/* width:100%; */ -/* height:50px; */ -/* overflow:auto; */ -/* display: block; */ -/* } */ -/* .image_marker_settings h4{ */ -/* padding: 0; */ -/* margin: 0; */ -/* text-decoration: underline; */ -/* margin-bottom: 10px; */ -/* } */ -#image_marker_settings button { - width: 55px; - padding-left: 0px; -} -#image_marker_settings span.icon-triangle_down { - font-size: 8px; - position: absolute; - right: 5px; - top: 14px; - vertical-align: top; -} -.image_marker_tools { - margin-bottom: 25px; -} -.image_marker_tools input:checked + label { - font-weight: bold; -} -.image_marker_options_name { - float: left; - width: 75px; - margin-bottom: 20px; -} -.image_marker_canvasview { - background: url(/static/img/transparent_bg.png); - position: absolute; - bottom: 0; - top: 70px; - left: 0; - right: 0; - overflow: auto; -} -.image_marker_pointer_cursor { - cursor: pointer; -} -.image_marker_text_cursor { - cursor: text; -} -#image_marker_canvaslayer { - position: absolute; - display: block; - z-index: 15; -} -#image_marker_canvastextarea { - background: rgba(255, 255, 255, 0.7); - border: none; - display: none; - font-family: sans-serif; - outline: none; - overflow: hidden; - position: absolute; - padding: 5px; - transition-property: width, height; - transition: 0.2s ease; - white-space: pre; - z-index: 2; -} -#image_marker_canvasframe { - position: relative; - -webkit-user-select: none; - /*Chrome all / Safari all*/ - -moz-user-select: none; - /*Firefox all*/ - -ms-user-select: none; - /*IE 10+*/ -} -#canvas_textarea_span { - font-family: sans-serif; - line-height: normal; - display: none; - color: white; - position: absolute; - padding: 5px; - word-wrap: normal; - white-space: nowrap; -} -.image_marker_notification { - display: none; - position: absolute; - left: 50%; - top: 50%; - width: 100px; - margin-left: -50px; - padding: 10px; - color: #fff; - font-size: 32; - text-align: center; - box-shadow: 4px 4px 5px #666; -} -#savingBox { - background: #ddb933; - z-index: 10; -} -#savedBox { - background: #bdca70; - z-index: 15; -} -#errorBox { - background-color: #E66873; -} -.image_marker_tooltip { - display: none; - background-color: #FFF; - border: 1px solid #9baec0; - color: #5e7b97; - font-size: 12px; - padding: 5px; - position: absolute; - top: 35px; - z-index: 100; -} -.image_marker_button:hover .image_marker_tooltip { - display: block; -} -#image_marker_popup { - z-index: 95; -} -#image_marker_popup_window { - z-index: 97; -} -/********************/ -/* image marker END */ -/********************/ - -/************** -* basic.css * -**************/ -/********** -* colors * -***********/ -/********** -* helper * -***********/ -.list_vertical > ul { - margin: 0; - padding: 0; -} -.list_vertical > ul li { - list-style-type: none; -} -.list_horizontal > ul { - margin: 0; - padding: 0; -} -.list_horizontal > ul > li { - list-style-type: none; - float: left; - position: relative; -} -/************* -* functions * -**************/ -/****** -* css * -******/ -body { - color: #374858; -} -.clearfix:after { - content: " "; - visibility: hidden; - display: block; - height: 0; - clear: both; -} -#import_header { - border-bottom: 1px solid #DDD; - height: 50px; -} -#import_header .placeholder_frame { - display: inline-block; - float: right; - margin: 10px 10px 10px 0; -} -#import_header .placeholder_frame label { - width: 150px; -} -#import_loading { - position: absolute; - top: 50%; - left: 50%; - text-align: center; - width: 80px; - height: 80px; - margin-top: -40px; - margin-left: -40px; -} -.import_popup_content { - height: 100%; - position: relative; - width: 100%; -} -#import_container { - position: absolute; - left: 0; - right: 0; - top: 80px; - bottom: 60px; - overflow: auto; -} -#import_container ul { - padding-right: 40px; -} -#import_container li { - display: inline-block; - overflow: hidden; - width: 100%; -} -#import_container li > div { - border: 1px solid transparent; - position: relative; - cursor: pointer; - margin: 0 5px; - padding: 10px; - font-size: 18px; -} -#import_container .active > div { - background: #ededed; - font-weight: bold; - border: 1px solid #69bfee; - color: #69bfee; -} -#import_container li > div:hover { - border: 1px solid #69bfee; - color: #69bfee; -} -#import_container div > span { - position: absolute; - left: 10px; -} -#import_container div.info { - margin-left: 30px; -} -.info img { - width: 20px; - margin-left: 5px; - position: absolute; -} -#import_container .info div { - display: block; - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; -} -#import_container .figshare_main_search { - left: 50%; - margin: -40px 0 0 -200px; - position: absolute; - height: 80px; - text-align: center; - top: 50%; - width: 400px; -} -#import_container .figshare_main_search input { - width: 400px; -} -#import_container h3, -#import_container .load_more { - font-weight: normal; - text-align: center; -} -#import_footer { - position: absolute; - bottom: 0; - height: 60px; - left: 0; - border-top: 1px solid #DDD; - right: 0; -} -#import_footer .popup_dialog_cancel_save_panel { - position: absolute; - bottom: 15px; - right: 15px; -} -#import_footer .select_file { - float: left; - font-size: 12px; -} -#import_footer .popup_dialog_error { - margin: 15px 150px; -} -#breadcrumbs { - position: absolute; - left: 0; - right: 200px; - font-size: 18px; - padding: 15px; -} -div.import_source, -div.export_source { - height: 180px; - width: 800px; -} -div.import_logo, -div.export_logo { - /* display: inline-block; */ - float: left; - width: 130px; - height: 130px; -} -.upload_btn_wrap { - margin: 55px 20px; -} -.upload_btn_wrap .btn_on_grey { - height: 50px; - width: 112px; - padding-left: 8px; -} -.import_logo img, -.export_logo img { - cursor: pointer; - border: 1px solid transparent; - background: #ffffff; - width: 100%; - -webkit-transition: all 0.1s ease; - -moz-transition: all 0.1s ease; - -o-transition: all 0.1s ease; - transition: all 0.1s ease; -} -.import_logo img:hover, -.export_logo img:hover { - border: 1px solid #bac7d4; -} -.import_logo_set, -.export_logo_set { - line-height: 18px; - text-align: center; -} -.dropbox_folder_view { - box-shadow: 0px 0px 10px #AAA; - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; - max-height: 150px; - overflow-x: hidden; - overflow-y: auto; - padding: 0 10px; - margin-top: 10px; -} -.dropbox_folder_view ul { - margin: 0; - padding: 10px 0; -} -.dropbox_folder_view .name { - margin-left: 10px; -} -.dropbox_folder_view .folder { - border: 1px solid transparent; - cursor: pointer; - display: inline-block; - padding: 2px; - overflow: hidden; - width: 100%; -} -.dropbox_folder_view .folder:hover { - border: 1px solid #69bfee; - color: #69bfee; -} - -/************** -* basic.css * -**************/ -/********** -* colors * -***********/ -/********** -* helper * -***********/ -.list_vertical > ul { - margin: 0; - padding: 0; -} -.list_vertical > ul li { - list-style-type: none; -} -.list_horizontal > ul { - margin: 0; - padding: 0; -} -.list_horizontal > ul > li { - list-style-type: none; - float: left; - position: relative; -} -/************* -* functions * -**************/ -/****** -* css * -******/ -body { - color: #374858; -} -.clearfix:after { - content: " "; - visibility: hidden; - display: block; - height: 0; - clear: both; -} -#mendeley_auth { - background-color: #FFF; - border: 0; - border-radius: 5px; - height: 335px; - left: 50%; - margin: -155px 0 0 -235px; - outline: none; - overflow: hidden; - position: absolute; - top: 240px; - width: 470px; -} -.mendeley_auth_header { - text-align: center; -} -#my_popup_inner.mendeley_popup { - transition: all ease 1s; - overflow: hidden; -} -#mendeley_loading { - position: absolute; - top: 50%; - left: 50%; - text-align: center; - width: 80px; - height: 80px; - margin-top: -40px; - margin-left: -40px; -} -.reference_files_loading { - width: 20px; -} -.mendeley_library_loading { - position: absolute; - left: 41%; - text-align: center; - top: 35%; - font-size: 20px; -} -.mendeley_files_loading { - width: 20px; - margin-bottom: -4px; -} -.mendeley_popup_content { - height: 100%; - position: relative; - width: 100%; -} -#mendeley_library_view { - display: inline-block; - position: absolute; - width: 100%; - transition: all ease 0.5s; -} -.mendeley_library_progress { - display: none; - margin: 15px 0 0 15px; -} -.mendeley_loaded { - margin-left: 15px; -} -#mendeley_library_header .placeholder_frame { - float: right; - margin: 10px 10px 10px 0; -} -#mendeley_library_header .placeholder_frame label { - width: 150px; -} -#mend_lib_table { - width: 100%; -} -#mend_headers { - width: 100%; - height: 24px; - outline: 1px solid #DDD; - line-height: 24px; -} -#mend_headers th:hover { - color: #69bfee; -} -tr.mend_table_row_pair, -tr.mend_table_row { - display: block; - padding: 10px 0; - width: 100%; - min-height: 18px; -} -tr.mend_table_row:hover { - color: #69bfee; - outline: 1px solid #69bfee; - cursor: pointer; -} -tr.mend_table_row_pair { - background-color: #DDD; -} -#mend_headers th { - cursor: pointer; - display: inline-block; - -webkit-user-select: none; - /* Chrome all / Safari all */ - -moz-user-select: none; - /* Firefox all */ - -ms-user-select: none; - /* IE 10+ */ -} -td.mend_added, -td.mend_year { - text-align: center; -} -span.highlight { - background-color: yellow; -} -td.mend_author span { - margin-left: 10px; -} -td.mend_author, -#mend_header_author { - width: 25%; -} -td.mend_title { - width: 40%; -} -#mend_header_title { - width: 39%; -} -td.mend_year, -#mend_header_year { - width: 5%; -} -td.mend_published, -#mend_header_published { - text-align: center; - width: 15%; -} -td.mend_added, -#mend_header_added { - width: 10%; -} -#mend_lib_table_body { - overflow-x: hidden; - overflow-y: scroll; - height: 600px; - display: block; -} -#mend_lib_table th, -#mend_lib_table td { - display: inline-block; - height: 100%; -} -.placeholder_frame label { - pointer-events: none; -} -.epb_header_sticky div.action_button_import { - margin-left: 0px !important; -} -#mendeley_detail_view { - display: inline-block; - left: 100%; - position: absolute; - width: 100%; - height: 100%; - transition: all ease 0.5s; -} -#mendeley_detail_view div.popup_dialog_cancel_save_panel { - bottom: 25px; - left: 50px; - padding: 20px 0; - position: absolute; - right: 15px; -} -#mendeley_back_to_library { - background-color: #DDD; - cursor: pointer; - display: inline-block; - font-size: 30px; - height: 100%; - padding-right: 5px; - position: absolute; -} -#mendeley_back_to_library span { - margin-left: 5px; - top: calc(20%); - position: relative; -} -#mendeley_detail_page { - bottom: 30px; - display: inline-block; - left: 50px; - overflow: auto; - padding: 0 20px 20px 0; - position: absolute; - right: 0px; - top: 0px; -} -.reference_detail_label { - font-weight: bold; - margin-right: 5px; -} -button.mend_add_reference { - float: right !important; -} -div.mend_file_line { - height: 40px; - line-height: 30px; - padding-left: 20px; -} -.mend_file_line button { - margin-left: 20px; -} -.doc_details { - margin: 10px 0; -} -span.mend { - white-space: pre; -} - -/****************************** - MESSAGE LIST VIEW -*******************************/ -/************** -* basic.css * -**************/ -/********** -* colors * -***********/ -/********** -* helper * -***********/ -.list_vertical > ul { - margin: 0; - padding: 0; -} -.list_vertical > ul li { - list-style-type: none; -} -.list_horizontal > ul { - margin: 0; - padding: 0; -} -.list_horizontal > ul > li { - list-style-type: none; - float: left; - position: relative; -} -/************* -* functions * -**************/ -/****** -* css * -******/ -body { - color: #374858; -} -.clearfix:after { - content: " "; - visibility: hidden; - display: block; - height: 0; - clear: both; -} -#messages_header { - background: #EEE; - border-bottom: 1px solid #D6D4D5; - border-radius: 10px 10px 0 0; - display: block; - font-size: 14px; - height: 25px; - padding: 10px 0px 5px 15px; -} -#messages_content { - max-width: 900px; - padding-left: 10px; - display: block; - line-height: 18px; - overflow: auto; -} -.message_page_change { - box-sizing: border-box; - cursor: pointer; - display: inline-block; - width: 30px; - text-align: center; - font-size: 22px; - margin: 0; - line-height: 0.6; - height: 17px; - margin-top: 4px; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; -} -.message_pagination, -.message_total, -.message_shown { - font-size: 11px; -} -.message_pagination { - position: relative; - float: left; -} -.pagination_count { - float: left; - position: relative; - width: auto; - margin-right: 20px; - padding-top: 7px; -} -.message_page_change.disabled { - color: #4b6277; - cursor: default; -} -.message_empty_folder { - padding: 50px; - text-align: center; - font-size: 12px; -} -.message_list { - font-size: 14px; -} -.message_list table { - border-collapse: collapse; - outline: none; - table-layout: fixed; - width: 100%; - position: relative; -} -.message_list table td { - line-height: 1.2; - position: relative; -} -.column_name { - min-width: 100px; - width: 25%; -} -.column_delete { - width: 30px; -} -.column_date { - width: 89px; -} -.message_list_line { - font-size: 12px; - border-bottom: 1px solid #bac7d4; - cursor: pointer; - height: 34px; - line-height: 1.2; - white-space: nowrap; -} -.message_list_line:last-child { - border: none; -} -.message_list_line:hover .message_line_delete { - display: block; -} -.message_list_line:hover { - background: #ecf0f3; -} -.message_list_line:first-child:hover { - background: none; - cursor: default; -} -.unread_message { - font-weight: bold; -} -.unread_message .message_line_name:after { - content: ""; - width: 4px; - height: 4px; - border-radius: 50%; - background: #69bfee; - position: absolute; - left: -4px; - top: 14px; -} -.message_line_name { - white-space: nowrap; - text-overflow: ellipsis; - vertical-align: bottom; - overflow: hidden; - padding-left: 4px; -} -.message_line_text { - overflow: hidden; - text-overflow: ellipsis; -} -.message_line_content { - color: #9baec0; -} -.message_line_delete { - display: none; - text-align: center; -} -.message_line_delete .trash-img { - margin-top: -4px; -} -.message_line_delete:hover { - color: #4bb1d7; - text-align: center; -} -.message_line_date { - padding-right: 10px; - font-size: 11px; -} -.filter_dn_wrap { - width: 190px; - height: 200px; - position: absolute; - left: 0; - top: 25px; - z-index: 999; - display: none; -} -/****************************** - MESSAGE DIALOG VIEW -*******************************/ -#dialog_message_form div.input_block { - margin: 0; - padding: 3px 5px; -} -.message_content { - margin-top: 10px !important; - background: white; - color: #4b6277; - min-height: 150px; -} -#message_select_group { - margin: 0 0 10px 0; -} -#dialog_message_form .recipient_label { - display: inline-block; - vertical-align: top; - width: 22px; - padding: 5px 0 0 0; - margin-bottom: 5px; -} -#dialog_message_form .recipient_field { - cursor: text; - display: inline-block; - min-height: 33px; - width: 700px; -} -#dialog_message_form .add_recipient { - cursor: pointer; - display: inline-block; - margin-bottom: 5px; - padding: 5px 0 0 0; - vertical-align: top; - width: 20px; -} -#dialog_message_form .add_recipient.disabled { - cursor: default; - color: #bac7d4; -} -#recipientIds, -#recipientEmails { - display: none; -} -#dialog_message_form .recipient_token { - background: #f9fafb; - border: 1px solid #7b95ad; - border-radius: 3px; - cursor: move; - height: 25px; - width: auto; - display: inline-block; - padding: 5px; - margin: 0px 6px 0 0; -} -#dialog_message_form .recipient_token.selected { - border: 1px solid #4bb1d7 !important; -} -#dialog_message_form .recipient_token.invalid { - border: 1px solid #E66873; - color: #E66873; -} -#dialog_message_form .name_token { - display: inline-block; - line-height: 14px; - height: auto; - margin-right: 5px; - max-width: 250px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} -#dialog_message_form .erase_token { - cursor: pointer; - display: inline-block; - vertical-align: top; -} -#dialog_message_form .message_recipient textarea, -#recipient_width { - border: 1px solid rgba(0, 0, 0, 0); - display: inline-block; - font-size: 12px; - font-family: arial, sans-serif; - color: #4b6277; - height: 26px; - line-height: 12px; - outline: none; - padding: 6px; - resize: none; - vertical-align: bottom; - overflow: hidden; -} -#recipient_width { - display: none; -} -#dialog_message_form .message_content { - max-height: 450px; - overflow: auto; -} -#dialog_message_form .message_content textarea { - display: block; - font-size: 14px; - color: #4b6277; - height: 200px; - margin: 0; - resize: none; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -#dialog_message_form .placeholder_frame { - float: none; - width: 100%; -} -.recipient_tree { - display: none; - position: relative; - background: #ecf0f3; - box-sizing: border-box; - max-height: 150px; - overflow: auto; - padding: 0 10px; - margin-bottom: 10px; - font-size: 12px; -} -.recipient_tree a { - color: #4b6277; - line-height: 25px; - text-decoration: none; -} -.recipient_tree div.group_treeline_children { - padding-left: 15px; - margin-left: 0px; - box-sizing: border-box; -} -.recipient { - line-height: 24px; -} -.recipient:after { - content: ", "; -} -.recipient:last-child:after { - content: ""; -} -.message_subject { - font-weight: bold; -} -.member_input { - vertical-align: middle; - position: relative; - bottom: 1px; -} - -/**************** -* notebook.less * -*****************/ -/************** -* basic.css * -**************/ -/********** -* colors * -***********/ -/********** -* helper * -***********/ -.list_vertical > ul { - margin: 0; - padding: 0; -} -.list_vertical > ul li { - list-style-type: none; -} -.list_horizontal > ul { - margin: 0; - padding: 0; -} -.list_horizontal > ul > li { - list-style-type: none; - float: left; - position: relative; -} -/************* -* functions * -**************/ -/****** -* css * -******/ -body { - color: #374858; -} -.clearfix:after { - content: " "; - visibility: hidden; - display: block; - height: 0; - clear: both; -} -#action_buttons { - display: inline-block; - float: right; - height: 250px; - left: 50%; - margin-left: 410px; - position: fixed; - top: 110px; - width: 150px; -} -/**************** -* button + input* -****************/ -button { - border: 0; - font-size: 12px; - padding: 3px 4px; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; -} -button:focus { - opacity: 1; - -ms-filter: none; - filter: none; - outline: 0; -} -.search_button { - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; - border: solid 1px #bac7d4 !important; -} -.btn_on_grey { - color: #415568; - background: #f3f5f7; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #e0e6eb), color-stop(1, #f3f5f7)); - background: -ms-linear-gradient(bottom, #e0e6eb, #f3f5f7); - background: -moz-linear-gradient(center bottom, #e0e6eb 0%, #f3f5f7 100%); - background: -o-linear-gradient(#f3f5f7, #e0e6eb); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f3f5f7', endColorstr='#e0e6eb', GradientType=0); - border: 1px solid #7b95ad; - line-height: 1.2; -} -.btn_on_grey:hover { - color: #415568; - background: #f3f5f7; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #e0e6eb), color-stop(1, #f3f5f7)); - background: -ms-linear-gradient(bottom, #e0e6eb, #f3f5f7); - background: -moz-linear-gradient(center bottom, #e0e6eb 0%, #f3f5f7 100%); - background: -o-linear-gradient(#f3f5f7, #e0e6eb); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f3f5f7', endColorstr='#e0e6eb', GradientType=0); - outline: 0; - border: 1px solid #5e7b97; - -webkit-box-shadow: 0 0 8px rgba(255, 255, 255, 0.5); - -moz-box-shadow: 0 0 8px rgba(255, 255, 255, 0.5); - box-shadow: 0 0 8px rgba(255, 255, 255, 0.5); -} -.btn_on_grey:active { - color: #4b6277; - outline: 0; - -webkit-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.2); - -moz-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.2); - box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.2); - border: 1px solid #4b6277; - background: #cad4de; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #e0e6eb), color-stop(1, #cad4de)); - background: -ms-linear-gradient(bottom, #e0e6eb, #cad4de); - background: -moz-linear-gradient(center bottom, #e0e6eb 0%, #cad4de 100%); - background: -o-linear-gradient(#cad4de, #e0e6eb); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#cad4de', endColorstr='#e0e6eb', GradientType=0); -} -.btn_on_white { - color: #4b6277; - background: #e6ebef; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #d9e1e8), color-stop(1, #e6ebef)); - background: -ms-linear-gradient(bottom, #d9e1e8, #e6ebef); - background: -moz-linear-gradient(center bottom, #d9e1e8 0%, #e6ebef 100%); - background: -o-linear-gradient(#e6ebef, #d9e1e8); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#e6ebef', endColorstr='#d9e1e8', GradientType=0); - border: 1px solid #cad4de; - opacity: 1; - line-height: 13px; -} -.btn_on_white:hover:enabled { - -ms-filter: none; - filter: none; - outline: 0; - border: 1px solid #b4c2d0; -} -.btn_on_white:active { - color: #4b6277; - -ms-filter: none; - filter: none; - outline: 0; - -webkit-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.2); - -moz-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.2); - box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.2); - border: 1px solid #c7d2dc; - background: #d9e1e8; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #d9e1e8), color-stop(1, #d0d9e2)); - background: -ms-linear-gradient(bottom, #d9e1e8, #d0d9e2); - background: -moz-linear-gradient(center bottom, #d9e1e8 0%, #d0d9e2 100%); - background: -o-linear-gradient(#d0d9e2, #d9e1e8); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#d0d9e2', endColorstr='#d9e1e8', GradientType=0); -} -.btn_on_white.disabled { - opacity: 0.6; -} -.btn_on_white.disabled:active { - color: #4b6277; - -ms-filter: none; - filter: none; - outline: 0; - -webkit-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0); - -moz-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0); - box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0); - border: 1px solid #cad4de; - background: #e6ebef; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #d9e1e8), color-stop(1, #e6ebef)); - background: -ms-linear-gradient(bottom, #d9e1e8, #e6ebef); - background: -moz-linear-gradient(center bottom, #d9e1e8 0%, #e6ebef 100%); - background: -o-linear-gradient(#e6ebef, #d9e1e8); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#e6ebef', endColorstr='#d9e1e8', GradientType=0); -} -.btn_on_white.disabled:hover { - -ms-filter: none; - filter: none; - outline: 0; - border: 1px solid #cad4de; -} -.filter_btn { - color: #526c84; - background: #ecf0f3; - height: 24px; - padding: 2px 8px; - font-size: 12px; - cursor: pointer; - -webkit-border-radius: 0px; - -moz-border-radius: 0px; - border-radius: 0px; - -webkit-transition: all 0.1s ease; - -moz-transition: all 0.1s ease; - -o-transition: all 0.1s ease; - transition: all 0.1s ease; -} -.filter_btn > span { - height: 4px; - width: 12px; - display: block; - float: left; - margin: 2px 0 0 8px; -} -.filter_btn > p { - margin: 0; - float: left; -} -.filter_btn:hover { - -webkit-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.1); - -moz-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.1); - box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.1); - background: #e0e6eb; - padding-top: 2px; -} -.filter_btn:active { - -webkit-box-shadow: inset 0 1px 2px rgba(55, 72, 88, 0.2); - -moz-box-shadow: inset 0 1px 2px rgba(55, 72, 88, 0.2); - box-shadow: inset 0 1px 2px rgba(55, 72, 88, 0.2); - background: #cdd7e0; -} -span.close-x { - display: block; - float: left; - margin: 0 0 0 8px; - display: none; -} -.filter_on { - background: #527ca3; - color: white; -} -.filter_on:hover, -.filter_on:active { - background: #527ca3; - color: #e0e6eb; -} -.filter_active { - background: #5b96cd; - color: #ffffff; -} -.filter_active .arrow_down_s-img:after { - border-top-color: white; -} -.filter_active:hover { - background: #5b96cd; - color: #e6ebef; -} -.grey_link { - color: #4b6277; - background: transparent; - font-size: 12px; - padding: 0; - text-decoration: underline; - display: block; - cursor: pointer; -} -.grey_link:hover { - color: #415568; - text-decoration: underline; -} -.grey_link:active { - text-decoration: none; -} -.blue_link { - color: #1995d8; - background: transparent; - font-size: 12px; - padding: 0; - text-decoration: underline; - display: block; - cursor: pointer; -} -.blue_link:hover { - color: #69bfee; - text-decoration: underline; -} -.blue_link:active { - color: #1995d8; - text-decoration: none; -} -.feedback_btn { - color: white; - border: 1px solid #994097; - font-weight: bold; - font-size: 14px; - padding: 5px 0 5px 5px; - position: absolute; - top: 213px; - left: -2px; - z-index: 101; - background: #ab48a9; - cursor: pointer; -} -.feedback_btn > p { - margin: 0; -} -.feedback_btn:hover, -.feedback_btn:focus { - background: #ab48a9; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #bc60ba), color-stop(1, #ab48a9)); - background: -ms-linear-gradient(bottom, #bc60ba, #ab48a9); - background: -moz-linear-gradient(center bottom, #bc60ba 0%, #ab48a9 100%); - background: -o-linear-gradient(#ab48a9, #bc60ba); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ab48a9', endColorstr='#bc60ba', GradientType=0); -} -.feedback_btn:active { - opacity: 1; - -ms-filter: none; - filter: none; - outline: 0; - -webkit-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.2); - -moz-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.2); - box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.2); - border: 1px solid #873986; - background: #ab48a9; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #c575c3), color-stop(1, #ab48a9)); - background: -ms-linear-gradient(bottom, #c575c3, #ab48a9); - background: -moz-linear-gradient(center bottom, #c575c3 0%, #ab48a9 100%); - background: -o-linear-gradient(#ab48a9, #c575c3); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ab48a9', endColorstr='#c575c3', GradientType=0); -} -.feedback_btn_dialog { - color: white; - font-weight: bold; - font-size: 16px; - padding: 8px 10px; - background: #ab48a9; - cursor: pointer; - border: 0; - display: block; - margin: 90px auto 20px auto; -} -.feedback_btn_dialog > p { - margin: 0; -} -.feedback_btn_dialog:hover { - color: #e5c1e4; - -webkit-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.4); - -moz-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.4); - box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.4); -} -.feedback_btn_dialog:active { - -webkit-box-shadow: inset 0 2px 1px rgba(55, 72, 88, 0.5); - -moz-box-shadow: inset 0 2px 1px rgba(55, 72, 88, 0.5); - box-shadow: inset 0 2px 1px rgba(55, 72, 88, 0.5); -} -.invite_btn_dialog { - color: white; - font-weight: bold; - font-size: 16px; - padding: 8px 10px; - background: #93ba48; - cursor: pointer; - border: 0; - display: block; - margin: 20px auto; -} -.invite_btn_dialog > p { - margin: 0; -} -.invite_btn_dialog:hover { - color: #e0ebca; - -webkit-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.4); - -moz-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.4); - box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.4); -} -.invite_btn_dialog:active { - -webkit-box-shadow: inset 0 2px 1px rgba(55, 72, 88, 0.5); - -moz-box-shadow: inset 0 2px 1px rgba(55, 72, 88, 0.5); - box-shadow: inset 0 2px 1px rgba(55, 72, 88, 0.5); -} -.invite_btn { - border: 1px solid #85a940; - color: white; - font-weight: bold; - font-size: 14px; - padding: 4px 3px 5px 1px; - position: absolute; - top: 296px; - left: -2px; - z-index: 50; - background: #93ba48; - cursor: pointer; -} -.invite_btn > p { - margin: 0; - float: left; -} -.invite_btn > span { - margin: 2px 2px 0 4px; -} -.invite_btn:hover, -.invite_btnfocus { - background: #93ba48; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #a0c25e), color-stop(1, #93ba48)); - background: -ms-linear-gradient(bottom, #a0c25e, #93ba48); - background: -moz-linear-gradient(center bottom, #a0c25e 0%, #93ba48 100%); - background: -o-linear-gradient(#93ba48, #a0c25e); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#93ba48', endColorstr='#a0c25e', GradientType=0); -} -.invite_btn:active { - opacity: 1; - -ms-filter: none; - filter: none; - outline: 0; - -webkit-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.2); - -moz-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.2); - box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.2); - border: 1px solid #769639; - background: #93ba48; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #adcb74), color-stop(1, #93ba48)); - background: -ms-linear-gradient(bottom, #adcb74, #93ba48); - background: -moz-linear-gradient(center bottom, #adcb74 0%, #93ba48 100%); - background: -o-linear-gradient(#93ba48, #adcb74); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#93ba48', endColorstr='#adcb74', GradientType=0); -} -.checkbox_filled[type="checkbox"] { - display: none; -} -.checkbox_filled[type="checkbox"]:checked + label:after { - background: #69bfee; - border: 1px solid #5e7b97; -} -.checkbox_filled_bg { - font-size: 12px; - position: relative; - display: inline-block; - padding: 4px 0 4px 25px; - display: block; - width: 110px; - cursor: pointer; -} -.checkbox_filled_bg:hover { - background: #ecf0f3; -} -.checkbox_filled_bg:after { - content: ""; - position: absolute; - display: block; - top: 6px; - left: 5px; - width: 10px; - height: 10px; - border: 1px solid #bac7d4; -} -.checkbox_button_input[type="checkbox"] { - display: none; -} -.checkbox_button_input[type="checkbox"]:checked + label { - background: #e0e6eb; -} -.checkbox_button_input[type="checkbox"]:checked + label:after { - background: #69bfee; - -webkit-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.5); - -moz-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.5); - box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.5); - border: 1px solid #c5e6f8; -} -.empty_folder { - font-size: 12px; - color: #aabbca; -} -.checkbox_button { - font-size: 12px; - position: relative; - padding: 4px 0 4px 1px; - display: inline-block; - width: 100%; - margin: 0; - cursor: pointer; -} -.checkbox_button:hover { - background: #ecf0f3; -} -.checkbox_button b .folder_dn-img, -.checkbox_button b .folder_up-img { - margin-top: -2px; - margin-right: 6px; -} -.checkbox_button:after { - content: ""; - position: absolute; - display: block; - top: 5px; - right: 10px; - width: 10px; - height: 10px; - border: 1px solid #bac7d4; - border-radius: 50%; - -webkit-box-shadow: inset 0 1px 2px rgba(55, 72, 88, 0.2); - -moz-box-shadow: inset 0 1px 2px rgba(55, 72, 88, 0.2); - box-shadow: inset 0 1px 2px rgba(55, 72, 88, 0.2); -} -.own_name { - font-size: 12px; - position: relative; - padding: 4px 0 4px 1px; - display: inline-block; - width: 100%; - margin: 0; - background: #ecf0f3; - padding-left: 10px; - margin-bottom: 14px; - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - cursor: default; -} -.own_name:after { - content: ""; - position: absolute; - display: block; - top: 5px; - right: 10px; - width: 10px; - height: 10px; - border-radius: 50%; - background: #69bfee; - -webkit-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.5); - -moz-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.5); - box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.5); - border: 1px solid #c5e6f8; -} -.label_title { - display: inline-block; - width: calc(80% - 12px); - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} -.input_label_wrap { - position: relative; -} -.input_label_wrap p { - font-size: 12px; - margin: 0 0 4px 4px; -} -.input_label_wrap label { - position: absolute; - bottom: 4px; - left: 4px; - color: #aabbca; -} -/* div.action_button { */ -/* background: #FFF; */ -/* border: 1px solid #CCC; */ -/* border-radius: 5px 5px 5px 5px; */ -/* color: #374858; */ -/* cursor: pointer; */ -/* display: inline-block; */ -/* float: left; */ -/* font-size: 14px; */ -/* height: 25px; */ -/* line-height: 30px; */ -/* margin-right: 10px; */ -/* padding: 0 10px; */ -/* text-align: center; */ -/* top: 0; */ -/* } */ -/* div.action_button:hover { */ -/* color: #69bfee; */ -/* border: 1px solid #69bfee; */ -/* } */ -div.action_button_click_only { - cursor: pointer; -} -div.bigger_button { - font-size: 18px; - margin: 0; - padding: 5px; - width: 250px; - cursor: pointer; - transition: background 0.3s ease; -} -#button_add_entry { - /* margin-right: 10px; */ -} -.action_button { - height: 19px; - width: 24px; -} -.action_button img { - width: 24px; - height: 24px; - display: inline-block; - margin: auto; -} -.action_button p { - display: inline-block; - margin: 0; - margin-left: 5px; - text-align: left; -} -.file_upload_button { - width: auto; - height: 30px; -} -#saved_entry { - display: none; - background-color: #BDCA70; - border-radius: 5px; - color: white; - font-size: 18px; - left: 50%; - margin-left: -60px; - padding: 10px; - position: absolute; - text-align: center; - top: 0; - width: 100px; -} -div.dragging_entry { - background: #69bfee; - border-radius: 2px; - color: #FFF; - cursor: move; - font-size: 18px; - margin-top: -10px; - margin-left: -30px; - opacity: 0.5; - padding: 10px; - text-align: left; - width: 80px !important; - z-index: 100; -} -div.dd_entry_table { - display: table; - table-layout: fixed; - width: 100%; - height: 0; -} -div.dd_entry_row { - display: table-row; -} -div.dd_entry_cell { - border: 1px solid transparent; - display: table-cell; - vertical-align: top; -} -div.dd_entry_cell:hover { - border: 1px solid #CCC; -} -div.dd_entry_cell_wrapper { - position: relative; - height: 100%; - margin: 5px; -} -div.dd_entry_cell_content { - position: relative; - display: block; - min-height: 66px; - vertical-align: top; - -webkit-box-sizing: border-box; - /* Safari/Chrome, other WebKit */ - -moz-box-sizing: border-box; - /* Firefox, other Gecko */ - box-sizing: border-box; - /* Opera/IE 8+ */ - overflow: hidden; - /* For tables */ -} -.handsontable { - overflow: scroll; -} -div.dd_entry_empty_element { - font-size: 16px; - padding: 15px 10px; - text-align: center; - overflow: hidden; - word-break: break-word; -} -div.dd_entry_cell_content img { - -webkit-user-select: none; - /* Chrome all / Safari all */ - -moz-user-select: none; - /* Firefox all */ - -ms-user-select: none; - /* IE 10+ */ -} -div.dd_entry_cell_content .imageLayer { - left: 0; - margin-left: auto; - margin-right: auto; - position: absolute; - right: 0; - top: 0; -} -.file_placeholder { - text-align: center; - background-color: #d9e1e8; - border: 1px solid rgba(0, 0, 0, 0); - padding-top: 5px; - transition: background 0.3s ease; -} -.file_placeholder button { - cursor: pointer; - margin: 5px; - padding: 5px; -} -div.dd_entry_cell_file_download { - font-size: 16px; - padding: 15px 10px; - text-align: center; - overflow: hidden; - word-break: break-word; -} -div.dd_entry_cell_file_download span.icon-file { - font-size: 36px; -} -div.file_icon { - vertical-align: bottom; - display: inline-block; -} -div.file_extension { - position: absolute; - background-color: #374858; - color: #FFF; - font-size: 12px; - line-height: 12px; - margin: 12px 0 0 -16px; - padding: 2px; - -webkit-box-sizing: border-box; - /* Safari/Chrome, other WebKit */ - -moz-box-sizing: border-box; - /* Firefox, other Gecko */ - box-sizing: border-box; - /* Opera/IE 8+ */ - border: 1px solid #FFF; - width: 32px; -} -div.file_details { - display: inline-block; - text-align: left; - vertical-align: top; - line-height: 20px; -} -div.file_name { - display: block; - font-size: 18px; -} -div.file_size_link { - display: block; -} -div.file_size_link a { - margin-left: 10px; -} -div.dd_image_entry .dd_entry_cell_content { - text-align: center; - overflow: hidden; -} -.entry_button { - background-color: #e6ebef; - cursor: pointer; - display: none; - height: 30px; - margin: 0; - padding: 5px 0 0; - position: relative; - float: left; - text-align: center; - width: 35px; - z-index: 2; - font-size: 18px; - -webkit-transition: all 0.2s ease; - -moz-transition: all 0.2s ease; - -o-transition: all 0.2s ease; - transition: all 0.2s ease; -} -.entry_button:hover { - background-color: #d9e1e8; -} -.entry_button:active { - -webkit-box-shadow: inset 0 2px 1px rgba(55, 72, 88, 0.2); - -moz-box-shadow: inset 0 2px 1px rgba(55, 72, 88, 0.2); - box-shadow: inset 0 2px 1px rgba(55, 72, 88, 0.2); -} -div.zoom_button, -div.settings_button { - /* border-bottom: 1px solid #CCC; */ - /* border-left: 1px solid #CCC; */ - border-right: 0; - border-top: 0; - border-radius: 0; - right: 0; -} -div.cancel_button, -div.drag_button { - /* right: 35px; */ -} -div.save_button, -div.edit_button { - /* border-right: 1px solid #CCCCCC; */ - /* right: 70px; */ -} -div.zoom_button { - /* border-right: 1px solid #CCCCCC; */ - /* right: 105px; */ -} -div.zoom_button span { - font-size: 14px; - margin: 10px; - line-height: 1.6; - color: #4b6277; -} -div.drag_button { - cursor: move; -} -div.cancel_button, -div.save_button { - display: none; -} -div.zoom_button:hover, -div.cancel_button:hover, -.save_button:hover, -.settings_button:hover, -.drag_button:hover, -.edit_button:hover { - /* color: #69bfee; */ -} -div.zoom_button:hover, -div.settings_button:hover { - margin: 0; -} -div.dd_entry_cell:hover div.zoom_button, -div.dd_entry_cell:hover div.settings_button, -div.dd_entry_cell:hover div.drag_button, -div.dd_entry_cell:hover div.edit_button { - display: block; -} -/* we need !important to override inline css set in labfolder-project.js when showing or hiding buttons for redactor enabled/disabled */ -div.epb_entry.readOnly div.cancel_button, -div.epb_entry.readOnly div.drag_button, -div.epb_entry.readOnly div.settings_button, -div.epb_entry.readOnly div.save_button, -div.epb_entry.readOnly div.edit_button, -div.epb_entry.readOnly div.zoom_button, -div.epb_entry.readOnly button.file_upload_button, -div.epb_entry.readOnly div.more_options_item_remove_block_element { - display: none !important; -} -div.disabled_button { - display: none !important; -} -/*TODO nest better hdrop*/ -.hdrop { - height: 15px; - display: table; - table-layout: fixed; - width: 100%; - transition: background 0.3s ease; -} -.hdrop:only-child { - box-sizing: border-box; - height: 100px; - padding: 40px; -} -.hdrop:only-child:before { - content: "This entry is empty. You can add a TEXT, a SKETCH, a TABLE or attach a FILE by clicking or dragging the buttons in the toolbar above."; - font-size: 13px; - background: #ffffff; - padding: 2px 4px; -} -.hdrop.drop_active:only-child:before { - content: "Drag it here."; -} -.hdrop.drop_hover:only-child:before { - content: "Now drop it."; -} -.hdrop:last-child { - /* border-radius: 0 0 10px 10px; */ -} -.vdrop { - width: 20px; - display: table-cell; - transition: background 0.3s ease; -} -#button_add_entry.drop_active, -.drop_active { - background-color: #aea; -} -.file_placeholder.drop_active { - background-color: #97d3f3; -} -#button_add_entry.drop_hover, -.drop_hover { - background: #69bfee; -} -.file_placeholder.drop_hover { - background-color: #69bfee; -} -.dragBar { - cursor: col-resize; - display: table-cell; - text-align: center; - vertical-align: middle; - width: 10px; -} -.dragBar img { - height: 10px; - width: 2px; -} -.dragBar:hover { - background-color: #DDD; -} -div.epb_entry.readOnly .dragBar { - cursor: default; -} -div.epb_entry.readOnly .dragBar img { - display: none; -} -div.epb_entry.readOnly .dragBar:hover { - background-color: initial; -} -.hidden_entry { - visibility: hidden; -} -.button_wrapper_sticky { - position: fixed !important; - top: 131px !important; - right: inherit !important; - z-index: 20; -} -.dd_entry_cell.ui-state-disabled, -.dd_entry_cell.ui-widget-content .ui-state-disabled, -.dd_entry_cell.ui-widget-header .ui-state-disabled { - background-image: none !important; - opacity: 1 !important; -} -#paste_hidden_input { - opacity: 0; - position: absolute; - right: 10000px; - top: -10000px; -} -/************* -* action bar * -**************/ -.action_bar { - width: 100%; - height: 36px; - min-width: 800px; - padding-top: 10px; - background: white; - border-bottom: solid 2px #a1b3c4; - -webkit-box-shadow: 0 3px 4px rgba(55, 72, 88, 0.2); - -moz-box-shadow: 0 3px 4px rgba(55, 72, 88, 0.2); - box-shadow: 0 3px 4px rgba(55, 72, 88, 0.2); -} -.plus_btn { - width: 64px; - height: 22px; - color: white; - background: #38abf7; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #0b89dd), color-stop(1, #38abf7)); - background: -ms-linear-gradient(bottom, #0b89dd, #38abf7); - background: -moz-linear-gradient(center bottom, #0b89dd 0%, #38abf7 100%); - background: -o-linear-gradient(#38abf7, #0b89dd); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#38abf7', endColorstr='#0b89dd', GradientType=0); - text-align: left; - font-size: 27px; - font-family: Arial !important; - line-height: 0.6; - padding: 2px 9px; - position: relative; -} -.plus_btn:hover { - outline: 0; - color: #dcf0fb; -} -.plus_btn:active { - -webkit-box-shadow: inset 0 3px 2px rgba(55, 72, 88, 0.5); - -moz-box-shadow: inset 0 3px 2px rgba(55, 72, 88, 0.5); - box-shadow: inset 0 3px 2px rgba(55, 72, 88, 0.5); -} -.plus_btn:after { - content: "Add"; - font-size: 13px; - position: absolute; - right: 10px; - top: 12px; - font-weight: bold; - line-height: 0; -} -.plus_btn_wrap { - width: 200px; - float: left; - margin-top: -3px; -} -.plus_btn_hover { - height: 23px; - margin: 0 0 0 55px; -} -.add_dropdown { - display: none; - position: absolute; - top: 85px; - left: 0; - -webkit-box-shadow: 0 4px 10px rgba(55, 72, 88, 0.3); - -moz-box-shadow: 0 4px 10px rgba(55, 72, 88, 0.3); - box-shadow: 0 4px 10px rgba(55, 72, 88, 0.3); - z-index: 999; -} -.add_dropdown .default_button { - border: 0; - background: none; -} -.add_dropdown .default_button:active { - background: #4fb9f3; - -webkit-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0); - -moz-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0); - box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0); -} -.add_dropdown > ul { - width: 180px; - font-size: 14px; - color: white; - margin: 0; - padding: 12px 0 12px 0; - background: #18a2ed; -} -.add_dropdown > ul li { - list-style-type: none; - padding: 8px 10px 8px 50px; - cursor: pointer; -} -.add_dropdown > ul li:hover { - background: #4fb9f3; -} -.add_link { - padding: 0 0 0 50px !important; - height: 32px; -} -.add_link a { - width: auto; - padding: 8px 0 8px 0; - color: white; - text-decoration: none; - display: block; -} -.add_link a:hover { - text-decoration: none; -} -.action_menu_wrap { - float: left; - margin-top: -1px; -} -.filter_wrap > ul > li { - position: relative; - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - border-left: solid 1px #bac7d4; - border-top: solid 1px #bac7d4; - height: 25px; -} -.filter_wrap > ul > li:last-child { - padding: 6px 3px 0 10px; - border-left: solid 1px #bac7d4; - border-top: 0; -} -.filter_wrap > ul > li:first-child { - background: none; - border: none; - color: #7b95ad; - font-size: 12px; - padding: 6px 10px 0 0; - margin-left: 18px; -} -.more_filters { - /* display: none; */ -} -.filter_dropdown_wrap { - width: 190px; - height: auto; - position: absolute; - left: -1px; - top: 25px; - z-index: 999; - display: none; - color: #4b6277; -} -.filter_dropdown_wrap .folder_dn-img { - margin-top: 2px; -} -.filter_dropdown_wrap .folder_up-img { - margin-top: 0; -} -.filter_dropdown_wrap header { - font-size: 11px; - color: #d9e1e8; - background: #4b6277; - padding: 3px 6px 2px 6px; - float: left; -} -.filter_dropdown_wrap header > p { - margin: 0; - float: left; -} -.filter_dropdown_wrap header > span { - float: right; - padding: 0px 0 3px 8px; - color: white; - cursor: pointer; -} -.filter_dropdown { - overflow-y: auto; - overflow-x: hidden; - min-width: 190px; - max-height: 600px; - width: auto; - padding-bottom: 20px; - float: left; - border: solid 1px #bac7d4; - background: white; - -webkit-box-shadow: 0 4px 8px rgba(55, 72, 88, 0.3); - -moz-box-shadow: 0 4px 8px rgba(55, 72, 88, 0.3); - box-shadow: 0 4px 8px rgba(55, 72, 88, 0.3); -} -.filter_dropdown .list_vertical { - padding-top: 10px; -} -.filter_dropdown ul { - padding-left: 20px; -} -.filter_dropdown > ul { - margin: 0; - padding: 0; - width: 230px; -} -.filter_dropdown li { - list-style-type: none; -} -.filter_dropdown nav { - display: block; - height: 30px; - padding-top: 10px; -} -.filter_dropdown nav button { - float: left; - margin-right: 20px; -} -.filterOverlay.active { - opacity: 0.5; -} -.filter_project_dropdown > ul { - margin: 0; - padding: 0; - width: 270px; -} -.invalid_tag { - font-size: 12px; - color: #e66873; -} -.project_filter { - min-width: 255px !important; - padding: 0 6px 10px 4px; -} -.project_filter .tree_button { - display: none !important; -} -.project_filter .updateTS { - display: none !important; -} -.project_filter .treeline, -.project_filter .treeline_children_empty { - font-size: 12px; -} -.root_folder { - padding: 4px 0 4px 2px !important; - width: calc(100% - 29px); -} -.not_possible_project { - display: none; -} -.not_possible_author { - display: none; -} -.folder_label { - padding: 4px 0 4px 2px !important; - width: calc(100% - 29px); -} -.root_folder_wrap { - overflow: auto; - width: 100%; -} -.filter_date_header { - width: 190px; -} -.dropdown_padding { - padding: 10px; -} -.author_filter { - min-width: 255px !important; - padding: 0 6px 0 4px; -} -.tags_input { - margin-top: 10px; - border: solid 1px #bac7d4; - cursor: text; - padding: 2px; - min-height: 50px; - width: 100%; - overflow: auto; -} -.tags_input > span { - font-size: 11px; - padding: 1px 3px; - background: #f3f5f7; - border-radius: 3px; - border: solid 1px #cad4de; - height: 18px; - margin: 2px; - cursor: pointer; - display: inline-block; -} -.tags_input > span.selected_token { - border: 1px solid #4bb1d7; -} -.tags_input > span.invalid { - border: 1px solid #E66873; - color: #E66873; -} -.token_input { - border: none; - outline: none; - resize: none; - white-space: pre; - font-size: 11px; - line-height: 11px; - vertical-align: top; - font-family: arial, sans-serif; - padding: 5px 0 0 2px; - margin: 0px; - width: auto; - overflow: auto; -} -.token_input_width { - position: absolute; - height: 11px; - display: inline-block; - padding: 0px 10px; - visibility: hidden; -} -.tag_name { - display: inline-block; - margin-right: 5px; - max-width: 250px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} -.delete_tag { - color: #9baec0; - cursor: pointer; - display: inline-block; - padding: 1px 3px 1px 0px; - vertical-align: top; -} -.delete_tag:after { - content: "\00d7"; -} -.tag_data_wrap { - margin-top: 10px; -} -.tag_data_wrap > ul { - margin: 0; - padding: 0; -} -.tag_data_wrap > ul li { - list-style-type: none; -} -.tag_index { - padding-right: 5px; - text-align: center; - font-size: 10px; - font-weight: bold; - border-right: solid 1px #bac7d4; - float: left; -} -.tag_index > ul { - margin: 0; - padding: 0; -} -.tag_index > ul li { - list-style-type: none; -} -.tag_index li { - width: 15px; - padding: 3px 0 3px 0; - margin-bottom: 1px; - display: block; - cursor: pointer; -} -.tag_index li:hover { - background: #ecf0f3; -} -.existing_tag { - cursor: pointer; -} -.existing_tag.disabled { - color: white; - background: #7b95ad; - border: 1px solid #7b95ad; -} -li.index_selected { - background: #d9e1e8; -} -li.index_selected:hover { - background: #d9e1e8; -} -.all_tags_head { - font-size: 12px; - margin: 10px 0 5px 0; -} -.all_tags { - font-size: 12px; - margin: 40px 0 5px 0; -} -.tag_register { - overflow: auto; - max-height: 300px; - width: 100%; - float: left; - margin-left: 10px; - font-size: 11px; -} -.tag_register ul { - margin: 0; - padding: 0; -} -.tag_register ul li { - list-style-type: none; -} -.tag_register > ul > li { - margin-bottom: 15px; -} -.tag { - padding: 1px 3px; - background: #f3f5f7; - border-radius: 3px; - border: solid 1px #cad4de; - display: inline-block; -} -.my_tags li { - margin-bottom: 5px; -} -.my_tags span { - display: inline-block; - padding: 1px 3px; - background: #f3f5f7; - border-radius: 3px; - border: solid 1px #cad4de; -} -.my_tags .selected_tag { - background: #38abf7; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #0b89dd), color-stop(1, #38abf7)); - background: -ms-linear-gradient(bottom, #0b89dd, #38abf7); - background: -moz-linear-gradient(center bottom, #0b89dd 0%, #38abf7 100%); - background: -o-linear-gradient(#38abf7, #0b89dd); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#38abf7', endColorstr='#0b89dd', GradientType=0); - color: #ffffff; -} -.my_tags .selected_tag.disabled.selected_tag { - background: #f3f5f7; - border: 1px solid #E66873; - color: #E66873; -} -.group_tags li { - margin-bottom: 7px; -} -.group_tags span { - display: inline-block; - padding: 1px 3px; - background: #f3f5f7; - border-radius: 3px; - border: solid 1px #cad4de; -} -.managed_tags li { - margin-bottom: 7px; -} -.managed_tags span { - display: inline-block; - padding: 1px 3px; - background: #f3f5f7; - border-radius: 3px; - border: solid 1px #cad4de; -} -.custom_selectbox { - min-width: 100px; -} -.filter_date_input { - background: white; - border: solid 1px #bac7d4; - width: 120px; - height: 26px; - padding: 2px; - color: #4b6277; -} -.datepicker_wrap { - margin-top: 20px; -} -.datepicker_wrap > div:first-child { - margin-bottom: 15px; -} -.input_label_wrap label.hidden { - display: none; -} -.filter_date_icon { - display: block; - position: absolute; - right: 24px; - top: 20px; - font-size: 20px; - cursor: pointer; -} -.empty_filter_message { - font-size: 12px; - margin: 0 0 10px 10px; -} -/******* -* entry * -********/ -#epb_container { - position: relative; - width: 100%; -} -.epb_entry { - width: 100%; - margin: 19px 0 15px 0; - display: inline-block; -} -.readOnly .entry_toolbar_btns { - display: none; -} -.entry_loading { - background: rgba(255, 255, 255, 0.7); - position: fixed; - top: 85px; - bottom: 0; - left: 0; - z-index: 99; - right: 0; -} -.entry_loading span { - padding: 25px; - background: #fff; - opacity: 1; - border-radius: 10px; - border: 1px solid #9baec0; - -webkit-box-shadow: 0 2px 2px rgba(55, 72, 88, 0.3); - -moz-box-shadow: 0 2px 2px rgba(55, 72, 88, 0.3); - box-shadow: 0 2px 2px rgba(55, 72, 88, 0.3); - color: #5e7b97; - font-size: 24px; - top: 300px; - width: 250px; - margin-left: -125px; - left: 50%; - text-align: center; - position: absolute; -} -.entry_container { - min-width: 726px; - margin-right: 45px; -} -.entry_header { - width: 100%; - height: 33px; - font-size: 12px; - background: #cdd7e0; -} -.entry_author { - color: #374858; - float: left; -} -.entry_author > ul { - margin: 0; - padding: 0; -} -.entry_author > ul li { - list-style-type: none; -} -.entry_author figure { - background: #ecf0f3; - border: solid 1px #7b95ad; - margin: 2px; - width: 29px; - height: 29px; - float: left; - position: relative; -} -.entry_author figure img { - width: 27px; - height: 27px; - position: absolute; - top: 0; - left: 0; -} -.entry_author figure > span { - margin-left: 4px; -} -.author_name { - float: left; - padding: 2px; - line-height: 1.3; - width: 196px; -} -.author_firstname, -.author_lastname { - white-space: nowrap; - text-overflow: ellipsis; - display: block; - overflow: hidden; - padding: 0; - margin-left: 0; -} -.entry_title_wrap { - float: left; - position: relative; - padding: 2px 4px 3px 4px; - line-height: 1.3; - border-left: 1px solid #ffffff; -} -.entry_name_menu { - float: left; - height: 30px; - overflow: hidden; -} -.entry_name_menu > ul { - margin: 0; - padding: 0; -} -.entry_name_menu > ul li { - list-style-type: none; -} -.entry_name_menu p { - margin: 0; - display: inline-block; -} -.entry_name_menu li { - max-width: 800px; - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; -} -.entry_name_menu li:first-child { - float: left; - color: #4f677e; - margin-right: 10px; - font-size: 11px; - line-height: 1.4; -} -.entry_name_menu li:last-child { - float: left; -} -.entry_menu_list { - float: left; - width: 164px; - height: 30px; - overflow: hidden; -} -.entry_menu_list > ul { - margin: 0; - padding: 0; -} -.entry_menu_list > ul li { - list-style-type: none; -} -.entry_menu_list p { - margin: 0; - display: inline-block; -} -.entry_menu_list li { - width: 100%; - display: block; - clear: both; - white-space: nowrap; -} -.entry_menu_list li span { - display: inline-block; - vertical-align: top; -} -.entry_menu_list li span:first-child { - min-width: 45px; - max-width: 92px; - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - float: left; - margin-right: 10px; - color: #4f677e; - font-size: 11px; -} -.entry_menu_list li span:last-child { - float: left; - color: #374858; -} -.entry_menus { - height: 100%; - float: right; - position: relative; -} -.entry_menus > ul { - margin: 0; - padding: 0; -} -.entry_menus > ul > li { - list-style-type: none; - float: left; - position: relative; -} -.entry_menus > ul { - height: 100%; -} -.entry_menus > ul > li { - width: 200px; - border-right: solid 1px white; - padding: 2px 4px 3px 4px; - height: 33px; - line-height: 1.3; - background: #cdd7e0; - position: relative; -} -.entry_menus > ul > li:first-child { - border-left: solid 1px white; -} -.entry_menus > ul > li:last-child { - border-right: none; - width: 90px; -} -.entry_menu_more { - min-height: 33px; - height: auto !important; - overflow: visible; - border-bottom: solid 1px #ffffff; - border-left: solid 1px #ffffff; - -webkit-box-shadow: 0 1px 2px rgba(55, 72, 88, 0.5); - -moz-box-shadow: 0 1px 2px rgba(55, 72, 88, 0.5); - box-shadow: 0 1px 2px rgba(55, 72, 88, 0.5); - z-index: 10; -} -.entry_menu_more .entry_menu_options span:last-child { - position: absolute; - bottom: 6px; -} -.show_list_more { - height: auto; -} -.readOnly .drop_edit_menu { - display: none; -} -.entry_menu_less { - /* overflow: hidden; */ -} -.entry_menu_show { - overflow: visible; -} -.entry_menu_edit .entry_dropdown { - display: block; -} -.entry_menu_options { - float: right; - margin-left: 10px; - padding-left: 4px; - height: 100%; - width: 15px; -} -.entry_menu_options > span { - display: block; - margin-right: 0; - cursor: pointer; -} -.entry_menu_options .arrow_menu_dn-img { - height: 10px !important; - margin-top: 7px; -} -.entry_options { - padding-top: 5px; - float: right; -} -.entry_options > ul { - margin: 0; - padding: 0; -} -.entry_options > ul > li { - list-style-type: none; - float: left; - position: relative; -} -.entry_options > ul > li { - margin-left: 6px; -} -.entry_options > span { - cursor: pointer; -} -.epb_comments_count { - color: #ffffff; - width: 17px; - display: block; - text-align: center; - margin-top: 1px; - font-size: 9px; - height: 12px; - line-height: 12px; -} -@-moz-document url-prefix() { - .epb_comments_count { - line-height: 11px; - } -} -.entry_toolbar { - height: 25px; - margin-left: 31px; - position: relative; - padding: 5px; - background: #cdd7e0; - border-top: solid 1px white; - -webkit-box-shadow: 0 2px 2px rgba(55, 72, 88, 0.3); - -moz-box-shadow: 0 2px 2px rgba(55, 72, 88, 0.3); - box-shadow: 0 2px 2px rgba(55, 72, 88, 0.3); -} -.entry_toolbar > ul { - margin: 0; - padding: 0; -} -.entry_toolbar > ul > li { - list-style-type: none; - float: left; - position: relative; -} -.entry_toolbar > ul > li { - margin-right: 12px; - cursor: pointer; -} -.entry_toolbar > ul > li:first-child { - margin-left: 6px; -} -.entry_toolbar_btns { - /*display: none;*/ -} -.entry_content { - min-height: 300px; - background: #f9fafb; - border: solid 1px #cad4de; -} -.entry_footer { - margin-left: 30px; - height: 25px; - background: #cad4de; -} -.tag { - padding: 1px 3px; - background: #f3f5f7; - border-radius: 3px; - border: solid 1px #cad4de; -} -.entry_tags { - float: left; - height: 100%; - overflow: hidden; - max-width: 138px; -} -.entry_tags > span { - display: inline-block; - padding: 1px 3px; - background: #f3f5f7; - border-radius: 3px; - border: solid 1px #cad4de; - float: left; - line-height: 1; - padding: 0px 3px; - border: solid 1px #aabbca; - margin-right: 2px; -} -.entry_dropdown { - width: 101%; - min-width: 260px; - height: auto; - padding: 10px; - background: #cdd7e0; - border-left: solid 1px white; - border-right: solid 1px white; - border-bottom: solid 1px white; - position: absolute; - top: 0; - right: -1px; - z-index: 14; - -webkit-box-shadow: 0 4px 10px rgba(55, 72, 88, 0.3); - -moz-box-shadow: 0 4px 10px rgba(55, 72, 88, 0.3); - box-shadow: 0 4px 10px rgba(55, 72, 88, 0.3); - display: none; -} -.entry_dropdown > ul { - margin: 0; - padding: 0; -} -.entry_dropdown > ul li { - list-style-type: none; -} -.entry_dropdown input { - border: none; - height: 28px; - font-size: 12px; - padding-left: 6px; - width: 100%; - color: #4b6277; -} -.entry_dropdown label { - font-size: 11px; - display: block; - margin-bottom: 4px; -} -.entry_dropdown > nav { - width: 100%; - height: 18px; -} -.entry_name { - right: auto !important; - left: -1px !important; -} -.entry_name select { - width: 60%; -} -.entry_name > ul > li { - margin: 4px 0 12px 0; -} -.entry_name > ul > li:first-child { - margin-top: -8px; -} -.project_tree { - width: 100%; - height: 140px; - overflow: auto; - background: white; -} -.close_entry_menu { - height: 18px; - width: 100%; - margin-top: -5px; -} -.close_entry_menu span { - float: right; -} -.save_entry_menu { - height: 20px; - float: right; - margin-top: 10px; -} -.save_entry_menu .grey_link { - display: block; - float: left; - padding: 4px 20px 0 0; -} -.select_entry_menu { - width: 100%; - height: 25px; - float: left; - margin-top: 20px; -} -.select_entry_menu span, -.select_entry_menu button { - float: left; - margin-right: 15px; -} -.select_entry_menu .blue_link { - color: #3b97ed; -} -.entry_tag_index li:hover { - background: #d9e1e8; -} -.entry_tag_index li.index_selected { - background: #e6ebef; -} -.entry_tag_index li.index_selected:hover { - background: #e6ebef; -} -.entry_tags_input { - margin: 0; - background: white; - border: none; -} -.entry_dates { - width: 100%; -} -.entry_dates > li { - display: block; - width: 100%; - clear: both; - overflow: auto; - margin-bottom: 15px; -} -.entry_dates > li > span { - margin: 5px 0 0 6px; - cursor: pointer; -} -.entry_dates > li > span:active { - margin: 6px 0 0 6px; -} -.entry_dates input { - height: 25px; - background: #e9edf1; -} -.entry_dates input:focus { - background: white; -} -.entry_dates > li:last-child { - margin-bottom: 5px; -} -.entry_dates > li:last-child input { - background: white; -} -.entry_dates > li:first-child { - margin-bottom: 0; -} -.drag_handle { - background: #d9e1e8; - width: 9px; - height: 25px; - padding: 5px 3px; - float: left; - cursor: move; -} -.drag_handle span { - width: 3px; - height: 3px; - display: block; - background: #bac7d4; - margin: 1px 0 2px 0; -} -.date_key { - width: 120px; - float: left; - margin-right: 10px; - position: relative; -} -.date_key:after { - content: ":"; - position: absolute; - left: 123px; - top: 4px; - font-size: 12px; - font-weight: bold; -} -.date_value { - width: 80px; - float: left; - position: relative; -} -.entry_settings { - width: 150px; - background: white; - line-height: 1.0; - position: absolute !important; - top: 24px; - right: -13px; - z-index: 30; - display: none; - margin-right: 0 !important; - -webkit-box-shadow: 0 2px 4px rgba(55, 72, 88, 0.8); - -moz-box-shadow: 0 2px 4px rgba(55, 72, 88, 0.8); - box-shadow: 0 2px 4px rgba(55, 72, 88, 0.8); -} -.entry_settings > ul { - margin: 0; - padding: 0; -} -.entry_settings > ul li { - list-style-type: none; -} -.entry_settings .trash_dark-img { - right: 4px; -} -.entry_settings ul { - padding: 10px 0 10px 0; -} -.entry_settings li { - font-size: 12px; - padding: 8px 10px; - display: block; - cursor: pointer; -} -.entry_settings li:hover { - background: #e0e6eb; -} -.entry_settings_arrow { - position: relative; - background: #f9fafb; -} -.entry_settings_arrow:after { - top: -11px; - right: 19px; - border: solid transparent; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - border-color: rgba(136, 183, 213, 0); - border-bottom-color: #f9fafb; - border-width: 7px; - margin-left: -3px; -} -.epb_content_wrap { - display: table; - min-width: 696px; - margin-left: 30px; - margin-right: 45px; - min-height: 100px; - background: #f3f5f7; - border: solid 1px #aabbca; -} -.handsontable th { - background: #d9e1e8; - font-size: 12px; - color: #4b6277; -} -.handsontable th, -.handsontable td { - border-right: 1px solid #cad4de; - border-bottom: 1px solid #cad4de; -} -.handsontable tr:first-child th, -.handsontable tr:first-child td { - border-top: 1px solid #cad4de; -} -.handsontable th:first-child, -.handsontable td:first-child, -.handsontable .htNoFrame + th, -.handsontable .htNoFrame + td { - border-left: 1px solid #cad4de; -} -div.dd_entry_cell { - border: 1px solid #d9e1e8; - -webkit-transition: border 0.2s ease; - -moz-transition: border 0.2s ease; - -o-transition: border 0.2s ease; - transition: border 0.2s ease; -} -div.dd_entry_cell:hover { - border: 1px solid #3babe9; -} -div.dd_entry_cell:hover .button_wrapper { - display: block; -} -#button_add_entry.drop_active, -.drop_active { - background-color: #d8f1ff; -} -#button_add_entry.drop_hover, -.drop_hover { - background: #69bfee; -} -.settings_button span { - margin-top: 10px; - display: block; -} -.edit_button span { - margin: 5px 0 0 12px; -} -.drag_button span { - margin: 3px 0 0 10px; -} -.drag_button:active { - -webkit-box-shadow: inset 0 0 0 rgba(55, 72, 88, 0) !important; - -moz-box-shadow: inset 0 0 0 rgba(55, 72, 88, 0) !important; - box-shadow: inset 0 0 0 rgba(55, 72, 88, 0) !important; -} -.cancel_button span { - margin: 5px 0 0 12px; -} -.save_button span { - margin: 2px 0 0 10px; -} -.button_wrapper { - position: absolute; - right: -1px; - top: -1px; - display: none; - border: solid 1px #cad4de; - z-index: 8; - -webkit-box-shadow: -2px 1px 1px rgba(55, 72, 88, 0.1) !important; - -moz-box-shadow: -2px 1px 1px rgba(55, 72, 88, 0.1) !important; - box-shadow: -2px 1px 1px rgba(55, 72, 88, 0.1) !important; -} -.button_wrapper .more_options_panel { - -webkit-box-shadow: 0 2px 4px rgba(55, 72, 88, 0.4) !important; - -moz-box-shadow: 0 2px 4px rgba(55, 72, 88, 0.4) !important; - box-shadow: 0 2px 4px rgba(55, 72, 88, 0.4) !important; - border: 0; -} -.button_wrapper .more_options_item { - min-width: 140px; -} -.more_options_panel.in_block { - right: -1px; - top: 36px; - padding: 10px 0 10px 0; - background-color: #e6ebef; -} -.more_options_item_remove_block_element span { - float: left; -} -.more_options_item { - padding: 6px; -} -.more_options_item:hover { - background: #f9fafb; -} -/********* -* tables * -**********/ -.htContextMenu table.htCore { - outline: 1px solid #d9e1e8; - line-height: 1.0; - -webkit-box-shadow: 0 2px 4px rgba(55, 72, 88, 0.4); - -moz-box-shadow: 0 2px 4px rgba(55, 72, 88, 0.4); - box-shadow: 0 2px 4px rgba(55, 72, 88, 0.4); -} -.htContextMenu table tbody tr td { - font-size: 12px; - color: #4b6277; - background: #e9edf1; -} -.htContextMenu table tbody tr td:hover { - background: #f9fafb; -} -.htContextMenu table tbody tr td.current { - background: #f9fafb; -} -.htContextMenu table tbody tr td.htSeparator { - border-top: 1px solid #cad4de; -} -/**************** -* media queries * -****************/ -@media (max-height: 750px) { - .filter_dropdown { - max-height: 460px; - } -} -@media (max-width: 1750px) { - .entry_name_menu li { - max-width: 400px; - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - } -} -@media (max-width: 1380px) { - .entry_name_menu li { - max-width: 190px; - } - .entry_menus > ul > li { - width: 174px; - } - .entry_menu_list { - width: 138px; - } - .entry_menu_list li span { - font-size: 11px; - } - .entry_menu_list li span:first-child { - margin: 0; - } -} -@media (max-width: 1100px) { - .author_name { - width: auto; - margin-right: 20px; - } - .author_firstname, - .author_lastname { - width: 100px; - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - } -} -@media (max-width: 970px) { - .page_title { - margin-top: 2px; - font-size: 12px; - } - .plus_btn_wrap { - width: 130px; - } - .author_firstname, - .author_lastname { - width: 66px; - } - .entry_menus > ul > li { - width: 120px; - } - .entry_menu_list { - width: 84px; - } - .entry_menu_list li span:first-child { - display: block; - float: none; - } - .entry_tags { - width: 84px; - } - .entry_tags > span { - max-width: 84px; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } -} -@media (max-width: 870px) { - .entry_name_menu li { - max-width: 90px; - } -} - - - -/************** -* basic.css * -**************/ -/********** -* colors * -***********/ -/********** -* helper * -***********/ -.list_vertical > ul { - margin: 0; - padding: 0; -} -.list_vertical > ul li { - list-style-type: none; -} -.list_horizontal > ul { - margin: 0; - padding: 0; -} -.list_horizontal > ul > li { - list-style-type: none; - float: left; - position: relative; -} -/************* -* functions * -**************/ -/****** -* css * -******/ -body { - color: #374858; -} -.clearfix:after { - content: " "; - visibility: hidden; - display: block; - height: 0; - clear: both; -} -/********* -* icons * -**********/ -.icon_source { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; -} -.logo-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -6px -10px; - width: 130px; - height: 30px; - margin: 16px 0 0 22px; -} -.author_only-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -140px -3px; - width: 15px; - height: 15px; -} -.add_text-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -161px -3px; - width: 22px; - height: 15px; -} -.add_text-img:hover { - background-position: -161px -31px; -} -.add_text-img:active { - margin-top: 1px; -} -.add_sketch-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -190px -3px; - width: 22px; - height: 15px; -} -.add_sketch-img:hover { - background-position: -190px -31px; -} -.add_sketch-img:active { - margin-top: 1px; -} -.add_table-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -218px -3px; - width: 23px; - height: 15px; -} -.add_table-img:hover { - background-position: -218px -31px; -} -.add_table-img:active { - margin-top: 1px; -} -.add_upload-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -942px -3px; - width: 18px; - height: 15px; -} -.add_upload-img:hover { - background-position: -942px -31px; -} -.add_upload-img:active { - margin-top: 1px; -} -.add_import-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -246px -3px; - width: 23px; - height: 15px; -} -.add_import-img:hover { - background-position: -246px -31px; -} -.add_import-img:active { - margin-top: 1px; -} -.wheel-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -282px -3px; - width: 15px; - height: 15px; -} -.wheel-img:hover { - background-position: -282px -31px; -} -.arrow_down-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -303px -3px; - width: 15px; - height: 15px; - cursor: pointer; -} -.arrow_down-img:hover { - background-position: -303px -31px; -} -.arrow_up-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -327px -3px; - width: 15px; - height: 15px; - cursor: pointer; -} -.arrow_up-img:hover { - background-position: -327px -31px; -} -.comment-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -348px -3px; - width: 19px; - height: 19px; -} -.comment-img:hover { - background-position: -348px -31px; -} -.todo-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -1085px -4px; - width: 14px; - height: 13px; -} -.project-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -375px -3px; - width: 16px; - height: 16px; - margin-top: 6px !important; -} -/* .project-img:hover{ */ -/* background-position: -375px -31px; */ -/* } */ -.manage-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -400px -2px; - width: 20px; - height: 20px; -} -.manage_s-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -1050px -35px; - width: 10px; - height: 10px; - margin-top: 2px; -} -.desk-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -428px -3px; - width: 16px; - height: 16px; - margin-top: 6px !important; -} -.desk_s-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -1067px -35px; - width: 10px; - height: 10px; - margin-top: 3px; -} -.template_s-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -796px -3px; - width: 10px; - height: 16px; -} -.bell-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -454px -1px; - width: 22px; - height: 22px; -} -.bell-img:hover { - background-position: -454px -29px; -} -.search-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -488px -1px; - width: 26px; - height: 23px; -} -.search-img:hover { - background-position: -488px -29px; -} -.avatar-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -522px 1px; - width: 16px; - height: 22px; -} -.avatar_s-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -837px -37px; - width: 8px; - height: 10px; - margin-top: 4px; -} -.group-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -853px -35px; - width: 20px; - height: 13px; - margin-top: 3px; -} -.arrow_down_s-img { - position: relative; - background: transparent; -} -.arrow_down_s-img:after { - top: 100%; - left: 50%; - border: solid transparent; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - border-color: rgba(213, 213, 213, 0); - border-top-color: #374858; - border-width: 4px; - margin-left: -4px; -} -.arrow_down_s-img:hover { - background-position: -691px -39px; -} -.close_x-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -895px -8px; - width: 10px; - height: 9px; -} -.feedback-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -912px -2px; - width: 10px; - height: 61px; -} -.invite-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -925px -2px; - width: 10px; - height: 52px; -} -.pending-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -1011px -9px; - width: 17px; - height: 10px; -} -.single_tag_img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -970px -5px; - width: 12px; - height: 14px; -} -.root_tag_img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -986px -4px; - width: 19px; - height: 15px; -} -.menu_arrow-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -853px -7px; - width: 14px; - height: 11px; -} -.folder_up-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -738px -3px; - width: 24px; - height: 15px; -} -.folder_dn-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -764px -5px; - width: 24px; - height: 13px; -} -.project_s-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -814px -5px; - width: 12px; - height: 14px; -} -.notebook_s-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -1035px -34px; - width: 10px; - height: 12px; - margin-top: 2px; -} -.edit-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -659px -7px; - width: 11px; - height: 10px; -} -.trash_dark-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -631px -5px; - width: 10px; - height: 13px; -} -.trash-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -646px -4px; - width: 10px; - height: 13px; -} -.trash-img:hover { - background-position: -631px -4px; -} -.edit_light-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -674px -7px; - width: 11px; - height: 10px; -} -.edit_light-img:hover { - background-position: -659px -7px; -} -.edit_light-img:active { - margin-top: 1px; - margin-bottom: -1px; -} -.arrow_menu_dn-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -729px -11px; - width: 9px; - height: 5px; -} -.arrow_menu_dn-img:hover { - background-position: -729px -39px; -} -.arrow_menu_up-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -716px -11px; - width: 9px; - height: 5px; -} -.arrow_menu_up-img:hover { - background-position: -716px -39px; -} -.close_box-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - float: right; - margin: 0; - background-position: -546px -5px; - width: 17px; - height: 15px; - cursor: pointer; -} -.close_box-img:hover { - background-position: -546px -33px; -} -.close_box-img:active { - -webkit-box-shadow: 0 0 5px #ffffff; - -moz-box-shadow: 0 0 5px #ffffff; - box-shadow: 0 0 5px #ffffff; - background-position: -546px -5px; -} -.save-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - margin: 0; - background-position: -585px -5px; - width: 15px; - height: 15px; - cursor: pointer; -} -.drag-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - margin: 0; - background-position: -608px -5px; - width: 15px; - height: 15px; - cursor: pointer; -} -.close_dark_x-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -569px -8px; - width: 10px; - height: 9px; -} -.edit_dark-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -659px -7px; - width: 11px; - height: 10px; -} - -/************** -* basic.css * -**************/ -/********** -* colors * -***********/ -/********** -* helper * -***********/ -.list_vertical > ul { - margin: 0; - padding: 0; -} -.list_vertical > ul li { - list-style-type: none; -} -.list_horizontal > ul { - margin: 0; - padding: 0; -} -.list_horizontal > ul > li { - list-style-type: none; - float: left; - position: relative; -} -/************* -* functions * -**************/ -/****** -* css * -******/ -body { - color: #374858; -} -.clearfix:after { - content: " "; - visibility: hidden; - display: block; - height: 0; - clear: both; -} -.signing_statement { - margin-bottom: 10px; -} -.signing_method { - margin: 0; - padding: 0; -} -.signpad_canvas { - width: 100%; - height: 150px; - border: 1px solid black; - background-color: #ffffff; -} -#signing_clear_button { - font-size: 12px; - cursor: pointer; -} -.signing_method_container { - display: block; - border: 1px solid #d2d2d2; - margin-bottom: 10px; - transition: background-color 0.3s ease; -} -.signing_method_container.selected { - background: #ededed; -} -.signing_content_title { - line-height: 26px; - padding: 10px; -} -.signing_method_description { - display: block; -} -.signing_method_container .signing_content_body { - padding: 0 10px; -} -.selected .signing_content_body { - padding: 0 10px 10px 10px; -} -.signing_toggle { - cursor: pointer; -} -.signing_label { - display: inline-block; - margin-right: 50px; -} -.signing_method_container .triangle { - display: inline-block; - font-size: 10px; - margin: 10px 10px 0 0; -} -/* .signing_method_container .icon-triangle_down { */ -/* margin-top: 10px; */ -/* } */ - -/****************************** - TASK LIST VIEW -*******************************/ -/************** -* basic.css * -**************/ -/********** -* colors * -***********/ -/********** -* helper * -***********/ -.list_vertical > ul { - margin: 0; - padding: 0; -} -.list_vertical > ul li { - list-style-type: none; -} -.list_horizontal > ul { - margin: 0; - padding: 0; -} -.list_horizontal > ul > li { - list-style-type: none; - float: left; - position: relative; -} -/************* -* functions * -**************/ -/****** -* css * -******/ -body { - color: #374858; -} -.clearfix:after { - content: " "; - visibility: hidden; - display: block; - height: 0; - clear: both; -} -.eln_main_content_box.tasks { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - height: auto; - min-height: 400px; - margin: 0 25px 0 0; -} -#tasks_header { - background: #EEE; - border-bottom: 1px solid #D6D4D5; - border-radius: 10px 10px 0 0; - display: block; - font-size: 14px; - height: 35px; - padding: 10px 0px 5px 15px; -} -#task_filter_status.hidden { - display: none; -} -#task_filter_status .checkbox_filled_bg:hover { - background: none; -} -#task_content { - max-width: 1300px; - padding-left: 10px; - display: block; - line-height: 18px; - position: relative; - overflow: auto; -} -.task_empty_folder { - display: none; - padding: 50px; - text-align: center; - font-size: 12px; -} -.task_list { - font-size: 14px; -} -.task_list table { - border-collapse: collapse; - outline: none; - table-layout: fixed; - width: 100%; -} -.task_list table tr td:last-child { - font-size: 11px; -} -.column_task_name { - min-width: 100px; - width: 25%; -} -.column_task_delete { - width: 30px; -} -.column_task_date { - width: 89px; -} -.task_list_line { - font-size: 12px; - border-bottom: 1px solid #bac7d4; - cursor: pointer; - height: 34px; - line-height: 1.2; - white-space: nowrap; -} -.task_list_line:last-child { - border: none; -} -.task_list_line:hover { - background: #ecf0f3; -} -.task_list_line:hover .task_line_delete { - display: block; -} -.task_list_line:first-child { - cursor: auto; -} -.task_list_line:first-child:hover { - background: none; -} -.unread_task { - background: #EEF; -} -.task_line_name { - white-space: nowrap; - text-overflow: ellipsis; - vertical-align: bottom; - overflow: hidden; - padding-left: 4px; -} -.task_line_text { - overflow: hidden; - text-overflow: ellipsis; -} -.task_line_content { - color: #AAA; -} -.task_line_delete { - display: none; - text-align: center; -} -.task_line_delete:hover { - color: #4bb1d7; -} -.task_line_date { - padding-right: 10px; - text-align: right; -} -.task_checkbox_wrap { - position: relative; - float: left; - display: block; - font-size: 12px; -} -/****************************** - TASK DIALOG VIEW -*******************************/ -.task_select_left { - float: left; -} -.task_select { - border: 0; - outline: 0; - background: #FFF; - cursor: pointer; - margin-right: 10px; - padding: 4px 4px 4px 8px; - color: #5e7b97; -} -.task_options { - height: 45px; -} -.task_set_option { - display: inline-block; - margin: 5px 15px 0 15px; -} -#choose_asignee, -#choose_status, -#status_created { - display: none; -} -#dialog_task_form .input_block { - margin: 0; - padding-bottom: 20px; - overflow: auto; - height: auto; -} -#dialog_task_form .task_recipient_label { - display: inline-block; - vertical-align: top; - width: 20px; - padding: 5px 0 0 0; - margin-bottom: 5px; -} -.task_info_label { - margin-left: 16px; - margin-bottom: 6px; -} -.task_content_bg { - background: white; - padding: 0 10px 10px 10px; -} -#dialog_task_form .task_recipient_field { - cursor: text; - display: inline-block; - min-height: 33px; - width: 700px; -} -#dialog_task_form .add_task_recipient { - cursor: pointer; - display: inline-block; - margin-bottom: 5px; - padding: 5px 0 0 0; - vertical-align: top; -} -#dialog_task_form .add_task_recipient.disabled { - cursor: default; - color: #AAA; -} -#taskRecipientIds, -#taskRecipientEmails { - display: none; -} -#dialog_task_form .task_recipient textarea, -#task_recipient_width { - border: 1px solid transparent; - display: inline-block; - font-size: 14px; - color: #374858; - height: 14px; - margin: 0 5px 5px 0; - outline: none; - padding: 5px; - resize: none; - vertical-align: bottom; - overflow: hidden; -} -#task_recipient_width { - display: none; -} -#dialog_task_form .task_message_content { - max-height: 450px; - height: auto; - overflow: auto; -} -.task_message_text { - margin: 10px 0 0 15px; -} -#dialog_task_form .task_message_content textarea { - font-size: 14px; - height: 200px; - margin: 0; - resize: none; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -#dialog_task_form .placeholder_frame { - float: none; - width: 100%; -} -.task_recipient_tree { - display: none; - position: relative; - box-shadow: 0px 0px 10px #AAA; - box-sizing: border-box; - max-height: 150px; - overflow: auto; - padding: 0 10px; -} -.task_recipient_tree a { - color: #374858; - line-height: 25px; - text-decoration: none; -} -.task_recipient_tree div.group_treeline_children { - padding-left: 15px; - margin-left: 0px; - box-sizing: border-box; -} -.task_recipient { - line-height: 24px; -} -.task_recipient:last-child:after { - content: ""; -} -/****************************** - TASK FILTERING -*******************************/ -.task_filter { - list-style-type: none; - overflow: auto; - margin: 0; - padding: 6px 0 0 10px; -} -.task_filter > li { - float: left; - padding-left: 6px; - padding-right: 6px; -} -.task_filter label { - vertical-align: middle; - bottom: 3px; - position: relative; - margin-left: 2px; -} -.CLOSED, -.not_assigned, -.assigned { - display: none; -} - -/************** -* basic.css * -**************/ -/********** -* colors * -***********/ -/********** -* helper * -***********/ -.list_vertical > ul { - margin: 0; - padding: 0; -} -.list_vertical > ul li { - list-style-type: none; -} -.list_horizontal > ul { - margin: 0; - padding: 0; -} -.list_horizontal > ul > li { - list-style-type: none; - float: left; - position: relative; -} -/************* -* functions * -**************/ -/****** -* css * -******/ -body { - color: #374858; -} -.clearfix:after { - content: " "; - visibility: hidden; - display: block; - height: 0; - clear: both; -} -.treeInPopup .treeline { - background-repeat: no-repeat; - color: #374858; - cursor: pointer; - border: 1px solid transparent; - display: block; - font-size: 14px; - height: 21px; - line-height: 22px; - outline: none; - padding-left: 5px; - text-decoration: none; -} -/* .treeline:hover{ */ -/* background-position: 0 0; */ -/* border: 1px solid #69bfee; */ -/* text-decoration: none; */ -/* } */ -.treeline:hover .icon-arrow_down, -.treeline:hover .icon-arrow_right, -.treeline:hover .icon-folder, -.treeline:hover .icon-notebook, -.treeline:hover .icon-template, -.treeline:hover .name, -.treeline:hover .updateTS { - /* color: #69bfee; */ -} -.treeline.active { - background-color: #ededed; -} -.treeInPopup .treeline.active { - background-color: transparent; -} -.treeline.is_hidden_item .icon-arrow_down, -.treeline.is_hidden_item .icon-arrow_right, -.treeline.is_hidden_item .icon-folder, -.treeline.is_hidden_item .icon-notebook, -.treeline.is_hidden_item .icon-template, -.treeline.is_hidden_item .name, -.treeline.is_hidden_item .updateTS, -.treeline.is_hidden_item:hover .icon-arrow_down, -.treeline.is_hidden_item:hover .icon-arrow_right, -.treeline.is_hidden_item:hover .icon-folder, -.treeline.is_hidden_item:hover .icon-notebook, -.treeline.is_hidden_item:hover .icon-template, -.treeline.is_hidden_item:hover .name, -.treeline.is_hidden_item:hover .updateTS { - color: #CCC; -} -.treeline img { - vertical-align: top; -} -.treeline .icon-arrow_right { - font-size: 33px; - margin-right: -10px; - margin-left: -3px; - vertical-align: -4px; -} -.treeInPopup .icon-arrow_right { - font-size: 23px; - margin-right: -6px; - line-height: 14px; - margin-left: -3px; -} -.treeline span { - /* float: left; */ - margin-right: 5px; -} -.treeline .icon-template { - float: left; -} -.treeline .name { - overflow: hidden; - margin-left: 5px; -} -.treeInPopup .name { - font-size: 12px; - overflow: hidden; -} -.treeline .updateTS { - font-size: 15px; - float: right; - margin-right: 15px; -} -.treeline .tree_button { - float: right; - display: none; - margin-top: 0; - margin-right: 10px; -} -.droppable_folder { - background-color: #e4eef7 !important; -} -.hover_droppable_folder { - background-color: #d0e1f1 !important; -} -.treeline:hover .tree_button { - display: inline; -} -.treeline.active .tree_button { - display: inline; -} -.treeline_children { - display: none; - margin-left: 30px; -} -.treeInPopup .treeline_children { - margin-left: 20px; -} -.treeline_children_empty { - font-size: 15px; - font-style: italic; - padding: 10px 0 10px 30px; -} -.treeInPopup .treeline_children_empty { - font-size: 12px; - font-style: italic; - padding: 0 0 0 25px; -} -.treeInPopupContainer { - display: none; - background: white; - box-sizing: border-box; - max-height: 150px; - margin-top: 10px; - overflow-y: auto; - -webkit-box-shadow: inset 0 2px 1px rgba(55, 72, 88, 0.2); - -moz-box-shadow: inset 0 2px 1px rgba(55, 72, 88, 0.2); - box-shadow: inset 0 2px 1px rgba(55, 72, 88, 0.2); -} -.treeInPopupContainer img { - display: block; - margin: auto; -} -.treeInPopup { - overflow-y: auto; - height: 148px; - padding-top: 10px; - margin-top: 2px; -} -.treeInPopup .treeline.selected { - background-color: #e6ebef; -} -.tree_my_eln_projects, -.tree_my_eln_templates { - max-width: 900px; -} -.tree_my_eln_projects .folder_dn-img, -.tree_my_eln_templates .folder_dn-img, -.tree_my_eln_projects .project_s-img, -.tree_my_eln_templates .project_s-img { - margin-top: 2px; -} -.treeline { - color: #4b6277; - background-repeat: no-repeat; - cursor: pointer; - border: 1px solid transparent; - display: block; - font-size: 14px; - height: 26px; - line-height: 20px; - outline: none; - padding: 2px 8px 2px 4px; - text-decoration: none; - transition: background 0.1s ease; -} -.treeline:hover { - background: #e0e6eb; - text-decoration: none; -} -.treeline .updateTS { - font-size: 13px; - float: right; - margin-right: 15px; -} -.treeline .tree_button { - float: right; - display: none; - margin: 0 10px; -} -.treeline .tree_button button { - padding: 3px; - background: transparent; - cursor: pointer; -} -.treeline .name { - white-space: nowrap; - text-overflow: ellipsis; - display: block; - overflow: hidden; - padding: 0; - margin-left: 0; - line-height: 1.5; - float: left; -} -.treeline .icon-template { - margin-top: 3px; -} -.more_options_panel { - position: absolute; - right: 10px; - z-index: 10; - display: none; - -webkit-box-shadow: 0 4px 10px rgba(55, 72, 88, 0.3); - -moz-box-shadow: 0 4px 10px rgba(55, 72, 88, 0.3); - box-shadow: 0 4px 10px rgba(55, 72, 88, 0.3); - border: solid 1px #bac7d4; -} -.more_options_panel > ul { - margin: 0; - padding: 0; -} -.more_options_panel > ul li { - list-style-type: none; -} -.more_options_panel .more_options_item { - min-width: 140px; - font-size: 12px; - padding-left: 5px; - cursor: pointer; -} -.more_options_panel .menu_arrow-img { - position: absolute; - top: -11px; - left: 60px; -} -.more_options_panel > ul > li { - padding: 2px 7px 2px 6px; - display: block; - text-align: left; - cursor: pointer; - line-height: 20px; - position: relative; -} -.more_options_panel > ul > li:hover { - background: #ecf0f3; -} -.more_options_panel > ul > li > span { - right: 0; - top: 3px; - position: absolute; -} -.more_options_panel > ul li:first-child { - margin-top: 8px; -} -.more_options_panel.in_tree { - top: 23px; -} -.group_more_options { - width: 200px; -} - -/****************************** - WITNESS COLLECTION -*******************************/ -.eln_main_content_box.witness { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - height: 95%; - margin: 0 25px 0 0; -} -#witness_header { - background: #EEE; - border-bottom: 1px solid #D6D4D5; - border-radius: 10px 10px 0 0; - display: block; - font-size: 14px; - height: 35px; - padding: 10px 0px 5px 15px; -} -#witness_content { - display: block; - line-height: 18px; - position: absolute; - overflow: auto; - padding: 10px; - top: 50px; - left: 0; - right: 0; - bottom: 0px; -} -.witness_empty_folder { - padding: 50px; - text-align: center; - font-size: 12px; -} -.witness_list { - font-size: 14px; -} -.witness_list table { - border-collapse: collapse; - outline: none; - table-layout: fixed; - width: 100%; -} -.witness_list table tr td:last-child { - font-size: 11px; -} -.witness_list_line { - border-bottom: 1px solid #DDD; - cursor: pointer; - height: 40px; - line-height: 40px; - white-space: nowrap; -} -.witness_list_line:hover { - background: #EEE; -} -.witness_list_line:first-child:hover { - background: none; - cursor: default; -} -.witness_line_name { - white-space: nowrap; - text-overflow: ellipsis; - vertical-align: bottom; - overflow: hidden; - padding-left: 10px; -} -.witness_line_text { - overflow: hidden; - text-overflow: ellipsis; -} -.column_witness_name { - min-width: 100px; - width: 25%; -} -.column_witness_project { - min-width: 100px; - width: 60%; -} -.column_witness_date { - width: 106px; -} - diff --git a/unittests/example_labfolder_data/static/css/data-elements.css b/unittests/example_labfolder_data/static/css/data-elements.css deleted file mode 100644 index 5d451615b0120307dd4a18cabf67eaba83eeb07f..0000000000000000000000000000000000000000 --- a/unittests/example_labfolder_data/static/css/data-elements.css +++ /dev/null @@ -1,104 +0,0 @@ -.data-elements { - display: block; - font-family: 'Open Sans', Helvetica, Arial, sans-serif; -} -.notebook-element-content { - height: calc(100% - 10px); - background: #FFF; - padding: 1.25em 0 0.75em; -} -.notebook-element-content .data-element { - display: block; - -webkit-touch-callout: none; - /* iOS Safari */ - -webkit-user-select: none; - /* Chrome/Safari/Opera */ - -khtml-user-select: none; - /* Konqueror */ - -moz-user-select: none; - /* Firefox */ - -ms-user-select: none; - /* Internet Explorer/Edge */ - user-select: none; - /* Non-prefixed version, currently not supported by any browser */ -} -/* Match element or class (class is used in compose mode) */ -.data-element-wrap { - margin-bottom: 0.75em; - margin-right: 1em; - display: flex; - align-items: baseline; - position: relative; -} -.data-element-wrap .data-element-icon { - width: 12px; - height: 12px; - margin: 0.65em; - margin-right: 0.75em; - margin-left: 1.15em; - fill: #9D9D9D; - flex-shrink: 0; -} -.data-element-wrap .data-element-display { - border: solid 1px #c0c0c0; - border-radius: 5px; - padding: 0.5em 0.75em; - overflow-wrap: break-word; - word-wrap: break-word; - -ms-word-break: break-all; - word-break: break-all; - word-break: break-word; -} -.data-element-wrap .data-element-display .empty-value { - color: #9D9D9D; - font-size: 1.75em; - line-height: 0.25em; -} -.data-element-wrap .data-element-display .element-title { - font-weight: bold; -} -.data-group-wrap .data-group-icon { - align-self: flex-start; -} -.data-group-wrap .data-group-content.display-mode { - /** - * Fix for nested flexbox sizing in IE11. See: - * https://github.com/philipwalton/flexbugs/issues/170 - * https://github.com/philipwalton/flexbugs/issues/71 - */ - min-width: 0%; - border: solid 1px #c0c0c0; - border-radius: 5px; - padding: 0.5em 0.75em 0; -} -.data-group-wrap .data-group-content.display-mode .data-element-display { - border: none; - padding: 0; -} -.data-group-wrap .data-group-content .data-group-header .element-title { - font-weight: bold; -} -.data-group-wrap .data-group-content .data-element-icon { - margin: 0; - margin-right: 0.75em; -} -.data-group-wrap .data-group-content .data-group-icon { - margin-top: 0.75em; -} -.descriptive-element-wrap { - align-items: baseline; -} -.descriptive-element-wrap .descriptive-element-display .element-title { - font-weight: bold; -} -.material-element-wrap { - align-items: flex-start; -} -.material-element-wrap .material-element-display .element-title { - color: #6cc0ec; - font-weight: bold; - word-wrap: break-word; -} -.material-element-wrap .material-element-display .element-title:hover { - color: #96dbff; -} diff --git a/unittests/example_labfolder_data/static/css/eln_layout.css b/unittests/example_labfolder_data/static/css/eln_layout.css deleted file mode 100644 index 97944ad5855d52a2fb503e940fa3a77ee9d22abd..0000000000000000000000000000000000000000 --- a/unittests/example_labfolder_data/static/css/eln_layout.css +++ /dev/null @@ -1,3101 +0,0 @@ -/******************* -* eln_layout.css * -********************/ -/************** -* basic.css * -**************/ -/********** -* colors * -***********/ -/********** -* helper * -***********/ -.list_vertical > ul { - margin: 0; - padding: 0; -} -.list_vertical > ul li { - list-style-type: none; -} -.list_horizontal > ul { - margin: 0; - padding: 0; -} -.list_horizontal > ul > li { - list-style-type: none; - float: left; - position: relative; -} -/************* -* functions * -**************/ -/****** -* css * -******/ -body { - color: #374858; -} -.clearfix:after { - content: " "; - visibility: hidden; - display: block; - height: 0; - clear: both; -} -::selection { - background: #c5e6f8; -} -::-moz-selection { - background: #c5e6f8; -} -*, -*::before, -*::after { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -a { - cursor: pointer; -} - -@font-face { - font-family: 'Oxygen'; - src: url('/static/font/Oxygen-Regular.ttf'); - font-weight: normal; - font-style: normal; -} -@font-face { - font-family: 'Oxygen Bold'; - src: url('/static/font/Oxygen-Bold.woff'); - font-weight: normal; - font-style: normal; -} -@font-face { - font-family: 'Source Sans Pro Light'; - src: url('/static/font/SourceSansPro-Light.ttf'); - font-weight: normal; - font-style: normal; -} -@font-face { - font-family: 'Source Sans Pro'; - src: url('/static/font/SourceSansPro-Regular.woff'); - font-weight: normal; - font-style: normal; -} -body { - font-size: 14px; - margin: 0; - padding: 0; - font-family: arial, sans-serif; - height: 100%; - width: 100%; -} -html { - height: 100%; -} -.body_bg { - background: #ffffff url(../img/squares.png); - height: 100%; - width: 100%; - position: fixed; - z-index: -1; - top: 33px; - left: -10px; -} -a { - text-decoration: none; - color: #1995d8; - outline: none; -} -a:hover { - text-decoration: none; -} -img { - border: 0; -} -button { - margin: 0; -} -button::-moz-focus-inner { - border: 0; -} -.clear { - clear: both; -} -.content_top_margin { - margin-top: 50px; -} -/****************************** - DEFAULT BLUE BUTTONS -*******************************/ -.default_button { - border: 1px solid #455a6e; - padding: 4px 8px; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; - color: white; - opacity: 1; - line-height: 1.2; - background: #304d69; - font-size: 14px; - -webkit-transition: all 0.1s linear; - -moz-transition: all 0.1s linear; - -o-transition: all 0.1s linear; - transition: all 0.1s linear; - -webkit-backface-visibility: hidden; - cursor: pointer; - /* background-color:#374858; */ - /* border:1px solid #ffffff; */ - /* border-radius:6px; */ - /* box-shadow:0px 0px 1px black; */ - /* -webkit-box-sizing: border-box; */ - /* -moz-box-sizing: border-box; */ - /* box-sizing: border-box; */ - /* color:#ffffff; */ - /* cursor:pointer; */ - /* display:inline-block; */ - /* float:left; */ - /* font-family:din-medi; */ - /* font-size:14px; */ - /* height:28px; */ - /* line-height:28px; */ - /* margin:0 1px 1px 0; */ - /* outline: none; */ - /* padding: 0 10px; */ - /* transition: background-color 0.2s ease, box-shadow 0.2s ease; */ -} -.default_button:hover, -.default_button:focus { - background: #375877; - -ms-filter: none; - filter: none; - outline: 0; - color: white; - text-decoration: none; -} -.default_button:active { - background: #304d69; - -ms-filter: none; - filter: none; - outline: 0; - -webkit-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.5); - -moz-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.5); - box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.5); -} -.default_button:hover { - /* background-color: #607D99; */ - /* text-decoration:none; */ -} -.default_button:active { - opacity: 1.0; - /* box-shadow:0px 0px 10px #888888; */ - /* text-decoration:none; */ -} -.default_button.disabled { - opacity: 0.5; - /* background-color:#DDD; */ - /* border:1px solid #FFF; */ - /* box-shadow:0px 0px 1px #AAA; */ - /* color:#AAA; */ - /* cursor:default; */ -} -/****************************** - DEFAULT FIELDS -*******************************/ -.default_textfield { - background-color: white; - border: 0; - -webkit-box-sizing: border-box; - /* Safari/Chrome, other WebKit */ - -moz-box-sizing: border-box; - /* Firefox, other Gecko */ - box-sizing: border-box; - /* Opera/IE 8+ */ - font-family: Arial; - color: #4b6277; - font-size: 14px; - line-height: 1.8; - font-style: normal; - font-variant: normal; - font-weight: normal; - margin: 0 5px 5px 0; - padding-left: 5px; - min-height: 30px; - transition: box-shadow ease 0.2s; -} -.textfield_on_white { - border: solid 1px #bac7d4; -} -.default_textfield:hover { - /* box-shadow: 0 0 3px #69bfee; */ -} -.default_textfield:focus { - /* border: 1px solid #69bfee; */ - /* box-shadow: 0 0 6px #69bfee; */ -} -/****************************** - DEFAULT SELECT -*******************************/ -.default_select { - background: #FFF; - border: 1px solid #d9e1e8; - color: #4b6277; - cursor: pointer; - margin: 0 0 0 10px; - padding: 4px 4px 4px 8px; -} -.dialog_wide_select { - margin: 0; - width: 100%; -} -/****************************** - DEFAULT PROFILE PICTURE -*******************************/ -img.default_profile_picture { - border: 1px solid #888; - height: 100px; - width: 100px; -} -img.default_profile_picture_small { - border: 1px solid #888; - height: 32px; - width: 32px; - margin-top: 3px; -} -/* ****************** */ -/* more_options START */ -/* ****************** */ -.more_options { - float: right; - position: relative; -} -.more_options_panel { - position: absolute; - right: 0; - z-index: 10; - display: none; - -webkit-box-shadow: 0 4px 6px rgba(55, 72, 88, 0.3); - -moz-box-shadow: 0 4px 6px rgba(55, 72, 88, 0.3); - box-shadow: 0 4px 6px rgba(55, 72, 88, 0.3); - border: 1px solid #CDCDCD; - /* border-radius: 10px; */ - background-color: #FDFDFD; -} -.more_options_panel.in_project { - top: 38px; -} -.more_options_panel.in_block { - top: 40px; -} -.more_options_item { - font-size: 12px; - /* line-height: 40px; */ - padding-left: 12px; - padding-right: 12px; - cursor: pointer; - /* border-top: 1px solid #D6D4D5; */ - transition: background ease 0.2s; -} -.more_options_item:hover { - /* background: #ededed; */ - /* color: #69bfee; */ -} -.more_options_item:first-child { - /* border-radius: 10px 10px 0 0; */ - /* border: 0; */ -} -.more_options_item:last-child { - /* border-radius: 0 0 10px 10px; */ -} -.more_options_item span { - position: absolute; - right: 0; -} -div.zoom_bar { - width: 180px; - padding: 4px 14px !important; - height: 44px; - -webkit-user-select: none; - /* Chrome all / Safari all */ - -moz-user-select: none; - /* Firefox all */ - -ms-user-select: none; - /* IE 10+ */ -} -div.zoom_bar:hover { - background: #e6ebef; -} -div.zoom_bar:hover { - color: #374858; -} -/* **************** */ -/* more_options END */ -/* **************** */ -/* ****************** */ -/* gear_button START */ -/* ****************** */ -/* ************ */ -/* layout START */ -/* ************ */ -/* generic rules */ -.eln_row { - left: 0; - right: 0; - /* overflow:hidden; */ - position: absolute; -} -.eln_scroll-x { - overflow-x: auto; -} -.eln_scroll-y { - overflow-y: scroll; -} -/* specific rules */ -.eln_header.eln_row { - position: relative; - /* height:50px; */ - /* background: #FFF; */ - /* box-shadow:0 3px 10px #BBB; */ - min-width: 800px; -} -.eln_content.eln_row { - top: 70px; - bottom: 0; - margin-left: 200px; - min-width: 600px; -} -.eln_main_title.eln_row { - top: 70px; - margin-right: 40px; - margin-left: 100px; - min-width: 436px; - overflow: visible; -} -.eln_main_content.eln_row { - top: 86px; - bottom: 0; - margin-left: 49px; - min-width: 600px; -} -.eln_folder_title.eln_row { - top: 70px; - margin-left: 100px; - min-width: 600px; - overflow: visible; -} -.eln_folder_content.eln_row { - top: 86px; - bottom: 0; - margin-left: 49px; - min-width: 640px; -} -.eln_project_title.eln_row { - top: 70px; - margin-left: 100px; - min-width: 640px; - overflow: visible; -} -.eln_project_content.eln_row { - top: 86px; - bottom: 0; - /* margin-left:100px; */ - margin-left: 29px; - min-width: 600px; -} -.eln_main_content_box { - height: auto; - min-height: 400px; - margin: 0 25px 25px 0; - background-color: white; - border-bottom: solid 1px #cad4de; - border-left: solid 1px #cad4de; - border-right: solid 1px #cad4de; - position: relative; - padding: 20px 20px 20px 135px; - color: #4b6277; -} -.eln_main_content_box .header { - display: block; - font-size: 24px; - height: 35px; -} -.eln_main_content_box .header button { - margin-right: 10px; -} -.app_wrap { - position: relative; - background: #f3f5f7; - border: solid 1px #cad4de; - -webkit-box-shadow: 0 2px 2px rgba(55, 72, 88, 0.1); - -moz-box-shadow: 0 2px 2px rgba(55, 72, 88, 0.1); - box-shadow: 0 2px 2px rgba(55, 72, 88, 0.1); - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - height: calc(95% - 15px); -} -.app_content_wrap { - max-width: 900px; - padding: 10px; - display: block; - line-height: 18px; - position: absolute; - overflow: auto; - top: 10px; - left: 0; - right: 0; - bottom: 0px; -} -.app_header { - height: 29px; - background: #cad4de; - padding: 6px; -} -.app_header > h2 { - display: block; - float: left; - font-size: 14px; - margin: 0 13px 0 0; - color: #374858; -} -.app_header .filter_dn_wrap { - top: 23px; -} -.app_header .dropdown_button { - height: 20px; -} -.app_header .dropdown_button p { - margin: 0; - float: left; -} -.app_header .dropdown_button span { - height: 4px; - width: 12px; - display: block; - float: left; - margin: 2px 0 0 4px; -} -.app_plus_btn { - width: 35px; - height: 18px; - line-height: 1; - margin-right: 2px !important; - padding: 0; -} -.get_more_apps { - height: 100%; - padding: 20px; -} -/* ********** */ -/* layout END */ -/* ********** */ -/* ****************** */ -/* action links START */ -/* ****************** */ -.action_link_submit { - background: url(/static/img/design/action/submit.png) top right no-repeat; - width: 112px; - height: 25px; - display: block; -} -.action_link_submit:hover { - background-image: url(/static/img/design/action/submit_hover.png); -} -.action_link_signout { - background: url(/static/img/design/action/signout.png); - width: 83px; - height: 24px; - display: block; - float: right; - margin: 10px 0; -} -.action_link_signout:hover { - background: url(/static/img/design/action/signout_hover.png); -} -.action_link_profile { - background: url(/static/img/design/action/profile.png); - width: 71px; - height: 24px; - display: block; - float: right; - margin: 10px 0; -} -.action_link_profile:hover { - background: url(/static/img/design/action/profile_hover.png); -} -/* **************** */ -/* action links END */ -/* **************** */ -/* ************ */ -/* header START */ -/* ************ */ -/* LOGO */ -.eln_header_logo { - float: left; - padding-top: 7px; - padding-left: 17px; -} -/* Storage icon */ -#eln_header_storage_button { - background: none repeat scroll 0 0 transparent; - border: none; - cursor: pointer; - float: right; - font-size: 14px; - margin-top: 5px; - padding: 0; - height: 27px; - width: 32px; -} -#eln_header_storage_button span { - font-size: 10px; - margin-top: 14px; - position: absolute; - text-align: center; - width: 32px; - z-index: 6; -} -#eln_header_storage_stored { - background-color: #ededed; - height: 32px; - width: 32px; -} -#eln_header_storage_mask { - position: absolute; - z-index: 5; -} -#eln_header_storage_fill { - background-color: #BDCA70; - bottom: -5px; - position: absolute; - width: 32px; - z-index: 2; -} -/* Storage drop down panel */ -#eln_header_storage_panel { - background-color: #FFFFFF; - border: 3px solid #DDDDDD; - top: 53px; - z-index: 7; -} -#eln_header_storage_info { - cursor: default; -} -#eln_header_storage_info:hover { - color: #374858; -} -#eln_header_storage_info span { - font-size: 14px; - padding-right: 10px; - text-align: right; - width: 80px; -} -/* Storage percent bar */ -#eln_header_storage_bar_container { - float: right; - padding: 12px 10px 0; -} -#eln_header_storage_bar { - border: 1px solid #888; - height: auto; - line-height: 15px; - padding: 2px; - position: relative; - width: 80px; -} -span#eln_header_storage_bar_percent { - font-size: 12px; - line-height: 12px; - padding: 0; - position: absolute; - text-align: center; - width: 80px; -} -#eln_header_storage_bar_fill { - background-color: #bdca70; - height: 10px; -} -#eln_header_name { - display: inline-block; - line-height: 40px; - text-align: center; - text-overflow: ellipsis; - overflow: hidden; - padding: 0 5px; - vertical-align: top; - white-space: nowrap; -} -#eln_header_name div { - display: inline; -} -#eln_header_actions { - margin-right: 43px; -} -#eln_header_actions_button { - -webkit-box-sizing: border-box; - /* Safari/Chrome, other WebKit */ - -moz-box-sizing: border-box; - /* Firefox, other Gecko */ - box-sizing: border-box; - /* Opera/IE 8+ */ - background: none repeat scroll 0 0 transparent; - border: none; - cursor: pointer; - float: right; - font-size: 14px; - height: 50px; - margin: 0; - padding: 5px; -} -#eln_header_storage_button:hover, -#eln_header_actions_button:hover { - cursor: pointer; - background: #ededed; - border: none; - border-radius: 0; -} -#eln_header_storage_button:active { - margin: 5px 1px 0px 0px; -} -div#eln_header_actions_button.active { - background: #ededed; - border: none; - border-radius: 0; - margin: 0; -} -#eln_header_arrow span { - font-size: 18px; -} -#eln_header_arrow { - display: inline-block; - margin-top: 8px; - padding-left: 5px; - vertical-align: top; -} -#eln_header_actions_panel { - background-color: #FFFFFF; - position: absolute; - top: 53px; - z-index: 7; -} -.eln_header_actions_item { - border-top: 1px solid #D6D4D5; - cursor: pointer; - font-size: 14px; - line-height: 40px; - padding: 0 20px; -} -.eln_header_actions_item:first-child { - border-top: 0; -} -.eln_header_actions_item span { - float: right; - font-size: 18px; - line-height: 18px; - padding-top: 12px; - text-align: center; - width: 36px; -} -.eln_header_actions_item:hover { - background: #ededed; - color: #69bfee; -} -.colorbar { - height: 4px; - background: url(/static/img/design/colorbar.png); -} -/* ************ */ -/* header END */ -/* ************ */ -/* **************** */ -/* navigation START */ -/* **************** */ -#eln_navigation { - position: fixed; - top: 70px; - width: 75px; - border-radius: 0 10px 0 0; - box-shadow: 0 3px 10px #888; - background: #FFF; - bottom: 0; - left: 0; - z-index: 2; - text-align: center; -} -#eln_navigation a { - border-bottom: 1px solid #d6d4d5; - display: block; - text-decoration: none; - padding: 10px 0; - font-size: 12px; - color: #374858; - transition: all ease 0.2s; -} -#eln_navigation a:hover { - background: #ededed; - color: #69bfee; -} -#eln_navigation a:first-child { - border-radius: 0 10px 0 0; -} -#eln_navigation span { - display: block; - font-size: 24px; - margin-bottom: 3px; -} -#eln_navigation span.icon-group { - font-size: 20px; - margin-left: 9px; -} -#eln_navigation span.icon-inventory { - margin-left: 4px; -} -#eln_navigation span.icon-template { - margin-left: 5px; -} -#eln_navigation .highlight { - color: #69bfee; -} -#eln_navigation .disabled, -#eln_navigation .disabled:hover { - color: #ccc; -} -#eln_navigation button { - border: 5px solid white; - border-radius: 10px; - color: #FFF; - cursor: pointer; - font-size: 11px; - outline: none; - width: 70px; - height: 70px; -} -#feedback_button span, -#invite_button span { - font-size: 22px; -} -#invite_button { - background-color: #bdca70; -} -#feedback_submit { - margin-right: 6px; - width: 60px; - height: 30px; - font-weight: bold; -} -#feedback_button { - background-color: #ad4e88; -} -.eln_navigation_support_buttons { - margin-top: 100px; -} -#feedback_panel { - display: none; - position: fixed; - top: -2px; - left: 0; - z-index: 102; - background: #d9e1e8; - border: 3px solid #ab48a9; - -webkit-box-shadow: 2px 6px 10px rgba(55, 72, 88, 0.3); - -moz-box-shadow: 2px 6px 10px rgba(55, 72, 88, 0.3); - box-shadow: 2px 6px 10px rgba(55, 72, 88, 0.3); -} -.feedback_title { - background: #ab48a9; - color: white; - padding: 5px; - text-align: center; - font-size: 15px; - line-height: 20px; -} -.feedback_title h4 { - display: inline-block; -} -.feedback_title img { - vertical-align: top; - margin-left: 10px; -} -.feedback_content { - padding: 10px; - width: 390px; -} -.feedback_content h4 { - font-size: 12px; -} -#feedback_panel h4 { - margin: 10px; - margin-bottom: 5px; -} -#feedback_comment { - margin: 0 10px 30px 10px; - margin-top: 0; - width: 350px; - height: 120px; -} -#feedback_submit_loader { - display: none; - margin: 8px 15px; -} -/* ************** */ -/* navigation END */ -/* ************** */ -/* ********* */ -/* EPB START */ -/* ********* */ -#epb_container { - /* padding-top: 10px; */ - /* padding-bottom: 80px; */ -} -img.imageOriginal { - border: 1px solid #DDD; - -webkit-box-sizing: border-box; - /* Safari/Chrome, other WebKit */ - -moz-box-sizing: border-box; - /* Firefox, other Gecko */ - box-sizing: border-box; - /* Opera/IE 8+ */ - transition: all linear 0.2s; -} -img.imageLayer { - left: 0; - margin-left: auto; - margin-right: auto; - position: absolute; - right: 0; - top: 0; - transition: all linear 0.2s; -} -#commentBlock { - border-radius: 10px; - cursor: pointer; - position: absolute; - right: 15px; - width: 200px; - background: #FFF; - top: 1px; -} -#epb_older_blocks_panel, -#epb_newer_blocks_panel { - text-align: center; - color: #999; - height: 30px; - line-height: 30px; - margin: 10px 0; -} -.show_more_entries { - font-size: 13px; - margin: auto; - width: 300px; - background: white; - padding: 10px; - text-align: center; - -webkit-box-shadow: 0 3px 4px rgba(55, 72, 88, 0.3); - -moz-box-shadow: 0 3px 4px rgba(55, 72, 88, 0.3); - box-shadow: 0 3px 4px rgba(55, 72, 88, 0.3); -} -.show_more_entries span { - color: #1995d8; - cursor: pointer; -} -.epb_entry { - /* background-color: white; */ - /* border: 1px solid #CCC; */ - /* border-radius: 10px; */ - display: inline-block; - /* margin-right:25px; */ - margin-bottom: 20px; -} -#epb_container { - padding-bottom: 60px; -} -.epb_entry:last-child { - margin-bottom: 10px; -} -.epb_entry_removed { - border: 1px solid #F88; - box-sizing: border-box; -} -.epb_entry p { - margin: 0 !important; -} -.epb_header { - /* height: 35px; */ - /* min-width: 640px; */ - /* border-bottom: 1px solid #d6d4d5; */ - /* padding: 10px 10px 0 10px; */ - /* background-color: #ededed; */ - /* border-radius: 10px 10px 0 0; */ - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; -} -/* .epb_header_container { */ -/* height: 45px; */ -/* } */ -.epb_header_sticky { - position: fixed; - top: 86px; - z-index: 10; - transition: width ease-in 0.3s; -} -.epb_header_sticky div.action_button_text { - margin-left: 5px; -} -.epb_header_sticky div.more_options { - margin-right: 5px; -} -/*Hack for comments*/ -.epb_content_wrap { - display: table; - /* width: 100%; */ -} -.epb_show_comments .epb_content_container { - display: table-cell; - width: 85%; -} -.epb_show_comments .comment_block_container { - display: table-cell; -} -/*End of comment Hack */ -.epb_footer { - font-size: 9px; - height: auto; - margin-left: 30px; - margin-right: 45px; - position: relative; - padding: 5px; - background: #cad4de; - border-top: solid 1px white; - -webkit-box-shadow: 0 2px 2px rgba(55, 72, 88, 0.3); - -moz-box-shadow: 0 2px 2px rgba(55, 72, 88, 0.3); - box-shadow: 0 2px 2px rgba(55, 72, 88, 0.3); -} -.epb_footer_signing_infos { - display: inline-block; - text-align: left; -} -.epb_footer_witness_actions { - display: inline-block; - margin-right: 10px; -} -.epb_footer_witness_actions a { - padding-left: 10px; - line-height: 25px; -} -.epb_date { - border-right: 1px solid #d6d4d5; - margin-right: 10px; - padding-right: 10px; - padding-top: 2px; - font-size: 12px; - float: right; - text-align: right; -} -.epb_author { - border-right: 1px solid #d6d4d5; - margin-right: 10px; - padding-right: 10px; - padding-top: 2px; - padding-left: 5px; - font-size: 12px; - float: right; -} -.epb_author_picture { - border: 1px solid #d6d4d5; - float: right; - margin-top: 2px; -} -.epb_comments_alert { - /* color: #FFFFFF; */ - /* float:right; */ - /* margin-right: 5px; */ - cursor: pointer; -} -.epb_comments_count { - /* position: relative; */ - /* top: 7px; */ - /* left: 50%; */ - /* margin-left: 3px; */ - /* vertical-align: top; */ -} -.epb_header_action { - line-height: 24px; - padding-right: 15px; - padding-top: 2px; - font-size: 12px; - float: left; -} -.epb_default_slider_container { - cursor: pointer; -} -div.epb_relative_zoom { - margin-left: 2px; - font-size: 14px; - display: inline-block; - position: relative; - width: 12px; - height: 16px; - vertical-align: text-bottom; -} -div.epb_relative_zoom:hover { - /* color: #69bfee; */ -} -.epb_default_slider { - background-color: #ededed; - border: 1px solid #DDDDDD; - border-radius: 7px; - box-shadow: #B6B4A8 0 1px 7px inset; - box-sizing: border-box; - cursor: pointer; - display: inline-block; - height: 14px; - max-width: 100%; - overflow: hidden; - padding: 0; - position: relative; - width: 114px; - margin: 0 5px 0 4px; -} -.epb_default_slider_active { - background-color: #EFEFE7; - border: 1px solid #99968F; - border-radius: 6px; - box-sizing: border-box; - height: 12px; - position: relative; - width: 12px; - transition: all ease 0.2s; - left: 0; - z-index: 2; -} -.epb_default_slider_active:hover { - box-shadow: #888888 -1px -1px 3px inset; -} -.epb_default_slider_active:active { - background-color: #DDD; - box-shadow: #AAA 1px 1px 2px inset; -} -.epb_default_slider_bar { - background: #69bfee; - /* fallback */ - background: rgba(75, 177, 215, 0.5); - box-shadow: #B6B4A8 0 1px 7px inset; - box-sizing: border-box; - border-bottom-left-radius: 6px; - border-top-left-radius: 6px; - border: 0; - height: 16px; - margin-top: -14px; - padding: 0; - position: relative; - width: 0px; - transition: all ease 0.2s; - z-index: 1; -} -.epb_default_slider_zoom { - cursor: default; - display: block; - line-height: 30px; - width: 100%; - text-align: center; -} -.epb_text_save_cancel { - display: none; -} -.epb_text_save_cancel a { - padding-left: 10px; -} -.epb_file { - margin: 20px 0; -} -.epb_image { - margin: 20px 0; - position: relative; -} -.epb_image .imageLayer { - position: absolute; - top: 0; - left: 0; -} -.epb_image_zoom { - margin-top: 5px; -} -.epb_image_zoom img { - cursor: pointer; -} -.epb_image_zoom_square { - background-color: transparent; - border: 1px solid #666; - margin: 0 1px; -} -.epb_image_zoom_square_active { - background-color: #666; -} -.epb_new_panel { - background: #ededed; - border: 2px solid #CCC; - border-bottom: none; - border-radius: 5px 5px 0 0; - bottom: 0; - height: 40px; - left: 50%; - margin-left: -250px; - padding: 5px; - position: absolute; - text-align: center; - z-index: 2; -} -.epb_new_panel_middle { - background: url(/static/img/design/epb_new_panel_middle.png) repeat-x; - float: left; - height: 55px; - padding-top: 25px; -} -.epb_new_panel_left { - background: url(/static/img/design/epb_new_panel_left.png) no-repeat; - float: left; - height: 80px; - width: 30px; - position: relative; -} -.epb_new_panel_right { - background: url(/static/img/design/epb_new_panel_right.png) no-repeat; - float: left; - height: 80px; - width: 30px; -} -.epb_new_panel .default_button { - margin: 0 5px; -} -#epb_new_panel_jump_to_end { - display: none; -} -#epb_new_panel_jump_to_end div { - float: left; - font-size: 14px; - line-height: 30px; -} -.epb_entry_removed_msg_head { - display: none; - margin: 0 200px; - text-align: center; - color: #F88; - padding-top: 5px; -} -/* ******* */ -/* EPB END */ -/* ******* */ -/* ******************* */ -/* block history START */ -/* ******************* */ -.block_history_table { - border-collapse: collapse; - width: 100%; -} -tr.history_row:nth-child(odd) { - background-color: #fff; - cursor: pointer; - height: 23px; -} -tr.history_row:nth-child(even) { - background-color: #f0f0f0; - cursor: pointer; - height: 23px; -} -.block_history_table td.col1 { - padding: 3px 0 3px 5px; -} -.block_history_table td.col2 { - padding: 3px 10px 3px 10px; -} -.block_history_table td.col3 { - padding: 3px 0; -} -#block_history_navigation { - position: absolute; - width: 350px; - bottom: 0; - top: 30px; - left: 0; - overflow: auto; - border-right: 2px solid #374858; -} -#block_history_item_content { - position: absolute; - right: 0; - bottom: 0; - top: 30px; - left: 350px; - padding: 0 20px; - overflow: scroll; -} -.block_history_row_selected { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - background-color: #DDD !important; - color: #4BB1D1; -} -/* ***************** */ -/* block history END */ -/* ***************** */ -/* ************** */ -/* plupload START */ -/* ************** */ -.plupload_select { - width: 110px; - height: 24px; - margin: 0 auto; -} -.plupload_drop { - border: 2px dashed black; - width: 200px; - height: 80px; - margin: 0 auto; - background-color: #77ff66; -} -#plupload_container { - position: absolute; - top: -100px; - left: 0; - width: 100px; - height: 50px; - overflow: hidden; -} -/* ************ */ -/* plupload END */ -/* ************ */ -/* *************** */ -/* workspace START */ -/* *************** */ -.workspace_header_actions { - height: 50px; -} -.workspace_header_actions .default_button { - margin-right: 15px; -} -.workspace_header_link { - margin-right: 15px; - line-height: 36px; -} -.workspace_header_link span { - font-weight: bold; -} -/** Modified at the end of the section -.workspace_header { - background-color: #F3F3F3; - border: 1px solid #DDD; - line-height: 36px; - padding: 5px; - padding-left: 15px; -}*/ -.workspace_header_path a { - outline: none; - color: #fff; - text-decoration: none; -} -.workspace_header_path a:hover { - color: #69bfee; -} -.project_list_children { - display: none; - margin-left: 30px; -} -.project_list_head { - border: 1px solid #DDD; - border-radius: 10px; - background-color: #f3f3f3; - padding: 10px 0; - height: 12px; -} -.project_list_head .name { - margin-left: 15px; -} -.project_list_head .updateTS { - float: right; - margin-right: 15px; -} -.project_list { - min-height: 350px; - margin: 0 25px 25px 0; - background-color: #ffffff; - border-bottom: solid 1px #cad4de; - border-left: solid 1px #cad4de; - border-right: solid 1px #cad4de; - position: relative; - padding: 20px 20px 20px 135px; - -webkit-box-shadow: 0 2px 2px rgba(55, 72, 88, 0.1); - -moz-box-shadow: 0 2px 2px rgba(55, 72, 88, 0.1); - box-shadow: 0 2px 2px rgba(55, 72, 88, 0.1); -} -.project_list_line { - /* background: url(/static/icon/project40.png) no-repeat 0 -40px; */ - display: block; - outline: none; - color: #4b6277; - cursor: pointer; - text-decoration: none; - line-height: 1.2; - font-size: 14px; - padding: 5px 15px; - border: 1px solid transparent; - overflow: hidden; -} -.project_list_line > span { - color: #4b6277; - line-height: 1.2; - font-size: 14px; -} -.project_list_line:hover { - background-position: 0 0; - background: #ecf0f3; - text-decoration: none; -} -.project_list_line.is_folder { - background: url(/static/icon/folder40.png) no-repeat 0 -40px; -} -.project_list_line:hover.is_folder { - background-position: 0 0; -} -.project_list_line.is_group { - /* background: url(/static/icon/group40.png) no-repeat 0 -40px; */ -} -.project_list_line:hover.is_group { - background-position: 0 0; -} -.project_list_line img { - vertical-align: top; -} -.project_list_line .name { - font-size: 14px; -} -.project_list_line .updateTS { - font-size: 15px; - float: right; - margin-right: 15px; -} -a.order_link { - font-size: 12px; - outline: none; - color: #374858; - text-decoration: none; -} -a.order_link:hover { - color: #69bfee; -} -a.order_link_asc { - padding-right: 12px; - background: url(/static/icon/order_sign.png) no-repeat right -65px; -} -a.order_link_desc { - padding-right: 12px; - background: url(/static/icon/order_sign.png) no-repeat right -45px; -} -a.order_link_asc:hover { - padding-right: 12px; - background: url(/static/icon/order_sign.png) no-repeat right -25px; -} -a.order_link_desc:hover { - padding-right: 12px; - background: url(/static/icon/order_sign.png) no-repeat right -5px; -} -.workspace_header { - background: #374858 repeat-x 0 0; - border: 1px solid #DDD; - border-radius: 10px; - height: 35px; - line-height: 5px; - padding: 5px 10px; -} -.workspace_name { - color: #FFFFFF; - float: left; - font-size: 24px; - height: 32px; - line-height: 32px; - margin-top: 5px; - overflow: hidden; - text-overflow: ellipsis; - width: 90%; - white-space: nowrap; -} -.workspace_name a { - color: #FFF; -} -.workspace_name a:hover { - color: #69bfee; - text-decoration: none; -} -/* ************* */ -/* workspace END */ -/* ************* */ -/* ******************* */ -/* profile block START */ -/* ******************* */ -#user_settings_innovation_level_form select { - background: #ffffff; - border: 1px solid #d9e1e8; - color: #5e7b97; - cursor: pointer; - margin: 0 0 0 10px; - padding: 4px 4px 4px 8px; - outline: 0; -} -#profile_picture_edit_panel { - float: left; - margin-right: 20px; - margin-bottom: 15px; - padding-left: 5px; -} -#profile_picture_edit_panel img { - border: 1px solid #bac7d4; - margin-top: 10px; - width: 100px; - height: 100px; -} -.profile_block { - padding-left: 15px; - width: 550px; - margin-bottom: 20px; -} -.profile_block_edit { - display: block; - float: right; - margin-right: 5px; - font-size: 12px; -} -.profile_edit .placeholder_frame { - margin: 0 5px 5px 0; -} -.project_pdf_export_list { - background: #ffffff; - border: 1px solid #DDD; - height: 125px; - margin: 15px 0 30px 0; - padding: 5px; - overflow-y: scroll; -} -.project_pdf_export_list div { - line-height: 18px; - height: 18px; - overflow: hidden; -} -.pdf_range_export label { - display: block; - text-align: left; -} -/*FIND A BETTER WAY WITH last-child*/ -#profile_contact { - border: none; - padding-bottom: 0px; -} -#profile_picture_edit_link { - position: relative; -} -#profile_picture_edit_panel span { - opacity: 0; - height: 25px; - left: 0; - line-height: 25px; - position: absolute; - text-align: center; - top: 86px; - width: 100px; - -webkit-transition: all 0.3s ease; - -moz-transition: all 0.3s ease; - -o-transition: all 0.3s ease; - transition: all 0.3s ease; -} -#profile_picture_edit_panel:hover span { - background: rgba(75, 98, 119, 0.95); - opacity: 1; - color: white; -} -.profile_block_img { - display: block; -} -#updatePersonalForm .placeholder_frame { - float: none; - width: 380px; -} -.profile_block_key { - float: left; - font-weight: bold; - font-size: 12px; - height: 24px; - line-height: 24px; - margin-bottom: 10px; - width: 100px; -} -#profile_settings .profile_block_key { - padding-left: 5px; - width: 200px; -} -#profile_settings .profile_block h2 { - margin: 0 0 15px 0; -} -.edit_wrap { - width: 100%; - height: 10px; -} -.profile_block_value { - float: left; - line-height: 24px; - font-size: 12px; -} -.general_setting_item { - margin-bottom: 20px; -} -.profile_block_value input[type=text], -.profile_block_value input[type=password] { - width: 330px; -} -.profile_block_error { - color: red; - display: block; - line-height: 20px; -} -.cancel_save_panel { - float: right; - margin-right: 5px; - line-height: 36px; - margin-top: 20px; -} -.cancel_save_panel .cancel { - float: left; - padding-right: 10px; - font-size: 12px; -} -.profile_block h1 { - margin: 0; - font-size: 14px; -} -.profile_block h2 { - margin: 0 0 5px 0; - padding: 0 0 2px 4px; - color: #7b95ad; - border-bottom: 1px solid #9baec0; - font-size: 12px; - font-weight: normal; -} -.profile_show { - padding: 10px 0 2px 4px; - margin-bottom: 20px; -} -.profile_edit { - padding: 10px 0 2px 4px; - float: left; - display: block; -} -.profile_edit_personal { - width: 400px; -} -.profile_block h3 { - font-size: 12px; - margin: 10px 0; - font-weight: normal; -} -.profile_section { - min-height: 100px; - display: block; - overflow: auto; - margin-bottom: 20px; -} -.profile_prof_head { - width: 400px; -} -.profile_name_field { - width: 200px; -} -.placeholder_frame label.profile_personalEdit { - padding: 5px; -} -.profileTitle_field { - width: 200px; -} -#profile_personal .profile_show div { - display: inline; -} -/* ***************** */ -/* profile block END */ -/* ***************** */ -/* ******************** */ -/* sticky infobox START */ -/* ******************** */ -.sticky_infobox { - width: 350px; - height: 310px; - background: url(/static/img/design/sticky_infobox_big.png) 0 0 no-repeat; - padding: 50px 65px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -/* ****************** */ -/* sticky infobox END */ -/* ****************** */ -/* ************ */ -/* search START */ -/* ************ */ -.search_wrap { - padding-left: 15px; -} -.search_wrap .placeholder_frame { - height: 30px; -} -.search_wrap .placeholder_frame input { - height: 30px; -} -.search_wrap .placeholder_frame label { - padding: 4px 0 0 5px; - font-size: 14px; -} -.search_wrap .placeholder_frame button.search_button { - height: 30px; -} -.top_searchbox_form { - float: right; - position: relative; - top: 12px; - padding-right: 10px; -} -.search_result_item { - padding-bottom: 20px; - width: 560px; -} -.search_result_item_title { - text-decoration: underline; - font-size: 12px; -} -.search_result_item_title:hover { - text-decoration: underline; - color: #3b97ed; -} -.search_result_item_text { - font-size: 12px; -} -#search_result_load_more_spinner { - display: none; -} -#search_result_load_more_link { - display: none; -} -#search_result_error_message { - display: none; - color: red; -} -#search_result_num_all_results { - display: none; - color: #999; - font-size: 12px; - padding: 3px; -} -.search_result_content { - padding-top: 20px; -} -/* ********** */ -/* search END */ -/* ********** */ -.default_font { - font-family: Arial, Helvetica, Verdana, Tahoma, sans-serif; - font-size: 15px; - line-height: 1.45em; - white-space: normal; -} -#data_element { - display: none; -} - -/**************/ -/* IE WARNING */ -/**************/ -#ie_warning { - display: none; - background-color: #E66873; - color: #FFF; - font-size: 14px; - height: 30px; - left: 50%; - line-height: 14px; - margin-left: -310px; - padding: 5px; - position: fixed; - text-align: center; - width: 550px; - z-index: 9999; -} -a#ie_warning_close { - color: #FFF; - float: right; - font-size: 12px; - cursor: pointer; -} -a#ie_warning_update { - color: #FFF; - font-size: 14px; - text-decoration: underline; -} -/****************************/ -/* admin active weeks START */ -/****************************/ -.activeWeeksTable { - border-spacing: 0; - border-collapse: collapse; - font-size: 8px; - background-color: #e5e5e5; - text-align: center; -} -.activeWeeksTable th { - border: 1px solid #374858; -} -.activeWeeksTable td { - border: 1px solid #374858; -} -.activeWeeksTable .week { - width: 20px; - height: 20px; -} -.activeWeeksTable .week.status1 { - background-color: white; -} -.activeWeeksTable .week.status2 { - background-color: #fcc; -} -.activeWeeksTable .week.status3 { - background-color: #cfc; -} -.activeWeeksTable .week.status3 { - background-color: #cfc; -} -.activeWeeksTable .premium { - background-color: #cfc; -} -/**************************/ -/* admin active weeks END */ -/**************************/ -/**************************/ -/* pdf viewer START */ -/**************************/ -#pdf_viewer { - border: 0; - display: block; - height: 100%; - width: 100%; -} -/**************************/ -/* pdf viewer END */ -/**************************/ -.activeExcelSheet { - font-weight: bold; -} -a.editor_reference { - color: #a21621; - cursor: pointer; - font-weight: bold; - text-decoration: none; -} -.pdf_checkbox_label { - line-height: 32px; - margin-left: 25px; -} -.pdf_checkbox_sublabel { - line-height: 32px; - margin-left: 45px; -} -.pdf_setting_description { - margin-left: 50px; - font-size: 12px; -} -.pdf_filename_label { - display: block; - margin: 10px 0 10px 32px; -} -/**************************/ -/* END */ -/**************************/ -#block_history_item_content .extract_preview_link, -.readOnly .extract_preview_link { - display: none; -} -.extract_preview { - overflow: auto; -} -.extract_preview_confirm { - float: right !important; - margin-right: 25px; -} -/*********************/ -/* jsTemplates START */ -/*********************/ -#jsTemplates { - display: none; -} -p.jsTemplate_dialog_title { - display: none; -} -/*******************/ -/* jsTemplates END */ -/*******************/ -/***************/ -/* popup START */ -/***************/ -.popup { - display: none; - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - z-index: 98; - -moz-opacity: .8; - opacity: 0.8; - background-color: white !important; -} -.popup_window { - display: none; - position: absolute; - z-index: 99; - background-color: white; - /* border: 2px solid #374858; */ - -webkit-box-shadow: 0 4px 10px rgba(55, 72, 88, 0.3); - -moz-box-shadow: 0 4px 10px rgba(55, 72, 88, 0.3); - box-shadow: 0 4px 10px rgba(55, 72, 88, 0.3); -} -.popup_window_default { - top: 75px; - bottom: 75px; - left: 75px; - right: 75px; -} -#my_popup_inner { - background-color: #cad4de; -} -.popup_dialog { - display: none; - position: absolute; - z-index: 99; - background-color: #cad4de; - top: 30%; - left: 50%; - width: 400px; - margin-top: -125px; - margin-left: -200px; - -webkit-box-shadow: 0 4px 10px rgba(55, 72, 88, 0.8); - -moz-box-shadow: 0 4px 10px rgba(55, 72, 88, 0.8); - box-shadow: 0 4px 10px rgba(55, 72, 88, 0.8); -} -.popup_title { - height: 30px; - line-height: 30px; - margin-top: -1px; - padding-left: 5px; - background: #304d69; - color: white; -} -.popup_title_close { - font-size: 20px; - width: 20px; - height: 20px; - text-align: center; - line-height: 20px; - float: right; - cursor: pointer; - margin: 4px; -} -.popup_title_left { - float: left; -} -.popup_title_center { - text-align: center; -} -.popup_title_center span { - display: none; -} -.popup_loading_image { - margin: 50px auto; - background: url(/static/img/ajax-loader-big.gif) no-repeat; - width: 32px; - height: 32px; -} -.popup_dialog .popup_dialog_content { - max-height: 650px; - overflow: auto; - padding: 10px; -} -.popup_dialog_cancel_save_panel { - float: right; - margin-top: 10px; - line-height: 30px; -} -.popup_dialog_cancel_save_panel .cancel { - float: left; - padding-right: 5px; - font-size: 12px; - visibility: hidden; -} -.popup_dialog_cancel_save_panel .dialog_confirm { - visibility: hidden; -} -#import_footer .dialog_confirm { - visibility: visible; -} -.popup_dialog_cancel_save_panel .default_button { - margin-left: 5px; -} -.popup_scroll_content { - position: absolute; - right: 0; - bottom: 0; - top: 30px; - left: 0; - padding: 10px; - overflow: auto; -} -.popup_list_row { - padding-bottom: 15px; - margin-bottom: 15px; - border-bottom: 1px solid #DDD; -} -.popup_list_row .default_button { - float: right; -} -.popup_list_row .deny_link { - float: right; - line-height: 36px; - font-size: 12px; - margin: 0 5px; -} -.popup_list_row_desc { - padding-top: 12px; - margin-right: 125px; -} -.popup_dialog_error { - background-color: #E66873; - color: #FFF; - display: none; - font-size: 14px; - line-height: 18px; - padding: 5px; - text-align: center; -} -.popup_dialog_loading_button { - padding: 0 10px; -} -#my_popup_content { - height: calc(100% - 29px); - overflow: auto; -} -.input_block { - margin-bottom: 20px; - word-wrap: break-word; - font-size: 12px; -} -.input_block .folder_up-img { - background-position: -738px -5px; - width: 24px; - height: 13px; -} -.tagline_hidden { - display: none; -} -.input_title { - margin: 10px 0 5px; - font-size: 12px; - color: #4b6277; -} -#my_popup_content .input_title:first-of-type { - /* margin: 0 0 5px 0; */ -} -#my_popup_content .spinner { - display: block; - margin: auto; -} -#my_popup_content textarea { - color: #4b6277; - line-height: 1.4; - font-size: 14px; - height: 150px; - resize: none; -} -/*************/ -/* popup END */ -/*************/ -/**************************/ -/* custom selectbox START */ -/**************************/ -div.lfSelectBox { - position: relative; - cursor: pointer; - background-color: white; - width: 0; - float: left; -} -div.lfSelectTitle { - border: 1px solid black; -} -div.lfSelectOptions { - position: absolute; - border: 1px solid black; - background: white; - z-index: 99; - display: none; -} -div.lfSelectOption:hover { - color: #E7E7E7; - background: #3988e5; -} -/************************/ -/* custom selectbox END */ -/************************/ -/* ************ */ -/* button START */ -/* ************ */ -a.btn, -button.btn { - background: transparent url(/static/img/button/button_right.gif) no-repeat scroll top right; - border: 0; - color: #666; - cursor: pointer; - display: block; - float: left; - font-size: 14px; - line-height: 16px; - height: 24px; - margin-right: 6px; - outline: none; - padding-right: 16px; - padding-top: 0; - text-decoration: none; -} -a.btn span, -button.btn span { - background: transparent url(/static/img/button/button_left.gif) no-repeat; - display: block; - padding: 4px 0 4px 18px; -} -a.btn img, -button.btn img { - vertical-align: top; -} -a.btn:active, -button.btn:active { - background-position: bottom right; -} -a.btn:active span, -button.btn:active span { - background-position: bottom left; - padding: 5px 0 3px 18px; -} -/* a.btn36, button.btn36 { */ -/* background-color: transparent; */ -/* border: 0; */ -/* margin: 0; */ -/* padding: 0; */ -/* color: white; */ -/* cursor: pointer; */ -/* display: block; */ -/* float: left; */ -/* font-size: 14px; */ -/* line-height: 16px; */ -/* height: 36px; */ -/* outline: none; */ -/* text-decoration: none; */ -/* font-family: 'din-medi'; */ -/* } */ -/* a.btn36 img, button.btn36 img { */ -/* vertical-align: top; */ -/* margin-right: 7px; */ -/* } */ -/* a.btn36 span, button.btn36 span { */ -/* display: block; */ -/* float: left; */ -/* } */ -/* a.btn36 span.m, button.btn36 span.m { */ -/* background: url(/static/img/button/b36_m.png) repeat-x 0 0; */ -/* height: 16px; */ -/* padding: 10px 1px 10px 1px; */ -/* } */ -/* a.btn36 span.l, button.btn36 span.l { */ -/* background: url(/static/img/button/b36_l.png) no-repeat 0 0; */ -/* width: 15px; */ -/* height: 36px; */ -/* } */ -/* a.btn36 span.r, button.btn36 span.r { */ -/* background: url(/static/img/button/b36_r.png) no-repeat 0 0; */ -/* width: 15px; */ -/* height: 36px; */ -/* } */ -/* a.btn36:hover span, button.btn36:hover span { */ -/* background-position: 0 -36px; */ -/* } */ -/* a.btn36:active span, button.btn36:active span { */ -/* background-position: 0 -72px; */ -/* } */ -/* a.btn36:active span.m, button.btn36:active span.m { */ -/* padding: 11px 0px 9px 2px; */ -/* } */ -/* ********** */ -/* button END */ -/* ********** */ -/* ************ */ -/* errors START */ -/* ************ */ -.errorBox { - border: 1px solid red; -} -.errorInput { - background-color: red; -} -.errorMessage { - color: red; -} -/* ********** */ -/* errors END */ -/* ********** */ -/* *********************** */ -/* input placeholder START */ -/* *********************** */ -.placeholder_frame { - position: relative; - float: left; -} -.placeholder_frame label { - position: absolute; - padding: 7px 0 0 5px; - top: 2px; - left: 0; - color: #9baec0; - font-style: italic; - font-family: Arial; - cursor: text; - font-size: 14px; -} -.placeholder_frame input { - padding: 5px; - margin: 0; - font-size: 14px; - line-height: 14px; - color: #4b6277; -} -.placeholder_frame button { - position: absolute; - height: 28px; - padding: 7px; - top: 0; - right: 0; -} -.placeholder_frame input.searchbox_input { - width: 250px ; - padding-right: 30px; - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; -} -.placeholder_frame.big label { - font-size: 20px; - padding: 10px 0 0 12px; -} -.placeholder_frame.big input { - padding: 10px; - padding-right: 50px; - width: 500px; - font-size: 20px; - line-height: 20px; -} -.placeholder_frame.big button { - padding: 10px; - font-size: 20px; -} -/* *********************** */ -/* input placeholder END */ -/* *********************** */ -/* ************ */ -/* inputs START */ -/* ************ */ -.input_with_padding { - padding: 3px; - width: 100%; -} -.form_around_input_with_padding { - padding-right: 5px; -} -/* ********** */ -/* inputs END */ -/* ********** */ -.aligned_radio_button { - display: -moz-inline-box; - display: inline-block; - vertical-align: middle; - line-height: 18px; - margin-bottom: 5px; -} -input { - outline: 0; -} -textarea { - outline-color: #69bfee; -} -input[type="checkbox"].default_checkbox { - position: absolute; - opacity: 0; -} -input[type="checkbox"].default_checkbox + div { - cursor: pointer; - display: inline-block; - vertical-align: middle; - width: 46px; - height: 13px; - border: 1px solid rgba(55, 72, 88, 0.47); - border-radius: 999px; - margin: 0 .5em; - background: #f9fafb; - background-image: linear-gradient(rgba(176, 205, 231, 0.2), rgba(0, 0, 0, 0)), linear-gradient(90deg, #374858, rgba(0, 0, 0, 0) 65%); - background-size: 200% 100%; - background-position: 100% 0; - background-origin: border-box; - background-clip: border-box; - overflow: hidden; - transition-duration: .3s; - transition-property: padding, width, background-position, text-indent; - box-shadow: 0 0.2em 0.4em rgba(14, 27, 37, 0.12) inset, 0 0.45em 0 0.1em rgba(45, 98, 133, 0.05) inset; - font-size: 150%; -} -input[type="checkbox"].default_checkbox:checked + div { - padding-left: 33px; - width: 46px; - background-position: 0 0; -} -input[type="checkbox"].default_checkbox + div:before { - content: 'On'; - float: left; - width: 13px; - height: 13px; - margin: -1px; - border: 1px solid rgba(55, 72, 88, 0.35); - border-radius: inherit; - background: white; - background-image: linear-gradient(#8fa1b4, transparent); - box-shadow: 0 0.1em 0.1em 0.1em rgba(255, 255, 255, 0.8) inset, 0 0 0.5em rgba(55, 72, 88, 0.3); - color: white; - text-shadow: 0 -1px 1px rgba(0, 0, 0, 0.3); - text-indent: -2.5em; -} -input[type="checkbox"].default_checkbox:active + div:before { - background-color: #eee; -} -input[type="checkbox"].default_checkbox + div:before, -input[type="checkbox"].default_checkbox + div:after { - font-size: 9px; - line-height: 12px; - font-weight: bold; - text-transform: uppercase; -} -input[type="checkbox"].default_checkbox + div:after { - content: 'Off'; - float: left; - text-indent: .5em; - color: #4b6277; - text-shadow: none; -} -/* Draggable */ -div.action_button.dragging_helper { - width: 42px; - height: 24px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - padding: 2px 10px; - background-image: url('/static/img/design/blank.png') !important; - background-color: #FFF; - border-radius: 2px; - box-shadow: 0 1px 4px #646464; - color: #69bfee; - cursor: pointer; - opacity: 0.8; - text-decoration: none; - z-index: 50; -} -a.dragging_helper { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - background-image: url('/static/img/design/blank.png') !important; - background-color: #FFF; - border-radius: 2px; - box-shadow: 1px 1px 5px #000; - color: #69bfee; - cursor: pointer; - opacity: 0.5; - padding: 10px 30px; - text-decoration: none; - z-index: 50; -} -.dialog_message_form textarea { - min-height: 150px; -} -/************* -* header css * -**************/ -.arrow_box { - position: relative; - background: white; -} -.arrow_box:after, -.arrow_box:before { - bottom: 100%; - left: 50%; - border: solid transparent; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; -} -.arrow_box:after { - border-color: rgba(0, 0, 0, 0); - border-bottom-color: white; - border-width: 5px; - margin-left: -4px; -} -.arrow_box:before { - border-color: rgba(0, 0, 0, 0); - border-bottom-color: #bac7d4; - border-width: 6px; - margin-left: -5px; -} -.headerbar_top { - width: 100%; - height: 50px; - background: white; - border-bottom: solid 1px #bac7d4; -} -.headerbar_top > header { - margin: 21px 0 0 65px; - font-weight: bold; - float: left; - position: relative; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - color: #415568; -} -.headerbar_top > header:hover .page_title { - position: absolute; - overflow: visible; - white-space: normal; - display: block; - margin-left: 21px; - z-index: 999; - background: white; - -webkit-box-shadow: 0 2px 4px rgba(55, 72, 88, 0.2); - -moz-box-shadow: 0 2px 4px rgba(55, 72, 88, 0.2); - box-shadow: 0 2px 4px rgba(55, 72, 88, 0.2); -} -.headerbar_top h1 { - font-size: 14px; - font-weight: normal; - margin: 0; -} -.headerbar_top > nav { - float: right; - height: 50px; -} -.headerbar_top a { - color: inherit; - text-decoration: none; - cursor: pointer; -} -.page_title { - white-space: nowrap; - text-overflow: ellipsis; - display: block; - overflow: hidden; - padding: 0; - background: white; - margin-left: 0; -} -.page_title a { - white-space: nowrap; -} -.nav_top { - float: left; - margin: 0 100px 0 10px; -} -.nav_top > ul { - margin: 0; - padding: 0; -} -.nav_top > ul > li { - width: 72px; - height: 49px; - margin-left: -1px; - list-style-type: none; - float: left; - position: relative; - -webkit-transition: all 0.2s ease; - -moz-transition: all 0.2s ease; - -o-transition: all 0.2s ease; - transition: all 0.2s ease; -} -.header_btn { - width: 100%; - height: 100%; - color: #4b6277; - padding: 0; - text-align: center; - font-size: 10px; - position: relative; - cursor: pointer; - background: transparent; - border-left: solid 1px transparent; - border-right: solid 1px transparent; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; - -webkit-transition: all 0.2s ease; - -moz-transition: all 0.2s ease; - -o-transition: all 0.2s ease; - transition: all 0.2s ease; -} -.header_btn span { - margin-left: auto; - margin-right: auto; - margin-top: 2px; - display: block; - float: none; -} -.header_btn p { - margin: 7px 0; -} -.header_btn:hover { - background: #f3f5f7; - -webkit-box-shadow: inset 0 1px 6px rgba(55, 72, 88, 0.1); - -moz-box-shadow: inset 0 1px 6px rgba(55, 72, 88, 0.1); - box-shadow: inset 0 1px 6px rgba(55, 72, 88, 0.1); - border-left: solid 1px #cad4de; - border-right: solid 1px #cad4de; - padding-top: 0; -} -.header_btn:active { - background: #d9e1e8; - padding-top: 0; - -webkit-box-shadow: inset 0 1px 6px rgba(55, 72, 88, 0.2); - -moz-box-shadow: inset 0 1px 6px rgba(55, 72, 88, 0.2); - box-shadow: inset 0 1px 6px rgba(55, 72, 88, 0.2); -} -.nav_top_active { - -webkit-box-shadow: inset 0 1px 6px rgba(55, 72, 88, 0.1); - -moz-box-shadow: inset 0 1px 6px rgba(55, 72, 88, 0.1); - box-shadow: inset 0 1px 6px rgba(55, 72, 88, 0.1); - background: #e0e6eb !important; - border-left: solid 1px #cad4de !important; - border-right: solid 1px #cad4de !important; -} -.manage_hover:hover .header_btn { - background: #f3f5f7; - -webkit-box-shadow: inset 0 1px 6px rgba(55, 72, 88, 0.1); - -moz-box-shadow: inset 0 1px 6px rgba(55, 72, 88, 0.1); - box-shadow: inset 0 1px 6px rgba(55, 72, 88, 0.1); - border-left: solid 1px #bac7d4; - border-right: solid 1px #bac7d4; - padding-top: 0px; -} -.manage_hover:active .header_btn { - background: #d9e1e8; - padding-top: 0px; - -webkit-box-shadow: inset 0 1px 6px rgba(55, 72, 88, 0.2); - -moz-box-shadow: inset 0 1px 6px rgba(55, 72, 88, 0.2); - box-shadow: inset 0 1px 6px rgba(55, 72, 88, 0.2); -} -.manage_dropdown { - position: absolute; - top: 49px; - left: 0; - font-size: 13px; - z-index: 999; -} -.manage_dropdown li { - width: 120px; -} -.manage_dropdown > span { - position: absolute; - top: -11px; - left: 25px; -} -.header_top_dropdown { - background: white; - display: none; - border: solid 1px #bac7d4; - border-right: solid 1px #bac7d4; - border-bottom: solid 1px #bac7d4; - -webkit-box-shadow: 0 4px 10px rgba(55, 72, 88, 0.3); - -moz-box-shadow: 0 4px 10px rgba(55, 72, 88, 0.3); - box-shadow: 0 4px 10px rgba(55, 72, 88, 0.3); - font-size: 13px; -} -.header_top_dropdown > ul { - margin: 0; - padding: 0; -} -.header_top_dropdown > ul li { - list-style-type: none; -} -.header_top_dropdown > ul { - padding: 12px 0 12px 0; -} -.header_top_dropdown > ul > li { - display: block; - text-align: left; - cursor: pointer; -} -.header_top_dropdown > ul > li > a { - padding: 8px 0 8px 12px; - display: block; -} -.header_top_dropdown > ul > li:hover { - background: #ecf0f3; -} -.bread_arrow { - font-size: 11px; -} -.options_top { - float: right; - margin: 10px 0 0 10px; - position: relative; -} -.options_top > ul { - margin: 0; - padding: 0; -} -.options_top > ul > li { - list-style-type: none; - float: left; - position: relative; -} -.options_top > ul > li { - width: 40px; - height: 50px; - margin-right: 15px; - display: block; - float: left; - font-size: 10px; - position: relative; -} -.options_top > ul > li:first-child > span { - margin-left: 10px; -} -.signout_wrap { - position: relative; - display: block; - width: 40px; - height: 32px; -} -.notes_count { - padding: 2px 2px 1px 2px; - line-height: 10px; - color: white; - background: #22a6ee; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; - position: absolute; - text-align: right; - left: 20px; - top: 0px; -} -.avatar { - border-radius: 50%; - width: 28px; - height: 28px; - background: #cad4de; - margin-top: -3px; - float: left; - -webkit-box-shadow: 0px 1px 2px rgba(55, 72, 88, 0.6); - -moz-box-shadow: 0px 1px 2px rgba(55, 72, 88, 0.6); - box-shadow: 0px 1px 2px rgba(55, 72, 88, 0.6); -} -.avatar span { - display: block; - float: none; -} -.avatar img { - border-radius: 50%; - width: 28px; - height: 28px; - position: absolute; -} -.avatar .avatar-img { - margin: 3px 0 0 4px; -} -.avatar .arrow_down_s-img { - position: absolute; - top: 12px; - right: 2px; -} -.dropdown_button { - cursor: pointer; -} -.search_dropdown { - width: 250px; - height: 51px; - padding: 10px; - position: absolute; - top: 39px; - left: -111px; - z-index: 999; -} -.search_dropdown > span { - position: absolute; - top: -11px; - left: 114px; -} -.search_dropdown input { - height: 30px; - width: 100%; - font-size: 14px; - color: #4b6277; - padding-left: 4px; - display: block; - margin: auto; - border: solid 1px #bac7d4; -} -.search_dropdown button { - position: absolute; - top: 10px; - right: 10px; - padding: 7px; - height: 30px; -} -.bell_dropdown { - position: absolute; - top: 39px; - left: -166px; - font-size: 12px; - line-height: 1.4; - z-index: 99; - max-height: 530px; - overflow-y: auto; - overflow-x: hidden; -} -.bell_dropdown > span { - position: absolute; - top: -11px; - left: 169px; -} -.bell_dropdown li { - width: 250px; - padding: 8px 0 8px 8px; -} -.bell_dropdown li span { - color: #69bfee; - font-weight: bold; -} -.bell_dropdown li article { - width: 200px; - display: inline-block; - margin-left: 10px; -} -.bell_dropdown li p { - color: #9baec0; - margin: 5px 0; -} -.bell_dropdown li:last-child { - text-align: center; - margin: 14px 0 -12px 0 !important; - background: #d9e1e8; -} -.profile_dropdown { - position: absolute; - top: 39px; - left: -70px; - font-size: 13px; - z-index: 999; - width: 120px; -} -.profile_dropdown > span { - position: absolute; - top: -11px; - left: 77px; -} -.profile_dropdown ul > li { - padding-left: 10px; -} -.profile_dropdown ul > li a { - width: 100%; -} -.med_blue_btn { - padding: 8px 17px 8px 17px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - color: white; - opacity: 1; - background: #3277b8; - font-size: 16px; - -webkit-transition: all 0.1s linear; - -moz-transition: all 0.1s linear; - -o-transition: all 0.1s linear; - transition: all 0.1s linear; - -webkit-backface-visibility: hidden; -} -.med_blue_btn:hover, -.med_blue_btn:focus { - background: #2a6398; - -ms-filter: none; - filter: none; - outline: 0; - color: white; - text-decoration: none; -} -.med_blue_btn:active { - background: #245684; - -ms-filter: none; - filter: none; - outline: 0; - -webkit-box-shadow: inset 0 3px 6px rgba(0, 0, 0, 0.4); - -moz-box-shadow: inset 0 3px 6px rgba(0, 0, 0, 0.4); - box-shadow: inset 0 3px 6px rgba(0, 0, 0, 0.4); -} -.orange_btn { - padding: 4px 17px 5px 17px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - color: #ffffff; - opacity: 1; - background: #e37900; - font-size: 20px; - -webkit-transition: all 0.1s linear; - -moz-transition: all 0.1s linear; - -o-transition: all 0.1s linear; - transition: all 0.1s linear; - -webkit-backface-visibility: hidden; -} -.upgrade_box { - position: relative; - background: #ffffff; - display: inline-block; - vertical-align: middle; - margin-right: 6px; -} -.upgrade_btn { - color: white; - background: #ff8617; - border: 0; - opacity: 1; - position: absolute; - top: 44px; - right: 40px; - border-radius: 3px; - color: white !important; - text-decoration: none; - padding: 3px 16px; - font-weight: bold; - height: 22px; - margin-top: 3px; - font-size: 14px; - display: block; -} -.upgrade_btn:hover { - background: #ffa14a; - outline: 0; -} -.upgrade_btn:active { - background: #ff8617; - outline: 0; - -webkit-box-shadow: inset 0 1px 2px rgba(55, 72, 88, 0.3); - -moz-box-shadow: inset 0 1px 2px rgba(55, 72, 88, 0.3); - box-shadow: inset 0 1px 2px rgba(55, 72, 88, 0.3); -} -.upgrade_box:after { - left: 100%; - top: 50%; - border: solid rgba(0, 0, 0, 0); - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - border-color: rgba(213, 213, 213, 0); - border-left-color: #ffffff; - border-width: 4px; - margin-top: -5px; -} -.filterbox_wrap { - position: relative; - float: left; - min-width: 100px; - width: auto; -} -.filterbox_wrap .filter_btn { - border-left: solid 1px #bac7d4; - border-right: solid 1px #bac7d4; - border-top: solid 1px #bac7d4; -} -.filterbox_task_wrap { - position: relative; - float: left; - min-width: 150px; -} -.filterbox_task_wrap .filter_btn { - border-left: solid 1px #bac7d4; - border-right: solid 1px #bac7d4; - border-top: solid 1px #bac7d4; -} -.filter_box_dropdown { - width: auto; - min-width: 100px; - padding: 10px 0; - float: left; - border: solid 1px #cad4de; - background: white; - font-size: 12px; - -webkit-box-shadow: 0 2px 4px rgba(55, 72, 88, 0.2); - -moz-box-shadow: 0 2px 4px rgba(55, 72, 88, 0.2); - box-shadow: 0 2px 4px rgba(55, 72, 88, 0.2); -} -.filter_box_dropdown > ul { - margin: 0; - padding: 0; -} -.filter_box_dropdown li { - list-style-type: none; - padding: 8px 8px 8px 8px; - cursor: pointer; -} -.filter_box_dropdown li:hover { - background: #ecf0f3; -} -.notebook_notification { - font-size: 16px; - margin: 40px auto; - width: 390px; - padding: 20px; - background: #ffffff; - -webkit-box-shadow: 0 1px 2px rgba(55, 72, 88, 0.5); - -moz-box-shadow: 0 1px 2px rgba(55, 72, 88, 0.5); - box-shadow: 0 1px 2px rgba(55, 72, 88, 0.5); -} -/********************* -* overwrite jqueryUI * -*********************/ -.ui-datepicker { - -webkit-box-shadow: 0 4px 8px rgba(55, 72, 88, 0.3); - -moz-box-shadow: 0 4px 8px rgba(55, 72, 88, 0.3); - box-shadow: 0 4px 8px rgba(55, 72, 88, 0.3); -} -.ui-corner-all, -.ui-corner-bottom, -.ui-corner-right, -.ui-corner-br { - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} -.ui-widget-header { - border: 0 /*{borderColorHeader}*/; - background: #d9e1e8; - color: #4b6277; - /*{fcHeader}*/ - font-weight: normal; -} -.ui-datepicker .ui-datepicker-prev, -.ui-datepicker .ui-datepicker-next { - border: 0; - position: absolute; - top: 0; - width: 1.8em; - height: 100%; -} -.ui-datepicker .ui-datepicker-prev:hover, -.ui-datepicker .ui-datepicker-next:hover { - border: 0; - background: #bac7d4; -} -.ui-datepicker th { - padding: .7em .3em; - text-align: center; - font-weight: normal; - color: #4b6277; - border: 0; -} -.ui-widget-content { - border: 1px solid #9baec0; - background: #ecf0f3; - color: #4b6277; -} -.ui-state-default, -.ui-widget-content .ui-state-default, -.ui-widget-header .ui-state-default { - border: 1px solid #cad4de; - background: white; - font-weight: normal /*{fwDefault}*/; -} -.ui-state-hover, -.ui-widget-content .ui-state-hover, -.ui-widget-header .ui-state-hover, -.ui-state-focus, -.ui-widget-content .ui-state-focus, -.ui-widget-header .ui-state-focus { - border: 1px solid #bac7d4 /*{borderColorHover}*/; - background: #e4eef7; - font-weight: normal /*{fwDefault}*/; - color: #4b6277; - /*{fcHover}*/ -} -.ui-state-default, -.ui-widget-content .ui-state-default, -.ui-widget-header .ui-state-default { - color: #4b6277; -} -.ui-state-hover .ui-icon, -.ui-state-focus .ui-icon { - background-image: none; -} -.ui-widget-header .ui-icon { - background-image: none; -} -.ui-icon { - overflow: visible !important; -} -.ui-icon-circle-triangle-w { - position: relative; - background: white; - display: inline-block; - height: 0; - width: 0; -} -.ui-icon-circle-triangle-w:after { - right: 100%; - top: 50%; - border: solid transparent; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - border-color: rgba(136, 183, 213, 0); - border-right-color: #4b6277; - border-width: 8px; - margin-top: -7px; -} -.ui-icon-circle-triangle-e { - position: relative; - background: white; - display: inline-block; - height: 0; - width: 0; -} -.ui-icon-circle-triangle-e:after { - left: 100%; - top: 50%; - border: solid transparent; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - border-color: rgba(136, 183, 213, 0); - border-left-color: #4b6277; - border-width: 8px; - margin-top: -7px; -} -.ui-datepicker .ui-datepicker-prev span, -.ui-datepicker .ui-datepicker-next span { - display: block; - position: absolute; - left: 50%; - margin-left: -2px; - top: 50%; - margin-top: 0px; -} -.ui-tooltip { - padding: 5px 10px; - background: #374858; - -webkit-box-shadow: 0 2px 3px rgba(55, 72, 88, 0.3); - -moz-box-shadow: 0 2px 3px rgba(55, 72, 88, 0.3); - box-shadow: 0 2px 3px rgba(55, 72, 88, 0.3); - font: normal 14px; - color: white; - border: 0; - z-index: 11; -} -.ui-tooltip:after { - bottom: 100%; - left: 13px; - border: solid transparent; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - border-color: transparent; - border-bottom-color: #374858; - border-width: 7px; - margin-left: -7px; -} -/**************** -* media queries * -****************/ -@media (max-width: 1750px) { - .headerbar_top > header { - width: 30%; - } -} -@media (max-width: 1160px) { - .group_content_block { - width: 100%; - } - .headerbar_top > header { - width: 30%; - margin: 19px 0 0 20px; - } - .eln_main_content_box, - .project_list { - padding: 20px 20px 20px 20px; - width: auto; - } - #messages_content, - #task_content, - #comments_content { - padding: 0 10px 0 10px; - } -} -@media (max-width: 1100px) { - .author_firstname, - .author_lastname { - width: 100px; - } -} -@media (max-width: 970px) { - .nav_top { - margin: 0 30px 0 10px; - } - .headerbar_top > header { - width: 200px; - } - .page_title { - margin-top: 2px; - font-size: 12px; - } - .author_firstname, - .author_lastname { - width: 66px; - } - .group_content_box { - padding: 20px; - } - .profile_block { - max-width: 550px; - width: calc(100% - 25px); - } -} -@media (max-height: 600px) { - .popup_dialog { - top: 50%; - } -} - diff --git a/unittests/example_labfolder_data/static/css/export-entry-footer.css b/unittests/example_labfolder_data/static/css/export-entry-footer.css deleted file mode 100644 index 22800c8c993c889a58c40db9b432c44841b0dcd5..0000000000000000000000000000000000000000 --- a/unittests/example_labfolder_data/static/css/export-entry-footer.css +++ /dev/null @@ -1,43 +0,0 @@ -.entry_footer { - background: #cad4de; - margin-left: 30px; - margin-right: 45px; - padding-top: 2px; - padding-bottom: 2px; - min-width: 696px; - height: auto; - font-size: 0.6em; -} - -.entry_footer > span { - color: #748dad; - font-weight: 900; - padding: 8px 8px 6px 8px; -} - -.entry_footer_line { - margin-top: 2px; - height: auto; - display: flex; - flex-direction: column; - position: relative; - padding: 5px 5px 5px 22px; - background: #f2f5f7; - border-left: solid 1px #aabbca; - border-right: solid 1px #aabbca; -} - -.entry_footer_signature > img { - position: absolute; - right: 10px; - margin-top: -2px; - height: 30px; -} - -.width_80_percent { - width: 80%; -} - -.min_height_35 { - min-height: 35px; -} diff --git a/unittests/example_labfolder_data/static/css/export-table-element.css b/unittests/example_labfolder_data/static/css/export-table-element.css deleted file mode 100644 index b1032434d10f6f28b980d01d6c3dbdba513f22ff..0000000000000000000000000000000000000000 --- a/unittests/example_labfolder_data/static/css/export-table-element.css +++ /dev/null @@ -1,35 +0,0 @@ -.table-el-container, .well-plate-el-container { - padding: 100px 10px; - min-height: calc(100% - 10px) !important; - height: 243px; - background: white; - text-align: center; -} - -.table-el-info, .well-plate-el-info { - color: #bababa; -} - -.table-el-download, .well-plate-el-download { - margin-top: 8px; -} - -.table-el-download > a, .well-plate-el-download > a { - color: #6cc0ec; -} - -.table-el-icon, .well-plate-el-icon { - width: 16px; - height: 16px; - vertical-align: middle; - margin-right: 0.2em; - fill: #6cc0ec;; - flex-shrink: 0; -} - -.table-el-filename, .well-plate-el-filename { - display: inline-block; - vertical-align: middle; - font-size: 16px; - word-break: break-all -} diff --git a/unittests/example_labfolder_data/static/css/jquery-ui.css b/unittests/example_labfolder_data/static/css/jquery-ui.css deleted file mode 100644 index 3f4d674f568c48c1a41b171861ee455f8fafa1ed..0000000000000000000000000000000000000000 --- a/unittests/example_labfolder_data/static/css/jquery-ui.css +++ /dev/null @@ -1,474 +0,0 @@ -/*! jQuery UI - v1.9.2 - 2012-11-23 -* http://jqueryui.com -* Includes: jquery.ui.core.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css, jquery.ui.theme.css -* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ - -/* Layout helpers -----------------------------------*/ -.ui-helper-hidden { display: none; } -.ui-helper-hidden-accessible { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; } -.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } -.ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; } -.ui-helper-clearfix:after { clear: both; } -.ui-helper-clearfix { zoom: 1; } -.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } - - -/* Interaction Cues -----------------------------------*/ -.ui-state-disabled { cursor: default !important; } - - -/* Icons -----------------------------------*/ - -/* states and images */ -.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } - - -/* Misc visuals -----------------------------------*/ - -/* Overlays */ -.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } - -.ui-accordion .ui-accordion-header { display: block; cursor: pointer; position: relative; margin-top: 2px; padding: .5em .5em .5em .7em; zoom: 1; } -.ui-accordion .ui-accordion-icons { padding-left: 2.2em; } -.ui-accordion .ui-accordion-noicons { padding-left: .7em; } -.ui-accordion .ui-accordion-icons .ui-accordion-icons { padding-left: 2.2em; } -.ui-accordion .ui-accordion-header .ui-accordion-header-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } -.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; overflow: auto; zoom: 1; } - -.ui-autocomplete { - position: absolute; - top: 0; - left: 0; - cursor: default; -} - -/* workarounds */ -* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ - -.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ -.ui-button, .ui-button:link, .ui-button:visited, .ui-button:hover, .ui-button:active { text-decoration: none; } -.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ -button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ -.ui-button-icons-only { width: 3.4em; } -button.ui-button-icons-only { width: 3.7em; } - -/*button text element */ -.ui-button .ui-button-text { display: block; line-height: 1.4; } -.ui-button-text-only .ui-button-text { padding: .4em 1em; } -.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } -.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } -.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; } -.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } -/* no icon support for input elements, provide padding by default */ -input.ui-button { padding: .4em 1em; } - -/*button icon element(s) */ -.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } -.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } -.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } -.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } -.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } - -/*button sets*/ -.ui-buttonset { margin-right: 7px; } -.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } - -/* workarounds */ -button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ - -.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; } -.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } -.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } -.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } -.ui-datepicker .ui-datepicker-prev { left:2px; } -.ui-datepicker .ui-datepicker-next { right:2px; } -.ui-datepicker .ui-datepicker-prev-hover { left:1px; } -.ui-datepicker .ui-datepicker-next-hover { right:1px; } -.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } -.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } -.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } -.ui-datepicker select.ui-datepicker-month-year {width: 100%;} -.ui-datepicker select.ui-datepicker-month, -.ui-datepicker select.ui-datepicker-year { width: 49%;} -.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } -.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } -.ui-datepicker td { border: 0; padding: 1px; } -.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } -.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } -.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } -.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } - -/* with multiple calendars */ -.ui-datepicker.ui-datepicker-multi { width:auto; } -.ui-datepicker-multi .ui-datepicker-group { float:left; } -.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } -.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } -.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } -.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } -.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } -.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } -.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } -.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; } - -/* RTL support */ -.ui-datepicker-rtl { direction: rtl; } -.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } -.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } -.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } -.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } -.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } -.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } -.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } -.ui-datepicker-rtl .ui-datepicker-group { float:right; } -.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } -.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } - -/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ -.ui-datepicker-cover { - position: absolute; /*must have*/ - z-index: -1; /*must have*/ - filter: mask(); /*must have*/ - top: -4px; /*must have*/ - left: -4px; /*must have*/ - width: 200px; /*must have*/ - height: 200px; /*must have*/ -} -.ui-dialog { position: absolute; top: 0; left: 0; padding: .2em; width: 300px; overflow: hidden; } -.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; } -.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; } -.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; } -.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; } -.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; } -.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; } -.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; } -.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; } -.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; } -.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; } -.ui-draggable .ui-dialog-titlebar { cursor: move; } - -.ui-menu { list-style:none; padding: 2px; margin: 0; display:block; outline: none; } -.ui-menu .ui-menu { margin-top: -3px; position: absolute; } -.ui-menu .ui-menu-item { margin: 0; padding: 0; zoom: 1; width: 100%; } -.ui-menu .ui-menu-divider { margin: 5px -2px 5px -2px; height: 0; font-size: 0; line-height: 0; border-width: 1px 0 0 0; } -.ui-menu .ui-menu-item a { text-decoration: none; display: block; padding: 2px .4em; line-height: 1.5; zoom: 1; font-weight: normal; } -.ui-menu .ui-menu-item a.ui-state-focus, -.ui-menu .ui-menu-item a.ui-state-active { font-weight: normal; margin: -1px; } - -.ui-menu .ui-state-disabled { font-weight: normal; margin: .4em 0 .2em; line-height: 1.5; } -.ui-menu .ui-state-disabled a { cursor: default; } - -/* icon support */ -.ui-menu-icons { position: relative; } -.ui-menu-icons .ui-menu-item a { position: relative; padding-left: 2em; } - -/* left-aligned */ -.ui-menu .ui-icon { position: absolute; top: .2em; left: .2em; } - -/* right-aligned */ -.ui-menu .ui-menu-icon { position: static; float: right; } - -.ui-progressbar { height:2em; text-align: left; overflow: hidden; } -.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; } -.ui-resizable { position: relative;} -.ui-resizable-handle { position: absolute;font-size: 0.1px; display: block; } -.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } -.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } -.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } -.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; } -.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; } -.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } -.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } -.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } -.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;} -.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; } - -.ui-slider { position: relative; text-align: left; } -.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; } -.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; } - -.ui-slider-horizontal { height: .8em; } -.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; } -.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; } -.ui-slider-horizontal .ui-slider-range-min { left: 0; } -.ui-slider-horizontal .ui-slider-range-max { right: 0; } - -.ui-slider-vertical { width: .8em; height: 100px; } -.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; } -.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } -.ui-slider-vertical .ui-slider-range-min { bottom: 0; } -.ui-slider-vertical .ui-slider-range-max { top: 0; } -.ui-spinner { position:relative; display: inline-block; overflow: hidden; padding: 0; vertical-align: middle; } -.ui-spinner-input { border: none; background: none; padding: 0; margin: .2em 0; vertical-align: middle; margin-left: .4em; margin-right: 22px; } -.ui-spinner-button { width: 16px; height: 50%; font-size: .5em; padding: 0; margin: 0; text-align: center; position: absolute; cursor: default; display: block; overflow: hidden; right: 0; } -.ui-spinner a.ui-spinner-button { border-top: none; border-bottom: none; border-right: none; } /* more specificity required here to overide default borders */ -.ui-spinner .ui-icon { position: absolute; margin-top: -8px; top: 50%; left: 0; } /* vertical centre icon */ -.ui-spinner-up { top: 0; } -.ui-spinner-down { bottom: 0; } - -/* TR overrides */ -.ui-spinner .ui-icon-triangle-1-s { - /* need to fix icons sprite */ - background-position:-65px -16px; -} - -.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ -.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; } -.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 0; margin: 1px .2em 0 0; border-bottom: 0; padding: 0; white-space: nowrap; } -.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; } -.ui-tabs .ui-tabs-nav li.ui-tabs-active { margin-bottom: -1px; padding-bottom: 1px; } -.ui-tabs .ui-tabs-nav li.ui-tabs-active a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-tabs-loading a { cursor: text; } -.ui-tabs .ui-tabs-nav li a, .ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ -.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; } - -.ui-tooltip { - padding: 8px; - position: absolute; - z-index: 9999; -/* max-width: 300px; labfolder hack*/ - -webkit-box-shadow: 0 0 5px #aaa; - box-shadow: 0 0 5px #aaa; -} -/* Fades and background-images don't work well together in IE6, drop the image */ -* html .ui-tooltip { - background-image: none; -} -body .ui-tooltip { border-width: 2px; } - -/* Component containers -----------------------------------*/ -.ui-widget { font-family: Verdana,Arial,sans-serif/*{ffDefault}*/; font-size: 1.1em/*{fsDefault}*/; } -.ui-widget .ui-widget { font-size: 1em; } -.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif/*{ffDefault}*/; font-size: 1em; } -.ui-widget-content { border: 1px solid #aaaaaa/*{borderColorContent}*/; background: #ffffff/*{bgColorContent}*/ url(images/ui-bg_flat_75_ffffff_40x100.png)/*{bgImgUrlContent}*/ 50%/*{bgContentXPos}*/ 50%/*{bgContentYPos}*/ repeat-x/*{bgContentRepeat}*/; color: #222222/*{fcContent}*/; } -.ui-widget-content a { color: #222222/*{fcContent}*/; } -.ui-widget-header { border: 1px solid #aaaaaa/*{borderColorHeader}*/; background: #cccccc/*{bgColorHeader}*/ url(images/ui-bg_highlight-soft_75_cccccc_1x100.png)/*{bgImgUrlHeader}*/ 50%/*{bgHeaderXPos}*/ 50%/*{bgHeaderYPos}*/ repeat-x/*{bgHeaderRepeat}*/; color: #222222/*{fcHeader}*/; font-weight: bold; } -.ui-widget-header a { color: #222222/*{fcHeader}*/; } - -/* Interaction states -----------------------------------*/ -.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3/*{borderColorDefault}*/; background: #e6e6e6/*{bgColorDefault}*/ url(images/ui-bg_glass_75_e6e6e6_1x400.png)/*{bgImgUrlDefault}*/ 50%/*{bgDefaultXPos}*/ 50%/*{bgDefaultYPos}*/ repeat-x/*{bgDefaultRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #555555/*{fcDefault}*/; } -.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555/*{fcDefault}*/; text-decoration: none; } -.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999/*{borderColorHover}*/; background: #dadada/*{bgColorHover}*/ url(images/ui-bg_glass_75_dadada_1x400.png)/*{bgImgUrlHover}*/ 50%/*{bgHoverXPos}*/ 50%/*{bgHoverYPos}*/ repeat-x/*{bgHoverRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #212121/*{fcHover}*/; } -.ui-state-hover a, .ui-state-hover a:hover, .ui-state-hover a:link, .ui-state-hover a:visited { color: #212121/*{fcHover}*/; text-decoration: none; } -.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa/*{borderColorActive}*/; background: #ffffff/*{bgColorActive}*/ url(images/ui-bg_glass_65_ffffff_1x400.png)/*{bgImgUrlActive}*/ 50%/*{bgActiveXPos}*/ 50%/*{bgActiveYPos}*/ repeat-x/*{bgActiveRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #212121/*{fcActive}*/; } -.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121/*{fcActive}*/; text-decoration: none; } - -/* Interaction Cues -----------------------------------*/ -.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fcefa1/*{borderColorHighlight}*/; background: #fbf9ee/*{bgColorHighlight}*/ url(images/ui-bg_glass_55_fbf9ee_1x400.png)/*{bgImgUrlHighlight}*/ 50%/*{bgHighlightXPos}*/ 50%/*{bgHighlightYPos}*/ repeat-x/*{bgHighlightRepeat}*/; color: #363636/*{fcHighlight}*/; } -.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636/*{fcHighlight}*/; } -.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a/*{borderColorError}*/; background: #fef1ec/*{bgColorError}*/ url(images/ui-bg_glass_95_fef1ec_1x400.png)/*{bgImgUrlError}*/ 50%/*{bgErrorXPos}*/ 50%/*{bgErrorYPos}*/ repeat-x/*{bgErrorRepeat}*/; color: #cd0a0a/*{fcError}*/; } -.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a/*{fcError}*/; } -.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a/*{fcError}*/; } -.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } -.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } -.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } -.ui-state-disabled .ui-icon { filter:Alpha(Opacity=35); } /* For IE8 - See #6059 */ - -/* Icons -----------------------------------*/ - -/* states and images */ -.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png)/*{iconsContent}*/; } -.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png)/*{iconsContent}*/; } -.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png)/*{iconsHeader}*/; } -.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png)/*{iconsDefault}*/; } -.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png)/*{iconsHover}*/; } -.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png)/*{iconsActive}*/; } -.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png)/*{iconsHighlight}*/; } -.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png)/*{iconsError}*/; } - -/* positioning */ -.ui-icon-carat-1-n { background-position: 0 0; } -.ui-icon-carat-1-ne { background-position: -16px 0; } -.ui-icon-carat-1-e { background-position: -32px 0; } -.ui-icon-carat-1-se { background-position: -48px 0; } -.ui-icon-carat-1-s { background-position: -64px 0; } -.ui-icon-carat-1-sw { background-position: -80px 0; } -.ui-icon-carat-1-w { background-position: -96px 0; } -.ui-icon-carat-1-nw { background-position: -112px 0; } -.ui-icon-carat-2-n-s { background-position: -128px 0; } -.ui-icon-carat-2-e-w { background-position: -144px 0; } -.ui-icon-triangle-1-n { background-position: 0 -16px; } -.ui-icon-triangle-1-ne { background-position: -16px -16px; } -.ui-icon-triangle-1-e { background-position: -32px -16px; } -.ui-icon-triangle-1-se { background-position: -48px -16px; } -.ui-icon-triangle-1-s { background-position: -64px -16px; } -.ui-icon-triangle-1-sw { background-position: -80px -16px; } -.ui-icon-triangle-1-w { background-position: -96px -16px; } -.ui-icon-triangle-1-nw { background-position: -112px -16px; } -.ui-icon-triangle-2-n-s { background-position: -128px -16px; } -.ui-icon-triangle-2-e-w { background-position: -144px -16px; } -.ui-icon-arrow-1-n { background-position: 0 -32px; } -.ui-icon-arrow-1-ne { background-position: -16px -32px; } -.ui-icon-arrow-1-e { background-position: -32px -32px; } -.ui-icon-arrow-1-se { background-position: -48px -32px; } -.ui-icon-arrow-1-s { background-position: -64px -32px; } -.ui-icon-arrow-1-sw { background-position: -80px -32px; } -.ui-icon-arrow-1-w { background-position: -96px -32px; } -.ui-icon-arrow-1-nw { background-position: -112px -32px; } -.ui-icon-arrow-2-n-s { background-position: -128px -32px; } -.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } -.ui-icon-arrow-2-e-w { background-position: -160px -32px; } -.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } -.ui-icon-arrowstop-1-n { background-position: -192px -32px; } -.ui-icon-arrowstop-1-e { background-position: -208px -32px; } -.ui-icon-arrowstop-1-s { background-position: -224px -32px; } -.ui-icon-arrowstop-1-w { background-position: -240px -32px; } -.ui-icon-arrowthick-1-n { background-position: 0 -48px; } -.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } -.ui-icon-arrowthick-1-e { background-position: -32px -48px; } -.ui-icon-arrowthick-1-se { background-position: -48px -48px; } -.ui-icon-arrowthick-1-s { background-position: -64px -48px; } -.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } -.ui-icon-arrowthick-1-w { background-position: -96px -48px; } -.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } -.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } -.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } -.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } -.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } -.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } -.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } -.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } -.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } -.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } -.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } -.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } -.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } -.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } -.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } -.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } -.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } -.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } -.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } -.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } -.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } -.ui-icon-arrow-4 { background-position: 0 -80px; } -.ui-icon-arrow-4-diag { background-position: -16px -80px; } -.ui-icon-extlink { background-position: -32px -80px; } -.ui-icon-newwin { background-position: -48px -80px; } -.ui-icon-refresh { background-position: -64px -80px; } -.ui-icon-shuffle { background-position: -80px -80px; } -.ui-icon-transfer-e-w { background-position: -96px -80px; } -.ui-icon-transferthick-e-w { background-position: -112px -80px; } -.ui-icon-folder-collapsed { background-position: 0 -96px; } -.ui-icon-folder-open { background-position: -16px -96px; } -.ui-icon-document { background-position: -32px -96px; } -.ui-icon-document-b { background-position: -48px -96px; } -.ui-icon-note { background-position: -64px -96px; } -.ui-icon-mail-closed { background-position: -80px -96px; } -.ui-icon-mail-open { background-position: -96px -96px; } -.ui-icon-suitcase { background-position: -112px -96px; } -.ui-icon-comment { background-position: -128px -96px; } -.ui-icon-person { background-position: -144px -96px; } -.ui-icon-print { background-position: -160px -96px; } -.ui-icon-trash { background-position: -176px -96px; } -.ui-icon-locked { background-position: -192px -96px; } -.ui-icon-unlocked { background-position: -208px -96px; } -.ui-icon-bookmark { background-position: -224px -96px; } -.ui-icon-tag { background-position: -240px -96px; } -.ui-icon-home { background-position: 0 -112px; } -.ui-icon-flag { background-position: -16px -112px; } -.ui-icon-calendar { background-position: -32px -112px; } -.ui-icon-cart { background-position: -48px -112px; } -.ui-icon-pencil { background-position: -64px -112px; } -.ui-icon-clock { background-position: -80px -112px; } -.ui-icon-disk { background-position: -96px -112px; } -.ui-icon-calculator { background-position: -112px -112px; } -.ui-icon-zoomin { background-position: -128px -112px; } -.ui-icon-zoomout { background-position: -144px -112px; } -.ui-icon-search { background-position: -160px -112px; } -.ui-icon-wrench { background-position: -176px -112px; } -.ui-icon-gear { background-position: -192px -112px; } -.ui-icon-heart { background-position: -208px -112px; } -.ui-icon-star { background-position: -224px -112px; } -.ui-icon-link { background-position: -240px -112px; } -.ui-icon-cancel { background-position: 0 -128px; } -.ui-icon-plus { background-position: -16px -128px; } -.ui-icon-plusthick { background-position: -32px -128px; } -.ui-icon-minus { background-position: -48px -128px; } -.ui-icon-minusthick { background-position: -64px -128px; } -.ui-icon-close { background-position: -80px -128px; } -.ui-icon-closethick { background-position: -96px -128px; } -.ui-icon-key { background-position: -112px -128px; } -.ui-icon-lightbulb { background-position: -128px -128px; } -.ui-icon-scissors { background-position: -144px -128px; } -.ui-icon-clipboard { background-position: -160px -128px; } -.ui-icon-copy { background-position: -176px -128px; } -.ui-icon-contact { background-position: -192px -128px; } -.ui-icon-image { background-position: -208px -128px; } -.ui-icon-video { background-position: -224px -128px; } -.ui-icon-script { background-position: -240px -128px; } -.ui-icon-alert { background-position: 0 -144px; } -.ui-icon-info { background-position: -16px -144px; } -.ui-icon-notice { background-position: -32px -144px; } -.ui-icon-help { background-position: -48px -144px; } -.ui-icon-check { background-position: -64px -144px; } -.ui-icon-bullet { background-position: -80px -144px; } -.ui-icon-radio-on { background-position: -96px -144px; } -.ui-icon-radio-off { background-position: -112px -144px; } -.ui-icon-pin-w { background-position: -128px -144px; } -.ui-icon-pin-s { background-position: -144px -144px; } -.ui-icon-play { background-position: 0 -160px; } -.ui-icon-pause { background-position: -16px -160px; } -.ui-icon-seek-next { background-position: -32px -160px; } -.ui-icon-seek-prev { background-position: -48px -160px; } -.ui-icon-seek-end { background-position: -64px -160px; } -.ui-icon-seek-start { background-position: -80px -160px; } -/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ -.ui-icon-seek-first { background-position: -80px -160px; } -.ui-icon-stop { background-position: -96px -160px; } -.ui-icon-eject { background-position: -112px -160px; } -.ui-icon-volume-off { background-position: -128px -160px; } -.ui-icon-volume-on { background-position: -144px -160px; } -.ui-icon-power { background-position: 0 -176px; } -.ui-icon-signal-diag { background-position: -16px -176px; } -.ui-icon-signal { background-position: -32px -176px; } -.ui-icon-battery-0 { background-position: -48px -176px; } -.ui-icon-battery-1 { background-position: -64px -176px; } -.ui-icon-battery-2 { background-position: -80px -176px; } -.ui-icon-battery-3 { background-position: -96px -176px; } -.ui-icon-circle-plus { background-position: 0 -192px; } -.ui-icon-circle-minus { background-position: -16px -192px; } -.ui-icon-circle-close { background-position: -32px -192px; } -.ui-icon-circle-triangle-e { background-position: -48px -192px; } -.ui-icon-circle-triangle-s { background-position: -64px -192px; } -.ui-icon-circle-triangle-w { background-position: -80px -192px; } -.ui-icon-circle-triangle-n { background-position: -96px -192px; } -.ui-icon-circle-arrow-e { background-position: -112px -192px; } -.ui-icon-circle-arrow-s { background-position: -128px -192px; } -.ui-icon-circle-arrow-w { background-position: -144px -192px; } -.ui-icon-circle-arrow-n { background-position: -160px -192px; } -.ui-icon-circle-zoomin { background-position: -176px -192px; } -.ui-icon-circle-zoomout { background-position: -192px -192px; } -.ui-icon-circle-check { background-position: -208px -192px; } -.ui-icon-circlesmall-plus { background-position: 0 -208px; } -.ui-icon-circlesmall-minus { background-position: -16px -208px; } -.ui-icon-circlesmall-close { background-position: -32px -208px; } -.ui-icon-squaresmall-plus { background-position: -48px -208px; } -.ui-icon-squaresmall-minus { background-position: -64px -208px; } -.ui-icon-squaresmall-close { background-position: -80px -208px; } -.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } -.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } -.ui-icon-grip-solid-vertical { background-position: -32px -224px; } -.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } -.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } -.ui-icon-grip-diagonal-se { background-position: -80px -224px; } - - -/* Misc visuals -----------------------------------*/ - -/* Corner radius */ -.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px/*{cornerRadius}*/; -webkit-border-top-left-radius: 4px/*{cornerRadius}*/; -khtml-border-top-left-radius: 4px/*{cornerRadius}*/; border-top-left-radius: 4px/*{cornerRadius}*/; } -.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px/*{cornerRadius}*/; -webkit-border-top-right-radius: 4px/*{cornerRadius}*/; -khtml-border-top-right-radius: 4px/*{cornerRadius}*/; border-top-right-radius: 4px/*{cornerRadius}*/; } -.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px/*{cornerRadius}*/; -webkit-border-bottom-left-radius: 4px/*{cornerRadius}*/; -khtml-border-bottom-left-radius: 4px/*{cornerRadius}*/; border-bottom-left-radius: 4px/*{cornerRadius}*/; } -.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px/*{cornerRadius}*/; -webkit-border-bottom-right-radius: 4px/*{cornerRadius}*/; -khtml-border-bottom-right-radius: 4px/*{cornerRadius}*/; border-bottom-right-radius: 4px/*{cornerRadius}*/; } - -/* Overlays */ -.ui-widget-overlay { background: #aaaaaa/*{bgColorOverlay}*/ url(images/ui-bg_flat_0_aaaaaa_40x100.png)/*{bgImgUrlOverlay}*/ 50%/*{bgOverlayXPos}*/ 50%/*{bgOverlayYPos}*/ repeat-x/*{bgOverlayRepeat}*/; opacity: .3;filter:Alpha(Opacity=30)/*{opacityOverlay}*/; } -.ui-widget-shadow { margin: -8px/*{offsetTopShadow}*/ 0 0 -8px/*{offsetLeftShadow}*/; padding: 8px/*{thicknessShadow}*/; background: #aaaaaa/*{bgColorShadow}*/ url(images/ui-bg_flat_0_aaaaaa_40x100.png)/*{bgImgUrlShadow}*/ 50%/*{bgShadowXPos}*/ 50%/*{bgShadowYPos}*/ repeat-x/*{bgShadowRepeat}*/; opacity: .3;filter:Alpha(Opacity=30)/*{opacityShadow}*/; -moz-border-radius: 8px/*{cornerRadiusShadow}*/; -khtml-border-radius: 8px/*{cornerRadiusShadow}*/; -webkit-border-radius: 8px/*{cornerRadiusShadow}*/; border-radius: 8px/*{cornerRadiusShadow}*/; } \ No newline at end of file diff --git a/unittests/example_labfolder_data/static/css/notebook.css b/unittests/example_labfolder_data/static/css/notebook.css deleted file mode 100644 index 75a33689139b3e33af8fa6e7357f34ce95bd01d0..0000000000000000000000000000000000000000 --- a/unittests/example_labfolder_data/static/css/notebook.css +++ /dev/null @@ -1,2194 +0,0 @@ -/**************** -* notebook.less * -*****************/ -/************** -* basic.css * -**************/ -/********** -* colors * -***********/ -/********** -* helper * -***********/ -.list_vertical > ul { - margin: 0; - padding: 0; -} -.list_vertical > ul li { - list-style-type: none; -} -.list_horizontal > ul { - margin: 0; - padding: 0; -} -.list_horizontal > ul > li { - list-style-type: none; - float: left; - position: relative; -} -/************* -* functions * -**************/ -/****** -* css * -******/ -body { - color: #374858; -} -.clearfix:after { - content: " "; - visibility: hidden; - display: block; - height: 0; - clear: both; -} -#action_buttons { - display: inline-block; - float: right; - height: 250px; - left: 50%; - margin-left: 410px; - position: fixed; - top: 110px; - width: 150px; -} -/**************** -* button + input* -****************/ -button { - border: 0; - font-size: 12px; - padding: 3px 4px; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; -} -button:focus { - opacity: 1; - -ms-filter: none; - filter: none; - outline: 0; -} -.search_button { - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; - border: solid 1px #bac7d4 !important; -} -.btn_on_grey { - color: #415568; - background: #f3f5f7; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #e0e6eb), color-stop(1, #f3f5f7)); - background: -ms-linear-gradient(bottom, #e0e6eb, #f3f5f7); - background: -moz-linear-gradient(center bottom, #e0e6eb 0%, #f3f5f7 100%); - background: -o-linear-gradient(#f3f5f7, #e0e6eb); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f3f5f7', endColorstr='#e0e6eb', GradientType=0); - border: 1px solid #7b95ad; - line-height: 1.2; -} -.btn_on_grey:hover { - color: #415568; - background: #f3f5f7; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #e0e6eb), color-stop(1, #f3f5f7)); - background: -ms-linear-gradient(bottom, #e0e6eb, #f3f5f7); - background: -moz-linear-gradient(center bottom, #e0e6eb 0%, #f3f5f7 100%); - background: -o-linear-gradient(#f3f5f7, #e0e6eb); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f3f5f7', endColorstr='#e0e6eb', GradientType=0); - outline: 0; - border: 1px solid #5e7b97; - -webkit-box-shadow: 0 0 8px rgba(255, 255, 255, 0.5); - -moz-box-shadow: 0 0 8px rgba(255, 255, 255, 0.5); - box-shadow: 0 0 8px rgba(255, 255, 255, 0.5); -} -.btn_on_grey:active { - color: #4b6277; - outline: 0; - -webkit-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.2); - -moz-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.2); - box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.2); - border: 1px solid #4b6277; - background: #cad4de; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #e0e6eb), color-stop(1, #cad4de)); - background: -ms-linear-gradient(bottom, #e0e6eb, #cad4de); - background: -moz-linear-gradient(center bottom, #e0e6eb 0%, #cad4de 100%); - background: -o-linear-gradient(#cad4de, #e0e6eb); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#cad4de', endColorstr='#e0e6eb', GradientType=0); -} -.btn_on_white { - color: #4b6277; - background: #e6ebef; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #d9e1e8), color-stop(1, #e6ebef)); - background: -ms-linear-gradient(bottom, #d9e1e8, #e6ebef); - background: -moz-linear-gradient(center bottom, #d9e1e8 0%, #e6ebef 100%); - background: -o-linear-gradient(#e6ebef, #d9e1e8); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#e6ebef', endColorstr='#d9e1e8', GradientType=0); - border: 1px solid #cad4de; - opacity: 1; - line-height: 13px; -} -.btn_on_white:hover:enabled { - -ms-filter: none; - filter: none; - outline: 0; - border: 1px solid #b4c2d0; -} -.btn_on_white:active { - color: #4b6277; - -ms-filter: none; - filter: none; - outline: 0; - -webkit-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.2); - -moz-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.2); - box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.2); - border: 1px solid #c7d2dc; - background: #d9e1e8; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #d9e1e8), color-stop(1, #d0d9e2)); - background: -ms-linear-gradient(bottom, #d9e1e8, #d0d9e2); - background: -moz-linear-gradient(center bottom, #d9e1e8 0%, #d0d9e2 100%); - background: -o-linear-gradient(#d0d9e2, #d9e1e8); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#d0d9e2', endColorstr='#d9e1e8', GradientType=0); -} -.btn_on_white.disabled { - opacity: 0.6; -} -.btn_on_white.disabled:active { - color: #4b6277; - -ms-filter: none; - filter: none; - outline: 0; - -webkit-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0); - -moz-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0); - box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0); - border: 1px solid #cad4de; - background: #e6ebef; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #d9e1e8), color-stop(1, #e6ebef)); - background: -ms-linear-gradient(bottom, #d9e1e8, #e6ebef); - background: -moz-linear-gradient(center bottom, #d9e1e8 0%, #e6ebef 100%); - background: -o-linear-gradient(#e6ebef, #d9e1e8); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#e6ebef', endColorstr='#d9e1e8', GradientType=0); -} -.btn_on_white.disabled:hover { - -ms-filter: none; - filter: none; - outline: 0; - border: 1px solid #cad4de; -} -.filter_btn { - color: #526c84; - background: #ecf0f3; - height: 24px; - padding: 2px 8px; - font-size: 12px; - cursor: pointer; - -webkit-border-radius: 0px; - -moz-border-radius: 0px; - border-radius: 0px; - -webkit-transition: all 0.1s ease; - -moz-transition: all 0.1s ease; - -o-transition: all 0.1s ease; - transition: all 0.1s ease; -} -.filter_btn > span { - height: 4px; - width: 12px; - display: block; - float: left; - margin: 2px 0 0 8px; -} -.filter_btn > p { - margin: 0; - float: left; -} -.filter_btn:hover { - -webkit-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.1); - -moz-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.1); - box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.1); - background: #e0e6eb; - padding-top: 2px; -} -.filter_btn:active { - -webkit-box-shadow: inset 0 1px 2px rgba(55, 72, 88, 0.2); - -moz-box-shadow: inset 0 1px 2px rgba(55, 72, 88, 0.2); - box-shadow: inset 0 1px 2px rgba(55, 72, 88, 0.2); - background: #cdd7e0; -} -span.close-x { - display: block; - float: left; - margin: 0 0 0 8px; - display: none; -} -.filter_on { - background: #527ca3; - color: white; -} -.filter_on:hover, -.filter_on:active { - background: #527ca3; - color: #e0e6eb; -} -.filter_active { - background: #5b96cd; - color: #ffffff; -} -.filter_active .arrow_down_s-img:after { - border-top-color: white; -} -.filter_active:hover { - background: #5b96cd; - color: #e6ebef; -} -.grey_link { - color: #4b6277; - background: transparent; - font-size: 12px; - padding: 0; - text-decoration: underline; - display: block; - cursor: pointer; -} -.grey_link:hover { - color: #415568; - text-decoration: underline; -} -.grey_link:active { - text-decoration: none; -} -.blue_link { - color: #1995d8; - background: transparent; - font-size: 12px; - padding: 0; - text-decoration: underline; - display: block; - cursor: pointer; -} -.blue_link:hover { - color: #69bfee; - text-decoration: underline; -} -.blue_link:active { - color: #1995d8; - text-decoration: none; -} -.feedback_btn { - color: white; - border: 1px solid #994097; - font-weight: bold; - font-size: 14px; - padding: 5px 0 5px 5px; - position: absolute; - top: 213px; - left: -2px; - z-index: 101; - background: #ab48a9; - cursor: pointer; -} -.feedback_btn > p { - margin: 0; -} -.feedback_btn:hover, -.feedback_btn:focus { - background: #ab48a9; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #bc60ba), color-stop(1, #ab48a9)); - background: -ms-linear-gradient(bottom, #bc60ba, #ab48a9); - background: -moz-linear-gradient(center bottom, #bc60ba 0%, #ab48a9 100%); - background: -o-linear-gradient(#ab48a9, #bc60ba); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ab48a9', endColorstr='#bc60ba', GradientType=0); -} -.feedback_btn:active { - opacity: 1; - -ms-filter: none; - filter: none; - outline: 0; - -webkit-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.2); - -moz-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.2); - box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.2); - border: 1px solid #873986; - background: #ab48a9; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #c575c3), color-stop(1, #ab48a9)); - background: -ms-linear-gradient(bottom, #c575c3, #ab48a9); - background: -moz-linear-gradient(center bottom, #c575c3 0%, #ab48a9 100%); - background: -o-linear-gradient(#ab48a9, #c575c3); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ab48a9', endColorstr='#c575c3', GradientType=0); -} -.feedback_btn_dialog { - color: white; - font-weight: bold; - font-size: 16px; - padding: 8px 10px; - background: #ab48a9; - cursor: pointer; - border: 0; - display: block; - margin: 90px auto 20px auto; -} -.feedback_btn_dialog > p { - margin: 0; -} -.feedback_btn_dialog:hover { - color: #e5c1e4; - -webkit-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.4); - -moz-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.4); - box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.4); -} -.feedback_btn_dialog:active { - -webkit-box-shadow: inset 0 2px 1px rgba(55, 72, 88, 0.5); - -moz-box-shadow: inset 0 2px 1px rgba(55, 72, 88, 0.5); - box-shadow: inset 0 2px 1px rgba(55, 72, 88, 0.5); -} -.invite_btn_dialog { - color: white; - font-weight: bold; - font-size: 16px; - padding: 8px 10px; - background: #93ba48; - cursor: pointer; - border: 0; - display: block; - margin: 20px auto; -} -.invite_btn_dialog > p { - margin: 0; -} -.invite_btn_dialog:hover { - color: #e0ebca; - -webkit-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.4); - -moz-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.4); - box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.4); -} -.invite_btn_dialog:active { - -webkit-box-shadow: inset 0 2px 1px rgba(55, 72, 88, 0.5); - -moz-box-shadow: inset 0 2px 1px rgba(55, 72, 88, 0.5); - box-shadow: inset 0 2px 1px rgba(55, 72, 88, 0.5); -} -.invite_btn { - border: 1px solid #85a940; - color: white; - font-weight: bold; - font-size: 14px; - padding: 4px 3px 5px 1px; - position: absolute; - top: 296px; - left: -2px; - z-index: 50; - background: #93ba48; - cursor: pointer; -} -.invite_btn > p { - margin: 0; - float: left; -} -.invite_btn > span { - margin: 2px 2px 0 4px; -} -.invite_btn:hover, -.invite_btnfocus { - background: #93ba48; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #a0c25e), color-stop(1, #93ba48)); - background: -ms-linear-gradient(bottom, #a0c25e, #93ba48); - background: -moz-linear-gradient(center bottom, #a0c25e 0%, #93ba48 100%); - background: -o-linear-gradient(#93ba48, #a0c25e); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#93ba48', endColorstr='#a0c25e', GradientType=0); -} -.invite_btn:active { - opacity: 1; - -ms-filter: none; - filter: none; - outline: 0; - -webkit-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.2); - -moz-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.2); - box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.2); - border: 1px solid #769639; - background: #93ba48; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #adcb74), color-stop(1, #93ba48)); - background: -ms-linear-gradient(bottom, #adcb74, #93ba48); - background: -moz-linear-gradient(center bottom, #adcb74 0%, #93ba48 100%); - background: -o-linear-gradient(#93ba48, #adcb74); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#93ba48', endColorstr='#adcb74', GradientType=0); -} -.checkbox_filled[type="checkbox"] { - display: none; -} -.checkbox_filled[type="checkbox"]:checked + label:after { - background: #69bfee; - border: 1px solid #5e7b97; -} -.checkbox_filled_bg { - font-size: 12px; - position: relative; - display: inline-block; - padding: 4px 0 4px 25px; - display: block; - width: 110px; - cursor: pointer; -} -.checkbox_filled_bg:hover { - background: #ecf0f3; -} -.checkbox_filled_bg:after { - content: ""; - position: absolute; - display: block; - top: 6px; - left: 5px; - width: 10px; - height: 10px; - border: 1px solid #bac7d4; -} -.checkbox_button_input[type="checkbox"] { - display: none; -} -.checkbox_button_input[type="checkbox"]:checked + label { - background: #e0e6eb; -} -.checkbox_button_input[type="checkbox"]:checked + label:after { - background: #69bfee; - -webkit-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.5); - -moz-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.5); - box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.5); - border: 1px solid #c5e6f8; -} -.empty_folder { - font-size: 12px; - color: #aabbca; -} -.checkbox_button { - font-size: 12px; - position: relative; - padding: 4px 0 4px 1px; - display: inline-block; - width: 100%; - margin: 0; - cursor: pointer; -} -.checkbox_button:hover { - background: #ecf0f3; -} -.checkbox_button b .folder_dn-img, -.checkbox_button b .folder_up-img { - margin-top: -2px; - margin-right: 6px; -} -.checkbox_button:after { - content: ""; - position: absolute; - display: block; - top: 5px; - right: 10px; - width: 10px; - height: 10px; - border: 1px solid #bac7d4; - border-radius: 50%; - -webkit-box-shadow: inset 0 1px 2px rgba(55, 72, 88, 0.2); - -moz-box-shadow: inset 0 1px 2px rgba(55, 72, 88, 0.2); - box-shadow: inset 0 1px 2px rgba(55, 72, 88, 0.2); -} -.own_name { - font-size: 12px; - position: relative; - padding: 4px 0 4px 1px; - display: inline-block; - width: 100%; - margin: 0; - background: #ecf0f3; - padding-left: 10px; - margin-bottom: 14px; - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - cursor: default; -} -.own_name:after { - content: ""; - position: absolute; - display: block; - top: 5px; - right: 10px; - width: 10px; - height: 10px; - border-radius: 50%; - background: #69bfee; - -webkit-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.5); - -moz-box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.5); - box-shadow: inset 0 1px 1px rgba(55, 72, 88, 0.5); - border: 1px solid #c5e6f8; -} -.label_title { - display: inline-block; - width: calc(80% - 12px); - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} -.input_label_wrap { - position: relative; -} -.input_label_wrap p { - font-size: 12px; - margin: 0 0 4px 4px; -} -.input_label_wrap label { - position: absolute; - bottom: 4px; - left: 4px; - color: #aabbca; -} -/* div.action_button { */ -/* background: #FFF; */ -/* border: 1px solid #CCC; */ -/* border-radius: 5px 5px 5px 5px; */ -/* color: #374858; */ -/* cursor: pointer; */ -/* display: inline-block; */ -/* float: left; */ -/* font-size: 14px; */ -/* height: 25px; */ -/* line-height: 30px; */ -/* margin-right: 10px; */ -/* padding: 0 10px; */ -/* text-align: center; */ -/* top: 0; */ -/* } */ -/* div.action_button:hover { */ -/* color: #69bfee; */ -/* border: 1px solid #69bfee; */ -/* } */ -div.action_button_click_only { - cursor: pointer; -} -div.bigger_button { - font-size: 18px; - margin: 0; - padding: 5px; - width: 250px; - cursor: pointer; - transition: background 0.3s ease; -} -#button_add_entry { - /* margin-right: 10px; */ -} -.action_button { - height: 19px; - width: 24px; -} -.action_button img { - width: 24px; - height: 24px; - display: inline-block; - margin: auto; -} -.action_button p { - display: inline-block; - margin: 0; - margin-left: 5px; - text-align: left; -} -.file_upload_button { - width: auto; - height: 30px; -} -#saved_entry { - display: none; - background-color: #BDCA70; - border-radius: 5px; - color: white; - font-size: 18px; - left: 50%; - margin-left: -60px; - padding: 10px; - position: absolute; - text-align: center; - top: 0; - width: 100px; -} -div.dragging_entry { - background: #69bfee; - border-radius: 2px; - color: #FFF; - cursor: move; - font-size: 18px; - margin-top: -10px; - margin-left: -30px; - opacity: 0.5; - padding: 10px; - text-align: left; - width: 80px !important; - z-index: 100; -} -div.dd_entry_table { - display: table; - table-layout: fixed; - width: 100%; -} -div.dd_entry_row { - display: table-row; -} -div.dd_entry_cell { - border: 1px solid transparent; - display: table-cell; - vertical-align: top; -} -div.dd_entry_cell:hover { - border: 1px solid #CCC; -} -div.dd_entry_cell_wrapper { - position: relative; -} -div.dd_entry_cell_content { - position: relative; - display: block; - min-height: 66px; - vertical-align: top; - -webkit-box-sizing: border-box; - /* Safari/Chrome, other WebKit */ - -moz-box-sizing: border-box; - /* Firefox, other Gecko */ - box-sizing: border-box; - /* Opera/IE 8+ */ - overflow: hidden; - /* For tables */ -} -.handsontable { - overflow: scroll; -} -div.dd_entry_cell_content img { - -webkit-user-select: none; - /* Chrome all / Safari all */ - -moz-user-select: none; - /* Firefox all */ - -ms-user-select: none; - /* IE 10+ */ -} -div.dd_entry_cell_content .imageLayer { - left: 0; - margin-left: auto; - margin-right: auto; - position: absolute; - right: 0; - top: 0; -} -.file_placeholder { - text-align: center; - background-color: #d9e1e8; - border: 1px solid rgba(0, 0, 0, 0); - padding-top: 5px; - transition: background 0.3s ease; -} -.file_placeholder button { - cursor: pointer; - margin: 5px; - padding: 5px; -} -div.dd_entry_cell_file_download { - font-size: 16px; - padding: 15px 10px; - text-align: center; - overflow: hidde; - word-break: break-word; -} -div.dd_entry_cell_file_download span.icon-file { - font-size: 36px; -} -div.file_icon { - vertical-align: bottom; - display: inline-block; -} -div.file_extension { - position: absolute; - background-color: #374858; - color: #FFF; - font-size: 12px; - line-height: 12px; - margin: 12px 0 0 -16px; - padding: 2px; - -webkit-box-sizing: border-box; - /* Safari/Chrome, other WebKit */ - -moz-box-sizing: border-box; - /* Firefox, other Gecko */ - box-sizing: border-box; - /* Opera/IE 8+ */ - border: 1px solid #FFF; - width: 32px; -} -div.file_details { - display: inline-block; - text-align: left; - vertical-align: top; - line-height: 20px; -} -div.file_name { - display: block; - font-size: 18px; -} -div.file_size_link { - display: block; -} -div.file_size_link a { - margin-left: 10px; -} -div.dd_image_entry .dd_entry_cell_content { - text-align: center; - overflow: hidden; -} -.entry_button { - background-color: #e6ebef; - cursor: pointer; - display: none; - height: 30px; - margin: 0; - padding: 5px 0 0; - position: relative; - float: left; - text-align: center; - width: 35px; - z-index: 2; - font-size: 18px; - -webkit-transition: all 0.2s ease; - -moz-transition: all 0.2s ease; - -o-transition: all 0.2s ease; - transition: all 0.2s ease; -} -.entry_button:hover { - background-color: #d9e1e8; -} -.entry_button:active { - -webkit-box-shadow: inset 0 2px 1px rgba(55, 72, 88, 0.2); - -moz-box-shadow: inset 0 2px 1px rgba(55, 72, 88, 0.2); - box-shadow: inset 0 2px 1px rgba(55, 72, 88, 0.2); -} -div.zoom_button, -div.settings_button { - /* border-bottom: 1px solid #CCC; */ - /* border-left: 1px solid #CCC; */ - border-right: 0; - border-top: 0; - border-radius: 0; - right: 0; -} -div.cancel_button, -div.drag_button { - /* right: 35px; */ -} -div.save_button, -div.edit_button { - /* border-right: 1px solid #CCCCCC; */ - /* right: 70px; */ -} -div.zoom_button { - /* border-right: 1px solid #CCCCCC; */ - /* right: 105px; */ -} -div.zoom_button span { - font-size: 14px; - margin: 10px; - line-height: 1.6; - color: #4b6277; -} -div.drag_button { - cursor: move; -} -div.cancel_button, -div.save_button { - display: none; -} -div.zoom_button:hover, -div.cancel_button:hover, -.save_button:hover, -.settings_button:hover, -.drag_button:hover, -.edit_button:hover { - /* color: #69bfee; */ -} -div.zoom_button:hover, -div.settings_button:hover { - margin: 0; -} -div.dd_entry_cell:hover div.zoom_button, -div.dd_entry_cell:hover div.settings_button, -div.dd_entry_cell:hover div.drag_button, -div.dd_entry_cell:hover div.edit_button { - display: block; -} -/* we need !important to override inline css set in labfolder-project.js when showing or hiding buttons for redactor enabled/disabled */ -div.epb_entry.readOnly div.cancel_button, -div.epb_entry.readOnly div.drag_button, -div.epb_entry.readOnly div.settings_button, -div.epb_entry.readOnly div.save_button, -div.epb_entry.readOnly div.edit_button, -div.epb_entry.readOnly div.zoom_button, -div.epb_entry.readOnly button.file_upload_button, -div.epb_entry.readOnly div.more_options_item_remove_block_element { - display: none !important; -} -div.disabled_button { - display: none !important; -} -/*TODO nest better hdrop*/ -.hdrop { - height: 15px; - display: table; - table-layout: fixed; - width: 100%; - transition: background 0.3s ease; -} -.hdrop:only-child { - box-sizing: border-box; - height: 100px; - padding: 40px; -} -.hdrop:only-child:before { - content: "This entry is empty. You can add a TEXT, a SKETCH, a TABLE or attach a FILE by clicking or dragging the buttons in the toolbar above."; - font-size: 13px; - background: #ffffff; - padding: 2px 4px; -} -.hdrop.drop_active:only-child:before { - content: "Drag it here."; -} -.hdrop.drop_hover:only-child:before { - content: "Now drop it."; -} -.hdrop:last-child { - /* border-radius: 0 0 10px 10px; */ -} -.vdrop { - width: 20px; - display: table-cell; - transition: background 0.3s ease; -} -#button_add_entry.drop_active, -.drop_active { - background-color: #aea; -} -.file_placeholder.drop_active { - background-color: #97d3f3; -} -#button_add_entry.drop_hover, -.drop_hover { - background: #69bfee; -} -.file_placeholder.drop_hover { - background-color: #69bfee; -} -.dragBar { - cursor: col-resize; - display: table-cell; - text-align: center; - vertical-align: middle; - width: 10px; -} -.dragBar img { - height: 10px; - width: 2px; -} -.dragBar:hover { - background-color: #DDD; -} -div.epb_entry.readOnly .dragBar { - cursor: default; -} -div.epb_entry.readOnly .dragBar img { - display: none; -} -div.epb_entry.readOnly .dragBar:hover { - background-color: initial; -} -.hidden_entry { - visibility: hidden; -} -.button_wrapper_sticky { - position: fixed !important; - top: 131px !important; - right: inherit !important; - z-index: 20; -} -.dd_entry_cell.ui-state-disabled, -.dd_entry_cell.ui-widget-content .ui-state-disabled, -.dd_entry_cell.ui-widget-header .ui-state-disabled { - background-image: none !important; - opacity: 1 !important; -} -#paste_hidden_input { - opacity: 0; - position: absolute; - right: 10000px; - top: -10000px; -} -/************* -* action bar * -**************/ -.action_bar { - width: 100%; - height: 36px; - min-width: 800px; - padding-top: 10px; - background: white; - border-bottom: solid 2px #a1b3c4; - -webkit-box-shadow: 0 3px 4px rgba(55, 72, 88, 0.2); - -moz-box-shadow: 0 3px 4px rgba(55, 72, 88, 0.2); - box-shadow: 0 3px 4px rgba(55, 72, 88, 0.2); -} -.plus_btn { - width: 64px; - height: 22px; - color: white; - background: #38abf7; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #0b89dd), color-stop(1, #38abf7)); - background: -ms-linear-gradient(bottom, #0b89dd, #38abf7); - background: -moz-linear-gradient(center bottom, #0b89dd 0%, #38abf7 100%); - background: -o-linear-gradient(#38abf7, #0b89dd); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#38abf7', endColorstr='#0b89dd', GradientType=0); - text-align: left; - font-size: 27px; - font-family: Arial !important; - line-height: 0.6; - padding: 2px 9px; - position: relative; -} -.plus_btn:hover { - outline: 0; - color: #dcf0fb; -} -.plus_btn:active { - -webkit-box-shadow: inset 0 3px 2px rgba(55, 72, 88, 0.5); - -moz-box-shadow: inset 0 3px 2px rgba(55, 72, 88, 0.5); - box-shadow: inset 0 3px 2px rgba(55, 72, 88, 0.5); -} -.plus_btn:after { - content: "Add"; - font-size: 13px; - position: absolute; - right: 10px; - top: 12px; - font-weight: bold; - line-height: 0; -} -.plus_btn_wrap { - width: 200px; - float: left; - margin-top: -3px; -} -.plus_btn_hover { - height: 23px; - margin: 0 0 0 55px; -} -.add_dropdown { - display: none; - position: absolute; - top: 85px; - left: 0; - -webkit-box-shadow: 0 4px 10px rgba(55, 72, 88, 0.3); - -moz-box-shadow: 0 4px 10px rgba(55, 72, 88, 0.3); - box-shadow: 0 4px 10px rgba(55, 72, 88, 0.3); - z-index: 999; -} -.add_dropdown .default_button { - border: 0; - background: none; -} -.add_dropdown .default_button:active { - background: #4fb9f3; - -webkit-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0); - -moz-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0); - box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0); -} -.add_dropdown > ul { - width: 180px; - font-size: 14px; - color: white; - margin: 0; - padding: 12px 0 12px 0; - background: #18a2ed; -} -.add_dropdown > ul li { - list-style-type: none; - padding: 8px 10px 8px 50px; - cursor: pointer; -} -.add_dropdown > ul li:hover { - background: #4fb9f3; -} -.add_link { - padding: 0 0 0 50px !important; - height: 32px; -} -.add_link a { - width: auto; - padding: 8px 0 8px 0; - color: white; - text-decoration: none; - display: block; -} -.add_link a:hover { - text-decoration: none; -} -.action_menu_wrap { - float: left; - margin-top: -1px; -} -.filter_wrap > ul > li { - position: relative; - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - border-left: solid 1px #bac7d4; - border-top: solid 1px #bac7d4; - height: 25px; -} -.filter_wrap > ul > li:last-child { - padding: 6px 3px 0 10px; - border-left: solid 1px #bac7d4; - border-top: 0; -} -.filter_wrap > ul > li:first-child { - background: none; - border: none; - color: #7b95ad; - font-size: 12px; - padding: 6px 10px 0 0; - margin-left: 18px; -} -.more_filters { - /* display: none; */ -} -.filter_dropdown_wrap { - width: 190px; - height: auto; - position: absolute; - left: -1px; - top: 25px; - z-index: 999; - display: none; - color: #4b6277; -} -.filter_dropdown_wrap .folder_dn-img { - margin-top: 2px; -} -.filter_dropdown_wrap .folder_up-img { - margin-top: 0; -} -.filter_dropdown_wrap header { - font-size: 11px; - color: #d9e1e8; - background: #4b6277; - padding: 3px 6px 2px 6px; - float: left; -} -.filter_dropdown_wrap header > p { - margin: 0; - float: left; -} -.filter_dropdown_wrap header > span { - float: right; - padding: 0px 0 3px 8px; - color: white; - cursor: pointer; -} -.filter_dropdown { - overflow-y: auto; - overflow-x: hidden; - min-width: 190px; - max-height: 600px; - width: auto; - padding-bottom: 20px; - float: left; - border: solid 1px #bac7d4; - background: white; - -webkit-box-shadow: 0 4px 8px rgba(55, 72, 88, 0.3); - -moz-box-shadow: 0 4px 8px rgba(55, 72, 88, 0.3); - box-shadow: 0 4px 8px rgba(55, 72, 88, 0.3); -} -.filter_dropdown .list_vertical { - padding-top: 10px; -} -.filter_dropdown ul { - padding-left: 20px; -} -.filter_dropdown > ul { - margin: 0; - padding: 0; - width: 230px; -} -.filter_dropdown li { - list-style-type: none; -} -.filter_dropdown nav { - display: block; - height: 30px; - padding-top: 10px; -} -.filter_dropdown nav button { - float: left; - margin-right: 20px; -} -.filterOverlay.active { - opacity: 0.5; -} -.filter_project_dropdown > ul { - margin: 0; - padding: 0; - width: 270px; -} -.invalid_tag { - font-size: 12px; - color: #e66873; -} -.project_filter { - min-width: 255px !important; - padding: 0 6px 10px 4px; -} -.project_filter .tree_button { - display: none !important; -} -.project_filter .updateTS { - display: none !important; -} -.project_filter .treeline, -.project_filter .treeline_children_empty { - font-size: 12px; -} -.root_folder { - padding: 4px 0 4px 2px !important; - width: calc(100% - 29px); -} -.not_possible_project { - display: none; -} -.not_possible_author { - display: none; -} -.folder_label { - padding: 4px 0 4px 2px !important; - width: calc(100% - 29px); -} -.root_folder_wrap { - overflow: auto; - width: 100%; -} -.filter_date_header { - width: 190px; -} -.dropdown_padding { - padding: 10px; -} -.author_filter { - min-width: 255px !important; - padding: 0 6px 0 4px; -} -.tags_input { - margin-top: 10px; - border: solid 1px #bac7d4; - cursor: text; - padding: 2px; - min-height: 50px; - width: 100%; - overflow: auto; -} -.tags_input > span { - font-size: 11px; - padding: 1px 3px; - background: #f3f5f7; - border-radius: 3px; - border: solid 1px #cad4de; - height: 18px; - margin: 2px; - cursor: pointer; - display: inline-block; -} -.tags_input > span.selected_token { - border: 1px solid #4bb1d7; -} -.tags_input > span.invalid { - border: 1px solid #E66873; - color: #E66873; -} -.token_input { - border: none; - outline: none; - resize: none; - white-space: pre; - font-size: 11px; - line-height: 11px; - vertical-align: top; - font-family: arial, sans-serif; - padding: 5px 0 0 2px; - margin: 0px; - width: auto; - overflow: auto; -} -.token_input_width { - position: absolute; - height: 11px; - display: inline-block; - padding: 0px 10px; - visibility: hidden; -} -.tag_name { - display: inline-block; - margin-right: 5px; - max-width: 250px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} -.delete_tag { - color: #9baec0; - cursor: pointer; - display: inline-block; - padding: 1px 3px 1px 0px; - vertical-align: top; -} -.delete_tag:after { - content: "\00d7"; -} -.tag_data_wrap { - margin-top: 10px; -} -.tag_data_wrap > ul { - margin: 0; - padding: 0; -} -.tag_data_wrap > ul li { - list-style-type: none; -} -.tag_index { - padding-right: 5px; - text-align: center; - font-size: 10px; - font-weight: bold; - border-right: solid 1px #bac7d4; - float: left; -} -.tag_index > ul { - margin: 0; - padding: 0; -} -.tag_index > ul li { - list-style-type: none; -} -.tag_index li { - width: 15px; - padding: 3px 0 3px 0; - margin-bottom: 1px; - display: block; - cursor: pointer; -} -.tag_index li:hover { - background: #ecf0f3; -} -.existing_tag { - cursor: pointer; -} -.existing_tag.disabled { - color: white; - background: #7b95ad; - border: 1px solid #7b95ad; -} -li.index_selected { - background: #d9e1e8; -} -li.index_selected:hover { - background: #d9e1e8; -} -.all_tags_head { - font-size: 12px; - margin: 10px 0 5px 0; -} -.all_tags { - font-size: 12px; - margin: 40px 0 5px 0; -} -.tag_register { - overflow: auto; - max-height: 300px; - width: 100%; - float: left; - margin-left: 10px; - font-size: 11px; -} -.tag_register ul { - margin: 0; - padding: 0; -} -.tag_register ul li { - list-style-type: none; -} -.tag_register > ul > li { - margin-bottom: 15px; -} -.tag { - padding: 1px 3px; - background: #f3f5f7; - border-radius: 3px; - border: solid 1px #cad4de; - display: inline-block; -} -.my_tags li { - margin-bottom: 5px; -} -.my_tags span { - display: inline-block; - padding: 1px 3px; - background: #f3f5f7; - border-radius: 3px; - border: solid 1px #cad4de; -} -.my_tags .selected_tag { - background: #38abf7; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #0b89dd), color-stop(1, #38abf7)); - background: -ms-linear-gradient(bottom, #0b89dd, #38abf7); - background: -moz-linear-gradient(center bottom, #0b89dd 0%, #38abf7 100%); - background: -o-linear-gradient(#38abf7, #0b89dd); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#38abf7', endColorstr='#0b89dd', GradientType=0); - color: #ffffff; -} -.my_tags .selected_tag.disabled.selected_tag { - background: #f3f5f7; - border: 1px solid #E66873; - color: #E66873; -} -.group_tags li { - margin-bottom: 7px; -} -.group_tags span { - display: inline-block; - padding: 1px 3px; - background: #f3f5f7; - border-radius: 3px; - border: solid 1px #cad4de; -} -.managed_tags li { - margin-bottom: 7px; -} -.managed_tags span { - display: inline-block; - padding: 1px 3px; - background: #f3f5f7; - border-radius: 3px; - border: solid 1px #cad4de; -} -.custom_selectbox { - min-width: 100px; -} -.filter_date_input { - background: white; - border: solid 1px #bac7d4; - width: 120px; - height: 26px; - padding: 2px; - color: #4b6277; -} -.datepicker_wrap { - margin-top: 20px; -} -.datepicker_wrap > div:first-child { - margin-bottom: 15px; -} -.input_label_wrap label.hidden { - display: none; -} -.filter_date_icon { - display: block; - position: absolute; - right: 24px; - top: 20px; - font-size: 20px; - cursor: pointer; -} -.empty_filter_message { - font-size: 12px; - margin: 0 0 10px 10px; -} -/******* -* entry * -********/ -#epb_container { - position: relative; - width: 100%; -} -.epb_entry { - width: 100%; - margin: 19px 0 15px 0; - display: inline-block; -} -.readOnly .entry_toolbar_btns { - display: none; -} -.entry_loading { - background: rgba(255, 255, 255, 0.7); - position: fixed; - top: 85px; - bottom: 0; - left: 0; - z-index: 99; - right: 0; -} -.entry_loading span { - padding: 25px; - background: #fff; - opacity: 1; - border-radius: 10px; - border: 1px solid #9baec0; - -webkit-box-shadow: 0 2px 2px rgba(55, 72, 88, 0.3); - -moz-box-shadow: 0 2px 2px rgba(55, 72, 88, 0.3); - box-shadow: 0 2px 2px rgba(55, 72, 88, 0.3); - color: #5e7b97; - font-size: 24px; - top: 300px; - width: 250px; - margin-left: -125px; - left: 50%; - text-align: center; - position: absolute; -} -.entry_container { - min-width: 726px; - margin-right: 45px; -} -.entry_header { - width: 100%; - height: 33px; - font-size: 12px; - background: #cdd7e0; -} -.entry_author { - color: #374858; - float: left; -} -.entry_author > ul { - margin: 0; - padding: 0; -} -.entry_author > ul li { - list-style-type: none; -} -.entry_author figure { - background: #ecf0f3; - border: solid 1px #7b95ad; - margin: 2px; - width: 29px; - height: 29px; - float: left; - position: relative; -} -.entry_author figure img { - width: 27px; - height: 27px; - position: absolute; - top: 0; - left: 0; -} -.entry_author figure > span { - margin-left: 4px; -} -.author_name { - float: left; - padding: 2px; - line-height: 1.3; - width: 196px; -} -.author_firstname, -.author_lastname { - white-space: nowrap; - text-overflow: ellipsis; - display: block; - overflow: hidden; - padding: 0; - margin-left: 0; -} -.entry_title_wrap { - float: left; - position: relative; - padding: 2px 4px 3px 4px; - line-height: 1.3; - border-left: 1px solid #ffffff; -} -.entry_name_menu { - float: left; - height: 30px; - overflow: hidden; -} -.entry_name_menu > ul { - margin: 0; - padding: 0; -} -.entry_name_menu > ul li { - list-style-type: none; -} -.entry_name_menu p { - margin: 0; - display: inline-block; -} -.entry_name_menu li { - max-width: 800px; - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; -} -.entry_name_menu li:first-child { - float: left; - color: #4f677e; - margin-right: 10px; - font-size: 11px; - line-height: 1.4; -} -.entry_name_menu li:last-child { - float: left; -} -.entry_menu_list { - float: left; - width: 164px; - height: 30px; - overflow: hidden; -} -.entry_menu_list > ul { - margin: 0; - padding: 0; -} -.entry_menu_list > ul li { - list-style-type: none; -} -.entry_menu_list p { - margin: 0; - display: inline-block; -} -.entry_menu_list li { - width: 100%; - display: block; - clear: both; -} -.entry_menu_list li span:first-child { - min-width: 45px; - max-width: 92px; - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - float: left; - margin-right: 10px; - color: #4f677e; - font-size: 11px; -} -.entry_menu_list li span:last-child { - float: left; - color: #374858; -} -.entry_menus { - height: 100%; - float: right; - position: relative; -} -.entry_menus > ul { - margin: 0; - padding: 0; -} -.entry_menus > ul > li { - list-style-type: none; - float: left; - position: relative; -} -.entry_menus > ul { - height: 100%; -} -.entry_menus > ul > li { - width: 200px; - border-right: solid 1px white; - padding: 2px 4px 3px 4px; - height: 33px; - line-height: 1.3; - background: #cdd7e0; - position: relative; -} -.entry_menus > ul > li:first-child { - border-left: solid 1px white; -} -.entry_menus > ul > li:last-child { - border-right: none; - width: 90px; -} -.entry_menu_more { - min-height: 33px; - height: auto !important; - overflow: visible; - border-bottom: solid 1px #ffffff; - border-left: solid 1px #ffffff; - -webkit-box-shadow: 0 1px 2px rgba(55, 72, 88, 0.5); - -moz-box-shadow: 0 1px 2px rgba(55, 72, 88, 0.5); - box-shadow: 0 1px 2px rgba(55, 72, 88, 0.5); - z-index: 10; -} -.entry_menu_more .entry_menu_options span:last-child { - position: absolute; - bottom: 6px; -} -.show_list_more { - height: auto; -} -.readOnly .drop_edit_menu { - display: none; -} -.entry_menu_less { - /* overflow: hidden; */ -} -.entry_menu_show { - overflow: visible; -} -.entry_menu_edit .entry_dropdown { - display: block; -} -.entry_menu_options { - float: right; - margin-left: 10px; - padding-left: 4px; - height: 100%; - width: 15px; -} -.entry_menu_options > span { - display: block; - margin-right: 0; - cursor: pointer; -} -.entry_menu_options .arrow_menu_dn-img { - height: 10px !important; - margin-top: 7px; -} -.entry_options { - padding-top: 5px; - float: right; -} -.entry_options > ul { - margin: 0; - padding: 0; -} -.entry_options > ul > li { - list-style-type: none; - float: left; - position: relative; -} -.entry_options > ul > li { - margin-left: 6px; -} -.entry_options > span { - cursor: pointer; -} -.epb_comments_count { - color: #ffffff; - width: 17px; - display: block; - text-align: center; - margin-top: 1px; - font-size: 9px; - height: 12px; - line-height: 12px; -} -@-moz-document url-prefix() { - .epb_comments_count { - line-height: 11px; - } -} -.entry_toolbar { - height: 25px; - margin-left: 31px; - position: relative; - padding: 5px; - background: #cdd7e0; - border-top: solid 1px white; - -webkit-box-shadow: 0 2px 2px rgba(55, 72, 88, 0.3); - -moz-box-shadow: 0 2px 2px rgba(55, 72, 88, 0.3); - box-shadow: 0 2px 2px rgba(55, 72, 88, 0.3); -} -.entry_toolbar > ul { - margin: 0; - padding: 0; -} -.entry_toolbar > ul > li { - list-style-type: none; - float: left; - position: relative; -} -.entry_toolbar > ul > li { - margin-right: 12px; - cursor: pointer; -} -.entry_toolbar > ul > li:first-child { - margin-left: 6px; -} -.entry_toolbar_btns { - /*display: none;*/ -} -.entry_content { - min-height: 300px; - background: #f9fafb; - border: solid 1px #cad4de; -} -.entry_footer { - margin-left: 30px; - height: 25px; - background: #cad4de; -} -.tag { - padding: 1px 3px; - background: #f3f5f7; - border-radius: 3px; - border: solid 1px #cad4de; -} -.entry_tags { - float: left; - height: 100%; - overflow: hidden; - max-width: 138px; -} -.entry_tags > span { - display: inline-block; - padding: 1px 3px; - background: #f3f5f7; - border-radius: 3px; - border: solid 1px #cad4de; - float: left; - line-height: 1; - padding: 0px 3px; - border: solid 1px #aabbca; - margin-right: 2px; -} -.entry_dropdown { - width: 101%; - min-width: 260px; - height: auto; - padding: 10px; - background: #cdd7e0; - border-left: solid 1px white; - border-right: solid 1px white; - border-bottom: solid 1px white; - position: absolute; - top: 0; - right: -1px; - z-index: 14; - -webkit-box-shadow: 0 4px 10px rgba(55, 72, 88, 0.3); - -moz-box-shadow: 0 4px 10px rgba(55, 72, 88, 0.3); - box-shadow: 0 4px 10px rgba(55, 72, 88, 0.3); - display: none; -} -.entry_dropdown > ul { - margin: 0; - padding: 0; -} -.entry_dropdown > ul li { - list-style-type: none; -} -.entry_dropdown input { - border: none; - height: 28px; - font-size: 12px; - padding-left: 6px; - width: 100%; - color: #4b6277; -} -.entry_dropdown label { - font-size: 11px; - display: block; - margin-bottom: 4px; -} -.entry_dropdown > nav { - width: 100%; - height: 18px; -} -.entry_name { - right: auto !important; - left: -1px !important; -} -.entry_name select { - width: 60%; -} -.entry_name > ul > li { - margin: 4px 0 12px 0; -} -.entry_name > ul > li:first-child { - margin-top: -8px; -} -.project_tree { - width: 100%; - height: 140px; - overflow: auto; - background: white; -} -.close_entry_menu { - height: 18px; - width: 100%; - margin-top: -5px; -} -.close_entry_menu span { - float: right; -} -.save_entry_menu { - height: 20px; - float: right; - margin-top: 10px; -} -.save_entry_menu .grey_link { - display: block; - float: left; - padding: 4px 20px 0 0; -} -.select_entry_menu { - width: 100%; - height: 25px; - float: left; - margin-top: 20px; -} -.select_entry_menu span, -.select_entry_menu button { - float: left; - margin-right: 15px; -} -.select_entry_menu .blue_link { - color: #3b97ed; -} -.entry_tag_index li:hover { - background: #d9e1e8; -} -.entry_tag_index li.index_selected { - background: #e6ebef; -} -.entry_tag_index li.index_selected:hover { - background: #e6ebef; -} -.entry_tags_input { - margin: 0; - background: white; - border: none; -} -.entry_dates { - width: 100%; -} -.entry_dates > li { - display: block; - width: 100%; - clear: both; - overflow: auto; - margin-bottom: 15px; -} -.entry_dates > li > span { - margin: 5px 0 0 6px; - cursor: pointer; -} -.entry_dates > li > span:active { - margin: 6px 0 0 6px; -} -.entry_dates input { - height: 25px; - background: #e9edf1; -} -.entry_dates input:focus { - background: white; -} -.entry_dates > li:last-child { - margin-bottom: 5px; -} -.entry_dates > li:last-child input { - background: white; -} -.entry_dates > li:first-child { - margin-bottom: 0; -} -.drag_handle { - background: #d9e1e8; - width: 9px; - height: 25px; - padding: 5px 3px; - float: left; - cursor: move; -} -.drag_handle span { - width: 3px; - height: 3px; - display: block; - background: #bac7d4; - margin: 1px 0 2px 0; -} -.date_key { - width: 120px; - float: left; - margin-right: 10px; - position: relative; -} -.date_key:after { - content: ":"; - position: absolute; - left: 123px; - top: 4px; - font-size: 12px; - font-weight: bold; -} -.date_value { - width: 80px; - float: left; - position: relative; -} -.entry_settings { - width: 150px; - background: white; - line-height: 1.0; - position: absolute !important; - top: 24px; - right: -13px; - z-index: 30; - display: none; - margin-right: 0 !important; - -webkit-box-shadow: 0 2px 4px rgba(55, 72, 88, 0.8); - -moz-box-shadow: 0 2px 4px rgba(55, 72, 88, 0.8); - box-shadow: 0 2px 4px rgba(55, 72, 88, 0.8); -} -.entry_settings > ul { - margin: 0; - padding: 0; -} -.entry_settings > ul li { - list-style-type: none; -} -.entry_settings .trash_dark-img { - right: 4px; -} -.entry_settings ul { - padding: 10px 0 10px 0; -} -.entry_settings li { - font-size: 12px; - padding: 8px 10px; - display: block; - cursor: pointer; -} -.entry_settings li:hover { - background: #e0e6eb; -} -.entry_settings_arrow { - position: relative; - background: #f9fafb; -} -.entry_settings_arrow:after { - top: -11px; - right: 19px; - border: solid transparent; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - border-color: rgba(136, 183, 213, 0); - border-bottom-color: #f9fafb; - border-width: 7px; - margin-left: -3px; -} -.epb_content_wrap { - display: table; - min-width: 696px; - margin-left: 30px; - margin-right: 45px; - min-height: 100px; - background: #f3f5f7; - border: solid 1px #aabbca; -} -.handsontable th { - background: #d9e1e8; - font-size: 12px; - color: #4b6277; -} -.handsontable th, -.handsontable td { - border-right: 1px solid #cad4de; - border-bottom: 1px solid #cad4de; -} -.handsontable tr:first-child th, -.handsontable tr:first-child td { - border-top: 1px solid #cad4de; -} -.handsontable th:first-child, -.handsontable td:first-child, -.handsontable .htNoFrame + th, -.handsontable .htNoFrame + td { - border-left: 1px solid #cad4de; -} -div.dd_entry_cell { - border: 1px solid #d9e1e8; - -webkit-transition: border 0.2s ease; - -moz-transition: border 0.2s ease; - -o-transition: border 0.2s ease; - transition: border 0.2s ease; -} -div.dd_entry_cell:hover { - border: 1px solid #3babe9; -} -div.dd_entry_cell:hover .button_wrapper { - display: block; -} -#button_add_entry.drop_active, -.drop_active { - background-color: #d8f1ff; -} -#button_add_entry.drop_hover, -.drop_hover { - background: #69bfee; -} -.settings_button span { - margin-top: 10px; - display: block; -} -.edit_button span { - margin: 5px 0 0 12px; -} -.drag_button span { - margin: 3px 0 0 10px; -} -.drag_button:active { - -webkit-box-shadow: inset 0 0 0 rgba(55, 72, 88, 0) !important; - -moz-box-shadow: inset 0 0 0 rgba(55, 72, 88, 0) !important; - box-shadow: inset 0 0 0 rgba(55, 72, 88, 0) !important; -} -.cancel_button span { - margin: 5px 0 0 12px; -} -.save_button span { - margin: 2px 0 0 10px; -} -.button_wrapper { - position: absolute; - right: -1px; - top: -1px; - display: none; - border: solid 1px #cad4de; - z-index: 8; - -webkit-box-shadow: -2px 1px 1px rgba(55, 72, 88, 0.1) !important; - -moz-box-shadow: -2px 1px 1px rgba(55, 72, 88, 0.1) !important; - box-shadow: -2px 1px 1px rgba(55, 72, 88, 0.1) !important; -} -.button_wrapper .more_options_panel { - -webkit-box-shadow: 0 2px 4px rgba(55, 72, 88, 0.4) !important; - -moz-box-shadow: 0 2px 4px rgba(55, 72, 88, 0.4) !important; - box-shadow: 0 2px 4px rgba(55, 72, 88, 0.4) !important; - border: 0; -} -.button_wrapper .more_options_item { - min-width: 140px; -} -.more_options_panel.in_block { - right: -1px; - top: 36px; - padding: 10px 0 10px 0; - background-color: #e6ebef; -} -.more_options_item_remove_block_element span { - float: left; -} -.more_options_item { - padding: 6px; -} -.more_options_item:hover { - background: #f9fafb; -} -/********* -* tables * -**********/ -.htContextMenu table.htCore { - outline: 1px solid #d9e1e8; - line-height: 1.0; - -webkit-box-shadow: 0 2px 4px rgba(55, 72, 88, 0.4); - -moz-box-shadow: 0 2px 4px rgba(55, 72, 88, 0.4); - box-shadow: 0 2px 4px rgba(55, 72, 88, 0.4); -} -.htContextMenu table tbody tr td { - font-size: 12px; - color: #4b6277; - background: #e9edf1; -} -.htContextMenu table tbody tr td:hover { - background: #f9fafb; -} -.htContextMenu table tbody tr td.current { - background: #f9fafb; -} -.htContextMenu table tbody tr td.htSeparator { - border-top: 1px solid #cad4de; -} -/**************** -* media queries * -****************/ -@media (max-height: 750px) { - .filter_dropdown { - max-height: 460px; - } -} -@media (max-width: 1750px) { - .entry_name_menu li { - max-width: 400px; - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - } -} -@media (max-width: 1380px) { - .entry_name_menu li { - max-width: 190px; - } - .entry_menus > ul > li { - width: 174px; - } - .entry_menu_list { - width: 138px; - } -} -@media (max-width: 1100px) { - .author_name { - width: auto; - margin-right: 20px; - } - .author_firstname, - .author_lastname { - width: 100px; - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - } -} -@media (max-width: 970px) { - .page_title { - margin-top: 2px; - font-size: 12px; - } - .plus_btn_wrap { - width: 130px; - } - .author_firstname, - .author_lastname { - width: 66px; - } - .entry_menus > ul > li { - width: 120px; - } - .entry_menu_list { - width: 84px; - } - .entry_menu_list li span:first-child { - display: block; - float: none; - } - .entry_tags { - width: 84px; - } - .entry_tags > span { - max-width: 84px; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } -} -@media (max-width: 870px) { - .entry_name_menu li { - max-width: 90px; - } -} - diff --git a/unittests/example_labfolder_data/static/css/pixel_icon.css b/unittests/example_labfolder_data/static/css/pixel_icon.css deleted file mode 100644 index 50aed1d7ae74ac5565f36e14c00ada4098d210c5..0000000000000000000000000000000000000000 --- a/unittests/example_labfolder_data/static/css/pixel_icon.css +++ /dev/null @@ -1,570 +0,0 @@ -/************** -* basic.css * -**************/ -/********** -* colors * -***********/ -/********** -* helper * -***********/ -.list_vertical > ul { - margin: 0; - padding: 0; -} -.list_vertical > ul li { - list-style-type: none; -} -.list_horizontal > ul { - margin: 0; - padding: 0; -} -.list_horizontal > ul > li { - list-style-type: none; - float: left; - position: relative; -} -/************* -* functions * -**************/ -/****** -* css * -******/ -body { - color: #374858; -} -.clearfix:after { - content: " "; - visibility: hidden; - display: block; - height: 0; - clear: both; -} -/********* -* icons * -**********/ -.icon_source { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; -} -.logo-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -6px -10px; - width: 130px; - height: 30px; - margin: 16px 0 0 22px; -} -.author_only-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -140px -3px; - width: 15px; - height: 15px; -} -.add_text-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -161px -3px; - width: 22px; - height: 15px; -} -.add_text-img:hover { - background-position: -161px -31px; -} -.add_text-img:active { - margin-top: 1px; -} -.add_sketch-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -190px -3px; - width: 22px; - height: 15px; -} -.add_sketch-img:hover { - background-position: -190px -31px; -} -.add_sketch-img:active { - margin-top: 1px; -} -.add_table-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -218px -3px; - width: 23px; - height: 15px; -} -.add_table-img:hover { - background-position: -218px -31px; -} -.add_table-img:active { - margin-top: 1px; -} -.add_upload-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -942px -3px; - width: 18px; - height: 15px; -} -.add_upload-img:hover { - background-position: -942px -31px; -} -.add_upload-img:active { - margin-top: 1px; -} -.add_import-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -246px -3px; - width: 23px; - height: 15px; -} -.add_import-img:hover { - background-position: -246px -31px; -} -.add_import-img:active { - margin-top: 1px; -} -.wheel-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -282px -3px; - width: 15px; - height: 15px; -} -.wheel-img:hover { - background-position: -282px -31px; -} -.arrow_down-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -303px -3px; - width: 15px; - height: 15px; - cursor: pointer; -} -.arrow_down-img:hover { - background-position: -303px -31px; -} -.arrow_up-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -327px -3px; - width: 15px; - height: 15px; - cursor: pointer; -} -.arrow_up-img:hover { - background-position: -327px -31px; -} -.comment-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -348px -3px; - width: 19px; - height: 19px; -} -.comment-img:hover { - background-position: -348px -31px; -} -.todo-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -1085px -4px; - width: 14px; - height: 13px; -} -.project-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -375px -3px; - width: 16px; - height: 16px; - margin-top: 6px !important; -} -/* .project-img:hover{ */ -/* background-position: -375px -31px; */ -/* } */ -.manage-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -400px -2px; - width: 20px; - height: 20px; -} -.manage_s-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -1050px -35px; - width: 10px; - height: 10px; - margin-top: 2px; -} -.desk-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -428px -3px; - width: 16px; - height: 16px; - margin-top: 6px !important; -} -.desk_s-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -1067px -35px; - width: 10px; - height: 10px; - margin-top: 3px; -} -.template_s-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -796px -3px; - width: 10px; - height: 16px; -} -.bell-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -454px -1px; - width: 22px; - height: 22px; -} -.bell-img:hover { - background-position: -454px -29px; -} -.search-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -488px -1px; - width: 26px; - height: 23px; -} -.search-img:hover { - background-position: -488px -29px; -} -.avatar-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -522px 1px; - width: 16px; - height: 22px; -} -.avatar_s-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -837px -37px; - width: 8px; - height: 10px; - margin-top: 4px; -} -.group-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -853px -35px; - width: 20px; - height: 13px; - margin-top: 3px; -} -.arrow_down_s-img { - position: relative; - background: transparent; -} -.arrow_down_s-img:after { - top: 100%; - left: 50%; - border: solid transparent; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - border-color: rgba(213, 213, 213, 0); - border-top-color: #374858; - border-width: 4px; - margin-left: -4px; -} -.arrow_down_s-img:hover { - background-position: -691px -39px; -} -.close_x-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -895px -8px; - width: 10px; - height: 9px; -} -.feedback-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -912px -2px; - width: 10px; - height: 61px; -} -.invite-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -925px -2px; - width: 10px; - height: 52px; -} -.pending-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -1011px -9px; - width: 17px; - height: 10px; -} -.single_tag_img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -970px -5px; - width: 12px; - height: 14px; -} -.root_tag_img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -986px -4px; - width: 19px; - height: 15px; -} -.menu_arrow-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -853px -7px; - width: 14px; - height: 11px; -} -.folder_up-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -738px -3px; - width: 24px; - height: 15px; -} -.folder_dn-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -764px -5px; - width: 24px; - height: 13px; -} -.project_s-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -814px -5px; - width: 12px; - height: 14px; -} -.notebook_s-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -1035px -34px; - width: 10px; - height: 12px; - margin-top: 2px; -} -.edit-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -659px -7px; - width: 11px; - height: 10px; -} -.trash_dark-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -631px -5px; - width: 10px; - height: 13px; -} -.trash-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -646px -4px; - width: 10px; - height: 13px; -} -.trash-img:hover { - background-position: -631px -4px; -} -.edit_light-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -674px -7px; - width: 11px; - height: 10px; -} -.edit_light-img:hover { - background-position: -659px -7px; -} -.edit_light-img:active { - margin-top: 1px; - margin-bottom: -1px; -} -.arrow_menu_dn-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -729px -11px; - width: 9px; - height: 5px; -} -.arrow_menu_dn-img:hover { - background-position: -729px -39px; -} -.arrow_menu_up-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -716px -11px; - width: 9px; - height: 5px; -} -.arrow_menu_up-img:hover { - background-position: -716px -39px; -} -.close_box-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - float: right; - margin: 0; - background-position: -546px -5px; - width: 17px; - height: 15px; - cursor: pointer; -} -.close_box-img:hover { - background-position: -546px -33px; -} -.close_box-img:active { - -webkit-box-shadow: 0 0 5px #ffffff; - -moz-box-shadow: 0 0 5px #ffffff; - box-shadow: 0 0 5px #ffffff; - background-position: -546px -5px; -} -.save-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - margin: 0; - background-position: -585px -5px; - width: 15px; - height: 15px; - cursor: pointer; -} -.drag-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - margin: 0; - background-position: -608px -5px; - width: 15px; - height: 15px; - cursor: pointer; -} -.close_dark_x-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -569px -8px; - width: 10px; - height: 9px; -} -.edit_dark-img { - background-image: url("../img/labfolder_icons.png"); - background-repeat: no-repeat; - margin-right: 5px; - float: left; - background-position: -659px -7px; - width: 11px; - height: 10px; -} - diff --git a/unittests/example_labfolder_data/static/css/redactor.css b/unittests/example_labfolder_data/static/css/redactor.css deleted file mode 100644 index fa4e0dd56156ce53b84e7734d1df319bc5f715e8..0000000000000000000000000000000000000000 --- a/unittests/example_labfolder_data/static/css/redactor.css +++ /dev/null @@ -1,1112 +0,0 @@ -/* - Icon font -*/ -@font-face { - font-family: 'RedactorFont'; - src: url('../font/redactor-font.eot'); -} -@font-face { - font-family: 'RedactorFont'; - src: url(data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMggi/NUAAAC8AAAAYGNtYXAaVcx2AAABHAAAAExnYXNwAAAAEAAAAWgAAAAIZ2x5Zm8dIFkAAAFwAAATSGhlYWQACVb9AAAUuAAAADZoaGVhA+ECBQAAFPAAAAAkaG10eEEBA94AABUUAAAAkGxvY2FVlFE8AAAVpAAAAEptYXhwAC8AkgAAFfAAAAAgbmFtZRHEcG0AABYQAAABZnBvc3QAAwAAAAAXeAAAACAAAwIAAZAABQAAAUwBZgAAAEcBTAFmAAAA9QAZAIQAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADmHwHg/+D/4AHgACAAAAABAAAAAAAAAAAAAAAgAAAAAAACAAAAAwAAABQAAwABAAAAFAAEADgAAAAKAAgAAgACAAEAIOYf//3//wAAAAAAIOYA//3//wAB/+MaBAADAAEAAAAAAAAAAAAAAAEAAf//AA8AAQAAAAAAAAAAAAIAADc5AQAAAAABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAwAAACUCAAGSAAQACQANAAA3EQURBQEFEQURATUXBwACAP4AAdv+SgG2/tySkiUBbgH+lAEBSgH+3AEBJv7/3G9sAAAGAAAASQIAAW4ABAAJAA4AEwAYAB0AABMhFSE1FSEVITUVIRUhNSczFSM1FTMVIzUVMxUjNZIBbv6SAW7+kgFu/pKSSUlJSUlJAW5JSW5JSW5JSdxJSW5JSW5JSQAAAAACAAAAJQH3AZIAFgAuAAAlLgMnBzIuAic+AyMXNh4CByUnMg4CBx4DIxcnHgMXNi4CBwH3Dik/XUABAR04Vjg+WDUYAQFNeEcZEv7MAQENHDMlHzIfEQEBASZUTDYHCSBIZj4lGCQaEARqFi5HLzJFKhJqDC1RZSzVPQoWIxkbJBQID0wCCQ4VDxo4KA8PAAACAG4AJQGSAZIABAAzAAA3IQchJzceAzMyPgI3PgMnNyMXDgMHDgMjIi4CJy4DNycjBx4DF24BJQH+3QFABRIUGg0QGBUQCAYKBgQBAUABAQEEBAQCCAgKBQYJCQcEAgUCAwEBPwEBAwcJCEkkJD8HCgYEBAYKBwcRFRkPtcMGCQkHAwMFAwEBAwUDAwcJCQbDtQ8ZFREHAAUAAP//AgABtwAGAA4AFgBHAF8AAAEzFTMVIzUfAQc1IzUzNS8BNxUzFSMVFx4DFRwBDgEHDgMHMh4CFx4DHwEjJzwBJjQjLgMrARUjNTMyHgIXBzMyPgI3PgM1NC4CJy4DKwEVAUkjS24mkZFvb96RkW9vDAMFAwECAwICBQUGBAECAgIBAQICAgEbIBMBAQIEBQUCCh0qCAwKCQM3DgMFBQMCAQIBAQEBAgECAwQGAw4BtpYgtv9cXEolSUhcXEklSlUDCAoNBwQJBwcCAwUDAgEBAQIBAQMEBANCLgEBAQIGBwYCSLYBAwUDRAECAgECBAQGAwQFBQQBAgIBATIAAAAAAwBtAAABkgGTAAMADAARAAAlIzcXBzM3MxczAyMDFyEVITUBI0YjI7ZKF2MXSmVbZQEBJP7c5nh4eUlJASb+2iRJSQAKAAAAJQIAAZIABAAJAA4AEwAYAB0AIgAnACwAMQAANxEFEQU3FzUHFTU3NScVJwcVFzUVJxU3NRUHFRc1NxUXNQclBxUXNRUnFTc1FQcVFzUAAgD+ALeSkpKSJW1tbW1tbSWSkgEkbW1tbW1tJQFuAf6UASUBSgFIbQFIAUq4AUgBSm8BSgFIbQFIAUrbSAFKAQEBSAFKbwFKAUhtAUgBSgAAAAIACQAlAgABkgAWAC4AACUOAxU1DgMHJj4CFzU0HgIXBT4DNxU1FD4CNy4DNRUmDgIXAgA5VTkcQVxAKA8RGEh3Thc2Vz/+PAY3S1UlECAxICYyHQw9Z0chCt8wRi8VAWsFDxsjGS1kUiwLaQETKUYxYBAUDwgDTRABCRMlGhoiFwkBPhAQJzkZAAAAAgBJAEkBtwFuAEcAjwAAAQ4DFRQeAhceAxc+Azc+AzU0LgInLgMHJg4CBwYiBiYHNAYmIicwLgE0NTQ+Ajc+Azc1DgMHJw4DFRQeAhceAxc+Azc+AzU0LgInLgMHJg4CBwYiBiYVJgYmIjUiJjQmNTQ+Ajc+Azc1DgMHATkJDQkEAwYKBgcOEBAJCA4NDAUGCAUDAwQHBQUKCgwGBQoICAMBAgIBAQEBAQEBAQMGCgYGDxITCxMhHBYJzQkNCQQDBwkHBg4QEQgIDg0MBgUIBQMCBQcFBAoLDAYFCQkIAwECAgEBAQEBAQEBAwcJBgcPERQLEyEcFwkBIgwYHBsQCxgUEgcICwgDAQECBggGBQ0MDwYIDA0KBgUIBAQBAQICBQECAgEBAQECAQQCBQEKEhQRCggQDAwDFwgQFBQNAQwYHBsQCxgUEgcICwgDAQECBggGBQ0MDwYIDA0KBgUIBAQBAQICBQECAgEBAQECAQQCBQEKEhQRCggQDAwDFwgQFBQNAAT//wBJAgABbgAEAAkADgASAAATIRUhNRchFSE1FSEVITUHNQcXAAIA/gC3AUn+twFJ/rclk5MBbklJbklJbklJSbdcWwAAAAUAAABJAgABbgAEAAkADgAaAG0AABMhFSE1FSEVITUVIRUhNSczNSM1IwcVNxUjFRc+Azc+Azc0PgE0NTQuAicuAyMiBioBByIOAiMVPgM3Mj4BMjM6AR4BFx4CFBUcAQYUBw4DBw4DDwEVMzUjPgM3MZIBbv6SAW7+kgFu/pKNRBgUFhYYIAUHBQMBAgICAQEBAQEDBAICBgcHBQEEAwQCAgMEBAICBAQDAgIDAwMCAgMDAwEBAgEBAQEBAgICAQQGCQULRC0BAwQEAgFuSUluSUluSUlrFF0GFAZJFJEFBwYEAQIDBAMBAgMDAwIDBwUFAgIEAgEBAQEBAhUBAgIBAQEBAQIBAQIDBAIBAgMCAQICAwMCAQUHCQYNExQBBAMFAgADAAAASQIAAW4ALAAxAGwAACUiLgInNTMeAzMyPgI1NC4CIyIOAgcjNT4DMzIeAhUUDgIjJzMVIzUnIg4CByMVDgMVFB4CFxUzHgMzMj4CNzMVDgMjIi4CNTQ+AjMyHgIXFSMuAyMBbgoUEhEIHgUKCwsGEyEZDg4ZIRMGCwsKBR4IERIUCh41KBcXKDUet5KSJQYLCwoFHgQHBQICBQcEHgUKCwsGBgsLCgUeCBESFAoeNSgXFyg1HgoUEhEIHgUKCwsGSQMGBwU0AgQDAQ0XHhESHhcNAQMEAjQFBwYDFyg1Hx41KBe3SUkvAQMEAhgFCw0OBwcNDQsGFwIEAwEBAwQCNAUHBgMXKDUeHzUoFwMGBwU0AgQDAQAAAAEAAAC3AgABAAAEAAATIRUhNQACAP4AAQBJSQABAJIASQGSAZIADAAAAQ8CFzcHNxc3DwEXAQcpQQvBC0ApQAvBC0EBWdYBOAE6AdgBOgE4AQAAAAQAAABJAgABbgAEAAkADgASAAATIRUhNRchFSE1FSEVITUHNRcHAAIA/gC3AUn+twFJ/re3k5MBbklJbklJbklJSbdcWwAAAAMAAAAlAgABkgAEAAkAEgAANxEFEQUBBREFEQc/ARcVJTU3FwACAP4AAdv+SgG2tiQwPv6Sbm4lAW4B/pQBAUoB/twBASa4AV5eSgFIk5MABAAlAAAB2wG3AAMAGgAeADUAAAEVJzMHHgIGDwEOAS4BJy4BNDY/AT4BHgEXARcnFTceATI2PwE+AS4BJy4CBg8BDgEeARcB29vbKgMDAQICcwIGBgYCAwMBAnQCBQYGAv5029sqAwYGBQJzAgEBAgMCBgYGAnICAgEDAgG33NwrAgYGBgJzAgEBAgMDBQYGAnMCAQECA/51AdvaKgMDAQJzAgUGBgMCAwECAnMCBQYGAgAABAAA/9sCAAHbAAMAGgAeADUAACU1Fwc3LgI2PwE+AR4BFx4BFAYPAQ4BIiYnBycXNQcuASIGDwEOAR4BFx4CNj8BPgEuAScBJdvbKgMDAQICcwIGBgYCAwMBAnQCBQYGAnTb2yoDBgYFAnMCAQECAwIGBgYCcgICAQMC/9zbASwCBgYGAnICAgEDAgMGBgUCcwIBAwN1AdzbKgMDAQJzAgUGBgMCAwECAnICBgYGAgABAG4AJQFuAZIAEgAAJREjESM1Ii4CNTQ+AjsBESMBSSRKFigeEREeKBaTJSUBSf63khEeKBcWKB4R/pMAAAAAAwAlAAEB3AG2AAoAVwB4AAAlMwcnMzUjNxcjFQcOAwcOAyMiLgInLgM1ND4CNz4DOwE1NC4CJy4DIyIOAgcOAwc1PgM3PgIyMzIeAhceAx0BIzU1IyIOAgcOAxUUHgIXHgMzMj4CNz4DPQEBkkpcXEpKXFxK6wIGBgcEAwgICQUIDw4LBQUHBQIDBQkGBQ8SFAwlAQMDAgMFBwgFBAoJCQQFCQkJBQQJCQkEBQkKCQUNFRENBQUIBQI0FQgMCggDAwUDAQECAwICBQUHAwUJCQcCAwUCApKRkZORkZMHBAYFBQECAwIBAgUHBQULDQ8JCRANCwQFBgUCCQMGBQQCAgICAQEBAgEBAwQFAy8CAwMCAQEBAQIFCAUGDhIXDXgYSwECAwICBgYIBQQGBgUCAgMCAQIEBgQECgsOBwQAAAAEACUASgHbAW4AAwAMAC0AegAANyM3FwczNzMXMwMjAyUVFA4CBw4DIyIuAicuAzU0PgI3PgM7ATcuAyMqAQ4BBw4DBxU+Azc+AzMyHgIXHgMdASMiDgIHDgMVFB4CFx4DMzI+Ajc+AzcVMzU0LgInrjUbGok4EUsSOE1ETQF/AQMFAwMHCQoFBAYGBQIDAwIBAgMEAwMJCw0IFiIFDhIWDQYKCgoFBAoJCgQFCgoJBQUJCgoFBAkHBgIDAwMBJg0WEw8GBgkGAwIFCAUFDA4QCQUJCQgEBAcHBgI3AgUIBsV1dXZHRwEf/uFlBAcOCwsEBAYEAwICAwICBQYHAwUJBwUCAgMCAWIFCAYCAQEBAQMCBAIwAwUEAwIBAgEBAQIDAQIEBgYDCQMEBwQFCw4QCgkPDgsFBQcFAgEBAwICBQUHAxh7DhcTDwUAAAIASQBJAbcBkwAEAIEAABMhFSE1Fx4DFx4DFRQOAgcOAyMiLgInLgMnFR4DFx4DMzI+Ajc+AzU0LgInLgMvAS4DJy4DNTQ+Ajc+AzMyHgIXHgMXNS4DJy4DIyIOAgcOAxUUHgIXHgMfAUkBbv6SvwQIBgYCAgMDAQIDBQQDCAkLBgYNDAwGBg0NDQYGCwwNBgYNDAwHDxoXEggHCwgDAgUHBAUMDxIKHAcNCQcDAgMDAQIDBQMDCAkKBgYLCgsGBQsLCgYGCwwLBgYLDAsGDBcUEQcICwcDAgQHBAUMERUNIAEAJSUxAgMFBAMDBgYHAwUICAYDAgQDAQECAwMCBQcIBEEDBAUDAgECAQEDBgkGBQ8SFQwJEA8NBgYKCggDCwIFBQQDAgUFBgMFBwcFAwIDAwEBAgMCAgQGBgM9AgUDBAEBAgEBAwcJBgYPERMLCA8ODAQFCgoJBQsAAAQAAABJAgABbgAEAAkADgATAAA/ARcHJxc3FwcnJScHFzcXJwcXNwAltiO4AbYluCMB/yO4JbYBuCO2Jdsdkh6TAZQekhwBHZIekwGUHpIcAAAAAAUAAP/bAgAB2wAEAAkADgATABgAABcRIREhASERIREHITUhFRUhNSEVFSE1IRUAAgD+AAHb/koBtkn+3AEk/twBJP7cASQlAgD+AAHc/kkBt5JJSW5JSW5JSQAAAwCTAEkBbQGSABcALwBbAAA3Mh4CFx4DFwYUDgEHDgMrATczNzIeAhceAhQXBhQOAQcOAysBNzMDMzI+Ajc+Ayc2LgInLgMnPgM3PgMnNi4CJy4DKwED+AcNCQkDBAMEAQEBBAQEAgkKDQcqASgBBQsIBwIDAwQBAQQCBAEICAsFKgEoZGQRGRgRCAYLBgQBAQMEBwQGCg8OCggMDQgFAwcDAwEBBAYLBgcQFBcOZAHeAQMEAwMICQwHBgsJCAIDBAMBYYECAgMDAgYHCQUFCQcGAgIEAgFN/uoDBQgGBQ4RFQsKEQ8NBgUJBgQBAQMFBwUECwwOCAsSDw0FBggFAv63AAADACUAAAHbAbcABAANABEAADcRIREhEyMDMzczFzMDBxcjNyUBtv5K/URMOBBLETdLIho0GgABt/5JAW7+20hIASU1eHgAAAACAEIAHwG8AZkAIQBLAAAlBycOAS4BJwcXBw4BIiYvAS4BNDY/AT4BMhYfAR4BFAYHJy4BIgYPAQ4BFBYXHgE+AT8BLgMnLgI2PwE+AhYXBxc3PgE0JicBvJQEBQsMCwYhHg8PJygnDw8PDw8P1w8nKCcPDw8QEA8lCxscHAvFCwwLCgsbHRsLJwMFBgUCCgwDBQhSBg8QEgl+JoYLCwoL9pQEAQECAwMgHg8PDw8PDxAmKCcP1w8QEA8PDycoJw9+CwoLC8YLGx0bCwoLAQsLJgIDBAUCChcXFQhSBgYBBAV9JYYLHBwbCwAAAAMAAABJAgABbgAEAAkADgAAEyEVITUXIRUhNRczFSM1AAIA/gCSAW7+kpPb2wFuSUluSUluSUkAAwAAAEkCAAFuAAQACQAOAAATIRUhNRUhFSE1FTMVIzUAAgD+AAFt/pPc3AFuSUluSUluSUkAAAADAAAASQIAAW4ABAAJAA4AABMhFSE1FSEVITUVIRUhNQAB//4BAf/+AQIA/gABbklJbklJbklJAAMAAABJAgABbgAEAAkADgAAEyEHIScHIRchNxchByEnbgElAf7dAW0B/wH9/wFtASUB/t0BAW5JSW5JSW5JSQAGAAAAJwIAAZUACAANABQAGAAdACEAADc1IxEhFTMRIQEhFSE1FyMVIRUhNQcjNxcXITUhFScXIzdJSQG3Sf5JAUn+kwFtSiX+twFu27hcXG3+2wElKSlJICdJASVK/twBSdzcSbcl3EltbSUlJW5JSQAAAAEAAAABAADCHXSvXw889QALAgAAAAAAz3WLJQAAAADPdYsl////2wIAAdsAAAAIAAIAAAAAAAAAAQAAAeD/4AAAAgD//wAAAgAAAQAAAAAAAAAAAAAAAAAAACQAAAAAAAAAAAAAAAABAAAAAgAAAAIAAAACAAAAAgAAbgIAAAACAABtAgAAAAIAAAkCAABJAgD//wIAAAACAAAAAgAAAAIAAJICAAAAAgAAAAIAACUCAAAAAgAAbgIAACUCAAAlAgAASQIAAAACAAAAAgAAkwIAACUCAABCAgAAAAIAAAACAAAAAgAAAAIAAAAAAAAAAAoAFAAeAEAAcAC4AQQBhgGoAfoCQAMCAyYDuARGBFQEcASUBLwFFgVuBY4GLgbUB4IHrAfaCFwIgAj2CRIJLglKCWoJpAAAAAEAAAAkAJAACgAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAOAK4AAQAAAAAAAQAYAAAAAQAAAAAAAgAOAGoAAQAAAAAAAwAYAC4AAQAAAAAABAAYAHgAAQAAAAAABQAWABgAAQAAAAAABgAMAEYAAQAAAAAACgAoAJAAAwABBAkAAQAYAAAAAwABBAkAAgAOAGoAAwABBAkAAwAYAC4AAwABBAkABAAYAHgAAwABBAkABQAWABgAAwABBAkABgAYAFIAAwABBAkACgAoAJAAUgBlAGQAYQBjAHQAbwByAEYAbwBuAHQAVgBlAHIAcwBpAG8AbgAgADEALgAwAFIAZQBkAGEAYwB0AG8AcgBGAG8AbgB0UmVkYWN0b3JGb250AFIAZQBkAGEAYwB0AG8AcgBGAG8AbgB0AFIAZQBnAHUAbABhAHIAUgBlAGQAYQBjAHQAbwByAEYAbwBuAHQARwBlAG4AZQByAGEAdABlAGQAIABiAHkAIABJAGMAbwBNAG8AbwBuAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==) format('truetype'), url(data:application/font-woff;charset=utf-8;base64,d09GRk9UVE8AABIoAAoAAAAAEeAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABDRkYgAAAA9AAADgEAAA4Bg0Rie09TLzIAAA74AAAAYAAAAGAIIvzVY21hcAAAD1gAAABMAAAATBpVzHZnYXNwAAAPpAAAAAgAAAAIAAAAEGhlYWQAAA+sAAAANgAAADYACVb9aGhlYQAAD+QAAAAkAAAAJAPhAgVobXR4AAAQCAAAAJAAAACQQQED3m1heHAAABCYAAAABgAAAAYAJFAAbmFtZQAAEKAAAAFmAAABZhHEcG1wb3N0AAASCAAAACAAAAAgAAMAAAEABAQAAQEBDVJlZGFjdG9yRm9udAABAgABADr4HAL4GwP4GAQeCgAZU/+Lix4KABlT/4uLDAeKZviU+HQFHQAAAT8PHQAAAUQRHQAAAAkdAAAN+BIAJQEBDRkbHSAlKi80OT5DSE1SV1xhZmtwdXp/hImOk5idoqessba7wFJlZGFjdG9yRm9udFJlZGFjdG9yRm9udHUwdTF1MjB1RTYwMHVFNjAxdUU2MDJ1RTYwM3VFNjA0dUU2MDV1RTYwNnVFNjA3dUU2MDh1RTYwOXVFNjBBdUU2MEJ1RTYwQ3VFNjBEdUU2MEV1RTYwRnVFNjEwdUU2MTF1RTYxMnVFNjEzdUU2MTR1RTYxNXVFNjE2dUU2MTd1RTYxOHVFNjE5dUU2MUF1RTYxQnVFNjFDdUU2MUR1RTYxRXVFNjFGAAACAYkAIgAkAgABAAQABwAKAA0AQQCYAPEBSQH6Ai8CxwMhA98EGwTXBYEFkQW0BfEGLwagBxEHOgf0CLUJaQmsCfwKhAq5C0QLdAuiC9AMAQxo/JQO/JQO/JQO+5QOi7AVi/gB+JSLi/wB/JSLBfhv990V/EqLi/u5+EqLi/e5Bfu4+5QVi/dv9yb7Avsm+wEFDvcm+AIV+AKLi0L8AouL1AWL+wIV+AKLi0L8AouL1AWL+wIV+AKLi0L8AouL1AX7JvdwFdSLi0JCi4vUBYv7AhXUi4tCQouL1AWL+wIV1IuLQkKLi9QFDviLsBVky0yq+0KWCIshBYuLQMb7LPcT9z33GsW4i4sIiyEF92Wr9wT7QV77Cgj7yfdpFYvIBYuLb3ImSOFBtnqLiwiLfIvXBe6F9yJ7nGSl0PsO6Ps2YwgO9wLUFfe4i4tn+7iLi68FysoVnHmngrGLsounlJydnJ2Up4uyCIv3SUyLi/tXBYt8hoCDg4ODgId8i32Lf4+Dk4OTh5aLmgiL91dLi4v7SQWLZJRvnXkIDvfd+EoVrouL+yrWi4tr+wKLi/dKBbH7kxX3JS/7JS+L1fsDi4uw9wOLi9QF+3LTFfsl5/cl54tC9wOLi2b7A4uLQQWXNhWTg499i3iLf4mBhoSGg4SHgYmOio6KjYiNiI6GjoQIpklri3i5BYuMio2KjYaZhZKEiwiBi4tDbouL90q1iwWfi5mHk4MIVEcVmYsFk4uRjY+Pjo+NkYuUi5SJkoiOh4+FjYOLCH2Li1kFDve393oVRYuu9wyu+wwF+0r7DRXVi6LU7ouiQtWLJve6MIsm+7oFjGcV97iLi0L7uIuL1AUOi7AVi/gB+JSLi/wB/JSLBfdLrxX3JouL1Psmi4tCBYv3AhX3JouL1Psmi4tCBWb3SxX7AYuLQvcBi4vUBYv7AhX7AYuLQvcBi4vUBYv7AhX7AYuLQvcBi4vUBbD3cBWLQvcmi4vU+yaLBfe4ixX7AYuLQvcBi4vUBYv7AhX7AYuLQvcBi4vUBYv7AhX7AYuLQvcBi4vUBQ74lPdzFfss+xNAUIuLCIv1BftCgExsZEte9wr3BPdB92VrCIv1BYuLxV73PfsaCPxYLBWcsvcim+6RCIs/i5oFi4u2nOHVJs5vpIuLCItOBfs2s/sOLqVGCA73zfe2FXNsgGiLY4tpk3Ccd513n4Gji6CLnJKZmpqakpyLn4uehZt+mH+ZfJJ7i32LgIeChQiIiYmKiYuKi4mMioyKjoqPi5GLpJOknKOco6KcqJYIi6EFWXhlcnRrCPthixV0bH9oi2OLaZNwnXecd6CBoougi5ySmpqZmpKci5+LnoWbfph/mX2Seot+i3+IgoQIiImJioqLiYuKjIqMiY6Kj4uRi6SUpJujnKOinKmWCIuhBVh4ZnJzawgOi/gCFfiUi4tC/JSLi9QF90v7AhX33YuLQvvdi4vUBYv7AhX33YuLQvvdi4vUBWZCFYv3S/snL/cnMAUO9yb4AhX4AouLQvwCi4vUBYv7AhX4AouLQvwCi4vUBYv7AhX4AouLQvwCi4vUBfsh9hXPi4ufc4uL6HeLdYWLd6GRi0Jzi4t3Bav7JRWXl5KTjY6PkI2PjY+Mj4yPi5CLlIiThJCFkYKOf4uHi4aKhoqGioaKhokIi3YFkI6QjZCNkIyPjI+LkIuPio6IjoiMh4uGi4iLiImIiYeJh4eHiIiDgX18CIB+i3jPi4ufXosFjo+QkJGRCIuLBQ74AtQVcItyk3aYCIu/qYsFmIWZh5uLvYu0sIu5i7pisFmLe4t9h36FCG2Li78FoJikk6aL3IvMSYs6iztKSTqLCPtL90sV9yaLi0L7JouL1AVmuhV8i3yHfoUIbYuLcwWAfYR6i3iLeZJ5ln0Ii3SpiwWYhZqHmoubi5mPmJEIqYuLVwV2fnKDcIs6i0rNi9uL3MzN3Iumi6SDoH4Ii1dtiwV+kX2Pe4sIDov3lBX4lIuLQvyUi4vUBQ73m/ftFWL7a0qLgFL3VYuWxEuLtPdry4uWxPtVi4BSzIsFDov4AhX4lIuLQvyUi4vUBfdL+wIV992Li0L73YuL1AWL+wIV992Li0L73YuL1AX7S0IVi/dL9ycv+ycwBQ6LsBWL+AH4lIuL/AH8lIsF+G/33RX8SouL+7n4SouL97kF+0r7SxWvi7vqySyLQvwCi4vU9wL3JvcC+yYFDvhv+EsVi/tw+2/3cPdviwVhYBWShIyChoUI+wf7BwWFhoKMhJKEkoqUkJEI9wj3BwWQkJWKkYQI/CD8HxX3b4r7b/dvi/tuBbW1FZKElYqQkAj3B/cHBZCQipWEkoSRgo2FhQj7BvsHBYWGjYGRhQgO97n3kxWL93D3b/tv+2+KBbW3FYSSipSQkQj3B/cGBZGRlIqShJKEjIGGhgj7CPsHBYaGgYyFkgj7CPsJFftvjPdv+3CL928FYWEVhJKBjIaGCPsH+wcFhoaMgZKEkoSUipGRCPcG9wYFkZGJlIWSCA733bAVi/fdZ4uL+91Bi4v3JgVPi1q8i8iLx7y8x4sI9yeLi/wBZosFDvgm9yYV1Ysv+yUv9yXVi4v3J0GL5/cl5/slQYuL+ycF+3+EFYWCgoSBhoGGgIh/i3WLeZF+mH6XhZ2Looujkp2blpqXopGriwiwi4uUBYuUiJKFj4SQgo1/i3+Lf4l/iH+If4V+hAiLugWWkJeOl46XjZiMmIusi6KEmH6ZfZFyi2gIi/sMV4uLowWL1hV2iwV3i32IhIaDhoeCi36LgY6EkIWQhpOIlIuZi5aQkpaTlo+ai58Ii48FDvdC91kVVoum9wml+wkF+x37ChXDi5zS1oudRMOLPvezR4s++7MF+BPwFYuHBYt3h3uDgIOAf4V9i4GLg46GkYWRiJOLlIuYj5WTkJSQmY6giwihiwWt7RV9mXOSaYt8i36Kfol/iH6Hf4YIi1sFmJOYkJiPl46YjZmLl4uViJGHkoaOhIuCCIuCZYsFaYtyhXt/e3+DeItyi3SReZl+mH6ehaOLmIuXjZWQlpCTk5KUCItzwouL9w8Fi6+EpX2ZCA7U95QV+AKLi2b8AouLsAX3U1oVloeUhZGEkYSOgouCi36GgYKEgoR/iHuLe4t6jnuRepB6lHqXCItKBZqEm4Wch5yIm4mci7OLqZOfm5+alKOLq4ujhZ9/mn6bd5dwlAhvlgV3kX6ShZGFkIiTi5OLl4+UlJGTkZeOm4uai5mImoaZhpqEmYIIi8gFfJF8kHuPfI58jXuLaYtxg3h6d3uCdItui3WQeZd+l32hf61+CKuABQ6L928Vr6n3S/snZ277S/cmBYuLFfdL9yevbvtL+ydnqAX4lIsVZ6n7S/snr273S/cmBYuLFftL9ydnbvdL+yevqAUOi2YVi/iU+JSLi/yU/JSLBfhv+HAV/EqLi/xL+EqLi/hLBUL7JhX7uIuL1Pe4i4tCBYv7AhX7uIuL1Pe4i4tCBYv7AhX7uIuL1Pe4i4tCBQ73jPdyFZ6LmYiUg5ODj36LeYt6h3+DhIOEfYd3iwhii4vstIsFi/cVFZuLloiShJKFjoKLfYt+iIGEhYSFgIh7iwhii4vYtIsFJvuqFfCLBbWLqJKemp2ZlKKLqoulhZ9/mn+ZeZRzjZ+NmpKVl5aXkJuLoIungqB5mHqZcJJoiwgmi4v73QUOsIsVi/hL+EqLi/xL/EqLBfeR+AIVR4s/+7nDi5vT1oucQ8KLQPe5BWlWFaX7DFeLpfcMBQ74UPeKFfso+yiHjwV9h3uNfJMIamupbXx8BWJiSYtitAh8mgVitIvNtLQI92v3awW0tM2LtGIImnwFtGKLSWJiCGb3EhVuqFyKbm4I+1n7WgVtbotcp26ob7qLqKkIsrEFg4+EkIWScKaGsJ+gCN3dBZuapIyifwj7EvsRsWb3GvcaBaiojLpuqAgOi/gCFfiUi4tC/JSLi9QF9yb7AhX4AouLQvwCi4vUBfcn+wIV92+Li0L7b4uL1AUOi/gCFfiUi4tC/JSLi9QFi/sCFfgBi4tC/AGLi9QFi/sCFfdwi4tC+3CLi9QFDov4AhX4k4uLQvyTi4vUBYv7AhX4k4uLQvyTi4vUBYv7AhX4lIuLQvyUi4vUBQ73AvgCFfe4i4tC+7iLi9QF+wL7AhX4lIuLQvyUi4vUBfcC+wIV97iLi0L7uIuL1AUO1LIVi9RCi4v3ufhLi4tB1IuL+7j8S4sF99333RX8AYuL+3D4AYuL93AF1UIVZouL+0v73YuLZvgCi4v3cAX7b0IV+0yL5/cB5/sBBfcBZhX7uYuLsPe5i4tmBWL3AhW0QkKLq9QFDviUFPiUFYsMCgAAAAADAgABkAAFAAABTAFmAAAARwFMAWYAAAD1ABkAhAAAAAAAAAAAAAAAAAAAAAEQAAAAAAAAAAAAAAAAAAAAAEAAAOYfAeD/4P/gAeAAIAAAAAEAAAAAAAAAAAAAACAAAAAAAAIAAAADAAAAFAADAAEAAAAUAAQAOAAAAAoACAACAAIAAQAg5h///f//AAAAAAAg5gD//f//AAH/4xoEAAMAAQAAAAAAAAAAAAAAAQAB//8ADwABAAAAAQAAhlBJsl8PPPUACwIAAAAAAM91iyUAAAAAz3WLJf///9sCAAHbAAAACAACAAAAAAAAAAEAAAHg/+AAAAIA//8AAAIAAAEAAAAAAAAAAAAAAAAAAAAkAAAAAAAAAAAAAAAAAQAAAAIAAAACAAAAAgAAAAIAAG4CAAAAAgAAbQIAAAACAAAJAgAASQIA//8CAAAAAgAAAAIAAAACAACSAgAAAAIAAAACAAAlAgAAAAIAAG4CAAAlAgAAJQIAAEkCAAAAAgAAAAIAAJMCAAAlAgAAQgIAAAACAAAAAgAAAAIAAAACAAAAAABQAAAkAAAAAAAOAK4AAQAAAAAAAQAYAAAAAQAAAAAAAgAOAGoAAQAAAAAAAwAYAC4AAQAAAAAABAAYAHgAAQAAAAAABQAWABgAAQAAAAAABgAMAEYAAQAAAAAACgAoAJAAAwABBAkAAQAYAAAAAwABBAkAAgAOAGoAAwABBAkAAwAYAC4AAwABBAkABAAYAHgAAwABBAkABQAWABgAAwABBAkABgAYAFIAAwABBAkACgAoAJAAUgBlAGQAYQBjAHQAbwByAEYAbwBuAHQAVgBlAHIAcwBpAG8AbgAgADEALgAwAFIAZQBkAGEAYwB0AG8AcgBGAG8AbgB0UmVkYWN0b3JGb250AFIAZQBkAGEAYwB0AG8AcgBGAG8AbgB0AFIAZQBnAHUAbABhAHIAUgBlAGQAYQBjAHQAbwByAEYAbwBuAHQARwBlAG4AZQByAGEAdABlAGQAIABiAHkAIABJAGMAbwBNAG8AbwBuAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==) format('woff'); - font-weight: normal; - font-style: normal; -} -/* =Selection ------------------------------------------------------------------------------*/ -.redactor_box ::selection { - background: #ffff9e; -} -.redactor_box ::-moz-selection { - background: #ffff9e; -} -.redactor_box img::selection { - background: transparent; -} -.redactor_box img::-moz-selection { - background: transparent; -} -/* - BOX -*/ -.redactor_box { - position: relative; - overflow: visible; - background: #fff; - z-index: 1 !important; /*Labfolder fix*/ -} -.redactor_box iframe { - display: block; - margin: 0; - padding: 0; - border: 1px solid #eee; -} -.redactor_box textarea { - position: relative; - display: block; - overflow: auto; - margin: 0; - padding: 0; - width: 100%; - outline: none; - border: none; - background-color: #222; - box-shadow: none; - color: #ccc; - font-size: 13px; - font-family: Menlo, Monaco, monospace, sans-serif; - resize: none; -} -.redactor_box textarea:focus { - outline: none; -} -.redactor_box, -.redactor_box textarea { - z-index: auto !important; -} -.redactor_box_fullscreen { - z-index: 99 !important; -} -#redactor_modal_overlay, -#redactor_modal, -.redactor_dropdown { - z-index: 100 !important; -} -/* - AIR - -*/ -body .redactor_air { - position: absolute; - z-index: 502; -} -/* - FULLSCREEN -*/ -body .redactor_box_fullscreen { - position: fixed; - top: 0; - left: 0; - width: 100%; -} -/* - LINK TOOLTIP -*/ -.redactor-link-tooltip { - position: absolute; - z-index: 49999; - padding: 10px; - line-height: 1; - display: inline-block; - background-color: #000; - color: #555 !important; -} -.redactor-link-tooltip, -.redactor-link-tooltip a { - font-size: 12px; - font-family: Arial, Helvetica, Verdana, Tahoma, sans-serif; -} -.redactor-link-tooltip a { - color: #ccc; - margin: 0 5px; - text-decoration: none; -} -.redactor-link-tooltip a:hover { - color: #fff; -} -/* - IMAGE BOX -*/ -#redactor-image-box img { - width: 100%; -} -.redactor_editor { - position: relative; - overflow: auto; - margin: 0 !important; - padding: 10px 20px; - padding-bottom: 5px; - outline: none; - background: none; - background: #fff; - box-shadow: none !important; - white-space: normal; - border: 1px solid #eee; - vertical-align: baseline !important; - /*labfolder fix, vertical align*/ -} -.redactor_editor:focus { - outline: none; -} -.redactor_editor div, -.redactor_editor p, -/*removed because pre wrap causes double line jump in lists*/ -/*.redactor_editor ul, -.redactor_editor ol,*/ -.redactor_editor table, -.redactor_editor dl, -.redactor_editor blockquote, -.redactor_editor pre, -.redactor_editor h1, -.redactor_editor h2, -.redactor_editor h3, -.redactor_editor h4, -.redactor_editor h5, -.redactor_editor h6 { - overflow-wrap: break-word; /*labfolder fix*/ - word-wrap: break-word; /*labfolder fix*/ - font-family: Arial, Helvetica, Verdana, Tahoma, sans-serif; -} -.redactor_editor code, -.redactor_editor pre { - font-family: Menlo, Monaco, monospace, sans-serif; -} -.redactor_editor div, -.redactor_editor p, -.redactor_editor ul, -.redactor_editor ol, -.redactor_editor table, -.redactor_editor dl, -.redactor_editor blockquote, -.redactor_editor pre { - font-size: 14px; - line-height: 1.6em; -} -.redactor_editor p { -/* min-height: 22px; labfolder fix */ -} -.redactor_editor a { -/* labfolder fix, removed !important on both */ - color: #15c; - text-decoration: underline; -} -.redactor_editor .redactor_placeholder { - color: #999 !important; - display: block !important; -} -/* - TYPOGRAPHY -*/ -.redactor_editor object, -.redactor_editor embed, -.redactor_editor video, -.redactor_editor img { - max-width: 100%; - width: auto; -} -.redactor_editor video, -.redactor_editor img { - height: auto; -} -.redactor_editor div, -.redactor_editor p, -.redactor_editor ul, -.redactor_editor ol, -.redactor_editor table, -.redactor_editor dl, -.redactor_editor blockquote, -.redactor_editor pre { - margin: 0; - margin-bottom: 10px !important; - border: none; - background: none !important; - box-shadow: none !important; -} -.redactor_editor iframe, -.redactor_editor object, -.redactor_editor hr { - margin-bottom: 15px !important; -} -.redactor_editor blockquote { - margin-left: 1.5em !important; - padding-left: 0 !important; - color: #777; - font-style: italic !important; -} -.redactor_editor ul, -.redactor_editor ol { - padding-left: 2em !important; -} -.redactor_editor ul ul, -.redactor_editor ol ol, -.redactor_editor ul ol, -.redactor_editor ol ul { - margin: 2px !important; - padding: 0 !important; - padding-left: 2em !important; - border: none; -} -.redactor_editor dl dt { - font-weight: bold; -} -.redactor_editor dd { - margin-left: 1em; -} -.redactor_editor table { - border-collapse: collapse; - font-size: 1em !important; -} -.redactor_editor table td { - padding: 5px !important; - border: 1px solid #ddd; - vertical-align: top; -} -.redactor_editor table thead td { - border-bottom: 2px solid #000 !important; - font-weight: bold !important; -} -.redactor_editor code { - background-color: #d8d7d7 !important; -} -.redactor_editor pre { - overflow: auto; - padding: 1em !important; - border: 1px solid #ddd !important; - border-radius: 3px !important; - background: #f8f8f8 !important; - white-space: pre; - font-size: 90% !important; -} -.redactor_editor hr { - display: block; - height: 1px; - border: 0; - border-top: 1px solid #ccc; -} -/* - HEADERS -*/ -.redactor_editor h1, -.redactor_editor h2, -.redactor_editor h3, -.redactor_editor h4, -.redactor_editor h5, -.redactor_editor h6 { - margin-top: 0 !important; - padding: 0 !important; - background: none; - color: #000; - font-weight: bold; -} -.redactor_editor h1 { - font-size: 36px !important; - line-height: 1.111em !important; - margin-bottom: .15em !important; -} -.redactor_editor h2 { - font-size: 30px !important; - line-height: 1.111em !important; - margin-bottom: .25em !important; -} -.redactor_editor h3 { - font-size: 24px !important; - line-height: 1.333em !important; - margin-bottom: .2em !important; -} -.redactor_editor h4 { - font-size: 18px !important; - line-height: 1.5em !important; - margin-bottom: .2em !important; -} -.redactor_editor h5 { - font-size: 1em !important; - line-height: 1.6em !important; - margin-bottom: .25em !important; -} -.redactor_editor h6 { - font-size: .8em !important; - line-height: 1.6em !important; - text-transform: uppercase; - margin-bottom: .3em !important; -} -/* - TOOLBAR -*/ -.redactor_toolbar { - position: relative; - top: 0; - left: 0; - margin: 0 !important; - padding: 0; /*"labfolder hack, was !important*/ - list-style: none !important; - font-size: 14px !important; - font-family: Arial, Helvetica, Verdana, Tahoma, sans-serif; - line-height: 1 !important; - background: #fff; - border: none; - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); - z-index: 3; -} -.redactor_toolbar:after { - content: ""; - display: table; - clear: both; -} -.redactor_toolbar.redactor-toolbar-overflow { - overflow-y: auto; - height: 29px; - white-space: nowrap; -} -.redactor_toolbar.redactor-toolbar-external { - z-index: 999; - box-shadow: none; - border: 1px solid rgba(0, 0, 0, 0.1); -} -body .redactor_air .redactor_toolbar { - padding-right: 2px !important; -} -.redactor_toolbar li { - vertical-align: top; - display: inline-block; - margin: 0 !important; - padding: 0 !important; - outline: none; - list-style: none !important; - -webkit-box-sizing: content-box; - -moz-box-sizing: content-box; - box-sizing: content-box; -} -.redactor_toolbar li a { - display: block; - color: #333; - text-align: center; - /*labfolder padding: 9px 10px; */ - padding: 10px 10px; - outline: none; - border: none; - text-decoration: none; - cursor: pointer; - zoom: 1; - -webkit-box-sizing: content-box; - -moz-box-sizing: content-box; - box-sizing: content-box; -} -.redactor_toolbar li a:hover { - outline: none; - background-color: #1f78d8; - color: #fff; -} -.redactor_toolbar li a:hover i:before { - color: #fff; -} -.redactor_toolbar li a:active, -.redactor_toolbar li a.redactor_act { - outline: none; - background-color: #ccc; - color: #444; -} -.redactor_toolbar li a.redactor-btn-image { - width: 14px; - height: 14px; - background-position: center center; - background-repeat: no-repeat; -} -.redactor_button_disabled { - filter: alpha(opacity=30); - -moz-opacity: 0.3; - opacity: 0.3; -} -.redactor_button_disabled:hover { - outline: none; - background-color: transparent !important; - cursor: default; -} -.redactor_toolbar li a.fa-redactor-btn { - display: inline-block; - padding: 9px 10px 8px 10px; - line-height: 1; -} -.redactor_toolbar.redactor-toolbar-typewriter { - box-shadow: none; - background: rgba(240, 240, 240, 0.9); -} -.redactor_toolbar.redactor-toolbar-typewriter li a:hover { - outline: none; - background-color: #1f78d8; - color: #fff; -} -.redactor_toolbar.redactor-toolbar-typewriter li a:active, -.redactor_toolbar.redactor-toolbar-typewriter li a.redactor_act { - outline: none; - background-color: #ccc; - color: #444; -} -.re-icon { - font-family: 'RedactorFont'; - speak: none; - font-style: normal; - font-weight: normal; - font-variant: normal; - text-transform: none; - line-height: 1; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} -.re-icon i:before { - position: relative; - font-size: 14px; -} -.re-video:before { - content: "\e600"; -} -.re-unorderedlist:before { - content: "\e601"; -} -.re-undo:before { - content: "\e602"; -} -.re-underline:before { - content: "\e603"; -} -.re-textdirection:before { - content: "\e604"; -} -.re-fontcolor:before { - content: "\e605"; -} -.re-table:before { - content: "\e606"; -} -.re-redo:before { - content: "\e607"; -} -.re-quote:before { - content: "\e608"; -} -.re-outdent:before { - content: "\e609"; -} -.re-orderedlist:before { - content: "\e60a"; -} -.re-link:before { - content: "\e60b"; -} -.re-horizontalrule:before { - content: "\e60c"; -} -.re-italic:before { - content: "\e60d"; -} -.re-indent:before { - content: "\e60e"; -} -.re-image:before { - content: "\e60f"; -} -.re-fullscreen:before { - content: "\e610"; -} -.re-normalscreen:before { - content: "\e611"; -} -.re-formatting:before { - content: "\e612"; -} -.re-fontsize:before { - content: "\e613"; -} -.re-fontfamily:before { - content: "\e614"; -} -.re-deleted:before { - content: "\e615"; -} -.re-html:before { - content: "\e616"; -} -.re-clips:before { - content: "\e617"; -} -.re-bold:before { - content: "\e618"; -} -.re-backcolor:before { - content: "\e619"; -} -.re-file:before { - content: "\e61a"; -} -.re-alignright:before { - content: "\e61b"; -} -.re-alignment:before, -.re-alignleft:before { - content: "\e61c"; -} -.re-alignjustify:before { - content: "\e61d"; -} -.re-aligncenter:before { - content: "\e61e"; -} -.re-gallery:before { - content: "\e61f"; -} -/* - Toolbar classes -*/ -.redactor_format_blockquote { - padding-left: 10px; - color: #666 !important; - font-style: italic; -} -.redactor_format_pre { - font-family: monospace, sans-serif; -} -.redactor_format_h1, -.redactor_format_h2, -.redactor_format_h3, -.redactor_format_h4, -.redactor_format_h5 { - font-weight: bold; -} -.redactor_format_h1 { - font-size: 30px; - line-height: 36px; -} -.redactor_format_h2 { - font-size: 24px; - line-height: 36px; -} -.redactor_format_h3 { - font-size: 20px; - line-height: 30px; -} -.redactor_format_h4 { - font-size: 16px; - line-height: 26px; -} -.redactor_format_h5 { - font-size: 14px; - line-height: 23px; -} -.redactor-toolbar-typewriter .redactor_dropdown .redactor_format_h1, -.redactor-toolbar-typewriter .redactor_dropdown .redactor_format_h2, -.redactor-toolbar-typewriter .redactor_dropdown .redactor_format_h3, -.redactor-toolbar-typewriter .redactor_dropdown .redactor_format_h4, -.redactor-toolbar-typewriter .redactor_dropdown .redactor_format_h5 { - font-size: 1em; - line-height: 1.6em; - text-transform: uppercase; -} -.redactor-toolbar-typewriter .redactor_dropdown .redactor_format_h2 { - font-size: .85em; -} -/* - Typewriter -*/ -.redactor_editor.redactor-editor-typewriter { - background: #f5f5f5 !important; - padding: 25px 50px !important; -} -.redactor_editor.redactor-editor-typewriter div, -.redactor_editor.redactor-editor-typewriter p, -.redactor_editor.redactor-editor-typewriter ul, -.redactor_editor.redactor-editor-typewriter ol, -.redactor_editor.redactor-editor-typewriter table, -.redactor_editor.redactor-editor-typewriter dl, -.redactor_editor.redactor-editor-typewriter blockquote, -.redactor_editor.redactor-editor-typewriter pre, -.redactor_editor.redactor-editor-typewriter h1, -.redactor_editor.redactor-editor-typewriter h2, -.redactor_editor.redactor-editor-typewriter h3, -.redactor_editor.redactor-editor-typewriter h4, -.redactor_editor.redactor-editor-typewriter h5, -.redactor_editor.redactor-editor-typewriter h6 { - font-family: 'Courier New', 'Lucida Console', Consolas, Monaco, monospace, sans-serif; - font-size: 18px !important; - line-height: 1.5em !important; - margin-bottom: 1.5em !important; -} -.redactor_editor.redactor-editor-typewriter h2 { - font-size: 14px !important; -} -.redactor_editor.redactor-editor-typewriter h1, -.redactor_editor.redactor-editor-typewriter h2, -.redactor_editor.redactor-editor-typewriter h3, -.redactor_editor.redactor-editor-typewriter h4, -.redactor_editor.redactor-editor-typewriter h5, -.redactor_editor.redactor-editor-typewriter h6 { - text-transform: uppercase; -} -.redactor_editor.redactor-editor-typewriter a { - color: #000 !important; - text-decoration: underline !important; -} -/* - WYM -*/ -.redactor_editor.redactor_editor_wym { - padding: 10px 7px 0 7px !important; - background: #f6f6f6 !important; -} -.redactor_editor.redactor_editor_wym div, -.redactor_editor.redactor_editor_wym p, -.redactor_editor.redactor_editor_wym ul, -.redactor_editor.redactor_editor_wym ol, -.redactor_editor.redactor_editor_wym table, -.redactor_editor.redactor_editor_wym dl, -.redactor_editor.redactor_editor_wym pre, -.redactor_editor.redactor_editor_wym h1, -.redactor_editor.redactor_editor_wym h2, -.redactor_editor.redactor_editor_wym h3, -.redactor_editor.redactor_editor_wym h4, -.redactor_editor.redactor_editor_wym h5, -.redactor_editor.redactor_editor_wym h6, -.redactor_editor.redactor_editor_wym blockquote { - margin-top: 0; - margin-bottom: 5px !important; - padding: 10px !important; - border: 1px solid #e4e4e4 !important; - background-color: #fff !important; - z-index: 0; -} -.redactor_editor.redactor_editor_wym blockquote:before { - content: ''; -} -.redactor_editor.redactor_editor_wym img { - position: relative; - z-index: 1; -} -.redactor_editor.redactor_editor_wym div { - border: 1px dotted #aaa !important; -} -.redactor_editor.redactor_editor_wym pre { - border: 2px dashed #e4e4e4 !important; - background-color: #f8f8f8 !important; -} -.redactor_editor.redactor_editor_wym ul, -.redactor_editor.redactor_editor_wym ol { - padding-left: 2em !important; -} -.redactor_editor.redactor_editor_wym ul li ul, -.redactor_editor.redactor_editor_wym ol li ul, -.redactor_editor.redactor_editor_wym ul li ol, -.redactor_editor.redactor_editor_wym ol li ol { - border: none !important; -} -/* - DROPDOWN -*/ -.redactor_dropdown { - position: absolute; - top: 28px; - left: 0; - padding: 10px; - width: 200px; - background-color: #fff; - box-shadow: 0 1px 5px #bbb; - font-size: 13px; - font-family: Helvetica, Arial, Verdana, Tahoma, sans-serif; - line-height: 21px; -} -.redactor-toolbar-typewriter .redactor_dropdown { - font-family: 'Courier New', 'Lucida Console', Consolas, Monaco, monospace, sans-serif; - background-color: #f5f5f5; -} -.redactor_separator_drop { - padding: 0 !important; - border-top: 1px solid #ddd; - font-size: 0; - line-height: 0; -} -.redactor_dropdown a { - display: block; - padding: 3px 5px; - color: #000; - text-decoration: none; -} -.redactor_dropdown a:hover { - background-color: #dde4ef; - color: #444 !important; - text-decoration: none; -} -/* - MODAL -*/ -#redactor_modal_overlay { - position: fixed; - top: 0; - left: 0; - margin: auto; - width: 100%; - height: 100%; - background-color: #000 !important; - filter: alpha(opacity=30); - -moz-opacity: 0.3; - opacity: 0.3; -} -#redactor_modal { - position: fixed; - top: 50%; - left: 50%; - padding: 0; - background: #fff; - color: #000; - font-size: 12px !important; - font-family: Arial, Helvetica, Verdana, Tahoma, sans-serif; - box-shadow: 0 1px 10px rgba(0, 0, 0, 0.5); -} -#redactor_modal header { - padding: 20px 30px 5px 30px; - font-size: 16px; -} -#redactor_modal section { - padding: 20px 30px; -} -#redactor_modal label { - display: block !important; - float: none !important; - margin: 10px 0 3px 0 !important; - padding: 0 !important; - font-size: 12px !important; -} -#redactor_modal footer:after { - content: ""; - display: table; - clear: both; -} -#redactor_modal footer div { - float: left; -} -#redactor_modal input[type="radio"], -#redactor_modal input[type="checkbox"] { - position: relative; - top: -1px; -} -#redactor_modal input[type="text"], -#redactor_modal input[type="password"], -#redactor_modal input[type="email"], -#redactor_modal textarea { - position: relative; - z-index: 2; - margin: 0; - padding: 1px 2px; - height: 23px; - border: 1px solid #ccc; - border-radius: 1px; - background-color: white; - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2) inset; - color: #333; - font-size: 13px; - font-family: Arial, Helvetica, Verdana, Tahoma, sans-serif; - line-height: 1; - -moz-transition: border 0.3s ease-in; - transition: border 0.3s ease-in; -} -#redactor_modal textarea { - display: block; - margin-top: 4px; - line-height: 1.4em; -} -#redactor_modal input:focus, -#redactor_modal textarea:focus { - outline: none; - border-color: #5ca9e4; - box-shadow: 0 0 0 2px rgba(70, 161, 231, 0.3), 0 1px 2px rgba(0, 0, 0, 0.2) inset; -} -#redactor_modal_close { - position: absolute; - top: 5px; - right: 3px; - width: 20px; - height: 20px; - color: #999; - font-size: 26px; - cursor: pointer; -} -#redactor_modal_close:hover { - color: #000; -} -.redactor_input { - width: 99%; - font-size: 14px; -} -.redactor_modal_box { - overflow: auto; - margin-bottom: 10px; - height: 350px; -} -#redactor_image_box { - overflow: auto; - margin-bottom: 10px; - height: 270px; -} -#redactor_image_box_select { - display: block; - margin-bottom: 15px !important; - width: 200px; -} -#redactor_image_box img { - margin-right: 10px; - margin-bottom: 10px; - max-width: 100px; - cursor: pointer; -} -#redactor_tabs { - margin-bottom: 18px; -} -#redactor_tabs a { - display: inline-block; - margin-right: 2px; - padding: 4px 14px; - border: 1px solid #d2d2d2; - border-radius: 3px; - background: #fff; - color: #000; - text-decoration: none; - line-height: 1; -} -#redactor_tabs a:hover, -#redactor_tabs a.redactor_tabs_act { - border-color: #eee; - color: #999 !important; - text-decoration: none !important; -} -.redactor_modal_btn_hidden { - display: none; -} -#redactor_modal footer button { - position: relative; - width: 100%; - padding: 10px 16px; - margin: 0; - outline: none; - border: none; - background-color: #ddd; - color: #000; - text-align: center; - text-decoration: none; - font-weight: normal; - font-size: 12px; - font-family: Arial, Helvetica, Verdana, Tahoma, sans-serif; - line-height: 1; - cursor: pointer; -} -#redactor_modal footer button:hover { - color: #777; - background: none; - background: #bbb; - text-decoration: none; -} -#redactor_modal footer button.redactor_modal_delete_btn { - background: none; - color: #fff; - background-color: #b52525; -} -#redactor_modal footer button.redactor_modal_delete_btn:hover { - color: rgba(255, 255, 255, 0.6); - background-color: #881b1b; -} -#redactor_modal footer button.redactor_modal_action_btn { - background: none; - color: #fff; - background-color: #2461b5; -} -#redactor_modal footer button.redactor_modal_action_btn:hover { - color: rgba(255, 255, 255, 0.6); - background-color: #1a4580; -} -/* Drag and Drop Area */ -.redactor_droparea { - position: relative; - margin: auto; - margin-bottom: 5px; - width: 100%; -} -.redactor_droparea .redactor_dropareabox { - position: relative; - z-index: 1; - padding: 60px 0; - width: 99%; - border: 1px dashed #ddd; - background: #fff; - text-align: center; -} -.redactor_droparea .redactor_dropareabox, -.redactor_dropalternative { - color: #555; - font-size: 12px; -} -.redactor_dropalternative { - margin: 4px 0 2px 0; -} -.redactor_dropareabox.hover { - border-color: #aaa; - background: #efe3b8; -} -.redactor_dropareabox.error { - border-color: #dcc3c3; - background: #f7e5e5; -} -.redactor_dropareabox.drop { - border-color: #e0e5d6; - background: #f4f4ee; -} -/* =ProgressBar ------------------------------------------------------------------------------*/ -#redactor-progress { - position: fixed; - top: 0; - left: 0; - width: 100%; - z-index: 1000000; - height: 10px; -} -#redactor-progress span { - display: block; - width: 100%; - height: 100%; - background-color: #3d58a8; - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.2) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.2) 50%, rgba(255, 255, 255, 0.2) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.2) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.2) 50%, rgba(255, 255, 255, 0.2) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.2) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.2) 50%, rgba(255, 255, 255, 0.2) 75%, transparent 75%, transparent); - -webkit-animation: progress-bar-stripes 2s linear infinite; - -o-animation: progress-bar-stripes 2s linear infinite; - animation: progress-bar-stripes 2s linear infinite; - background-size: 40px 40px; -} -@-webkit-keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} -@-o-keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} -@keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} - -/* CUSTOM labfolder*/ - -.re-orderedlist, -.re-mendeley, -.re-alignjustify, -.re-lf-fontfamily, -.re-link, -.re-deleted, -.re-backcolor, -.re-lf-fontsize, -.re-redo { - border-right: 1px solid #d2d2d2 !important; -} - -a.re-lf-fontsize { - font-family: "Arial"; - width: 35px !important; -} - -.re-lf-fontfamily { - font-size: 14px; - overflow: hidden; - padding: 11px 9px 9px !important; - text-align: left !important; - text-overflow: ellipsis; - white-space: nowrap; - width: 75px !important; -} - -.redactor_arial_font { - font-family: 'Arial'; -} - -.redactor_arial_font:before { - content: "Arial"; -} - -.redactor_times_font { - font-family: 'Times new roman'; -} - -.redactor_times_font:before { - content: "Times New Roman"; -} - -.redactor_dropdown_box_specialChars a{ - display: inline-block; - height: 13px; - line-height: 13px; - margin: 1px; - text-align: center; - width: 13px; - word-break: break-all; -} - -a.char_section { - background: #DDD; - border: 1px solid #FFF; - color: #000; - display: block; - font-weight: bold; - height: 22px; - line-height: 13px; - margin: 0; - text-align: left; - width: 190px; -} - -/*a.char_section:hover { - color: #FFF !important; - background-color: #374858 !important; -}*/ - -.redactor_editor div.redactor_placeholder_container, -.redactor_editor div.redactor_placeholder_container:hover{ - border: 1px solid #AAA; - border-radius: 5px; - color: #374858; - display: inline-block; - margin: 0 !important; - padding: 2px 5px; - text-decoration: none; - background: linear-gradient(to bottom, #f1f1f1 0%,#e2e2e2 100%) !important; - user-select: none; -} - -.redactor_editor div.redactor_placeholder_input{ - background: #FFF !important; - border: 1px solid #DDD; - box-shadow: inset 0 0 2px #000; - color: #374858; - display: block; - min-width: 50px; - padding: 1px 5px; - font-size: 15px; - border-radius: 3px; - line-height: 15px; - margin: 0px 5px !important; - text-align: center; - text-decoration: none; -} - -.redactor_editor div.not_edited{ - color: #888; -} - -.redactor_editor .default_textfield p{ - line-height: 1em; - color: #374858; -} - -.redactor_toolbar li a.redactor_shortcut { - border-color: #b5b5b5; - background-color: #ddd; -} - -.tab:before { - content: "\0009"; -} diff --git a/unittests/example_labfolder_data/static/css/tree.css b/unittests/example_labfolder_data/static/css/tree.css deleted file mode 100644 index 0256223aa0dfd04bdf60fc274cc3d2fb38d6c00f..0000000000000000000000000000000000000000 --- a/unittests/example_labfolder_data/static/css/tree.css +++ /dev/null @@ -1,454 +0,0 @@ -/************** -* basic.css * -**************/ -/******************** -* Media variables * -********************/ -/********** -* colors * -***********/ -/*********** -* helpers * -************/ -.list_vertical > ul { - margin: 0; - padding: 0; -} -.list_vertical > ul li { - list-style-type: none; -} -.list_horizontal > ul { - margin: 0; - padding: 0; -} -.list_horizontal > ul > li { - list-style-type: none; - float: left; - position: relative; -} -/************* -* functions * -**************/ -/****** -* css * -******/ -body { - color: #374858; -} -.clearfix:after { - content: " "; - visibility: hidden; - display: block; - height: 0; - clear: both; -} -.treeInPopup .treeline { - background-repeat: no-repeat; - color: #374858; - cursor: pointer; - border: 1px solid transparent; - display: block; - font-size: 14px; - height: 21px; - line-height: 22px; - outline: none; - padding-left: 5px; - text-decoration: none; -} -/* .treeline:hover{ */ -/* background-position: 0 0; */ -/* border: 1px solid #69bfee; */ -/* text-decoration: none; */ -/* } */ -.treeline:hover .icon-arrow_down, -.treeline:hover .icon-arrow_right, -.treeline:hover .icon-folder, -.treeline:hover .icon-notebook, -.treeline:hover .icon-template, -.treeline:hover .name, -.treeline:hover .updateTS { - /* color: #69bfee; */ -} -.treeline.active { - background-color: #ededed; -} -.treeInPopup .treeline.active { - background-color: transparent; -} -.treeline.is_hidden_item > * { - opacity: 0.4; -} -.treeline img { - vertical-align: top; -} -.treeline .icon-arrow_right { - font-size: 33px; - margin-right: -10px; - margin-left: -3px; - vertical-align: -4px; -} -.treeInPopup .icon-arrow_right { - font-size: 23px; - margin-right: -6px; - line-height: 14px; - margin-left: -3px; -} -.treeline { - position: relative; -} -.treeline span { - float: left; - margin-right: 5px; -} -.treeline .icon-template { - float: left; -} -.treeInPopup .name { - font-size: 12px; - overflow: hidden; -} -.treeline .updateTS { - font-size: 15px; - float: right; - margin-right: 15px; -} -.treeline .tree_button { - float: right; - margin-top: 0; - margin-right: 10px; - position: absolute; - right: 0; - top: 1px; - opacity: 0; - transition: opacity 0.3s; - display: block; -} -.treeline:hover .tree_button { - opacity: 1; -} -.treeline_children .tree_button { - right: 116px; -} -.droppable_folder { - background-color: #e4eef7 !important; -} -.hover_droppable_folder { - background-color: #d0e1f1 !important; -} -.treeline:hover .tree_button { - display: inline; -} -.treeline.active .tree_button { - display: inline; -} -.treeline_children { - display: none; - margin-left: 15px; -} -.treeInPopup .treeline_children { - margin-left: 20px; -} -.treeline_children_empty { - font-size: 15px; - font-style: italic; - padding: 10px 0 10px 30px; -} -.treeInPopup .treeline_children_empty { - font-size: 12px; - font-style: italic; - padding: 0 0 0 25px; -} -.treeInPopupContainer { - display: none; - background: white; - box-sizing: border-box; - max-height: 150px; - margin-top: 10px; - overflow-y: auto; - -webkit-box-shadow: inset 0 2px 1px rgba(55, 72, 88, 0.2); - -moz-box-shadow: inset 0 2px 1px rgba(55, 72, 88, 0.2); - box-shadow: inset 0 2px 1px rgba(55, 72, 88, 0.2); -} -.treeInPopupContainer img { - display: block; - margin: auto; -} -.treeInPopup { - overflow-y: auto; - height: 148px; - padding-top: 10px; - margin-top: 2px; -} -.treeInPopup .treeline.selected { - background-color: #e6ebef; -} -.tree_my_eln_projects, -.tree_my_eln_templates { - max-width: 900px; -} -.tree_my_eln_projects .folder_dn-img, -.tree_my_eln_templates .folder_dn-img, -.tree_my_eln_projects .project_s-img, -.tree_my_eln_templates .project_s-img { - margin-top: 2px; -} -.treeline { - color: #4b6277; - background-repeat: no-repeat; - cursor: pointer; - border: 1px solid transparent; - display: block; - font-size: 14px; - height: 26px; - line-height: 20px; - outline: none; - padding: 2px 8px 2px 4px; - text-decoration: none; - transition: background 0.1s ease; -} -.treeline:hover { - background: #e0e6eb; - text-decoration: none; -} -.treeline .updateTS { - font-size: 13px; - float: right; - margin-right: 15px; -} -.treeline .tree_button { - float: right; - margin: 0 10px; -} -.treeline .tree_button button { - padding: 3px; - background: transparent; - cursor: pointer; -} -.treeline .name { - white-space: nowrap; - text-overflow: ellipsis; - display: block; - overflow: hidden; - padding: 0; - margin-left: 0; - line-height: 1.5; - float: left; -} -.treeline .icon-template { - margin-top: 3px; -} -.settings_panel { - position: absolute; - right: 10px; - background: #fdfdfd; - border: solid 1px #bac7d4; - top: 23px; - right: -58px; - display: none; - z-index: 10; - -webkit-box-shadow: 0 4px 10px rgba(55, 72, 88, 0.3); - -moz-box-shadow: 0 4px 10px rgba(55, 72, 88, 0.3); - box-shadow: 0 4px 10px rgba(55, 72, 88, 0.3); - border: 1px solid #bac7d4; -} -.show_settings .settings_panel { - display: block; -} -.settings_panel > ul { - margin: 0; - padding: 0; -} -.settings_panel > ul li { - list-style-type: none; -} -.settings_panel .more_options_item { - min-width: 140px; - font-size: 12px; - padding-left: 5px; - cursor: pointer; -} -.settings_panel .menu_arrow-img { - position: absolute; - top: -11px; - left: 60px; -} -.settings_panel > ul > li { - padding: 2px 7px 2px 6px; - display: block; - text-align: left; - cursor: pointer; - line-height: 20px; - position: relative; -} -.settings_panel > ul > li:hover { - background: #ecf0f3; -} -.settings_panel > ul > li > span { - right: 0; - top: 3px; - position: absolute; -} -.settings_panel > ul li:first-child { - margin-top: 8px; -} -.group_more_options { - width: 200px; -} -.treeline .name { - overflow: hidden; - margin-left: 5px; - max-width: 38%; -} -.treeline .details { - color: #39A0E4; - font-size: 13px; - float: right; - margin-right: 40px; -} -@media only screen and (max-width: 1024px) { - .treeline .more_options { - opacity: 1; - right: 0; - } - .treeline .box-last-update { - margin-left: 20px; - } - .treeline .box-last-update label { - display: none; - } - .treeline .updateTS { - display: none; - } - .treeline .name { - max-width: 30%; - } - .treeline .box-owner label { - display: none; - } -} -/* Projects list tree */ -.projects-list .headers, -.templates-list .headers { - padding: 2px 8px 2px 4px; - max-width: 900px; - text-align: right; -} -.projects-list .headers div, -.templates-list .headers div { - text-align: center; - display: inline-block; -} -.projects-list .headers .owner, -.templates-list .headers .owner { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - width: 160px; - text-align: center; - display: inline-block; - margin: 0; - padding: 0 20px; -} -.projects-list .headers .update, -.templates-list .headers .update { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - width: 150px; - text-align: center; - display: inline-block; - margin: 0; - padding: 0 20px; -} -.projects-list .headers .created, -.templates-list .headers .created { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - width: 150px; - text-align: center; - display: inline-block; - margin: 0; - padding: 0 20px; -} -.projects-list .details, -.templates-list .details { - margin: 0; -} -.projects-list .box-owner, -.templates-list .box-owner { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - width: 160px; - text-align: center; - display: inline-block; - margin: 0; - padding: 0 20px; -} -.projects-list .box-owner label, -.templates-list .box-owner label { - display: none; -} -.projects-list .box-last-update, -.templates-list .box-last-update { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - width: 150px; - text-align: center; - display: inline-block; - margin: 0; - padding: 0 20px; -} -.projects-list .box-last-update label, -.templates-list .box-last-update label { - display: none; -} -.projects-list .updateTS, -.templates-list .updateTS { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - width: 150px; - text-align: center; - display: inline-block; - margin: 0; - padding: 0 20px; -} -.projects-list .tree_button, -.templates-list .tree_button { - right: -6px; -} -.projects-list .treeline_children .tree_button, -.templates-list .treeline_children .tree_button { - right: 132px; -} -@media only screen and (max-width: 1024px) { - .projects-list .headers .created, - .templates-list .headers .created { - display: none; - } - .projects-list .box-owner, - .templates-list .box-owner { - margin-right: 0; - } - .projects-list .updateTS, - .templates-list .updateTS { - display: none; - } - .projects-list .tree_button, - .templates-list .tree_button { - right: -10px !important; - } - .projects-list .treeline, - .templates-list .treeline, - .projects-list .headers, - .templates-list .headers { - padding-right: 25px; - } - .projects-list .name, - .templates-list .name { - max-width: 22%; - } -} diff --git a/unittests/example_labfolder_data/static/font/icons11.eot b/unittests/example_labfolder_data/static/font/icons11.eot deleted file mode 100644 index 770bd07fd2bc41d7243ae8510907ae361dc6149f..0000000000000000000000000000000000000000 Binary files a/unittests/example_labfolder_data/static/font/icons11.eot and /dev/null differ diff --git a/unittests/example_labfolder_data/static/font/icons11.svg b/unittests/example_labfolder_data/static/font/icons11.svg deleted file mode 100644 index e0ca10998d141fe2baabcbfccec123e86df3763d..0000000000000000000000000000000000000000 --- a/unittests/example_labfolder_data/static/font/icons11.svg +++ /dev/null @@ -1,114 +0,0 @@ -<?xml version="1.0" standalone="no"?> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" > -<svg xmlns="http://www.w3.org/2000/svg"> -<metadata>Generated by IcoMoon</metadata> -<defs> -<font id="icomoon" horiz-adv-x="512"> -<font-face units-per-em="512" ascent="480" descent="-32" /> -<missing-glyph horiz-adv-x="512" /> -<glyph unicode=" " d="" horiz-adv-x="256" /> -<glyph unicode="" d="M354.080 402.768c-77.872 77.824-204.080 77.824-281.952 0-77.792-77.904-77.792-204.080 0-281.936 67.136-67.216 170.24-76.272 247.28-27.568l104.784-104.784 62.176 62.176-104.72 104.8c48.672 77.024 39.584 180.128-27.568 247.312zM213.136 124.272c-75.92 0.048-137.504 61.616-137.488 137.504 0 75.968 61.536 137.504 137.456 137.472 75.968 0.080 137.568-61.504 137.504-137.504 0-75.92-61.52-137.424-137.456-137.472zM117.392 238.32v46.912h191.424v-46.912h-191.424z" horiz-adv-x="496" /> -<glyph unicode="" d="M354.080 402.768c-77.872 77.824-204.080 77.824-281.952 0-77.792-77.904-77.792-204.080 0-281.904 67.136-67.232 170.24-76.272 247.28-27.568l104.784-104.8 62.176 62.176-104.72 104.8c48.688 77.008 39.6 180.128-27.568 247.296zM213.136 124.288c-75.904 0.032-137.504 61.616-137.488 137.488 0 75.968 61.536 137.504 137.456 137.472 75.968 0.080 137.552-61.504 137.504-137.504-0.016-75.888-61.536-137.408-137.456-137.456zM117.392 238.32v46.912h72.272v72.256h46.912v-72.256h72.24v-46.912h-72.24v-72.272h-46.912v72.272h-72.272z" horiz-adv-x="496" /> -<glyph unicode="" d="M360.192 411.104c2.352-8.736 4.064-17.456 5.216-26.192 0.624-8.736 1.168-18.032 0.624-27.904 0 0-25.056 74.192-81.472 81.456-7.584 2.304-15.168 2.304-22.64 0.56-7.648-1.728-14.592-6.96-21.024-14.56l16.912-7.536-48.336-14.544-19.776 45.968 16.88-8.144c10.448 11.072 22.128 20.944 35.472 29.072 12.816 8.736 26.784 11.648 42.496 10.48 21.552-1.744 37.84-8.72 48.944-19.808 11.6-11.6 20.288-27.872 26.688-48.832v0zM360.192 351.184c32.016 0 57.632-26.192 57.632-58.176 0-31.44-25.616-57.616-57.632-57.616-31.952 0-57.6 26.176-57.6 57.616 0 31.984 25.648 58.176 57.6 58.176v0zM297.328 221.44h125.744c26.704 0 48.288-21.568 48.288-48.32v-146.032h-24.416v120.976h-26.224v-120.976h-119.824v120.976h-26.208v-120.976h-25.632v146.032c0 26.752 21.552 48.32 48.272 48.32v0zM111.152 447.776c32.048 0 57.648-25.6 57.648-57.632 0-32-25.6-57.6-57.648-57.6-31.984 0-57.632 25.6-57.632 57.6 0 32.032 25.648 57.632 57.632 57.632v0zM48.32 318.592h125.696c26.816 0 48.864-22.112 48.864-48.88v-146.048h-25.008v121.632h-26.176v-121.632h-119.904v121.632h-26.16v-121.632h-25.632v146.048c0 26.784 21.552 48.88 48.32 48.88zM66 49.824c-0.976 8.992-1.344 17.888-1.12 26.72 0.848 8.688 1.68 17.968 3.808 27.664 0 0 13.152-77.232 67.76-93.232 7.072-3.504 14.528-4.64 22.304-4.144 7.76 0.56 15.472 4.64 22.928 11.12l-15.456 10.128 49.952 6.8 12.384-48.512-15.408 10.72c-12.080-9.312-25.12-17.264-39.616-23.2-14.016-6.608-28.272-7.312-43.584-3.744-21.008 5.104-36 14.56-45.168 27.232-9.696 13.312-15.792 30.768-18.8 52.448v0z" horiz-adv-x="464" /> -<glyph unicode="" d="M218.928 480c75.712 0 136.448-60.64 136.448-135.776 0-75.072-60.736-136.416-136.448-136.416-75.088 0-135.808 61.344-135.808 136.416 0 75.12 60.72 135.776 135.808 135.776v0zM107.424 218.448c-58.864 0-107.424-48.576-107.424-107.424v-143.024h444.128v143.024c0 58.848-47.904 107.424-107.456 107.424h-28.032c-25.344-19.168-56.816-30.8-91.008-30.8-34.24 0-65.728 11.632-90.352 30.8h-19.856z" /> -<glyph unicode="" d="M198.336 291.984l-89.296 44.896 61.44 123.12c9.904 19.856 37.952 25.952 62.64 13.616v0c24.736-12.336 36.72-38.4 26.8-58.24l-61.584-123.408zM178.336 224.224l20.864-10.432 88.864 178.048-20.896 10.416-88.848-178.032zM0 2.048c5.248 6.096 12.944 14.64 21.744 24.24l-15.888 7.936c-1.984-10.832-3.968-21.68-5.856-32.176zM94.544 104.224l91.264 183.696-69.040 34.464-91.728-183.792c0 0-0.016-0.208-0.016-0.256l69.136-34.496c0.256 0.224 0.384 0.384 0.384 0.384zM23.28 129.056c-2.928-15.92-9.216-49.824-15.776-85.584l20.608-10.304c21.6 23.552 47.472 50.944 59.584 63.712l-64.416 32.176zM115.28 16.352c2.176 12.656 1.504 25.216 0.576 37.92 10.288 1.28 16.48 8.144 23.824 14.592 17.44 15.168-0.080 64.032-24.016 45.216-9.984-7.856-10.928-38-10.736-50.192-8-0.512-9.52 3.44-17.904-0.784 2.224-7.648 11.664-9.968 18.496-9.568 1.008-12.032 1.632-23.424-0.448-35.424-1.296-7.536-2.512-32.56-10.272-38.368-16.496-4.768-20.672 7.552-34.656 6.016 3.184-9.568 14.432-18.224 24.832-18.224 26.752 0 26.752 28.208 30.304 48.8zM115.28 64.672c-0.064 6.688 1.472 42.016 10.48 42.016 22.912 0 6.608-39.328-10.48-42.016zM133.2-21.712c1.2 3.072-0.016 7.392-5.552 9.568h-1.616l-2.528-2.992c-2.688-7.136 1.36-9.296 2.672-9.808l7.024 3.216zM231.408 33.36c-15.424-0.352-32.704 15.584-41.488 27.168 66.064 26.432-1.248 110-35.216 62.304 34.48 9.072 85.072-30.912 25.216-58.144 0.192 17.248-0.032 39.424-0.048 40.688l-10.368-0.112c0.464-30.336-10.352-80.848-0.048-98.976 6.704 16.24 10.16 32.928 10.336 50.048 21.68-16.944 31.376-32.096 61.136-33.376l0.512 10.336c-3.552 0.192-6.88 0.112-10.032 0.064-10.24-0.24 3.152 0.048 0 0zM254.672 36.016l-1.888 7.344-1.824-2.816 1.472 2.912c-0.96 0.48-5.712 3.28-5.728 3.296l-5.232-8.944c4.544-2.656 7.392-4.32 9.536-4.32 1.456 0 2.576 0.768 3.68 2.528zM275.424 143.104l-10.272-1.408c4.544-33.552 5.376-59.856-0.928-93.968-0.672-3.616-1.328-7.168-1.952-10.688l10.208-1.776c6.688 38.128 8.080 69.84 2.944 107.84zM306.752 120.576c17.952 22-4.272 46.8-25.104 51.6-22.256 5.168-28.464-5.808-29.248-7.424l-6.896-16.736 9.584-3.952 6.624 16.16c0.032 0.064 3.52 5.12 17.616 1.856 34.192-7.888 22.24-33.376 1.84-48 67.984-8.208 22.96-48.24-8.656-71.12l6.080-8.4c16.48 11.92 89.92 73.68 28.176 86.016zM357.776 115.088c32.512-38.336 37.136 13.168 46.016 30.544 0.192-0.304 16.48-22 21.44-20.608 4.656 7.232 6.608 14.864 5.84 22.928 11.36-45.888 62.112 21.504 29.2 31.424-24.016 7.296-40.512-14.944-39.552-35.184-12.688 19.104-19.424 12.368-29.808 0.832-2.352 1.872-5.008 2.592-7.968 2.16 15.6-59.6-12.496-7.68-32.48-12.512-5.168-1.2-17.712-45.68-18.96-50.72l10.032-2.608c3.664 11.696 10.64 22.88 16.24 33.744zM431.52 156.96c-0.784 9.264 18.752 14.608 25.76 12.48 5.728-1.728-1.856-45.072-18.528-9.2l-7.232-3.28zM434.816 54.752c26.016 0 65.104 126.64 83.024 150.016-0.912-6.352-1.504-16.016 0.288-22.592l10.016 2.704c-2.384 8.672 4.848 31.024-10.336 31.152-15.664-0.704-12.48-34.32-23.552-41.2 9.36 68.176-60.432-7.216-14.544-11.68-7.488-8.896-16.56-15.584-20.144-24.688v0c-0.592-6.704-61.52-83.712-24.752-83.712v0zM460.4 115.216c0.128-19.024-8.608-39.424-25.072-49.76-11.296 11.232 16.496 43.376 25.072 49.76 0.016-2.976-1.52-1.136 0 0zM476.816 174.224c-0.8 9.568-3.232 11.808 2.576 17.92 5.168-5.488 6.512-11.824 4.016-19.008-2.192 0.208-4.368 0.576-6.512 1.088-0.048 0-0.064 0-0.080 0zM548.928 201.248c7.232-7.632-16.864-18.544-11.968-18.304 5.856 0.288 23.472 12.080 25.296 16.624 2.912 7.264-3.344 13.648-9.12 11.424-21.584-8.336-7.232 20.624-6.176 22.16-6.352-9.296-19.392-12.048-14.224-28.384z" /> -<glyph unicode="" d="M257.952 353.008c-82-14.352-146.592-62.288-195.424-136.128l-68.112 51.056 43.296-183.776 193.968 63.2-79.296 26.416c43.152 66.72 76.432 86.064 138.448 103.28 32.976 9.152 80.768 4.576 127.888-20.736 39.472-21.28 58.704-50.64 83.392-112.16 6.080 4.56 12.128 4.56 16.848 2-6.080 52.448-26.416 104.736-69.872 149.632-43.936 45.376-117.008 70.208-191.152 57.232z" /> -<glyph unicode="" d="M0.24-36.752l-0.24 516.752 257.44-257.424z" /> -<glyph unicode="" d="M443.376 480l-443.376-256 443.376-256z" /> -<glyph unicode="" d="M0 478.816l516.752 0.24-257.424-257.44z" /> -<glyph unicode="" d="M256 424.576c110.592 0 200.592-89.984 200.592-200.56 0-110.608-90.016-200.592-200.592-200.592-110.608 0-200.56 90-200.56 200.592 0 110.592 89.952 200.56 200.56 200.56zM256 480c-141.376 0-256-114.608-256-255.984 0-141.408 114.624-256.016 256-256.016 141.392 0 256 114.608 256 256.016 0 141.376-114.608 255.984-256 255.984v0zM97.664 224.016h158.352v158.336c-87.456 0-158.352-70.896-158.352-158.336z" /> -<glyph unicode="" d="M466.112 482.208l5.696-120.752-14.416 0.016c-2.8 21.248-6.576 36.448-11.392 45.536-7.84 14.672-18.272 25.52-31.312 32.464s-30.176 10.432-51.44 10.432h-72.528v-393.36c0-31.632 3.424-51.36 10.256-59.216 9.616-10.64 24.416-15.952 44.416-15.952h17.84v-14.016h-218.288v14.016h18.224c21.776 0 37.216 6.608 46.32 19.76 5.568 8.096 8.368 26.576 8.368 55.408v393.36h-61.888c-24.048 0-41.12-1.776-51.264-5.328-13.136-4.768-24.416-14.048-33.792-27.696-9.376-13.648-14.912-32.144-16.688-55.44h-14.416l6.080 120.752h420.24z" /> -<glyph unicode="" d="M45.664 436.128v-83.616l83.632 83.616h-83.632zM45.664 265.488v-253.616h308.48v424.256h-205.984v-104.304l-102.816 0.544 0.32-66.896zM0-32v512h399.856v-512h-399.856zM306.416 319.552v-38.592h-110.048v38.592h110.048zM327.376 340.528h-151.968v-80.512h151.968v80.512zM99.28 264.512v59.008l-14.96-13.008v14.432l14.96 12.992h13.504v-73.424h-13.504zM306.416 211.152v-38.576h-110.048v38.576h110.048zM327.376 232.128h-151.968v-80.512h151.968v80.512zM79.792 156.112v12.064l27.424 31.872c1.376 1.584 2.352 3.024 2.944 4.336 0.592 1.296 0.88 2.816 0.88 4.528 0 2.752-0.752 4.976-2.272 6.656-1.504 1.68-3.712 2.528-6.592 2.528-1.088 0-2.176-0.144-3.248-0.464-1.072-0.304-2.032-0.816-2.88-1.552-0.864-0.72-1.552-1.68-2.064-2.896-0.512-1.2-0.768-2.688-0.768-4.48h-13.408c0 3.376 0.592 6.384 1.744 9.024 1.168 2.64 2.752 4.896 4.736 6.752 2 1.856 4.352 3.264 7.072 4.24 2.704 0.96 5.648 1.44 8.816 1.44 3.232 0 6.224-0.496 8.992-1.488 2.768-1.008 5.136-2.416 7.104-4.224 1.968-1.824 3.52-4.064 4.624-6.704 1.12-2.656 1.664-5.616 1.664-8.928 0-1.792-0.176-3.392-0.528-4.784-0.336-1.408-0.848-2.768-1.488-4.064-0.656-1.312-1.472-2.608-2.48-3.872-0.992-1.28-2.112-2.624-3.344-4.080l-20.528-23.824h28.352v-12.064h-44.752zM306.416 93.296v-38.576h-110.048v38.576h110.048zM327.376 114.256h-151.968v-80.512h151.968v80.512zM124.784 59.488c0-3.632-0.624-6.832-1.856-9.584-1.248-2.752-2.912-5.056-5.056-6.864-2.128-1.84-4.608-3.184-7.44-4.080-2.832-0.896-5.84-1.344-8.992-1.344-2.96 0-5.84 0.416-8.672 1.232-2.816 0.832-5.312 2.128-7.472 3.872-2.176 1.76-3.904 3.984-5.216 6.704-1.312 2.736-2 6-2.064 9.856h13.408c0.064-1.664 0.368-3.088 0.928-4.288 0.56-1.184 1.264-2.208 2.16-2.992 0.896-0.784 1.952-1.376 3.152-1.744 1.2-0.384 2.464-0.576 3.776-0.576 2.88 0 5.248 0.88 7.12 2.624 1.856 1.76 2.784 4.288 2.784 7.584 0 3.088-0.896 5.536-2.688 7.376-1.792 1.808-4.336 2.736-7.632 2.736h-1.952v11.648h1.952c3.312 0 5.664 0.88 7.12 2.624 1.44 1.744 2.16 3.936 2.16 6.544 0 3.088-0.896 5.424-2.688 7.008-1.792 1.584-3.888 2.368-6.288 2.368-2.544 0-4.672-0.784-6.352-2.32-1.696-1.552-2.608-3.728-2.736-6.544h-13.408c0.064 3.312 0.704 6.24 1.904 8.816 1.2 2.576 2.8 4.768 4.8 6.56 2 1.776 4.352 3.168 7.056 4.128 2.72 0.96 5.616 1.44 8.72 1.44 3.232 0 6.224-0.512 8.992-1.552 2.752-1.024 5.136-2.464 7.152-4.32 2-1.872 3.552-4.080 4.672-6.656 1.104-2.576 1.664-5.408 1.664-8.512 0-3.984-0.816-7.168-2.448-9.536-1.632-2.384-3.648-4.208-6.064-5.52 2.608-1.376 4.832-3.392 6.704-6.032 1.856-2.656 2.784-6.208 2.784-10.672z" /> -<glyph unicode="" d="M718.384 16.192c0-26.624-21.552-48.192-48.176-48.192h-512.352c-26.624 0-48.192 21.568-48.192 48.192v127.808l-109.68 79.984 109.68 80v127.808c0 26.592 21.568 48.192 48.192 48.192h512.336c26.624 0 48.176-21.584 48.176-48.192v-415.632z" horiz-adv-x="720" /> -<glyph unicode="" d="M664.704 16.16c0-26.608-21.584-48.16-48.192-48.16h-424.976c-26.608 0-48.192 21.568-48.192 48.16v77.2c0 0-1.488 6.128-2.544 8.304-1.072 2.208-5.232 7.376-5.232 7.376l-117.936 91.744c0 0-17.456 13.776-17.632 23.2-0.192 9.728 17.632 24.992 17.632 24.992l117.952 98.832c0 0 4.16 5.536 5.232 7.824 1.008 2.16 2.544 8.272 2.544 8.272v67.888c-0.016 26.64 21.568 48.208 48.176 48.208h424.976c26.624 0 48.192-21.568 48.192-48.208v-415.632z" horiz-adv-x="672" /> -<glyph unicode="" d="M151.248 321.552v-43.296c0-9.424-6.736-16.944-16.032-19.168l9.056-1.008c0.032-0.464 2.272-24.704 12.384-50.656 6.112 5.024 10.128 12.672 10.128 21.552v93.264l-15.552-0.704zM139.984 451.088h-113.2c-14.688 0-26.784-12.976-26.784-28.512v-193.584c0-15.552 12.096-27.664 26.784-27.664h71.936c0.224 7.248 0.656 14.48 1.456 21.632h-37.936v14.688h40.512c1.344 6.672 2.96 13.584 5.040 20.736h-70.624c-12.080 0-21.584 8.64-21.584 19.872v138.272c0 10.352 9.504 19.888 21.584 19.888h92.48c1.856 0 3.616-0.288 5.328-0.704 6.912-1.68 12.4-6.48 14.848-12.416l16.992-14.192v13.472c0 15.552-12.096 28.512-26.816 28.512zM472.848 60.464v186.208h-118.016c-1.168-5.008-2.48-10.096-4.112-15.328l-35.44 4c-0.016 0.192-0.432 4.592-1.552 11.328h-56.048v-77.104l17.712 0.784v52.416h179.76v-137.056h-123.328l-23.728-24.384 52.288-0.272v-13.36h-60.976v-9.792h129.056v9.792h-57.408v13.296l101.792-0.528zM477.888 27.84h-222.512l-27.6-30.24 275.008-0.688zM239.36 150.544l18.224-14.368c-10.128-7.28-20.192-11.488-30.016-11.28-9.632 0.192-18.848 2.528-27.344 7.664-66.368 26.128-74.064 124.064-74.064 124.064-3.696-11.84-5.888-23.328-7.824-34.144-1.28-10.96-1.856-22.096-1.68-33.44 1.312-27.44 6.912-49.888 17.456-67.6 10.096-16.864 27.76-30.352 53.424-39.088 18.752-6.24 36.624-6.976 54.864-0.304 18.768 5.808 35.984 14.208 52.064 24.464l18.048-15.072-9.936 61.936-63.216-2.832zM272.032 411.024c-18.768 6.224-36.624 6.992-54.88 0.304-18.752-5.808-35.968-14.208-52.064-24.48l-18.032 15.072 9.936-61.936 63.216 2.832-18.224 14.368c10.128 7.28 20.208 11.504 30.016 11.264 9.648-0.192 18.848-2.512 27.344-7.648 66.368-26.144 74.064-124.064 74.064-124.064 3.696 11.84 5.872 23.312 7.808 34.128 1.28 10.96 1.856 22.112 1.696 33.44-1.328 27.456-6.896 49.904-17.456 67.616-10.096 16.864-27.76 30.336-53.424 39.088z" /> -<glyph unicode="" d="M562.208 267.856c0-117.136-112.592-192.816-281.104-212.112-83.056-56.272-184.16-87.712-251.6-87.712 82.224 60.336 105.248 115.968 94.432 123.952-8.432 4.288-16.56 8.928-24.304 13.872-60.928 38.896-99.632 97.040-99.632 162 0 117.184 125.856 212.144 281.12 212.144s281.088-94.96 281.088-212.144z" horiz-adv-x="560" /> -<glyph unicode="" d="M449.296 234.64c-0.192 6.592-0.448 14-0.448 16.496l0.048 0.544v48.192l-1.12 4.128c-10.336 39.024-40.080 42.048-48.944 42.048-1.36 0-2.784-0.064-4.192-0.176-1.072-0.032-2.192-0.096-3.264-0.192-7.552 17.968-25.696 30-48.016 30-8.64 0-16.752-1.68-23.952-4.672-10.032 10.464-25.008 16.992-41.984 16.992-2.736 0-5.392-0.176-8-0.496v22.032c0 20.288 0 74.176-51.264 74.176l-2.224-0.032h-1.584c-30.88 0-55.072-21.584-55.072-49.12l0.736-121.92c-10.448 7.888-22.256 11.872-35.328 11.872-7.84 0-14.944-1.36-22.736-2.976-14.096-2.96-25.984-12.272-32.544-25.584-6.944-14.048-7.232-30.992-0.88-45.728l40.832-120.128 2.448-3.6 65.68-97.968 15.344-43.248 7.84-22.048 199.584 1.408 6.16 24.784 42.16 170.048 0.176 0.944c2.144 11.552 1.872 34.064 0.56 74.208zM416.4 166.464l-41.92-169.136-150.656-1.040-16.736 47.12-67.952 101.376-39.952 117.504c-5.344 11.088-1.008 24.88 9.52 27.072 6.032 1.28 11.232 2.288 16 2.288 7.456 0 13.936-2.464 21.024-10.384l31.232-68.624c1.040-2.336 3.968-3.456 7.056-3.456 4.432 0 9.248 2.336 9.456 6.848l-1.328 218.56c0 9.008 9.888 16.224 22.176 16.224 1.312 0 2.56 0.048 3.808 0.048 10.48 0 18.384-2.080 18.384-41.28v-145.76c0.080-3.328 4.704-4.848 9.344-4.848 4.656 0 9.328 1.568 9.328 4.448v75.536c0 8.992 9.92 16.24 22.224 16.24 12.288 0 22.208-7.248 22.208-16.24v-68.512c-0.272-5.008 4.944-7.12 10.288-7.12 6.064 0 12.336 2.72 11.152 7.088v56.272c0 8.976 9.92 16.224 22.224 16.224h0.096c12.32 0 18.896-7.248 18.896-16.224v-72.96c-0.384-4.512 3.568-6.48 7.6-6.48 4.512 0 9.152 2.448 8.016 6.464v41.984c0 8.992 6.32 17.456 18.608 17.456 0.816 0.096 1.6 0.144 2.368 0.144 9.248 0 14.352-6.864 17.2-17.584v-42.56c-0.544-5.776 3.072-71.872 0.32-86.608z" /> -<glyph unicode="" d="M400.528 147.184c53.024 83.856 43.12 196.128-30.016 269.264-84.8 84.736-222.176 84.736-306.976 0-84.72-84.816-84.72-222.208 0-306.96 73.072-73.184 185.36-83.056 269.216-30.016l114.096-114.112 67.696 67.712-114.016 114.112zM322.928 157.072c-58.496-58.432-153.312-58.432-211.712 0-58.496 58.496-58.496 153.232 0 211.68 58.4 58.544 153.232 58.544 211.712 0 58.416-58.432 58.416-153.184 0-211.68z" /> -<glyph unicode="" d="M26 442.752h396.4l-11.904 5.328 64.864-72.064-4.112 10.736v-396.384l16.048 16.048h-461.264l16.048-16.048-0.016 468.448-16.048-16.048zM26-25.664h477.312v418.592l-4.112 4.576-69.664 77.344h-419.584v-500.512l16.048 0.016zM100.448 202.528h314.704l-16.048 16.048v-225.76l16.048 16.048h-314.704l16.048-16.048v225.76l-16.048-16.048zM100.448-23.232h330.752v257.856h-346.8v-257.856h16.048zM153.328 272.208h222.656v195.456h-238.704v-195.456h16.048zM153.328 435.568h206.608l-16.048 16.048v-163.36l16.048 16.048h-206.608l16.048-16.048v163.36l-16.048-16.048zM158.176 458.8h112.848v-175.36h-112.848z" /> -<glyph unicode="" d="M488.272 480h-488.272v-428.192l4.208-4.688 71.264-79.12h429.2v512.016h-16.4zM395.68 246.576h-289.12v198.112h289.12v-198.112zM32.816 64.416v382.768h40.928v-233.44h354.768v233.424h43.344v-446.368h-97.44v174.464h-244.16v-174.464h-40.176l-57.248 63.6zM163.072 142.464h74.528v-134.272h-74.528v134.272z" /> -<glyph unicode="" d="M378.736 393.824h28.288v-339.632h-28.288zM322.144 139.088h141.504v-28.32h-141.504zM407.040 54.192h28.32v-28.32h-28.32zM435.344 25.872h56.592v-28.288h-56.592zM350.432 54.192h28.304v-28.32h-28.304zM293.824 25.872h56.608v-28.288h-56.608zM293.824 450.416h56.608v-28.288h-56.608zM435.344 450.416h56.592v-28.288h-56.592zM407.040 422.128h28.32v-28.32h-28.32zM350.432 422.128h28.304v-28.32h-28.304zM1.968 333.024c13.792 2.304 31.84 4.272 54.816 4.272 28.224 0 48.912-6.56 62.032-18.384 12.144-10.496 19.36-26.592 19.36-46.288 0-20.032-5.904-35.776-17.072-47.264-15.104-16.080-39.712-24.288-67.616-24.288-8.528 0-16.416 0.32-22.976 1.968v-88.624h-28.56v218.608zM30.528 226.336c6.24-1.648 14.112-2.304 23.632-2.304 34.464 0 55.472 16.736 55.472 47.264 0 29.216-20.672 43.328-52.192 43.328-12.48 0-22-0.992-26.912-2.304v-86zM170.368 223.712c0 18.704-0.336 34.8-1.312 49.568h25.28l0.992-31.184h1.312c7.216 21.328 24.624 34.8 43.984 34.8 3.28 0 5.584-0.32 8.208-0.992v-27.248c-2.96 0.656-5.904 0.992-9.856 0.992-20.352 0-34.8-15.424-38.736-37.088-0.656-3.936-1.312-8.544-1.312-13.456v-84.688h-28.56v109.296z" /> -<glyph unicode="" d="M0.928 439.424h369.28v-38.16h-369.28zM118.112 480.864h134.912v-28.624h-134.912zM125.504 388.304v-419.568h45.376v419.632c-13.552 0.096-28 0.096-45.376-0.064zM200.304 387.968v-419.232h45.36v418.464c-17.312 0.272-31.744 0.576-45.36 0.768zM17.744 386.144l21.296-374.832c0-23.52 19.040-42.576 42.544-42.576h14.512v419.168c-21.248-0.384-46.576-0.912-78.352-1.76zM275.072 386.736v-418.016h14.48c23.52 0 42.56 19.056 42.56 42.576l21.296 374.832c-31.856 0.144-57.152 0.368-78.336 0.608z" /> -<glyph unicode="" d="M254.128 353.008c81.984-14.352 146.592-62.288 195.44-136.128l68.096 51.072-43.28-183.792-193.968 63.2 79.296 26.416c-43.136 66.72-76.432 86.064-138.448 103.296-32.976 9.152-80.768 4.576-127.872-20.736-39.504-21.28-58.736-50.64-83.424-112.16-6.064 4.56-12.128 4.56-16.848 2 6.080 52.448 26.416 104.736 69.888 149.632 43.904 45.36 116.96 70.176 191.136 57.2z" /> -<glyph unicode="" d="M509.376-29.184h-505.808v505.808h505.808v-505.808zM35.168 2.432h442.592v442.592h-442.592v-442.592z" /> -<glyph unicode="" d="M447.984 480h-383.984c-35.344 0-64-28.656-64-64v-383.984c0-35.36 28.656-64 64-64h383.984c35.344 0 64 28.656 64 64v383.984c0 35.344-28.656 64-64 64zM158.736 12.544h-111.312v47.504h111.312v-47.504zM158.736 100.64h-111.312v47.504h111.312v-47.504zM158.736 188.752h-111.312v47.504h111.312v-47.504zM158.736 276.848h-111.312v47.504h111.312v-47.504zM311.648 12.544h-111.312v47.504h111.312v-47.504zM311.648 100.64h-111.312v47.504h111.312v-47.504zM311.648 188.752h-111.312v47.504h111.312v-47.504zM311.648 276.848h-111.312v47.504h111.312v-47.504zM464.56 12.544h-111.312v47.504h111.312v-47.504zM464.56 100.64h-111.312v47.504h111.312v-47.504zM464.56 188.752h-111.312v47.504h111.312v-47.504zM464.56 276.848h-111.312v47.504h111.312v-47.504z" /> -<glyph unicode="" d="M696.992 479.984c-88.96 0-163.52-85.44-182.4-199.456l16.8-16.8c13.472 111.792 82.48 197.28 165.616 197.28 92.72 0 168.224-106.336 168.224-237.008s-75.52-237.008-168.224-237.008c-78.4 0-144.24 76.096-162.8 178.544l-16.192-16.336c23.456-104.768 94.832-181.184 178.976-181.184 103.168 0 187.136 114.832 187.136 255.984-0.016 141.152-83.984 256-187.136 255.984v0zM768.784 223.984c0-139.648-37.872-237.008-71.792-237.008-34.016 0-71.792 97.376-71.792 237.008 0 139.712 37.776 237.008 71.792 237.008 33.92 0 71.792-97.312 71.792-237.008zM696.992 479.984c-58.976 0-90.784-131.888-90.784-256 0-124.096 31.808-255.984 90.784-255.984 58.928 0 90.8 131.888 90.8 255.984-0.016 124.112-31.888 256-90.8 256zM696.992 479.984c-103.104 0-191.92-61.392-232.432-149.424l14.176-14.192c36.096 84.928 120.336 144.624 218.272 144.624 130.736 0 237.040-106.336 237.040-237.008s-106.32-237.008-237.040-237.008c-92.112 0-171.872 52.912-211.12 129.792l-14.144-14.256c43.296-80.016 128-134.512 225.232-134.512 141.168 0 255.984 114.832 255.984 255.984 0 141.152-114.8 256-255.968 256v0zM940.96 225.84h-371.68l12.448-12.448-6.496-6.544h365.728v18.992zM484.416 353.776h425.136v-18.976h-425.136v18.976zM484.416 97.808h425.136v-18.96h-425.136v18.96zM345.072 429.168v-59.072l39.936 39.968 4.592-4.608v66.448h-389.6v-498.88h389.6v46.656l-4.208-4.272-40.32 39.984v-39.632h-300.576v247.136l-0.32 65.184h99.712v101.088h201.184zM44.496 429.168h81.488l-81.488-81.472v81.472zM285.808 114.208h-114.896v-77.072h148.080v44.192l-33.184 32.88zM298.56 57.184h-107.232v36.976h107.232v-36.976zM294.944 165.52h-103.616v36.976h107.232v-33.312l20.432 20.592v32.816h-148.080v-77.12h104.128l19.024 19.2 0.88 0.848zM280.944 273.888h-89.632v36.96h94.512l20.064 20.048h-134.992v-77.088h130.128l-20.080 20.080zM141.824 66.544c0-4.576-0.8-8.544-2.384-11.888-1.584-3.344-3.728-6.128-6.384-8.304-2.672-2.24-5.744-3.872-9.248-4.992-3.504-1.104-7.184-1.664-11.024-1.664-3.6 0-7.136 0.48-10.608 1.536-3.456 1.008-6.576 2.592-9.312 4.768-2.736 2.176-4.944 5.008-6.624 8.448-1.664 3.488-2.512 7.664-2.512 12.56h20.096c0-3.088 0.848-5.408 2.576-6.928 1.712-1.504 3.824-2.24 6.368-2.24 2.608 0 4.752 0.752 6.432 2.304 1.664 1.584 2.512 3.888 2.512 7.008 0 2.608-0.864 4.8-2.624 6.56-1.776 1.728-3.984 2.624-6.672 2.624h-2.816v17.424h2.816c3.024 0 5.152 0.896 6.432 2.64 1.264 1.728 1.888 3.632 1.888 5.584 0 2.752-0.784 4.864-2.384 6.24s-3.456 2.096-5.584 2.096c-2.112 0-3.984-0.72-5.584-2.16-1.584-1.408-2.384-3.44-2.384-6.064h-20.080c0 4.080 0.736 7.76 2.192 11.024 1.472 3.264 3.472 6.048 6 8.336 2.528 2.272 5.504 4.016 8.88 5.184 3.392 1.2 7.056 1.792 10.976 1.792 4.080 0 7.808-0.624 11.216-1.904 3.392-1.264 6.352-3.040 8.88-5.312 2.528-2.32 4.496-5.040 5.888-8.224 1.376-3.184 2.080-6.64 2.080-10.416 0-2.368-0.272-4.464-0.8-6.336-0.528-1.824-1.216-3.424-2.096-4.784-0.848-1.344-1.808-2.496-2.864-3.424-1.056-0.944-2.176-1.792-3.296-2.528 1.216-0.816 2.432-1.776 3.6-2.864 1.184-1.104 2.256-2.432 3.2-3.952 0.928-1.504 1.728-3.264 2.336-5.264s0.912-4.272 0.912-6.88v0zM85.568 146.448v18.144l27.088 21.184c2.848 2.224 5.056 4.176 6.608 5.936s2.336 3.584 2.336 5.456c0 2.272-0.688 4.096-2.080 5.456-1.392 1.376-3.312 2.032-5.76 2.032-0.896 0-1.824-0.128-2.8-0.368-0.992-0.256-1.872-0.704-2.656-1.36-0.768-0.656-1.392-1.52-1.872-2.544-0.496-1.072-0.736-2.464-0.736-4.192h-20.112c0 4.336 0.768 8.16 2.256 11.408 1.536 3.28 3.568 6.064 6.144 8.336 2.576 2.304 5.568 4.016 9.008 5.152 3.424 1.152 7.024 1.712 10.768 1.712 3.92 0 7.584-0.576 10.976-1.712 3.392-1.136 6.352-2.784 8.88-4.96 2.528-2.16 4.512-4.8 5.936-7.904 1.424-3.104 2.144-6.624 2.144-10.56 0-2.432-0.416-4.736-1.296-6.864-0.848-2.112-2.064-4.176-3.68-6.176-1.6-2-3.488-3.984-5.696-5.936-2.192-1.968-4.64-3.984-7.36-6l-10.544-8.080h29.776v-18.144l-57.328-0.016zM105.44 248.56v51.728l-18.64-16.176v21.456l18.64 16.176h20.080v-73.168l-20.080-0.016zM323.76 289.904l76.896-76.912-77.056-77.664 61.552-61.024 137.824 138.992-137.936 137.92-61.28-61.312z" horiz-adv-x="960" /> -<glyph unicode="" d="M367.056 26.912l-12.896 12.784v-27.824h-308.48v253.632l-0.336 66.88h102.832l-0.496 103.744h206.48v-16.736l12.512 12.528 33.184-33.2v81.28h-399.856v-512h399.856v91.984l-2.72-2.768-30.080-30.304zM45.664 436.144h83.632l-83.632-83.616v83.616zM301.152 92.288l-20.784 20.592h-104.96v-79.136h151.968v32.528l-20.976 20.8v-32.704h-110.064v37.936h104.8zM175.424 224.080v-79.152h72.608l-4.8 4.768 15.728 15.84h-62.608v37.952h100.224l20.448 20.608h-141.6zM196.352 276.768v37.92h53.168l20.592 20.608h-94.688v-79.136h120.464l-20.624 20.624h-78.912zM115.76 55.040c-2.608 0-4.8 0.768-6.544 2.32-1.76 1.584-2.64 3.936-2.64 7.12h-20.64c0-5.024 0.864-9.312 2.576-12.896 1.728-3.552 4-6.448 6.816-8.656 2.8-2.256 6-3.856 9.536-4.912 3.552-1.072 7.2-1.584 10.88-1.584 3.936 0 7.696 0.56 11.312 1.696 3.6 1.136 6.768 2.832 9.488 5.104 2.736 2.256 4.928 5.104 6.576 8.528 1.616 3.44 2.448 7.52 2.448 12.192 0 2.688-0.32 5.072-0.928 7.104-0.624 2.064-1.424 3.856-2.384 5.408-0.976 1.552-2.064 2.912-3.28 4.048-1.216 1.104-2.448 2.096-3.712 2.944 1.168 0.768 2.304 1.632 3.376 2.576 1.104 0.976 2.064 2.16 2.944 3.536 0.912 1.376 1.616 3.008 2.16 4.896 0.544 1.888 0.816 4.048 0.816 6.48 0 3.856-0.72 7.424-2.144 10.688-1.424 3.28-3.44 6.080-6.048 8.416-2.608 2.368-5.648 4.192-9.12 5.488-3.488 1.328-7.328 1.968-11.488 1.968-4.032 0-7.792-0.624-11.264-1.84-3.488-1.184-6.544-3.008-9.12-5.328-2.608-2.352-4.64-5.216-6.16-8.56-1.504-3.36-2.256-7.152-2.256-11.312h20.624c0 2.688 0.816 4.768 2.448 6.208 1.648 1.472 3.568 2.224 5.744 2.224 2.176 0 4.080-0.736 5.728-2.16 1.632-1.424 2.448-3.568 2.448-6.4 0-2-0.656-3.936-1.952-5.728s-3.504-2.704-6.608-2.704h-2.896v-17.856h2.896c2.768 0 5.040-0.896 6.864-2.704 1.808-1.776 2.688-4.048 2.688-6.72 0-3.2-0.864-5.584-2.576-7.184-1.728-1.616-3.92-2.4-6.608-2.384v0zM146.688 164.592h-30.56l10.8 8.288c2.784 2.096 5.312 4.16 7.568 6.16 2.256 2.016 4.208 4.048 5.84 6.112 1.648 2.048 2.896 4.176 3.792 6.352 0.88 2.192 1.328 4.56 1.328 7.040 0 4.032-0.736 7.632-2.208 10.816-1.488 3.2-3.504 5.904-6.112 8.112-2.608 2.224-5.648 3.92-9.12 5.088-3.488 1.184-7.248 1.776-11.248 1.776-3.872 0-7.536-0.592-11.056-1.776-3.536-1.168-6.608-2.944-9.232-5.312-2.64-2.32-4.752-5.184-6.32-8.512-1.52-3.344-2.304-7.264-2.304-11.696h20.64c0 1.76 0.256 3.184 0.752 4.288 0.496 1.072 1.136 1.968 1.936 2.624 0.816 0.688 1.712 1.136 2.736 1.408 1.008 0.256 1.968 0.368 2.88 0.368 2.512 0 4.48-0.688 5.904-2.096 1.44-1.376 2.144-3.248 2.144-5.584 0-1.936-0.784-3.808-2.384-5.616-1.6-1.824-3.872-3.84-6.8-6.112l-27.792-21.744v-18.64h58.848v18.656zM128.816 250.784v75.072h-20.608l-19.136-16.576v-22.016l19.136 16.592v-53.088h20.608zM659.008 280.704h45.568c22.4 0 40.528 18.16 40.528 40.528v45.632c0 22.384-18.144 40.48-40.528 40.48h-45.568c-22.368 0-40.576-18.128-40.576-40.48v-45.632c0-22.384 18.224-40.528 40.576-40.528zM502.512 316.4c14.224 0 25.776 11.472 25.776 25.776v29.024c0 14.24-11.584 25.824-25.776 25.824h-29.056c-14.272 0-25.76-11.568-25.76-25.824v-20.288l34.528-34.528h20.304zM530.96 173.008v19.184l-19.008-19.184h19.008zM867.376 313.136h30.176c14.816 0 26.864 12.048 26.864 26.848v30.176c0 14.816-12.032 26.832-26.864 26.832h-30.176c-14.832 0-26.8-12.016-26.8-26.832v-30.176c0-14.8 11.968-26.848 26.8-26.848zM930.176 294.608h-95.472c-20.192 0-36.592-17.296-36.592-38.624v-26.656c-10.096 14.128-26.128 23.296-44.224 23.296h-144.288c-16.128 0-30.416-7.456-40.496-19.072v27.808c0 20.48-15.744 37.104-35.216 37.104h-33.744l36.032-36.032h2.4v-2.4l28.704-28.688c-1.936-2.448-3.664-5.024-5.216-7.776l-0.016-0.016-23.488-23.664v-26.848h15.76v-117.424h44.384v140.448h11.984v-140.448h138.576v140.448h11.904v-140.448h48.032c0 0.128 0 2.56 0 30.656v77.984h18.272v92.896h7.968v-92.896h91.664v92.896h7.92v-92.896h31.744c0 0.048 0 1.664 0 20.288v71.472c0 21.328-16.4 38.608-36.608 38.608zM303.808 308.608l78.928-78.944-79.088-79.728 63.152-62.64 141.456 142.64-141.568 141.568-62.88-62.896z" horiz-adv-x="960" /> -<glyph unicode="" d="M347.344-35.376c32.080 0 61.648 7.504 61.648 42.336v90.912c0 2.544-0.336 4.992-0.64 7.44h47.552c13.264 0 24 10.24 24 22.864v221.152c0 12.656-10.736 22.88-24 22.88h-38.912c-2.304 16-32.416 47.312-32.416 47.312v-47.312h-20.128v84.896c0 12.64-10.256 22.896-22.88 22.896h-203.232c-12.624 0-22.848-10.24-22.848-22.896v-84.896h-22.768l1.584 46.24c0 0-31.664-30.576-31.664-45.856l5.088-0.384h-43.696c-13.28 0-24.016-10.224-24.016-22.88v-221.152c0-12.624 10.752-22.864 24.016-22.864h48.256c-0.656-3.328-0.992-6.288-0.992-8.512v-83.664c0-34.752 18.736-48.496 50.816-48.496h225.248zM364.448 233.152h3.52c15.696 0 28.384-14.32 28.384-31.952v-66.336c-9.088-3.888-20.032-5.872-31.904-6.848v105.152zM133.040 405.392c0 12.608 10.528 22.88 23.568 22.88h166.72c13.008 0 23.6-10.272 23.6-22.88v-33.184h-213.888v33.184zM133.040 233.152h213.888v-105.92c-0.4 0-0.784-0.032-1.2-0.032v67.12c0 15.632-10.256 28.288-22.88 28.288h-165.792c-12.64 0-22.864-12.656-22.864-28.288v-67.12c-0.416 0-0.752 0-1.152 0v105.952zM346.928 105.312v-1.2c0-3.344-0.784-6.528-2.128-9.392 0.544 2.416 0.944 4.944 0.944 7.584v3.008h1.2zM150.416 172.608v10.864h181.008v-10.864h-181.008zM331.44 156.8v-10.864h-181.008v10.864h181.008zM133.040 105.312h1.152v-3.008c0-2.608 0.384-5.072 0.912-7.472-1.296 2.848-2.064 5.968-2.064 9.28v1.2zM111.952 233.152h3.536v-105.2c-6.752 0.816-11.072 2.336-31.92 4.496v68.736c0 17.632 12.672 31.968 28.384 31.968zM58.608 337.136c0 8.128 6.592 14.752 14.736 14.752 8.144 0 14.736-6.608 14.736-14.752 0-8.128-6.592-14.72-14.736-14.72-8.144 0-14.736 6.608-14.736 14.72zM83.568 9.056v96.256h31.92v-82.336c0-12.656 10.224-22.88 22.848-22.88h203.232c12.624 0 22.88 10.224 22.88 22.88v82.336h31.904v-96.256c0-17.632-12.688-31.936-28.384-31.936h-256.016c-15.712 0-28.384 14.304-28.384 31.936z" /> -<glyph unicode="" d="M512 160v-192h-512v192h64v-128h384v128zM96 64c-64-64-32-32 0 0z" /> -<glyph unicode="" d="M74.848 218.352l8.848-8.592 171.968 182.432-8.864 8.608zM227.328 419.024l10.688-10.096-171.92-182.432-10.704 10.096zM275.264 373.504l-10.768 10.112-171.44-182.4 10.224-10.112zM334.368 471.376c-16.784 16.176-43.936 15.328-59.648-1.984l-36.912-39.168 67.168-63.216 36.912 39.184c16.224 16.768 15.312 43.92-1.904 60.144l-5.616 5.056zM122.704 173.472l-10.24 9.664 171.68 182.224 10.224-9.648zM6.192 112.192l106.080 49.952-67.664 63.264zM316.176-40.64c-53.936 0-84.256 28.336-95.168 41.152-0.96 1.072-1.952 2.272-2.992 3.584-17.408-9.712-34.592-17.248-49.248-21.072-64.288-16.832-82.16-18.208-125.2 5.76-43.712 24.352-44.128 80.96-44.304 84.144l2.992 27.424 8.096-2.096 1.76-26.544c0.048-0.656 6.24-47.056 40.72-66.224 35.952-20 48.416-20.464 111.104-4 12.64 3.296 27.568 9.776 42.944 18.224-15.728 24.912-31.232 64.24-12.32 107.168 20.352 46.16 49.36 91.392 110.72 76.976 13.264-3.152 22.64-12.144 27.008-26.048 10.144-32.128-9.12-84.128-32.752-110.656-16.576-18.576-40.288-37.648-64.864-53.232 0.272-0.336 0.608-0.688 0.864-1.056 9.824-11.472 38.4-37.792 90.704-34.064 106.336 7.6 162.352 31.36 172.72 44.528l15.024-11.776c-15.936-20.272-79.696-44.176-186.384-51.792-3.92-0.288-7.712-0.416-11.408-0.416zM283.136 187.488c-29.216 0-50.128-20.704-71.104-68.32-15.584-35.344-2.208-68.592 11.296-89.776 23.504 14.736 46.368 32.976 61.968 50.432 21.968 24.688 35.968 69.472 28.8 92.176-2.368 7.456-6.56 11.664-13.2 13.216-6.224 1.504-12.144 2.272-17.76 2.272z" /> -<glyph unicode="" d="M406.256 480h-311.936c-52.096 0-94.32-42.224-94.32-94.32v-323.344c0-52.096 42.24-94.336 94.32-94.336h311.936c52.096 0 94.32 42.24 94.32 94.336v323.344c0.016 52.096-42.224 94.32-94.32 94.32zM453.44 62.336c0-26-21.136-47.168-47.152-47.168h-311.952c-26.032 0-47.152 21.136-47.152 47.168v323.344c0 26.032 21.168 47.152 47.152 47.152h311.936c26 0 47.152-21.136 47.152-47.152v-323.344zM79.296 369.488h342.016v-17.392h-342.016v17.392zM81.056 314.752h306.88v-17.392h-306.88v17.392zM608.976 325.248h115.632v-17.408h-115.632v17.408zM608.976 270.784h115.632v-17.392h-115.632v17.392zM635.344 196.64h57.824v-17.424h-57.824v17.424zM159.856 205.344h259.712v-17.408h-259.712v17.408zM159.856 150.656h220.816v-17.408h-220.816v17.408zM159.856 95.92h259.712v-17.392h-259.712v17.392zM696.112 480h-58.64c-52.096 0-94.336-42.224-94.336-94.32v-323.344c0-52.096 42.24-94.336 94.336-94.336h58.64c52.096 0 94.32 42.24 94.32 94.336v323.344c0.016 52.096-42.224 94.32-94.32 94.32zM743.296 62.336c0-26-21.168-47.168-47.152-47.168h-58.64c-26 0-47.152 21.136-47.152 47.168v323.344c0 26.032 21.136 47.152 47.152 47.152h58.64c26 0 47.152-21.136 47.152-47.152v-323.344zM608.976 398.64h115.632v-42.4h-115.632v42.4zM86.672 217.616h41.936v-41.936h-41.936v41.936zM86.672 164.704h41.936v-41.936h-41.936v41.936zM86.672 108.192h41.936v-41.936h-41.936v41.936zM635.344 143.728h57.824v-17.424h-57.824v17.424z" horiz-adv-x="784" /> -<glyph unicode="" d="M613.984 229.888v-205.184h-557.296v205.184h-56.688v-261.888h670.672v261.888zM521.312 239.584l-189.392 240.416-182.576-235.92 125.856-1.552v-83.52h119.408v77.6z" horiz-adv-x="672" /> -<glyph unicode="" d="M419.872-31.888v0c21.248 0 39.824 20.032 40.416 45.744v1.216l1.088 416.208c0 25.92-17.76 48.24-40.256 48.72l2.608-0.16-360.928 0.048c-21.136 0-38.944-19.712-40.464-44.416l-0.016-7.136-16.656 0.064c-3.040 0.016-5.552-1.44-5.552-3.248l-0.112-38.32c0.032-1.808 2.512-3.28 5.552-3.28l16.64-0.048-0.112-45.312-16.416 0.048c-3.040-0.016-5.552-1.488-5.552-3.264l-0.112-38.352c0.016-1.776 2.512-3.264 5.552-3.264l16.416-0.032-0.112-45.296-16.208 0.048c-3.056-0.016-5.568-1.456-5.568-3.264l-0.080-38.32c0-1.792 2.496-3.296 5.536-3.28l16.192-0.032-0.112-45.312-15.968 0.032c-3.056 0.016-5.552-1.44-5.536-3.232l-0.112-38.32c0-1.824 2.496-3.296 5.536-3.264l15.968-0.048-0.112-45.328-15.728 0.032c-3.056-0.016-5.552-1.44-5.536-3.232l-0.112-38.352c0-1.824 2.496-3.264 5.552-3.232l15.712-0.048-0.016-6.8c-0.080-26.32 18-47.792 40.368-47.888zM419.552 15.344l-0.016-0.992c-0.176-3.424-1.36-5.552-2.144-6.544l-353.52 0.896c-0.848 1.072-2.080 3.424-2.064 7.216l0.016 6.784 13.632-0.048c3.072-0.032 5.584 1.488 5.584 3.264l0.080 38.336c0.032 1.792-2.48 3.248-5.552 3.312l-13.632 0.032 0.112 45.28 13.408-0.048c3.056 0 5.568 1.456 5.584 3.296l0.096 38.304c0 1.792-2.496 3.28-5.584 3.296l-13.392 0.032 0.112 45.328 13.184-0.032c3.056-0.032 5.584 1.424 5.6 3.232l0.096 38.336c0 1.792-2.496 3.28-5.584 3.28l-13.184 0.032 0.112 45.312 13.008-0.032c3.056-0.032 5.568 1.44 5.6 3.248l0.064 38.336c0.016 1.76-2.48 3.248-5.552 3.28l-12.992 0.032 0.112 45.312 12.784-0.032c3.072-0.016 5.568 1.44 5.6 3.232l0.064 38.32c0.016 1.808-2.496 3.264-5.552 3.28l-12.928 0.032-0.128 3.952v0.272c0 3.664 1.568 6.176 2.368 7.424h353.568c0.848-1.248 2.112-4.56 2.112-8.352l-1.008-416.224zM364.368 272.4c-0.016-5.456-7.888-9.36-17.408-9.328h-218.048c-9.536 0.016-17.376 4.496-17.344 9.984l0.288 116.48c0.016 5.456 7.84 9.888 17.392 9.872h218.048c9.552-0.064 17.392-5.024 17.36-10.512l-0.272-116.496z" /> -<glyph unicode="" d="M76.704 241.92h174.080c-0.176 11.216-0.032 22.304 0.432 33.104h-174.512v-33.104zM359.92 267.584c-4.096-8.688-7.456-17.328-10.192-25.664h10.192v25.664zM278.4 122.112c8.464 5.232 10.336 9.6 3.472 14.384-9.84 2.304-13.264-1.648-16.432-0.224-2.64 6.752-9.024 7.808-12.688 8.704-5.872 1.456-5.872-4.384-10.96-1.456-7.152 4.112-5.584 10.32-17.728 10.224-12.976 0.096-24.544-16.672-8.64-30.784 9.168-5.808 51.328-5.44 62.976-0.848zM283.2 75.392c-22.992-1.392-23.648 22.096-44.96 15.6-13.408-5.84-21.392-34.352-23.664-58.464 58.368 0 116.72 0 175.088 0-6.976 37.12-23.648 85.76-47.312 89.664-42.224 2.928-38.128-32.288-59.152-46.8zM585.872 360.064l-14.256 119.936-34.72-45.216c-28.24 14.224-57.12 24.688-87.008 29.552-29.632 6.656-55.088-0.544-79.2-18.432-32.912-25.040-66.88-78.256-73.312-113.552-5.376-29.072-8.928-78-4.912-123.136h-246.432v56.736c0 25.376 20.64 46.032 46.032 46.032h162.048c1.104 9.904 2.384 19.328 3.904 27.52 1.072 5.92 2.736 12.128 4.816 18.512h-170.768c-50.848 0-92.064-41.216-92.064-92.064v-205.872c0-50.848 41.216-92.080 92.064-92.080h268.72c50.864 0 92.080 41.232 92.080 92.080v205.872c0 0.72-0.096 1.424-0.112 2.144-0.496 22.096-8.784 42.256-22.224 57.856-3.376 3.92-7.024 7.584-11.008 10.88-4.832-2.608-9.92-5.712-15.664-9.872-7.648-6.656-14.32-13.824-20.288-21.264 10.32-5.952 18.048-15.68 21.328-27.376 1.104-3.968 1.904-8.048 1.904-12.368v-56.736h-106c6.176 39.504 24.352 103.088 78.16 149.12 28.144 20.656 68.192 42.416 118.656 8l-26.144-48.624 114.4 42.352zM159.92 14.048h-67.856c-25.392 0-46.032 20.656-46.032 46.032v118.432h113.888v-164.464zM337.76 178.512h69.072v-118.432c0-25.376-20.64-46.032-46.048-46.032h-170.16v164.464h106.032c0.336-1.856 0.576-3.84 0.976-5.664 0 0-0.016 2.080 0.112 5.664h40.016z" horiz-adv-x="592" /> -<glyph unicode="" d="M750.944-32h-316.464c-33.696 0-60.096 24.288-60.096 55.28v220.368c0 26.064 18.656 47.392 44.624 53.52 3.264 17.040 11.44 46.368 42.752 46.368h109.904c32.352 0 40.272-28 42.976-44.592h136.304c33.696 0 60.096-24.288 60.096-55.312v-220.352c-0.016-30.992-26.4-55.28-60.096-55.28zM434.656 261.824c-13.056 0-23.152-8-23.152-18.176v-220.352c0-10.192 10.096-18.16 22.992-18.16h316.448c12.896 0 22.976 7.968 22.976 18.16v220.352c0 10.192-10.080 18.176-22.976 18.176h-166.176l-3.84 13.44c-1.056 3.76-1.616 7.888-2.16 12.256-2.432 18.896-4.704 18.896-7.088 18.896h-109.92c-0.56 0-0.816-0.064-0.816-0.064-3.056-2.16-5.472-16.032-6.288-20.608-0.64-3.744-1.264-7.312-2.176-10.464l-3.824-13.44h-14zM132.336 344.128c39.408 23.376 94.528 46.672 156.048-4.768l-40.384-60.16 154.848 40.704-3.264 158.512-51.136-54.64c-35.072 22.208-71.472 39.584-109.92 49.76-37.84 12.48-72.032 6.336-105.84-13.952-46.176-28.48-97.392-93.648-110.32-138.928-13.744-47.696-28.016-138.256-20.112-208.416 0.016 0 11.856 149.264 130.080 231.888z" horiz-adv-x="816" /> -<glyph unicode="" d="M589.824 360.064l-14.272 119.936-34.704-45.216c-28.256 14.224-57.12 24.704-87.024 29.568-29.632 6.64-55.072-0.56-79.2-18.448-32.896-25.040-66.88-78.256-73.296-113.552-5.376-29.088-8.944-78-4.928-123.152h-250.368v56.736c0 25.392 20.64 46.032 46.032 46.032h165.984c1.12 9.904 2.384 19.328 3.904 27.536 1.072 5.92 2.752 12.128 4.816 18.496h-174.704c-50.832 0.016-92.064-41.2-92.064-92.048v-205.872c0-50.848 41.232-92.080 92.064-92.080h268.736c50.848 0 92.064 41.232 92.064 92.080v205.872c0 0.24-0.032 0.48-0.032 0.704-0.16 21.328-7.6 40.896-19.904 56.416-3.568 4.512-7.568 8.656-11.904 12.416-4.128-2.368-8.432-5.072-13.2-8.512-8.144-7.104-15.264-14.768-21.536-22.736 10.448-6.976 17.744-18.144 19.808-31.072 0.368-2.368 0.736-4.752 0.736-7.232v-56.752h-102.064c6.192 39.504 24.352 103.088 78.16 149.12 28.144 20.656 68.192 42.416 118.672 8l-26.16-48.624 114.384 42.384zM159.936 14.048h-67.872c-25.392 0-46.032 20.64-46.032 46.032v118.432h113.888v-164.464zM341.712 178.512h65.12v-118.432c0-25.392-20.64-46.032-46.032-46.032h-170.176v164.464h109.952c0.352-1.856 0.592-3.84 0.992-5.664 0 0-0.032 2.080 0.096 5.664h40.048z" horiz-adv-x="592" /> -<glyph unicode="" d="M29.568 75.632c0 46.96 35.52 85.152 79.168 85.152h11.408l-16.736-46.864h39.488l-7.152-32.24 114.208-98.032 115.584 97.984-7.168 32.288h39.472l-16.736 46.864h11.392c43.664 0 79.2-38.208 79.2-85.152v-107.632h29.584v107.632c0 63.328-48.672 114.72-108.784 114.72h-283.76c-60.112-0.016-108.736-51.392-108.736-114.72v-107.632h29.568v107.632zM320.288 160.784h29.44l6.16-17.296h-34.4l11.312-50.848-80.848-68.512 68.336 136.656zM151.536 160.784h29.456l69.36-138.048-0.304-0.24-81.616 70.080 11.312 50.912h-34.4l6.192 17.296zM100.368 81.168h29.568v-113.168h-29.568v113.168zM371.328 81.168h29.568v-113.168h-29.568v113.168zM295.488 480h-89.648c-44.016 0-79.792-35.664-79.792-79.68v-89.68c0-44.016 35.76-79.696 79.792-79.696h89.648c44.064 0 79.696 35.68 79.696 79.696v89.68c0.016 44.016-35.632 79.68-79.696 79.68zM250.672 271.024c-39.376 0-67.792 29.376-69.008 30.64l16.032 15.296c0.256-0.224 23.248-23.76 52.976-23.76 28.4 0 52.96 23.76 53.2 24.016l15.536-15.824c-1.28-1.232-31.392-30.368-68.736-30.368z" horiz-adv-x="496" /> -<glyph unicode="" d="M521.84 316.368l13.728-20.48-109.28-73.056-17.632 17.616zM187.504 63.216l-12.88 20.272 103.504 69.424 17.44-17.456zM140 134.768l-13.664 20.448 89.568 59.904 17.744-17.728zM474.336 387.968l13.696-20.464-123.696-82.72-17.744 17.744zM499.424 350.976l11.216-17.344-116.96-78.192-14.864 14.864zM162.624 100.976l-11.2 17.264 96.704 64.672 14.848-14.848zM495.808 402.224l74.688 49.984c32.048 22.256 76.576 13.504 97.808-19.12l7.28-10.336c22-32.784 13.248-77.28-19.312-98.544l-74.736-50.016-85.728 128.032zM104.88 140.976l86.512-128.224-191.392-41.696zM546.96 279.408l13.104-19.488-102.272-68.592-16.928 16.928zM212.816 26.992l-13.088 19.52 110.608 74.192 16.912-16.944zM505.776 342.848l18.064-27.52-111.44-78.624-26.24 26.256zM181.904 74.112l-23.376 36.848 96.864 64.672 29.136-29.136zM60.096 425.52l54.528 54.512 457.408-457.536-54.528-54.512-457.408 457.536z" horiz-adv-x="688" /> -<glyph unicode="" d="M16.912 481.536l495.056-495.072-18.176-18.176-495.056 495.072z" /> -<glyph unicode="" d="M662.384 159.024c0 51.184-41.68 93.44-93.488 93.44h-24.368c-22.048-16.672-49.44-26.784-79.184-26.784-29.776 0-57.168 10.112-78.592 26.784h-17.28c-33.152 0-62.496-17.792-79.12-44.192h93.040l-0.272-173.696h279.232l0.016 124.448zM466.496 243.2c65.84 0 118.656 53.376 118.656 118.688 0 65.344-52.816 118.096-118.656 118.096-65.312 0-118.144-52.768-118.144-118.096 0-65.312 52.832-118.688 118.144-118.688zM349.136 178.976h-344.576l165.184-108.752 179.392 108.752zM0 142.576v-174.592h353.712v174.592l-184.768-110.976-168.944 110.976z" horiz-adv-x="656" /> -<glyph unicode="" d="M237.072 193.152h163.536l31.6 58.384h-197.776l1.584-56.768c0.32-0.48 0.72-1.088 1.056-1.616zM312.16 79.008h82.544l-0.16 2.4-73.344 40.464 10.56 19.2h-60.352c16.48-25.024 33.2-50.432 39.744-60.496 0.336-0.512 0.688-1.056 0.992-1.568zM176.272 480v-152.544l67.504 0.4-3.744-24.224h194.608v-47.584l36.080 66.64v157.312h-294.464zM434.656 362.032h-223.248v52.096h223.248v-52.096zM205.536 185.152l-2.272 81.36 4.672 30.416-110.848-0.656 0.304-109.792c0 0-82.912-131.552-90.384-145.28-7.472-13.728-24.464-72.096 51.968-72.992 76.432-0.928 191.104 0.928 191.104 0.928s42.256-2.96 51.568 26.208c9.296 29.152-1.872 46.384-16.24 68.512-14.384 22.128-79.856 121.312-79.856 121.312zM45.36 52.928l75.872 126.752v94.336h60.16l0.464-95.888 76.592-125.2h-213.088zM362.912 133.952l110.336-60.864 7.76 14.080-110.352 60.832zM478.416 22.352c40.032 8.624 91.888 27.408 107.584 67.712 24.384 62.736-49.744 123.056-67.616 136.448l59.408 109.728-49.568 28.128-99.904-184.544 10.624-6.016-12.976-23.664 26.96-15.52 13.088 23.824 11.888-6.736 20.816 38.496c21.648-17.504 60.48-56.672 49.328-85.36-11.888-30.608-80.576-46.224-121.056-48.88l2.144-33.136h-62.672v-38.464h251.072v37.696h-106.352l-32.752 0.32z" /> -<glyph unicode="" d="M256 424.784c110.432 0 200.784-90.352 200.784-200.784s-90.352-200.784-200.784-200.784c-110.432 0-200.784 90.352-200.784 200.784s90.352 200.784 200.784 200.784zM256 480c-142.224 0-256-113.776-256-256s113.776-256 256-256c140.544 0 256 113.776 256 256s-115.456 256-256 256v0zM209.152 101.856c6.688 1.68 11.712 3.344 13.392 5.024 3.344 3.344 5.024 10.032 5.024 18.4v113.776c0 8.368-1.68 13.392-3.344 16.736-3.344 3.344-8.368 5.024-15.056 6.688v10.032h75.296v-147.248c0-8.368 1.68-13.392 3.344-16.736 3.344-1.68 6.688-5.024 15.056-5.024v-10.032h-92.032v8.368zM235.92 352.832c6.688 6.688 13.392 8.368 21.744 8.368s15.056-3.344 21.744-8.368c5.024-6.688 6.688-13.392 6.688-21.744 0-8.368-3.344-15.056-8.368-21.744-6.688-6.688-13.392-8.368-21.744-8.368-8.368 0-15.056 3.344-21.744 8.368-6.688 6.688-8.368 13.392-8.368 21.744 0 8.368 3.344 15.056 10.032 21.744z" /> -<glyph unicode="" d="M613.984 229.888v-205.184h-557.296v205.184h-56.688v-261.888h670.672v261.888zM521.312 399.44l-189.392-240.432-182.576 235.92 125.856 1.552v83.52h119.408v-77.6z" horiz-adv-x="672" /> -<glyph unicode="" d="M462.528 431.136c0 26-17.92 48.368-40.624 48.864l-0.176-0.864-358.736 0.864c-21.2 0-39.056-19.824-40.592-44.592l-0.016-7.184-16.704 0.048c-3.040 0.016-5.568-1.44-5.568-3.248l-0.128-38.448c0.048-1.808 2.528-3.296 5.584-3.28l16.688-0.048-0.112-45.44-16.464 0.048c-3.056-0.016-5.568-1.504-5.568-3.28l-0.128-38.464c0.016-1.792 2.528-3.264 5.584-3.28l16.448-0.048-0.112-45.44-16.256 0.048c-3.056-0.016-5.584-1.472-5.584-3.28l-0.080-38.432c0-1.792 2.512-3.312 5.568-3.296l16.24-0.032-0.112-45.456-16.016 0.032c-3.056 0.016-5.568-1.44-5.552-3.232l-0.128-38.432c0-1.824 2.512-3.312 5.568-3.28l16-0.048-0.112-45.456-15.792 0.032c-3.056-0.016-5.568-1.456-5.552-3.248l-0.128-38.48c0-1.824 2.512-3.28 5.584-3.248l15.744-0.048-0.016-6.816c-0.080-26.384 18.032-47.936 40.48-48.032l0.672-0.032 358.32-0.88c21.84 0 40.112 20.96 40.72 46.752l0.080 0.176-0.080 1.040 1.024 417.456zM420.816 13.952l-0.016-1.008c0-0.048-0.016-0.080-0.016-0.128l0.048 14.88-0.224-16.416c-0.4-2.464-1.312-4.080-1.968-4.896l-354.576 0.896c-0.848 1.072-2.080 3.44-2.080 7.232l0.016 6.8 13.68-0.048c3.088-0.032 5.6 1.488 5.6 3.264l0.080 38.448c0.048 1.792-2.496 3.248-5.568 3.312l-13.68 0.032 0.112 45.424 13.456-0.048c3.056 0 5.584 1.44 5.6 3.296l0.080 38.416c0 1.792-2.496 3.296-5.6 3.312l-13.44 0.032 0.112 45.456 13.232-0.032c3.072-0.048 5.6 1.424 5.616 3.232l0.080 38.448c0 1.808-2.496 3.312-5.6 3.312l-13.216 0.032 0.112 45.44 13.040-0.032c3.072-0.032 5.584 1.44 5.616 3.248l0.048 38.464c0.016 1.776-2.464 3.248-5.568 3.28l-13.040 0.032 0.112 45.456 12.832-0.032c3.072-0.016 5.6 1.456 5.616 3.264l0.064 38.432c0.016 1.808-2.512 3.28-5.568 3.28l-12.832 0.032 0.016 3.952v0.288c0.096 3.68 1.312 5.952 2.112 6.976h354.624c0.864-1.088 2.112-4.336 2.112-8.128l-1.008-417.216zM72.864-34.016l-10.4 0.608h-0.384zM347.984 260.88c9.568-0.032 17.44 3.888 17.456 9.36l0.288 116.832c0.032 5.504-7.824 9.968-17.424 10.048l-218.688 0.496c-9.6 0.016-17.424-4.432-17.456-9.904l-0.288-116.832c-0.016-5.488 7.84-9.984 17.392-10.016h218.688zM239.312 221.664c-11.104 0-20.144-9.008-20.144-20.112v-22.656c0-11.12 9.040-20.128 20.144-20.128h22.64c11.136 0 20.128 9.008 20.128 20.128v22.656c0 11.104-8.992 20.112-20.128 20.112h-22.64zM147.184 216.544c-7.072 0-12.8-5.76-12.8-12.832v-14.416c0-7.088 5.712-12.8 12.8-12.8h14.432c7.056 0 12.8 5.712 12.8 12.8v14.416c0 7.072-5.744 12.832-12.8 12.832h-14.432zM342.784 216.544c-7.376 0-13.328-5.968-13.328-13.328v-14.992c0-7.328 5.952-13.328 13.328-13.328h14.976c7.36 0 13.328 5.984 13.328 13.328v14.992c0 7.36-5.968 13.328-13.328 13.328h-14.976zM373.968 165.696h-47.408c-10.032 0-18.144-8.592-18.144-19.168v-13.328c-5.008 7.056-12.976 11.632-21.968 11.632h-71.648c-7.984 0-15.12-3.6-20.128-9.312v13.648c0 10.176-7.808 18.432-17.472 18.432h-45.6c-9.648 0-17.472-8.256-17.472-18.432v-43.872h14.032v44.4h3.792v-44.4h43.792v44.4h3.792v-44.4h7.84v-58.304h22.032v69.728h5.952v-69.728h68.8v69.728h5.92v-69.728h23.84c0 0.064 0 1.28 0 15.216v38.736h9.056v46.128h3.968v-46.128h45.52v46.128h3.936v-46.128h15.744c0 0 0 0.816 0 10.064v35.504c0 10.576-8.144 19.168-18.176 19.168z" /> -<glyph unicode="" d="M541.616 412.512h-230.224c-5.008 17.504-0.896 67.488-41.024 67.488h-166.256c-35.68 0-36-49.984-41.008-67.488h-0.256c-35.248 0-62.848-24.384-62.848-55.568v-333.376c0-31.152 27.6-55.568 62.848-55.568h478.768c35.216 0 62.848 24.416 62.848 55.568v333.376c-0.016 31.184-27.616 55.568-62.848 55.568zM410.912 288.88c0 10.48 8.48 18.976 18.976 18.976h21.312c10.464 0 18.992-8.496 18.992-18.976v-21.328c0-10.464-8.512-18.976-18.992-18.976h-21.328c-10.496 0-18.976 8.528-18.976 18.976v21.328zM253.84 286.544c0 15.824 12.88 28.64 28.704 28.64h32.24c15.84 0 28.672-12.816 28.672-28.64v-32.272c0-15.824-12.816-28.672-28.672-28.672h-32.24c-15.824 0-28.704 12.848-28.704 28.672v32.272zM133.12 289.6c0 10.080 8.144 18.256 18.224 18.256h20.544c10.048 0 18.24-8.176 18.24-18.256v-20.528c0-10.096-8.176-18.208-18.24-18.208h-20.544c-10.080 0-18.224 8.128-18.224 18.208v20.528zM500.16 157.616c0-13.168 0-14.304 0-14.304l-22.432-0.048v65.68h-5.584v-65.68h-64.832v65.68h-5.648v-65.68h-12.912v-55.136c0-19.84 0-21.584 0-21.68h-33.952v99.312h-8.432v-99.312h-97.968v99.312h-8.48v-99.312h-31.376v83.024h-11.152v63.232h-5.392v-63.232h-62.352v63.232h-5.392v-63.232h-20v62.464c0 14.48 11.136 26.24 24.88 26.24h64.928c13.76 0 24.896-11.76 24.896-26.24v-19.552c7.136 8.176 17.28 13.376 28.672 13.376h102c12.848 0 24.16-6.624 31.28-16.704v19.12c0 15.056 11.6 27.296 25.856 27.296h67.504c14.288 0 25.872-12.24 25.872-27.296l0.016-50.56z" horiz-adv-x="608" /> -<glyph unicode="" d="M277.984 225.616h32.224c15.856 0 28.656 12.848 28.656 28.656v32.256c0 15.808-12.816 28.64-28.656 28.64h-32.224c-15.808 0-28.688-12.832-28.688-28.64v-32.256c0-15.808 12.88-28.656 28.688-28.656zM146.8 250.864h20.544c10.064 0 18.256 8.128 18.256 18.208v20.528c0 10.064-8.176 18.256-18.256 18.256h-20.544c-10.080 0-18.224-8.192-18.224-18.256v-20.528c0-10.080 8.128-18.208 18.224-18.208zM425.328 248.56h21.328c10.48 0 18.992 8.528 18.992 18.992v21.328c0 10.48-8.512 18.992-18.992 18.992h-21.328c-10.48 0-18.976-8.512-18.976-18.992v-21.328c0-10.464 8.496-18.992 18.976-18.992zM469.744 235.472h-67.504c-14.272 0-25.856-12.24-25.856-27.296v-18.896c-7.12 10.016-18.48 16.48-31.264 16.48h-102.032c-11.328 0-21.52-5.072-28.656-13.2v19.376c0 14.464-11.104 26.24-24.896 26.24h-64.928c-13.728 0-24.864-11.776-24.864-26.24v-62.464h20v63.216h5.36v-63.216h62.352v63.216h5.408v-63.216h11.152v-83.040h31.376v99.312h8.464v-99.312h97.984v99.312h8.416v-99.312h33.952c0 0.112 0 1.824 0 21.68v55.136h12.912v65.664h5.648v-65.68h64.832v65.68h5.6v-65.68h22.432c0 0 0 1.184 0 14.336v50.56c-0.016 15.088-11.616 27.328-25.888 27.344v0zM513.376-32h-431.44c-45.952 0-81.936 33.104-81.936 75.376v300.432c0 35.552 25.456 64.624 60.864 72.976 4.448 23.232 15.568 63.216 58.272 63.216h149.84c44.128 0 54.896-38.176 58.592-60.8h185.808c45.952 0 81.952-33.12 81.952-75.392v-300.432c0-42.272-36-75.376-81.952-75.376zM82.192 368.576c-17.808 0-31.584-10.88-31.584-24.784v-300.432c0-13.888 13.744-24.752 31.328-24.752h431.44c17.584 0 31.328 10.864 31.328 24.752v300.432c0 13.904-13.744 24.784-31.328 24.784h-226.544l-5.248 18.336c-1.456 5.12-2.192 10.736-2.944 16.704-3.312 25.76-6.384 25.76-9.664 25.76h-149.84c-0.784 0-1.104-0.096-1.104-0.096-4.192-2.928-7.488-21.84-8.56-28.064-0.896-5.12-1.744-9.984-2.96-14.288l-5.232-18.336-19.088-0.016z" horiz-adv-x="592" /> -<glyph unicode="" d="M366.784 295.552h66.4c32.624 0 59.008 26.416 59.008 58.992v66.448c0 32.576-26.384 59.008-59.008 59.008h-66.4c-32.608 0-59.088-26.416-59.088-59.008v-66.448c0-32.576 26.48-58.992 59.088-58.992zM96.56 347.504h42.32c20.72 0 37.568 16.72 37.568 37.52v42.304c0 20.752-16.832 37.6-37.568 37.6h-42.32c-20.768 0-37.552-16.832-37.552-37.6v-42.304c0-20.784 16.768-37.52 37.552-37.52zM670.272 342.8h43.936c21.584 0 39.136 17.504 39.136 39.088v43.984c0 21.536-17.552 39.056-39.136 39.056h-43.936c-21.584 0-39.024-17.504-39.024-39.056v-43.968c0-21.568 17.44-39.088 39.024-39.088v-0.016zM761.76 315.12h-139.040c-29.392 0-52.848-24.544-52.848-55.552v-38.912c-16.048 20.624-38.496 34.272-64.864 34.272h-210.112c-23.328 0-44.080-10.768-58.128-27.472v39.888c0 29.872-23.824 53.824-52.192 53.824h-133.744c-28.32 0-50.832-23.952-50.832-53.808v-128.784h40.144v130.416h12.032v-130.416h128.416v130.416h10.032v-130.416h24.064v-170.56h64.208v204.688h18.048v-204.688h200.672v204.688h18.048v-204.688h70.24c0 0 0 3.408 0 44.32v114.224h26.080v134.432h12.032v-134.432h132.416v134.432h12.048v-134.432h46.176c0 0 0 1.792 0 28.896v104.176c0 31.008-23.504 55.552-52.928 55.552v-0.048z" horiz-adv-x="816" /> -<glyph unicode="" d="M278.24 265.888h-59.664c-0.56-14.928 2.496-30.48 8.064-46.080h133.184v-205.728h-313.744v205.728h40.912c-6.352 14.656-10.528 30.080-12.48 46.080h-74.512v-297.888h405.904v297.888h-127.664zM263.040 290.752l61.088 105.856-87.728 83.408 2.176-57.088c-30.896-7.12-59.872-17.504-86.048-32.896-27.12-13.824-42.16-35.664-49.296-64.896-9.344-40.352-3.936-76.88 13.696-108.208 18.496-33.088 49.088-65.808 91.392-99.216 17.744-13.376 35.952-25.744 54.496-36.992 18.96-10.128 39.088-20.976 61.312-30.32 0 0-148.368 122.816-129.664 231.312-0.56 15.936 4.144 29.36 12.608 41.184 8.576 11.696 24.416 18.64 44.992 22.096l10.96-54.224z" /> -<glyph unicode="" d="M541.616-31.984h-478.768c-35.248 0-62.848 24.416-62.848 55.568v333.376c0 31.184 27.6 55.6 62.848 55.6h0.272c4.992 17.472 5.328 67.44 41.008 67.44h166.256c40.128 0 36.016-49.984 41.024-67.472h230.208c35.216 0 62.832-24.416 62.832-55.6v-333.376c-0.016-31.136-27.616-55.552-62.832-55.536v0 0z" horiz-adv-x="608" /> -<glyph unicode="" d="M513.376-31.984h-431.44c-45.936 0-81.936 33.104-81.936 75.36v300.416c0 35.552 25.456 64.624 60.864 72.992 4.448 23.232 15.584 63.216 58.272 63.216h149.824c44.128 0 54.896-38.176 58.592-60.8h185.808c45.952 0 81.952-33.12 81.952-75.392v-300.448c0.016-42.256-35.984-75.36-81.936-75.344v0zM82.192 368.592c-17.824 0-31.584-10.88-31.584-24.784v-300.432c0-13.872 13.744-24.752 31.328-24.752h431.44c17.568 0 31.312 10.88 31.312 24.752v300.432c0 13.904-13.744 24.784-31.312 24.784h-226.528l-5.248 18.352c-1.456 5.12-2.192 10.736-2.944 16.672-3.312 25.76-6.384 25.76-9.664 25.76h-149.84c-0.784 0-1.104-0.096-1.104-0.096-4.176-2.944-7.472-21.856-8.56-28.080-0.896-5.12-1.728-9.984-2.96-14.288l-5.232-18.336-19.104 0.016z" horiz-adv-x="592" /> -<glyph unicode="" d="M451.712 380.288l-71.44 71.424c-15.552 15.552-46.288 28.288-68.288 28.288h-240c-22 0-40-18-40-40v-432c0-22 18-40 40-40h368c22 0 40 18 40 40v304c0 22-12.736 52.736-28.288 68.288zM429.088 357.664c1.568-1.568 3.12-3.488 4.64-5.664h-81.728v81.728c2.176-1.52 4.096-3.072 5.664-4.64l71.44-71.424zM448 8c0-4.336-3.664-8-8-8h-368c-4.336 0-8 3.664-8 8v432c0 4.336 3.664 8 8 8h240c2.416 0 5.12-0.304 8-0.848v-127.152h127.152c0.544-2.88 0.848-5.584 0.848-8v-304z" /> -<glyph unicode="" d="M488.896 202.48c-1.376 31.92-6.24 63.984-14.592 96.224-8.864 35.952-21.36 70.032-36.384 101.632-22.928 47.296-45.168 70.784-67.856 69.488-18.272-1.072-29.504-16.64-34.288-47.984-54.544-77.392-155.44-131.136-239.952-167.36-28.736-14.912-42.288-37.28-40.976-67.776 2.848-52.464 18.448-77.968 46.896-76.48 0.848 0.336 2.304 0.384 4.016 1.056 2.32 0.416 3.152 0.704 3.776 0.448 25.52 1.392 45.2-23.072 58.384-73.104 9.952-41.424 20.32-73.856 70.544-71.424 10.992 0.8 15.568 2.992 15.952 7.104-0.72 3.184-73.328 157.36-40.848 158.48 59.184 3.44 158.128 1.84 209.792-29.088 14.576-8.656 24.672-13.184 28.416-12.72 16.56 0.416 27.808 16.080 33.248 45.648 3.52 19.040 4.928 41.232 3.856 65.872zM258.304 148.384c-23.536-0.144-35.728-0.384-37.2-0.432-17.536 2.144-31.648 12.016-41.392 29.936-7.888 14.16-12.432 31.104-13.552 50.848-1.008 23.216 11.76 43.84 39.168 62.16 22.624 15.536 45.456 31.632 68.656 46.896 25.376 18.528 45.216 37.376 59.456 58.080l-2.4-38.8c1.392-39.792 8.944-80.16 22.112-122.304 13.872-45.36 31.472-82.4 53.104-112.016-42.672 17.648-92.128 26.256-147.968 25.616zM78.096 112.992c-18.656 14.016-28.88 35.68-30.432 65.568-1.072 24.704 3.36 42.592 13.312 55.248-28.928-16.944-43.376-25.424-44.24-25.776-12.032-10.976-17.488-26.336-16.64-46.64 0.896-20.304 9.392-34.768 26.224-41.584 10.096-4.528 27.648-6.656 51.776-6.8v0zM647.184 328.832c-4.944 39.888-19.2 73.28-42.384 99.328-23.28 27.504-54.848 44.48-93.488 51.84 32.464-11.68 59.168-37.84 80.976-78.224 17.12-33.296 28.32-70.336 33.568-111.088 5.36-43.712 1.808-83.392-9.936-120.816 27.744 50.896 38 103.968 31.264 158.976v0zM596.944 313.536c-3.712 31.568-14.72 57.824-33.648 79.12-18.688 21.888-43.728 35.92-74.72 41.28 25.68-9.376 47.536-30.544 64.592-62.336 13.648-26.736 23.056-56.608 27.072-89.008 4.4-34.688 1.424-66.832-8.096-96 22.384 40.512 30.528 82.432 24.8 126.944v0zM552.496 298.592c-3.088 24.848-12.16 45.984-27.136 63.376-15.008 17.36-34.976 28.4-59.888 33.184 20.672-7.824 38-24.8 51.328-50.736 11.952-20.96 19.040-44.784 21.904-70.288 3.856-28.048 1.472-53.984-6.256-77.6 17.504 32.736 24.768 66.464 20.032 102.064z" /> -<glyph unicode="" d="M821.568 351.44c-96.128 86.112-216.864 128.56-359.92 128.56-141.968 0-262.688-42.448-359.92-128.56-39.136-35.76-73.808-78.24-101.728-127.456 27.936-50.288 62.608-92.752 101.728-127.424 97.232-86.064 217.952-128.56 359.92-128.56 143.056 0 263.792 42.496 359.92 128.56 40.272 34.672 73.776 77.152 101.728 127.424-27.952 49.216-61.456 91.696-101.728 127.456zM770.16 118.944c-82.736-70.496-185.536-105.088-308.512-105.088-121.872 0-224.704 34.592-308.512 105.088-33.536 29.024-62.608 63.632-87.216 105.040 24.608 40.24 53.664 76.048 87.216 105.088 83.824 70.448 186.64 105.12 308.512 105.12 122.976 0 225.776-34.656 308.512-105.12 34.672-29.040 63.696-64.848 87.168-105.088-23.472-41.408-52.496-76.016-87.168-105.040zM461.648 307.856c-45.808 0-83.84-37.984-83.84-83.872 0-45.808 38.016-83.84 83.84-83.84s83.824 38.048 83.824 83.84c0 45.888-38 83.872-83.824 83.872zM461.648 418.48c-107.296 0-195.6-87.136-195.6-194.496 0-107.296 88.304-195.584 195.6-195.584s195.6 88.304 195.6 195.584c0 107.344-88.272 194.496-195.6 194.496zM461.648 108.864c-63.712 0-115.12 51.408-115.12 115.12 0 63.696 51.408 115.152 115.12 115.152 63.68 0 115.12-51.456 115.12-115.152 0.016-63.712-51.44-115.12-115.12-115.12z" horiz-adv-x="928" /> -<glyph unicode="" d="M130.736 285.056h-126.016c-2.816 0-4.72-1.616-4.72-4.032v-8.448c0-2.416 1.888-4.080 4.72-4.080h13.12v-248.784c0-27.376 22.288-49.92 49.696-49.92 27.36 0 49.648 22.528 49.648 49.92v54.32l-12.736 13.296v-3.52h-73.872v182.128h73.872v-15.568l6.256-6.544 6.48-6.752v31.424h13.568c2.4 0 4.272 1.664 4.272 4.080v8.432c0 2.432-1.872 4.048-4.272 4.048zM126.608 313.536l8.288 1.632c2.384 0.464 3.968 2.848 3.44 5.616l-2.464 12.64 243.792 47.68c26.864 5.264 44.656 31.712 39.408 58.576-5.248 26.864-31.696 44.656-58.56 39.392l-243.808-47.68-2.544 13.072c-0.464 2.352-2.832 3.952-5.216 3.472l-8.288-1.616c-2.368-0.464-3.952-2.832-3.488-5.184l24.176-123.68c0.544-2.752 2.912-4.368 5.28-3.92zM364.224 467.136c6.256 0.496 12.896-0.048 17.76-1.68 5.984-2 10.736-6.592 10.736-6.592l-245.92-109.776-11.52-2.272-14.064 71.904 243.024 48.416zM215.68 4.848l-14.512-14.528-22.4 22.416c2.272-25.6 23.728-45.984 49.856-45.984 27.632 0 50.32 22.72 50.32 50.336v51.056l-63.264-63.296zM250.128 202.368h-58l-0.48 63.792h73.984v-48.288l13.296 13.28v37.008h13.328c2.96 0 4.928 1.984 4.928 4.432v8.416c0 2.432-1.968 4.448-4.928 4.448h-127.28c-2.464 0-4.432-2-4.432-4.448v-8.416c0-2.448 1.968-4.432 4.432-4.432h13.328v-91.968l22.832-22.816 48.992 48.992zM326.896 285.44c-2.464 0-4.432-2-4.432-4.448v-6.304l10.752 10.752h-6.32zM427.536 202.368h-14.368l-72.944-72.96v-112.352c0-27.616 22.672-50.336 50.288-50.336 27.648 0 50.32 22.72 50.32 50.336v212.976l-13.296-13.28v-14.384zM201.136 124.352l-104.976 104.976-52.496-52.464 157.488-157.504 313.52 313.568-52.496 52.464z" /> -<glyph unicode="" d="M213.456 299.792c-2.576 0-4.624-2.080-4.624-4.608v-8.736c0-2.56 2.048-4.592 4.624-4.592h13.84v-86.688l45.008 45.008h-30.656l-0.512 39.616h70.784l20.016 20.016h-118.48zM279.504-31.152c28.672 0 52.24 23.6 52.24 52.272v93.408l-103.456-103.472c4.736-23.936 25.952-42.208 51.216-42.208zM18.8 72.544v-48.496c0-27.072 22.272-49.344 49.376-49.344 13.312 0 25.408 5.424 34.336 14.128l-83.712 83.712zM31.92 207.392v60.32h72.448v-95.632l13.152-13.152v110.752h13.152c2.368 0 4.384 2.016 4.384 4.4v8.352c0 2.4-2 4.384-4.384 4.384h-124.592c-2.784 0-4.8-1.984-4.8-4.384v-8.352c0-2.4 2.016-4.4 4.8-4.4h12.736v-75.392l11.36 11.36 1.76 1.744zM126.592 314.56l8.192 1.6c2.352 0.464 3.936 2.816 3.408 5.552l-2.448 12.496 241.040 47.152c26.576 5.2 44.16 31.344 38.96 57.904-5.184 26.56-31.328 44.16-57.904 38.96l-241.072-47.136-2.528 12.912c-0.448 2.32-2.8 3.904-5.152 3.456l-8.208-1.6c-2.336-0.464-3.904-2.816-3.44-5.152l23.904-122.272c0.544-2.736 2.88-4.32 5.216-3.872zM361.536 466.448c6.208 0.48 12.752-0.064 17.568-1.664 5.904-1.968 10.592-6.512 10.592-6.512l-243.152-108.56-11.392-2.224-13.888 71.088 240.272 47.872zM154.288 81.504l-103.808 103.792-51.904-51.856 155.712-155.744 310 310.080-51.888 51.856z" /> -<glyph unicode="" d="M29.568 102.784v173.424h69.792v-63.072l4.896 4.88 7.76 7.776v52.32h12.672c2.272 0 4.224 1.952 4.224 4.24v8.048c0 2.32-1.952 4.224-4.224 4.224h-120.064c-2.672 0-4.624-1.92-4.624-4.224v-8.048c0-2.32 1.952-4.24 4.624-4.24h12.272v-236.672c0-26.080 21.456-47.552 47.584-47.552 26.048 0 47.552 21.472 47.552 47.552v23.84l-37.504 37.504h-44.96zM120.8 321.36l7.888 1.552c2.272 0.448 3.792 2.72 3.264 5.36l-2.336 12.048 232.288 45.424c25.6 5.024 42.544 30.192 37.552 55.824-5.008 25.616-30.208 42.56-55.792 37.568l-232.336-45.456-2.416 12.448c-0.432 2.224-2.688 3.76-4.944 3.312l-7.904-1.552c-2.256-0.448-3.76-2.688-3.312-4.912l23.056-117.856c0.512-2.608 2.752-4.176 5.024-3.728l-0.032-0.032zM347.168 467.712c5.984 0.464 12.288-0.048 16.944-1.6 5.68-1.888 10.208-6.288 10.208-6.288l-234.32-104.576-10.976-2.176-13.392 68.496 231.536 46.144zM235.904 86.352l-118.32 118.304-59.152-59.104 177.504-177.552 353.408 353.488-59.136 59.12-294.304-294.256z" horiz-adv-x="592" /> -<glyph unicode="" d="M512 480v-192l-69.136 69.136-106-106-53.744 53.744 106 106-69.136 69.136zM122.864 410.864l106-106-53.744-53.744-106 106-69.136-69.136v192h192zM442.864 90.864l69.136 69.136v-192h-192l69.136 69.136-106 106 53.744 53.744zM228.864 143.136l-106-106 69.136-69.136h-192v192l69.136-69.136 106 106z" /> -<glyph unicode="" d="M449.184 11.872h-407.104v296l351.936 0.176 64.416 43.632h-458.432v-383.68h491.28v208.16l-42.096-28.656v-135.632zM227.344 204.512c16.016 9.92 19.536 18.176 6.576 27.28-18.672 4.368-25.136-3.072-31.136-0.416-5.008 12.816-17.104 14.8-24.064 16.528-11.104 2.736-11.104-8.336-20.72-2.784-13.568 7.792-10.592 19.552-33.632 19.392-24.592 0.16-46.464-31.6-16.352-58.32 17.392-11.024 97.28-10.352 119.328-1.68v0zM412.912 124.928l-142.928-28.912c0 0-21.984-4-30.512 8.080-2.672 3.76-3.168 8.048-2.784 12.176-0.096-0.064-0.176-0.144-0.256-0.224-43.52-2.624-44.8 41.84-85.136 29.568-25.408-11.088-40.512-65.104-44.832-110.784 110.56 0 221.12 0 331.68 0-5.44 28.832-14 61.264-25.232 90.096v0zM365.952 239.44l253.888 169.776-9.968 14.944-253.888-169.792 9.968-14.928zM756.688 449.52l-5.312 7.536c-15.488 23.792-47.984 30.192-71.328 13.952l-54.496-36.464 62.56-93.408 54.496 36.48c23.76 15.536 30.16 47.984 14.080 71.904v0zM409.568 175.040l9.552-14.208 253.28 169.904-9.568 14.224-253.264-169.92zM263.84 120.016l139.616 30.4-63.104 93.52-76.512-123.92zM632.816 391.216l-0.544-0.368-4.080 6.304-253.872-169.76 8.144-12.608 1.136 0.768 8.32-13.072-0.672-0.448 9.408-14.784 253.872 169.728-9.2 13.712 0.656 0.464-13.168 20.064z" horiz-adv-x="768" /> -<glyph unicode="" d="M0-32.272l139.104 72.448-93.808 80.864zM426.976 458.72l-7.792 6.48c-23.28 20.72-59.52 18.128-79.568-5.808l-47.216-54.336 93.184-80.896 47.216 54.352c20.688 23.28 18.096 59.504-5.824 80.208zM293.696 376.608l-14.896 12.944-219.92-252.976 14.864-12.944zM138.448 68l14.208-12.304 219.328 252.944-14.224 12.32zM312.592 361.296l-0.48-0.56-6.128 5.488-219.92-252.96 12.272-10.992 0.976 1.136 12.544-11.44-0.592-0.688 14.256-12.96 219.952 252.96-13.696 11.872 0.56 0.672z" /> -<glyph unicode="" d="M521.392 224.224l-99.792 99.824v-72.192h-130.864v130.864h72.72l-99.84 99.792-99.824-99.792h72.176v-130.864h-130.848v72.192l-99.792-99.824 99.792-99.84v72.704h130.848v-130.832h-72.176l99.824-99.808 99.84 99.808h-72.72v130.832h130.864v-72.704z" /> -<glyph unicode="" d="M434.848 321.92c0.064 0.064 0.208 0.16 0.368 0.304l0.208 0.208-0.576-0.512zM0 479.984h107.648c72.96 1.776 98.128-126.624-10.816-129.12h-32.256v-75.312h-64.576v204.432zM64.576 393.92h21.504c32.448 2.192 28.144 42.336 0 43.072h-21.504v-43.072zM182.944 479.984h96.8c124.48-0.96 121.808-205.856 0-204.432h-96.8v204.432zM247.552 436.976v-118.336h10.752c76.368 1.504 75.808 118.704 0 118.336h-10.752zM396.592 479.984h161.456v-43.008h-96.864v-32.24h86.096v-43.104h-86.096v-86.080h-64.592v204.432zM359.792 208.8h-198.656v-77.92h-98.656l197.312-162.944 197.2 162.944h-97.2z" /> -<glyph unicode="" d="M396.944 292.144l-89.216 44.864 61.376 123.024c9.904 19.84 37.92 25.936 62.592 13.616v0c24.704-12.32 36.688-38.368 26.784-58.192l-61.536-123.296zM376.944 224.432l20.848-10.416 88.784 177.888-20.864 10.4-88.768-177.872zM198.768 2.448c5.248 6.096 12.944 14.64 21.728 24.224l-15.888 7.92c-1.968-10.816-3.968-21.664-5.84-32.144zM293.232 104.544l91.184 183.536-68.992 34.432-91.648-183.648c0 0-0.016-0.208-0.032-0.256l69.072-34.464c0.256 0.224 0.384 0.384 0.384 0.384zM222.032 129.36c-2.928-15.888-9.2-49.776-15.76-85.504l20.592-10.304c21.584 23.536 47.424 50.896 59.536 63.664l-64.368 32.144zM313.952 16.752c2.176 12.656 1.504 25.184 0.576 37.888 10.272 1.28 16.464 8.144 23.792 14.576 17.424 15.152-0.080 63.968-24 45.184-9.984-7.84-10.928-37.968-10.736-50.16-8-0.512-9.504 3.44-17.888-0.784 2.224-7.648 11.664-9.952 18.48-9.552 1.008-12.016 1.632-23.392-0.448-35.392-1.296-7.52-2.512-32.528-10.272-38.336-16.496-4.768-20.656 7.552-34.624 6.016 3.184-9.568 14.416-18.208 24.816-18.208 26.736 0 26.736 28.192 30.288 48.768zM313.936 65.024c-0.064 6.688 1.472 41.968 10.48 41.968 22.896 0 6.608-39.296-10.48-41.968zM331.856-21.28c1.2 3.072-0.016 7.376-5.536 9.568h-1.616l-2.528-2.992c-2.672-7.12 1.36-9.28 2.656-9.792l7.024 3.216zM429.968 33.744c-15.408-0.352-32.672 15.584-41.44 27.136 66 26.416-1.264 109.904-35.184 62.256 34.448 9.056 85.008-30.88 25.184-58.096 0.208 17.232-0.032 39.376-0.048 40.656l-10.352-0.112c0.464-30.32-10.336-80.784-0.048-98.896 6.704 16.224 10.144 32.896 10.32 50.016 21.664-16.928 31.36-32.080 61.088-33.344l0.512 10.336c-3.552 0.192-6.88 0.112-10.016 0.048-10.224-0.24 3.136 0.064 0 0zM453.232 36.4l-1.904 7.344-1.824-2.816 1.456 2.912c-0.96 0.48-5.696 3.264-5.712 3.296l-5.232-8.944c4.528-2.656 7.376-4.32 9.52-4.32 1.456 0 2.576 0.752 3.68 2.512zM473.952 143.392l-10.272-1.408c4.528-33.536 5.376-59.808-0.928-93.888-0.672-3.616-1.328-7.168-1.952-10.688l10.208-1.776c6.688 38.096 8.064 69.776 2.944 107.744zM505.264 120.896c17.952 21.968-4.272 46.752-25.088 51.568-22.24 5.152-28.432-5.808-29.232-7.424l-6.896-16.736 9.568-3.936 6.624 16.144c0.032 0.064 3.52 5.12 17.6 1.856 34.176-7.888 22.224-33.36 1.84-47.952 67.936-8.208 22.944-48.192-8.64-71.056l6.064-8.4c16.464 11.904 89.84 73.616 28.144 85.936zM556.24 115.408c32.48-38.304 37.104 13.152 45.984 30.528 0.192-0.304 16.464-21.984 21.424-20.592 4.656 7.232 6.592 14.864 5.824 22.912 11.344-45.856 62.064 21.488 29.184 31.392-23.984 7.296-40.48-14.928-39.52-35.152-12.672 19.088-19.408 12.368-29.776 0.832-2.352 1.856-5.008 2.592-7.968 2.16 15.584-59.552-12.48-7.664-32.464-12.496-5.168-1.216-17.696-45.648-18.944-50.672l10.016-2.608c3.664 11.68 10.64 22.864 16.224 33.712zM629.92 157.232c-0.784 9.264 18.736 14.592 25.744 12.48 5.728-1.728-1.856-45.040-18.512-9.2l-7.232-3.28zM633.216 55.12c25.984 0 65.040 126.528 82.96 149.888-0.912-6.352-1.504-16 0.288-22.576l10 2.704c-2.384 8.656 4.832 30.992-10.336 31.136-15.648-0.704-12.464-34.288-23.536-41.152 9.344 68.112-60.384-7.2-14.528-11.664-7.472-8.88-16.544-15.584-20.128-24.656v0c-0.592-6.704-61.472-83.648-24.72-83.648v0zM658.768 115.536c0.128-19.008-8.608-39.392-25.056-49.712-11.28 11.216 16.48 43.344 25.056 49.712 0.016-2.976-1.52-1.136 0 0zM675.168 174.496c-0.8 9.568-3.232 11.808 2.576 17.904 5.168-5.488 6.512-11.808 4-19.008-2.192 0.224-4.368 0.576-6.512 1.088-0.048 0-0.064 0-0.080 0zM747.216 201.488c7.232-7.616-16.848-18.528-11.968-18.288 5.856 0.288 23.456 12.064 25.28 16.608 2.896 7.264-3.36 13.632-9.104 11.408-21.568-8.336-7.216 20.608-6.176 22.128-6.336-9.296-19.36-12.032-14.208-28.352zM257.888 415.392c9.84 19.68-2.064 45.552-26.608 57.808v0c-24.496 12.24-52.304 6.16-62.128-13.52l-60.96-122.16 88.592-44.576 61.104 122.448zM176.928 225.728l20.704-10.352 88.16 176.656-20.72 10.336-88.144-176.64zM0 5.328c5.216 6.016 12.848 14.528 21.568 24.048l-15.76 7.872c-1.968-10.736-3.952-21.536-5.808-31.92zM93.808 106.688l90.544 182.272-68.496 34.176-91.008-182.352c0 0-0.016-0.208-0.032-0.256l68.592-34.224c0.24 0.224 0.384 0.384 0.384 0.384zM23.104 131.328c-2.912-15.792-9.152-49.408-15.648-84.896l20.448-10.208c21.424 23.344 47.088 50.544 59.104 63.216l-63.904 31.888z" /> -<glyph unicode="" d="M113.76-32l-113.76 112.848 142.432 143.648-142.208 142.208 113.296 113.296 255.072-255.040-254.832-256.96zM397.664-32l-113.76 112.848 142.448 143.648-142.192 142.208 113.296 113.296 255.056-255.040-254.848-256.96z" horiz-adv-x="656" /> -<glyph unicode="" d="M92.128 144.336c15.632 1.184 26.624 3.44 32.992 6.688 10.64 5.664 18.112 16.4 22.4 32.208l77.12 278.496c-40.48 0-67.232-3.056-80.272-9.152-13.040-6.112-28.208-24.608-45.536-55.536l-9.264 1.808 21.888 81.152h281.328l-23.184-86.048-9.28 1.296 1.296 18.288c0 16.144-3.664 28.208-10.992 36.208-7.312 7.984-21.808 11.984-43.488 11.984h-29.44l-73.92-262.528c-1.712-5.664-3.008-10.736-3.856-15.184-1.536-6.704-2.32-12.032-2.32-15.968 0-10.32 3.168-16.704 9.536-19.2 6.336-2.48 18.784-3.984 37.344-4.496v-8.496h-152.352v8.48zM0 82.88v26.032h301.616v-26.032h-301.616zM561.216 208.544l-49.12 49.104-95.712-95.76-95.76 95.76-49.088-49.104 95.76-95.728-95.76-95.712 49.088-49.104 95.76 95.712 95.712-95.712 49.12 49.104-95.744 95.712z" horiz-adv-x="560" /> -<glyph unicode="" d="M373.92 462.080c20.944-18.128 23.216-49.856 5.088-70.224l-41.344-47.616-81.616 70.848 41.344 47.584c17.584 20.96 49.312 23.232 69.696 5.088l6.832-5.68zM244.176 401.488l-192.608-221.536 12.992-11.328 192.64 221.552-13.024 11.312zM75.36 159.568l10.736-9.648 192.64 221.52-10.768 9.648-192.608-221.52zM97.456 140.32l12.464-11.344 192.608 221.504-13.056 11.328-192.016-221.488zM121.248 119.904l192.048 221.536 12.448-10.784-192.048-221.52-12.448 10.768zM121.808 95.552l-121.808-63.44 39.664 134.256 82.144-70.816zM291.024 361.472l-17.28 15.28-192.224-220.832 22.576-20.624zM543.52 208.544l-49.12 49.088-95.712-95.744-95.76 95.744-49.088-49.088 95.76-95.728-95.76-95.728 49.088-49.088 95.76 95.712 95.712-95.712 49.12 49.088-95.744 95.728z" horiz-adv-x="544" /> -<glyph unicode="" d="M416.576 413.36c0 24.896-16.912 45.52-38.368 45.984l-0.16-0.032-22.544 0.064 0.032 15.184c0.016 2.944-1.376 5.344-3.056 5.36l-36.272 0.080c-1.712 0.016-3.104-2.4-3.104-5.328l-0.048-15.2-32.784 0.080 0.032 15.008c0.016 2.944-1.376 5.344-3.056 5.36l-36.32 0.080c-1.712 0.016-3.104-2.4-3.104-5.328l-0.032-15.008-48.032 0.112 0.048 14.784c0.016 2.944-1.376 5.344-3.056 5.36l-36.288 0.080c-1.712 0.016-3.104-2.4-3.104-5.328l-0.032-14.8-38.128 0.096 0.032 14.592c0 2.944-1.376 5.344-3.072 5.36l-36.288 0.080c-1.712 0.016-3.104-2.4-3.104-5.328l-0.032-14.592-27.36 0.064c-20.016 0-36.864-18.976-38.336-42.688l-1.024-402.656c-0.080-25.248 17.056-45.872 38.224-45.968l0.288-0.032 338.656-0.832c20.64 0 37.888 20.064 38.448 44.736l0.096 0.176-0.080 1.008 0.96 399.456zM218.656 375.024h17.088l23.2-48.688 23.072 48.688h17.088v-90.032h-17.344v52.48l-16.96-34.128h-11.728l-17.072 34.128v-52.464h-17.344v90.016zM117.488 375.024h17.088l23.2-48.688 23.072 48.688h17.088v-90.032h-17.344v52.48l-16.976-34.128h-11.68l-17.12 34.128v-52.464h-17.328v90.016zM377.2 14.16l-0.016-0.976c-0.176-3.264-1.28-5.312-2.016-6.272l-334.8 0.864c-0.8 1.024-1.968 3.296-1.952 6.928l0.512 218.32h338.8l-0.528-218.864z" horiz-adv-x="416" /> -<glyph unicode="" d="M694.976 446.432h-224.944c-21.824 0-40.288-18.464-40.288-40.288v-132.624c0-21.824 18.464-40.288 40.288-40.288h224.944c21.824 0 40.288 18.464 40.288 40.288v132.624c0 21.824-18.464 40.288-40.288 40.288zM318.944 179.52h-224.944c-21.824 0-40.288-18.464-40.288-40.288v-132.624c0-21.824 18.464-40.288 40.288-40.288h224.944c21.824 0 40.288 18.464 40.288 40.288v132.624c0 21.824-18.464 40.288-40.288 40.288zM694.976 179.52h-224.944c-21.824 0-40.288-18.464-40.288-40.288v-132.624c0-21.824 18.464-40.288 40.288-40.288h224.944c21.824 0 40.288 18.464 40.288 40.288v132.624c0 21.824-18.464 40.288-40.288 40.288zM0 480h342.448v-45.328h-342.448v45.328zM0 387.664h342.448v-45.328h-342.448v45.328zM0 295.344h342.448v-45.328h-342.448v45.328z" horiz-adv-x="736" /> -<glyph unicode="" d="M512.576 393.12l-86.912 86.88-169.36-169.424-169.456 169.424-86.848-86.88 169.44-169.376-169.44-169.36 86.848-86.88 169.456 169.376 169.36-169.376 86.912 86.88-169.408 169.36z" /> -<glyph unicode="" d="M96.064 147.744h28.448c-1.136 5.376-2.32 11.072-3.52 17.008h-24.928v-17.008zM97.984 103.696h35.872l-3.6 17.008h-32.272v-17.008zM97.984 76.624h239.072v-17.008h-239.072v17.008zM156.704 144.032c19.040 15.872 6.64 9.904 24.208 19.68 0 0-15.088 137.536 125.84 209.024 22.88 8.48 73.52 21.040 136.112-3.824l-37.44-34.384 139.072 11.152 10.976 129.936-36.928-35.808c-37.024 16.768-76.24 29.376-118.384 36.272-41.184 8.816-80.224 2.48-120.24-15.392-54.736-24.832-91.056-57.248-110.272-94.608-20.016-39.232-28.336-86.848-26.464-143.6 1.632-23.328 8.832-56.192 13.552-78.432v0zM633.488 389.392h-54.48l-3.888-46.080h58.368c25.408 0 46.096-20.672 46.096-46.080v-140c0-25.408-20.672-46.080-46.096-46.080h-231.024c-25.408 0-46.080 20.672-46.080 46.080v140c0 0.88 0.256 1.696 0.272 2.56 0.56 32.048 22.848 52.656 22.848 52.656-3.632 0.256-7.264 0.368-10.88 0.368-18.336 0.016-33.2-3.184-44.080-6.56-8.976-14.224-14.24-30.976-14.24-49.024v-4.88h-57.328c-12.608-15.312-21.456-31.088-27.664-46.096h84.992v-81.504h-98.64l1.872-17.008h97.248c0 0.016 0 0.016 0 0.032 0.976-9.536 3.424-18.64 7.072-27.072h-141.232c-0.112-0.096-0.176-0.144-0.272-0.24l-20.096-16.768h171.28c10.384-14.528 24.864-25.856 41.776-32.384-0.032 0.016-0.080 0.016-0.112 0.032v-11.168c0-25.408-20.672-46.080-46.080-46.080h-231.008c-25.408 0-46.080 20.672-46.080 46.080v140.016c0 25.392 20.672 46.064 46.080 46.064h20.176c0.288 16.16 1.504 31.456 3.52 46.096h-23.68c-50.896 0-92.16-41.264-92.16-92.16v-140.016c0-50.912 41.264-92.16 92.16-92.16h231.040c50.896 0 92.16 41.248 92.16 92.16v4.896h218.192c50.896 0 92.16 41.28 92.16 92.16v140c0 50.896-41.264 92.16-92.16 92.16l-0.064-0.016zM322.256 111.936c0.032-0.064 0.080-0.112 0.112-0.16-0.032 0.064-0.080 0.112-0.112 0.16zM377.12 68.656c0 0 0.016 0 0 0 0.016 0 0 0 0 0zM385.168 66.736c0.592-0.128 1.2-0.176 1.808-0.288-0.592 0.096-1.216 0.16-1.808 0.288zM393.6 65.504c2.944-0.304 5.888-0.448 8.896-0.448-3.008 0-5.952 0.144-8.896 0.448zM406.432 261.792h242.896v-17.008h-242.896v17.008zM408.352 217.744h239.072v-17.024h-239.072v17.024zM408.352 173.712h239.072v-17.024h-239.072v17.024z" horiz-adv-x="720" /> -<glyph unicode="" d="M512.016 249.36c0 6.496-5.36 11.792-11.808 11.792h-21.584c-6.528 0-13.376 5.056-15.2 11.264l-29.376 68.624c-3.136 5.6-2.096 13.952 2.464 18.576l14.608 14.576c4.608 4.592 4.608 12.128 0 16.672l-35.12 35.168c-4.576 4.624-12.048 4.624-16.768 0l-15.792-15.872c-4.624-4.592-13.104-5.872-18.8-2.864l-59.728 23.856c-6.224 1.76-11.36 8.56-11.36 15.008v22.16c0 6.448-5.296 11.712-11.728 11.712h-49.856c-6.448 0-11.76-5.264-11.76-11.712v-22.16c0-6.448-5.104-13.312-11.248-15.232l-69.248-29.6c-5.536-3.264-13.808-2.176-18.448 2.4l-15.536 15.536c-4.56 4.56-12.032 4.56-16.656 0l-35.184-35.2c-4.656-4.592-4.656-12.096 0-16.672l16.864-16.992c4.672-4.56 5.92-12.928 2.944-18.72l-23.552-59.152c-1.728-6.304-8.496-11.36-14.992-11.36h-23.504c-6.432 0.016-11.712-5.28-11.712-11.776v-49.76c0-6.512 5.296-11.856 11.728-11.856h23.504c6.496 0 13.28-5.024 15.2-11.232l28.864-68.112c3.328-5.6 2.208-13.888-2.288-18.528l-16.192-16.064c-4.608-4.592-4.608-12.032 0-16.688l35.216-35.184c4.64-4.56 12.144-4.56 16.608 0l17.296 17.2c4.624 4.608 12.912 5.856 18.672 2.736l60.4-24.080c6.144-1.792 11.248-8.56 11.248-15.008v-23.040c0-6.448 5.312-11.76 11.76-11.76h49.856c6.416 0 11.728 5.312 11.728 11.76v23.040c0 6.448 5.088 13.216 11.344 15.136l67.52 28.64c5.6 3.2 13.84 2.064 18.512-2.496l15.232-15.264c4.576-4.56 12.048-4.56 16.672 0l35.216 35.216c4.608 4.56 4.608 12.096 0 16.672l-16.256 16.176c-4.48 4.624-5.76 12.976-2.736 18.736l24.464 60.88c1.728 6.24 8.576 11.264 15.104 11.328h21.584c6.448 0 11.808 5.296 11.808 11.792l-0.048 49.744zM256.048 140.272c-46.304 0-83.728 37.52-83.728 83.728 0 46.272 37.44 83.696 83.728 83.696 46.176 0 83.696-37.44 83.696-83.696 0-46.192-37.536-83.728-83.696-83.728zM976.88 224.016l-173.248-201.168-173.216 201.168z" horiz-adv-x="976" /> -<glyph unicode="" d="M512.048 249.36c0 6.48-5.36 11.776-11.792 11.776h-21.584c-6.528 0-13.36 5.056-15.184 11.28l-29.376 68.592c-3.136 5.616-2.096 13.984 2.48 18.592l14.608 14.576c4.592 4.592 4.592 12.096 0 16.688l-35.152 35.184c-4.576 4.608-12.048 4.608-16.784 0l-15.792-15.872c-4.624-4.608-13.104-5.872-18.816-2.848l-59.728 23.808c-6.24 1.792-11.36 8.56-11.36 15.024v22.16c0 6.48-5.296 11.728-11.712 11.728h-49.84c-6.448 0-11.76-5.264-11.76-11.728v-22.144c0-6.464-5.12-13.296-11.248-15.232l-69.248-29.616c-5.568-3.264-13.84-2.192-18.464 2.384l-15.536 15.552c-4.576 4.576-12.032 4.576-16.656 0l-35.2-35.2c-4.656-4.592-4.656-12.096 0-16.688l16.88-16.976c4.656-4.56 5.952-12.928 2.928-18.72l-23.52-59.152c-1.744-6.304-8.512-11.344-15.008-11.344h-23.488c-6.432 0-11.728-5.296-11.728-11.776v-49.792c0-6.496 5.28-11.84 11.728-11.84h23.488c6.496 0 13.28-5.024 15.2-11.232l28.88-68.080c3.312-5.616 2.208-13.92-2.304-18.528l-16.208-16.096c-4.592-4.608-4.592-12.016 0-16.688l35.216-35.184c4.608-4.576 12.096-4.576 16.608 0l17.296 17.216c4.608 4.576 12.896 5.856 18.672 2.752l60.4-24.096c6.144-1.792 11.248-8.56 11.248-15.008v-23.040c0-6.48 5.296-11.776 11.76-11.776h49.84c6.4 0 11.712 5.296 11.712 11.776v23.040c0 6.448 5.072 13.232 11.36 15.136l67.52 28.64c5.6 3.152 13.84 2.032 18.512-2.496l15.216-15.296c4.576-4.576 12.048-4.576 16.672 0l35.2 35.232c4.592 4.56 4.592 12.064 0 16.656l-16.256 16.176c-4.48 4.608-5.744 12.976-2.736 18.72l24.464 60.88c1.744 6.256 8.576 11.28 15.104 11.328h21.584c6.4 0 11.792 5.296 11.792 11.792v49.792l0.080-0.016zM256.080 140.288c-46.32 0-83.728 37.504-83.728 83.728 0 46.24 37.408 83.68 83.728 83.68 46.176 0 83.712-37.44 83.712-83.68 0-46.224-37.536-83.728-83.712-83.728z" /> -<glyph unicode="" d="M29.952 113.424v295.056h89.184c-43.952-4.544-75.856-18.224-75.856-34.4h215.648c0 16.176-31.92 29.84-75.856 34.384h89.184v-295.056h-55.12v-29.952h62.272c12.592 0 22.816 10.224 22.816 22.816v309.344c0 12.608-10.224 22.8-22.816 22.8h-97.968v14.544c0 14.944-12.112 27.040-27.024 27.040-14.944 0-27.056-12.096-27.056-27.040v-14.544h-104.544c-12.608 0-22.816-10.208-22.816-22.8v-309.328c0-12.592 10.208-22.816 22.816-22.816h61.888v29.952h-54.752zM154.416 466.608c7.664 0 13.856-6.208 13.856-13.856 0-7.664-6.208-13.872-13.856-13.872s-13.872 6.192-13.872 13.856c0 7.648 6.208 13.872 13.872 13.872zM178.144 194.752h-54.48v-140.704l-57.408-0.736 83.28-85.312 86.416 87.392-57.808 1.344z" horiz-adv-x="304" /> -<glyph unicode="" d="M256.576-29.904c-137.728 0-249.808 112.064-249.808 249.808 0 137.728 112.064 249.808 249.808 249.808 137.728 0 249.808-112.064 249.808-249.808 0-137.744-112.064-249.808-249.808-249.808zM256.576 461.888c-133.424 0-242-108.56-242-242s108.56-242 242-242c133.44 0 242 108.544 242 242 0 133.44-108.544 242-242 242zM61.056 255.456l86.016 86.736 109.504-108.576 108.416 108.4 86.368-86.384-194.432-194.432z" /> -<glyph unicode="" d="M256.576-28.368c-139.456 0-252.896 113.456-252.896 252.896s113.456 252.896 252.896 252.896 252.896-113.456 252.896-252.896-113.456-252.896-252.896-252.896zM256.576 445.84c-122.016 0-221.28-99.264-221.28-221.28s99.264-221.28 221.28-221.28 221.28 99.264 221.28 221.28-99.248 221.28-221.28 221.28z" /> -<glyph unicode="" d="M62.256 351.472l36.704-36.72v5.008h180.592l72 72h-324.592v-75.568l7.008 7.008zM378.72 40h-141.296l-50.656-50.704-50.688 50.704h-37.12v37.12l-2.736 2.752-69.264 69.248v-181.12h423.76v285.344l-72-72zM186.736 170.384l-124.48 124.528-62.256-62.256 186.752-186.784 371.872 371.952-62.256 62.176z" horiz-adv-x="560" /> -<glyph unicode="" d="M585.392 480l-365.136-365.12-146.832 146.8-73.424-73.36 220.288-220.32 438.528 438.624-73.424 73.376z" horiz-adv-x="656" /> -<glyph unicode="" d="M435.44 455.104l-10.912-12.592c-6.976-8.032-11.12-11.984-14.384-14.768-0.624-1.040-1.584-2.64-3.056-5.152l-7.36-12.4c84.672-22.4 147.376-99.44 147.376-191.040 0-109.040-88.752-197.76-197.84-197.76-46.48 0-89.2 16.24-123.008 43.168v0l-10.736-32.176-39.472 5.168c45.104-43.040 106.096-69.552 173.2-69.552 138.528 0 251.232 112.672 251.232 251.136 0 108.256-68.816 200.72-165.040 235.968v0zM374.96 228.432v172.992h-53.376v-200.96h5.744l101.952-100.928 37.568 37.952-91.888 90.944zM172 454.912c-38.96-19.184-73.376-56.288-100.544-112.72-19.584-41.28-27.312-81.792-19.536-124.832 5.808-44.032 2.752-36.112 18.8-75.056l-70.72-49.376 193.488-25.36 59.6 178.832-98.304-53.376c-0.88 2.432-1.568 4.72-2.336 7.056-19.68 60.736-0.624 89.488 8.432 112.24 77.776 145.136 218.528 126.4 218.528 126.4 10.528 18.080 4.048 5.312 20.912 24.768-22.624 5.392-56.192 13.616-80.080 15.824-58.208 3.168-107.36-4.448-148.24-24.4z" horiz-adv-x="608" /> -<glyph unicode="" d="M185.408 373.104c-0.816 13.872-3.648 27.648-8.48 41.36-6.816 19.696-10.272 33.264-10.272 40.736 0 10.448 2.48 18.368 7.376 23.824 4.912 5.44 11.056 8.128 18.288 8.128 6.208 0 11.664-2.704 16.304-8.128 4.608-5.456 6.976-13.216 6.976-23.184 0-9.088-2.704-21.712-7.984-37.92-5.424-16.16-8.672-31.136-9.856-44.8 11.088 7.056 21.008 15.568 29.888 25.632 13.696 15.904 23.808 25.776 30.512 29.584 6.576 3.84 13.328 5.696 20.224 5.696 6.544 0 12.16-2.256 16.688-6.768 4.528-4.512 6.848-9.872 6.848-16.128 0-7.44-3.328-14.096-10.016-19.872-6.592-5.872-23.264-11.696-49.776-17.568-15.488-3.392-28.304-7.312-38.608-11.728 10.448-5.424 23.264-9.568 38.368-12.384 24.304-4.384 40.256-9.92 47.792-16.56 7.536-6.672 11.312-13.92 11.312-21.744 0-6.048-2.288-11.264-6.8-15.712s-9.776-6.656-15.776-6.656c-6.048 0-12.784 2.128-20.080 6.384-7.376 4.16-17.296 13.648-29.744 28.352-8.224 9.808-18.528 19.088-30.816 27.712 0.432-11.488 2.768-23.952 6.976-37.424 7.216-23.744 10.88-39.936 10.88-48.576 0-7.984-2.432-14.864-7.264-20.336-4.832-5.568-9.952-8.32-15.392-8.32-7.456 0-14.208 2.912-20.224 8.736-4.224 4.256-6.336 10.944-6.336 20.208 0 9.648 2.352 21.264 6.992 34.896 4.608 13.536 7.488 22.896 8.704 28.064 1.216 5.12 2.352 12.688 3.36 22.72-11.92-7.824-22.256-16.56-31.104-26.24-14.736-16.48-25.712-26.96-33.184-31.392-5.248-3.168-10.688-4.832-16.304-4.832-6.848 0-12.672 2.352-17.504 6.944-4.832 4.672-7.232 9.776-7.232 15.392 0 5.040 2.016 10.272 6.192 15.824 4.096 5.52 10.256 10.096 18.544 13.776 5.392 2.336 17.808 5.584 37.136 9.6 12.48 2.608 24.592 6.432 36.496 11.488-10.928 5.392-23.888 9.648-38.976 12.672-24.688 5.2-39.984 9.952-45.84 14.16-9.040 6.64-13.568 14.704-13.568 24.128 0 5.456 2.304 10.448 6.736 14.944 4.56 4.512 9.84 6.816 15.872 6.816 6.656 0 13.696-2.144 21.12-6.352 7.44-4.256 16.72-12.736 27.744-25.536 11.104-12.72 22.368-22.592 33.84-29.648zM245.6 268.288l-0.8 1.296 0.128-0.8-0.64 0.496 0.752-1.328 29.088-229.92 53.072 61.664 78.944-136.72 22.976 13.312-78.896 136.688 79.888 15.152z" /> -<glyph unicode="" d="M471.664 207.552l-431.344 232.080 232.368-431.248z" /> -<glyph unicode="" d="M489.024 160.384l-100.72-101.552-128.224 127.152-126.96-126.944-101.12 101.136 227.664 227.68z" /> -<glyph unicode="" d="M220.144 54.976l-58.896 58.416 73.728 74.352-73.616 73.616 58.64 58.64 132.032-132.016z" /> -<glyph unicode="" d="M32 286.304l100.72 101.552 128.224-127.152 126.96 126.944 101.12-101.136-227.664-227.68z" /> -<glyph unicode="" d="M30.64 447.184l95.424-177.088 28.912 28.944 298.992-298.864 27.216 27.28-298.944 298.848 25.536 25.568z" /> -<glyph unicode="" d="M616.496 480h-424.96c-26.608 0-48.192-21.584-48.192-48.224v-67.872c0 0-1.536-6.112-2.544-8.288-1.072-2.288-5.232-7.824-5.232-7.824l-117.92-98.832c0 0-17.808-15.264-17.632-24.992 0.176-9.44 17.632-23.2 17.632-23.2l117.952-91.744c0 0 4.144-5.184 5.232-7.36 1.056-2.176 2.528-8.32 2.528-8.32v-77.184c0-26.624 21.568-48.176 48.192-48.176h424.96c26.624 0 48.208 21.552 48.208 48.176v415.6c-0.016 26.64-21.584 48.224-48.208 48.224zM358.336 396.72h76.272v-98.96l-20.080-158.736h-36.592l-19.6 158.736v98.96zM437.2 28.736h-80.912v79.376h80.912v-79.376z" horiz-adv-x="672" /> -<glyph unicode="" d="M442.992 79.28c-80.816 6.896-81.824 88.080-88 168.4-4.448 57.84-36.848 93.728-71.296 119.84-4.096 1.056-9.696 1.936-16.128 2.656 11.44 11.664 18.528 27.6 18.528 45.2 0 35.696-28.944 64.624-64.608 64.624s-64.624-28.928-64.624-64.608c0-17.872 7.248-34.048 18.992-45.744-6.768-0.944-12.512-2.144-16.576-3.648-40.016-25.472-68.896-67.472-72.816-125.92-5.024-74.672-8.416-155.568-86.48-159.28 0-20.224 0-40.448 0-60.672 23.792 0 92.512 0 169.392 0 0-28.784 23.328-52.128 52.112-52.128s52.112 23.344 52.112 52.128c76.88 0 145.6 0 169.392 0-0.016 19.712-0.016 39.424-0.016 59.152zM221.504 439.616c13.36 0 24.224-10.88 24.224-24.224s-10.864-24.224-24.224-24.224-24.224 10.88-24.224 24.224 10.864 24.224 24.224 24.224z" horiz-adv-x="448" /> -<glyph unicode="" d="M875.84 410.288c0 26.048-17.936 47.632-40.656 48.112l-0.176-0.032-23.936 0.064 0.048 15.904c0.016 3.088-1.456 5.616-3.248 5.632l-38.496 0.048c-1.808 0.016-3.264-2.496-3.264-5.584l-0.048-15.904-34.8 0.080 0.048 15.696c0.016 3.088-1.472 5.616-3.248 5.632l-38.496 0.064c-1.808 0.016-3.296-2.496-3.296-5.584l-0.032-15.696-50.928 0.112 0.032 15.472c0.016 3.088-1.44 5.616-3.232 5.632l-38.496 0.048c-1.808 0.016-3.296-2.496-3.296-5.584l-0.032-15.472-40.448 0.096 0.048 15.248c0 3.088-1.472 5.616-3.264 5.632l-38.48 0.064c-1.808 0.016-3.296-2.496-3.312-5.584l-0.048-15.248-28.992 0.064c-21.216 0-39.12-19.856-40.64-44.672l-0.288-106.816h122.080v-86.176h277.696l-0.56-199.776v-1.024c-0.192-3.424-1.36-5.552-2.16-6.56l-355.056 0.896c-0.864 1.088-2.080 3.456-2.080 7.248l0.304 123.376h-40.72l-0.32-123.264c-0.080-26.448 18.064-48.912 40.528-49.024h359.488c21.872 0 41.2 21.008 41.792 46.832v389.968zM643.968 275.952h-18.416v54.896l-17.984-35.712h-12.448l-18.128 35.712v-54.896h-18.384v94.208h18.128l24.592-50.928 24.48 50.928h18.144v-94.208zM751.248 275.952h-18.384v54.896l-17.984-35.712h-12.448l-18.144 35.712v-54.896h-18.368v94.208h18.128l24.592-50.928 24.48 50.928h18.128v-94.208zM628.944 193.072v-47.024c-3.44 3.824-7.168 6.512-11.184 8.032s-8.672 2.288-13.936 2.288c-5.024 0-9.728-0.832-14.144-2.48-4.448-1.664-8.080-3.936-10.992-6.848-2.496-2.512-4.496-5.488-5.952-8.912-1.44-3.44-2.496-7.088-3.152-10.928-0.672-3.824-1.072-7.76-1.184-11.792-0.128-4.032-0.208-7.984-0.208-11.792 0-3.84 0.064-7.808 0.208-11.92 0.112-4.096 0.512-8.064 1.184-11.904 0.64-3.84 1.712-7.44 3.152-10.816 1.456-3.376 3.44-6.384 5.952-9.040 2.912-2.912 6.608-5.2 11.088-6.832 4.48-1.664 9.216-2.496 14.24-2.496 5.536 0 10.272 0.848 14.24 2.496 3.968 1.648 7.728 4.464 11.296 8.432l-0.016-9.712h25.408v141.296h-26zM628.352 91.744c-0.384-3.648-1.2-6.784-2.464-9.424-1.232-2.656-3.024-4.736-5.312-6.256-2.304-1.52-5.328-2.288-9.136-2.288-3.792 0-6.816 0.768-9.12 2.288-2.288 1.52-4.016 3.6-5.2 6.256-1.168 2.624-1.952 5.776-2.352 9.424s-0.592 7.584-0.592 11.808c0 4.224 0.208 8.112 0.592 11.696s1.168 6.688 2.352 9.344c1.168 2.624 2.912 4.704 5.2 6.24 2.304 1.52 5.328 2.288 9.12 2.288 3.808 0 6.832-0.768 9.136-2.288 2.288-1.52 4.048-3.616 5.312-6.24 1.232-2.64 2.048-5.76 2.464-9.344s0.592-7.472 0.592-11.696c0-4.224-0.192-8.176-0.592-11.808zM740.272 146.032c-3.424 3.824-7.168 6.512-11.168 8.032-4.016 1.52-8.672 2.288-13.936 2.288-5.024 0-9.728-0.832-14.16-2.48s-8.064-3.936-10.96-6.848c-2.496-2.512-4.496-5.488-5.952-8.912-1.456-3.44-2.496-7.088-3.168-10.928-0.656-3.824-1.072-7.76-1.184-11.792s-0.192-7.984-0.192-11.792c0-3.84 0.048-7.808 0.192-11.92s0.528-8.064 1.184-11.904 1.712-7.44 3.168-10.816c1.456-3.376 3.44-6.384 5.952-9.040 2.912-2.912 6.608-5.2 11.072-6.832 4.496-1.664 9.232-2.496 14.256-2.496 5.536 0 10.272 0.848 14.24 2.496 3.952 1.648 7.712 4.464 11.296 8.432l-0.016-9.712h25.408v141.296h-26v-47.072zM739.696 91.744c-0.384-3.648-1.2-6.784-2.48-9.424-1.232-2.656-3.024-4.736-5.312-6.256s-5.328-2.288-9.12-2.288-6.832 0.768-9.12 2.288-4.016 3.6-5.2 6.256c-1.168 2.624-1.968 5.776-2.352 9.424-0.384 3.648-0.592 7.584-0.592 11.808 0 4.224 0.208 8.112 0.592 11.696 0.368 3.584 1.168 6.688 2.352 9.344 1.168 2.624 2.912 4.704 5.2 6.24s5.328 2.288 9.12 2.288 6.832-0.768 9.12-2.288 4.048-3.616 5.312-6.24c1.248-2.64 2.064-5.76 2.48-9.344 0.368-3.584 0.576-7.472 0.576-11.696 0-4.224-0.208-8.176-0.576-11.808zM525.456 274.48h-203.408v203.408h-118.656v-203.408h-203.408v-101.696h203.408v-204.736l118.656-0.032v204.784h203.408z" horiz-adv-x="880" /> -<glyph unicode="" d="M782.928 206.864h-24.528c-22.144-16.768-49.712-26.944-79.632-26.944-29.952 0-57.488 10.176-79.040 26.944h-17.376c-2.576 0-5.152-0.176-7.712-0.368v-69.68h-83.024c-2.064-7.664-3.248-15.648-3.248-23.92v-125.168h388.608v125.168c-0.016 51.488-41.888 93.968-94.016 93.968zM679.92 435.728c-65.696 0-118.816-53.056-118.816-118.784 0-10.464 1.488-20.56 4-30.24 2.304-8.736 5.456-17.104 9.568-24.96 19.824-38.064 59.472-64.208 105.296-64.208 66.256 0 119.376 53.696 119.376 119.36 0 65.712-53.12 118.784-119.376 118.784l-0.032 0.032zM527.648 275.744h-204.256v204.256h-119.152v-204.256h-204.256v-102.128h204.256v-205.6l119.152-0.032v205.632h204.256z" horiz-adv-x="880" /> -<glyph unicode="" d="M635.824 98.592c-0.096-0.048-0.4-0.304-0.64-0.464l-0.928-0.928 1.568 1.408zM795.152 413.056c0.144 0.112 0.432 0.336 0.832 0.608l0.432 0.4-1.264-1.008zM843.472 291.248h-280.272v-44.576h280.272v44.576zM411.92 109.856h431.552v-44.576h-431.552v44.576zM411.92 381.92h431.552v-44.592h-431.552v44.592zM843.472 200.528h-280.272v-44.656h280.272v44.656zM411.92 472.608h431.552v-44.592h-431.552v44.592zM411.92 19.168h431.552v-44.64h-431.552v44.64zM308.288 480h-104.512v-203.776h-203.776v-104.448h203.776v-203.76l104.512-0.016v203.792h203.744v104.48h-203.744z" horiz-adv-x="848" /> -<glyph unicode="" d="M772.448 458.704h-296.784c-61.728 0-111.744-50.032-111.744-111.76v-41.856h55.872v41.856c0 30.8 25.072 55.872 55.872 55.872h296.784c30.832 0 55.872-25.072 55.872-55.872v-220.496c0-30.784-25.072-55.872-55.872-55.872h-296.784c-30.832 0-55.872 25.104-55.872 55.872v20.768h-55.872v-20.768c0-61.728 50-111.76 111.744-111.76h296.784c61.712 0 111.744 50.032 111.744 111.76v220.496c0 61.712-50.048 111.76-111.744 111.76zM586.8 250.784h37.248v-229.952h-37.248v229.952zM558.992 278.064h296.784v-37.248h-296.784v37.248zM527.648 275.744h-204.256v204.256h-119.152v-204.256h-204.256v-102.128h204.256v-205.6l119.152-0.032v205.632h204.256zM654.384 219.968c12.096 0.080 10.528-6.080 17.648-10.176 5.040-2.928 5.040 2.912 10.896 1.456 3.664-0.896 9.984-1.936 12.608-8.688 3.168-1.408 6.576 2.512 16.352 0.224 6.832-4.784 4.976-9.12-3.44-14.336-11.584-4.56-53.552-4.912-62.688 0.864-15.792 14.032-4.288 30.72 8.608 30.64v0zM772.112 188.56c23.552-3.904 40.112-52.272 47.104-89.216-58.080 0-116.144 0-174.224 0 2.288 23.984 10.224 52.352 23.552 58.176 21.2 6.464 21.856-16.896 44.736-15.504 20.912 14.432 16.848 49.456 58.848 46.544v0z" horiz-adv-x="880" /> -<glyph unicode="" d="M458.368 462.368v-154.656h48.368l-0.096 26.8h79.6v81.12h249.28v-371.984h-328.544v81.2h-48.624v-127.92h425.856v465.424h-425.84zM506.992 355.952v59.696h59.696l-59.696-59.696zM643.216 56.832h137.328v71.504h-137.328v-71.504zM662.128 109.712h99.488v-34.304h-99.488v34.304zM643.216 157.312h137.328v71.536h-137.328v-71.536zM662.128 210.224h99.488v-34.272h-99.488v34.272zM643.216 257.792h137.328v71.52h-137.328v-71.52zM662.128 310.704h99.488v-34.272h-99.488v34.272zM615.392 90.528c-0.576 1.856-1.28 3.472-2.16 4.896-0.88 1.392-1.856 2.608-2.976 3.632-1.088 1.040-2.208 1.904-3.344 2.672 1.056 0.688 2.064 1.44 3.056 2.336 0.992 0.864 1.872 1.92 2.656 3.2 0.8 1.248 1.44 2.72 1.92 4.416 0.496 1.712 0.736 3.664 0.736 5.872 0 3.488-0.624 6.72-1.904 9.648-1.296 2.96-3.136 5.504-5.456 7.632-2.336 2.096-5.088 3.76-8.224 4.912-3.168 1.168-6.624 1.776-10.4 1.776-3.648 0-7.024-0.56-10.176-1.664-3.168-1.088-5.904-2.704-8.256-4.816-2.352-2.128-4.192-4.72-5.552-7.744-1.36-3.040-2.048-6.448-2.048-10.224h18.64c0 2.432 0.736 4.288 2.224 5.632 1.472 1.312 3.2 1.968 5.168 1.968 1.968 0 3.696-0.64 5.184-1.92 1.472-1.28 2.192-3.216 2.192-5.792 0-1.824-0.592-3.552-1.776-5.184-1.168-1.632-3.184-2.432-5.968-2.432h-2.624v-16.16h2.624c2.48 0 4.576-0.816 6.192-2.432 1.616-1.648 2.448-3.664 2.448-6.080 0-2.88-0.784-5.024-2.352-6.48-1.552-1.408-3.536-2.144-5.968-2.144-2.352 0-4.304 0.688-5.92 2.096-1.584 1.392-2.384 3.536-2.384 6.416h-18.656c0-4.544 0.8-8.432 2.336-11.664 1.552-3.216 3.584-5.856 6.144-7.824 2.512-2.016 5.408-3.488 8.624-4.448 3.216-0.96 6.496-1.424 9.824-1.424 3.568 0 6.976 0.512 10.24 1.552 3.248 1.056 6.128 2.576 8.576 4.608 2.48 2.048 4.448 4.608 5.92 7.728s2.208 6.768 2.208 11.008c0 2.432-0.288 4.576-0.848 6.416l0.032 0.032zM589.872 175.056h27.376v-16.816h-27.376v16.816zM590.208 212.24c2.272 0 4.032-0.64 5.344-1.888 1.28-1.264 1.92-2.928 1.92-5.056 0-1.76-0.736-3.44-2.16-5.056-1.312-1.456-3.168-3.136-5.424-4.928v-20.048l9.552 7.312c2.48 1.872 4.768 3.76 6.816 5.552 2.032 1.824 3.808 3.68 5.28 5.52 1.504 1.872 2.608 3.776 3.408 5.76s1.184 4.096 1.184 6.368c0 3.664-0.688 6.912-1.984 9.792-1.328 2.864-3.168 5.328-5.504 7.36-2.368 1.984-5.104 3.536-8.24 4.592-3.168 1.072-6.56 1.584-10.176 1.584-0.112 0-0.24-0.016-0.336-0.016v-16.816c0.096-0.016 0.224 0.016 0.336 0.016v-0.016zM601.104 320.816h-18.64l-11.296-9.84h18.704v-58.048h11.232v67.872zM527.648 275.744h-204.256v204.256h-119.152v-204.256h-204.256v-102.128h204.256v-205.6l119.152-0.032v205.632h204.256z" horiz-adv-x="880" /> -<glyph unicode="" d="M625.040 449.632c-119.568 0-219.472-55.792-244.768-140.288h186.944v-169.52l-136.176 0.016c9.648-8.864 20.288-17.104 31.904-24.496 6.912-4.432 14.16-8.56 21.68-12.416 9.664-7.136-10.912-56.848-84.352-110.752 60.256 0 150.576 28.096 224.768 78.384 150.576 17.248 251.152 84.832 251.152 189.504 0.016 104.704-112.432 189.552-251.136 189.552zM527.648 275.744h-204.256v204.256h-119.152v-204.256h-204.256v-102.128h204.256v-205.6l119.152-0.032v205.632h204.256z" horiz-adv-x="880" /> -<glyph unicode="" d="M405.008 480v-181.168h45.52l0.16 33.568h102.512l-0.464 103.728h206.448v-424.256h-308.496v137.328h-45.664v-181.2h399.84v511.984h-399.856zM450.672 352.496v83.664h83.616l-83.616-83.664zM308.288 480h-104.496v-203.776h-203.792v-104.432h203.776v-203.76l104.496-0.016v203.776h203.728v104.464h-203.712v203.728z" horiz-adv-x="800" /> -<glyph unicode="" d="M843.664 438.928h-342.64c-22.368 0-40.528-18.128-40.528-40.544v-57.088c0 0-1.28-5.136-2.128-6.96-0.912-1.904-4.416-6.576-4.416-6.576l-32.528-27.264h141.12v-153.696h-134.112l25.52-19.84c0 0 3.488-4.336 4.416-6.192 0.88-1.824 2.128-6.976 2.128-6.976v-64.912c0-22.368 18.144-40.496 40.528-40.496h342.656c22.384 0 40.528 18.112 40.528 40.496v349.52c-0.016 22.4-18.144 40.544-40.544 40.544zM527.648 275.744h-204.256v204.256h-119.152v-204.256h-204.256v-102.128h204.256v-205.6l119.152-0.032v205.632h204.256z" horiz-adv-x="880" /> -<glyph unicode="" d="M884.096 142.032c-9.696 44.736-29.648 132.288-37.472 137.36l-282.256 183.84c-10.512 6.832-24.624 3.84-31.472-6.656l-89.408-137.392h131.792v-151.072l139.648-90.96c2.656-1.696 31.984 3.28 31.984 3.28l12.080 2.512c-0.416-0.336 60.96 14.48 87.616 21.552 8.64 2.304 16.624 4.432 23.2 6.176 12.128 3.344 17.68 15.84 14.288 31.344zM833.664 156.384c-5.536-19.008-25.424-29.952-44.448-24.448-19.008 5.536-29.952 25.424-24.432 44.448s25.424 29.952 44.448 24.432c19.008-5.52 29.936-25.408 24.432-44.416zM802.336 143.904c4.752-8.688 10.704-29.12 10.704-58.592s-5.952-49.936-10.704-58.608c-4.752 8.688-10.688 29.136-10.688 58.608s5.92 49.904 10.688 58.592zM802.336 164.304c-15.296 0-27.712-35.376-27.712-78.992s12.416-79.008 27.712-79.008 27.728 35.376 27.728 79.008c0 43.632-12.432 78.992-27.728 78.992v0zM527.648 275.744h-204.256v204.256h-119.152v-204.256h-204.256v-102.128h204.256v-205.6l119.152-0.032v205.632h204.256z" horiz-adv-x="880" /> -<glyph unicode="" d="M830.656 300.272v0zM372.752 434.896v-128.224h52.144v73.888h407.12v-304.992h-407.104v70.32h-52.176v-124.688h511.44v413.696l-511.44 0.016zM566.272 309.52c17.504 0.128 15.248-8.8 25.536-14.72 7.312-4.224 7.312 4.208 15.744 2.128 5.296-1.312 14.48-2.832 18.272-12.544 4.56-2.048 9.488 3.632 23.68 0.304 9.84-6.912 7.168-13.168-5.008-20.72-16.768-6.608-77.456-7.12-90.672 1.264-22.896 20.288-6.24 44.448 12.448 44.288v0zM736.512 264.096c34.080-5.616 58.048-75.6 68.096-129.056-84 0-167.984 0-251.968 0 3.264 34.688 14.752 75.728 34.048 84.16 30.656 9.328 31.632-24.448 64.688-22.448 30.272 20.88 24.384 71.552 85.136 67.328v0zM638.048 161.712c-0.048-0.032-0.24-0.176-0.352-0.272l-0.528-0.528 0.88 0.8zM652.576 125.376c0 0-0.016-0.016-0.032-0.032-0.32-0.32-0.512-0.496-0.512-0.496l0.544 0.528zM527.648 275.744h-204.256v204.256h-119.152v-204.256h-204.256v-102.128h204.256v-205.6l119.152-0.032v205.632h204.256z" horiz-adv-x="880" /> -<glyph unicode="" d="M788.224 404.528h-152.496c-3.056 18.56-11.872 49.904-48.096 49.904h-122.96c-35.056 0-44.192-32.816-47.824-51.888-29.056-6.848-49.936-30.72-49.936-59.888v-39.52h41.536v39.52c0 11.408 11.296 20.336 25.92 20.336h15.664l4.32 15.040c0.992 3.504 1.712 7.504 2.432 11.696 0.912 5.104 3.6 20.64 7.040 23.056 0 0 0.256 0.064 0.912 0.064h122.96c2.688 0 5.232 0 7.936-21.152 0.64-4.88 1.248-9.488 2.432-13.696l4.304-15.040h185.904c14.416 0 25.696-8.944 25.696-20.336v-246.544c0-11.392-11.296-20.32-25.696-20.32h-354.144c-14.416 0-25.728 8.912-25.728 20.32v49.904h-41.536v-49.888c0-34.672 29.536-61.84 67.248-61.84h354.080c37.696 0 67.264 27.168 67.264 61.84v246.544c0 34.704-29.552 61.888-67.248 61.888v0zM308.272 480h-104.496v-203.776h-203.792v-104.464h203.792v-203.744l104.496-0.032v203.776h203.728v104.496h-203.728z" horiz-adv-x="848" /> -<glyph unicode="" d="M527.648 275.744h-204.256v204.256h-119.152v-204.256h-204.256v-102.128h204.256v-205.6l119.152-0.032v205.632h204.256zM842.448 409.616c-66.592 66.608-143.696 40.64-176.608 10.464-26.32-24.112-82.352-76.256-121.472-110.288h17.328v-48.352c34.048 43.952 96.368 99.504 123.824 124.224 6.928 6.24 75.632 59.824 135.088 0.336 59.424-59.392 5.344-116.752-0.912-123.088 0.016 0.016-179.584-184.384-218.432-216.304-31.456-25.856-96.848-58.128-166.672 11.968-25.344 25.424-33.456 46.976-34.624 81.024h-30.944c3.152-51.056 21.712-86.272 41.728-104.608 86.256-78.992 170.496-46.208 208.224-9.92 56.928 54.736 223.44 218.816 223.44 218.816 29.44 29.44 67.344 98.4 0 165.744zM530.864 309.792l83.584 75.952-25.12 29.44-112.752-105.392h25.664zM463.216 139.584h-33.024c3.792-17.024 10.8-39.024 23.776-51.536 41.936-40.416 105.824-46.8 140.864-14.176 48.416 45.072 170.016 169.344 170.016 169.344l-23.568 23.328c0 0-143.072-149.344-168.656-168.768-21.056-15.968-62.064-13.568-92.688 12.784-7.52 6.464-13.328 12-16.72 29.024z" horiz-adv-x="880" /> -<glyph unicode="" d="M772.448 458.704h-296.784c-61.728 0-111.744-50.032-111.744-111.76v-41.856h55.872v41.856c0 30.8 25.072 55.872 55.872 55.872h296.784c30.832 0 55.872-25.072 55.872-55.872v-220.496c0-30.784-25.072-55.872-55.872-55.872h-296.784c-30.832 0-55.872 25.104-55.872 55.872v20.768h-55.872v-20.768c0-61.728 50-111.76 111.744-111.76h296.784c61.712 0 111.744 50.032 111.744 111.76v220.496c0 61.712-50.048 111.76-111.744 111.76zM586.8 250.784h37.248v-229.952h-37.248v229.952zM558.992 278.064h296.784v-37.248h-296.784v37.248zM527.648 275.744h-204.256v204.256h-119.152v-204.256h-204.256v-102.128h204.256v-205.6l119.152-0.032v205.632h204.256z" horiz-adv-x="880" /> -<glyph unicode="" d="M835.2 432c0 25.6-17.6 48-40 48v0h-356.8c-20.8 0-38.4-19.2-40-44.8v-120h40v116.8c0 3.2 1.6 6.4 1.6 6.4l353.6-1.6c1.6-1.6 1.6-3.2 1.6-8l-1.6-416v-1.6c0-3.2-1.6-4.8-1.6-6.4l-352 1.6c-1.6 1.6-1.6 3.2-1.6 8v115.2h-40v-115.2c0-25.6 17.6-48 40-48v0l355.2 1.6c22.4 0 40 20.8 40 46.4v0 1.6l1.6 416zM793.6-11.2v20.8c0 0 0 0 0 0v-20.8zM721.6 396.8h-217.6c-9.6 0-17.6-4.8-17.6-9.6v-72h62.4v-54.4h172.8c9.6 0 17.6 4.8 17.6 9.6v116.8c0 6.4-8 9.6-17.6 9.6zM380.8 384h70.4c3.2 0 4.8 1.6 4.8 3.2v38.4c0 1.6-3.2 3.2-4.8 3.2h-70.4c-3.2 0-4.8-1.6-4.8-3.2v-38.4c-1.6-1.6 1.6-3.2 4.8-3.2zM456 334.4c0 1.6-3.2 3.2-4.8 3.2h-70.4c-3.2 0-4.8-1.6-4.8-3.2v-19.2h81.6l-1.6 19.2zM374.4 116.8c0-1.6 3.2-3.2 4.8-3.2h70.4c3.2 0 4.8 1.6 4.8 3.2v16h-81.6l1.6-16zM451.2 68.8h-70.4c-3.2 0-4.8-1.6-4.8-3.2v-38.4c0-1.6 3.2-3.2 4.8-3.2h70.4c3.2 0 4.8 1.6 4.8 3.2v38.4c0 1.6-1.6 3.2-4.8 3.2zM307.2 478.4h-104v-203.2h-203.2v-102.4h203.2v-203.2h104v203.2h201.6v102.4h-201.6z" horiz-adv-x="835" /> -<glyph unicode="" d="M609.6 308.8l-67.2 33.6 57.6 116.8c9.6 19.2 32 25.6 51.2 17.6v0c19.2-9.6 25.6-32 17.6-51.2l-59.2-116.8zM604.702 237.709l-15.741 7.873 84.45 168.863 15.741-7.873-84.45-168.863zM430.4 30.4c4.8 6.4 11.2 14.4 19.2 24l-12.8 6.4c-3.2-11.2-4.8-20.8-6.4-30.4zM512 129.6l86.4 174.4-52.8 25.6-86.4-174.4c0 0 0 0 0 0l52.8-25.6c0 0 0 0 0 0zM457.6 147.2c-3.2-14.4-11.2-46.4-19.2-78.4l16-8c19.2 22.4 41.6 49.6 52.8 62.4l-49.6 24zM27.2-9.6h492.8v-16h-492.8v16zM49.6 136c17.6-20.8 28.8-44.8 43.2-67.2 11.2-17.6 20.8-40 41.6-46.4 8-1.6 35.2 11.2 17.6 14.4-8 1.6-11.2 11.2-16 17.6-8 11.2-16 22.4-22.4 33.6-11.2 19.2-22.4 38.4-36.8 56-6.4 11.2-33.6 1.6-27.2-8v0zM54.4 38.4c32 33.6 70.4 60.8 92.8 102.4 6.4 12.8-22.4 9.6-27.2 1.6-20.8-38.4-57.6-65.6-88-97.6-12.8-14.4 16-14.4 22.4-6.4v0zM220.8 38.4c41.6 22.4 88 54.4 110.4 96 24 44.8-32 54.4-59.2 28.8-25.6-24-24-67.2-3.2-92.8 28.8-33.6 64 14.4 73.6 38.4 3.2 9.6-9.6 12.8-16 9.6-30.4-11.2-59.2-36.8-48-72 12.8-36.8 60.8-11.2 80 3.2 4.8 3.2 8 9.6 1.6 12.8-3.2 1.6-6.4 3.2-11.2 3.2-9.6 1.6-30.4-12.8-14.4-19.2 24-8 48-9.6 73.6-8 16 1.6 24 20.8 3.2 19.2-20.8-1.6-40 0-59.2 6.4-4.8-6.4-9.6-12.8-14.4-19.2 0 0 0 0 0 0 0 4.8 1.6 9.6 1.6 12.8-40-30.4-43.2 28.8-8 41.6-4.8 3.2-11.2 6.4-16 9.6-6.4-17.6-17.6-40-28.8-12.8-6.4 16-6.4 40 4.8 54.4 12.8-1.6 17.6-6.4 11.2-16-3.2-6.4-6.4-11.2-11.2-16-8-9.6-17.6-17.6-25.6-25.6-17.6-16-38.4-30.4-59.2-41.6-16-6.4 0-19.2 14.4-12.8v0z" horiz-adv-x="688" /> -<glyph unicode="" d="M438.4 308.8l-67.2 33.6 57.6 116.8c9.6 19.2 32 25.6 51.2 17.6v0c19.2-9.6 25.6-32 17.6-51.2l-59.2-116.8zM432.956 237.804l-15.745 7.865 84.375 168.9 15.745-7.865-84.375-168.9zM257.6 30.4c4.8 6.4 11.2 14.4 19.2 24l-12.8 6.4c-1.6-11.2-3.2-20.8-6.4-30.4zM340.8 129.6l86.4 174.4-52.8 25.6-86.4-172.8c0 0 0 0 0 0l52.8-27.2c0 0 0 0 0 0zM286.4 147.2c-3.2-14.4-11.2-46.4-19.2-78.4l16-8c19.2 22.4 41.6 49.6 52.8 62.4l-49.6 24zM27.2-9.6h246.4v-16h-246.4v16zM49.6 38.4c41.6 22.4 88 54.4 110.4 96 24 44.8-32 54.4-59.2 28.8-25.6-24-24-67.2-3.2-92.8 28.8-33.6 64 14.4 73.6 38.4 3.2 9.6-9.6 12.8-16 9.6-30.4-11.2-59.2-36.8-48-72 12.8-36.8 60.8-11.2 80 3.2 4.8 3.2 8 9.6 1.6 12.8-3.2 1.6-6.4 3.2-11.2 3.2-9.6 1.6-30.4-12.8-14.4-19.2 24-8 48-9.6 73.6-8 16 1.6 24 20.8 3.2 19.2-20.8-1.6-40 0-59.2 6.4-4.8-6.4-9.6-12.8-14.4-19.2 0 0 0 0 0 0 0 4.8 1.6 9.6 1.6 12.8-40-30.4-43.2 28.8-8 41.6-4.8 3.2-11.2 6.4-16 9.6-6.4-17.6-17.6-40-28.8-12.8-6.4 16-6.4 40 4.8 54.4 12.8-1.6 17.6-6.4 11.2-16-3.2-6.4-6.4-11.2-11.2-16-8-9.6-17.6-17.6-25.6-25.6-17.6-16-38.4-30.4-59.2-41.6-16-6.4 0-19.2 14.4-12.8v0zM755.2 308.8l-67.2 33.6 57.6 116.8c9.6 19.2 32 25.6 51.2 17.6v0c19.2-9.6 25.6-32 17.6-51.2l-59.2-116.8zM749.559 237.88l-15.749 7.86 84.318 168.938 15.749-7.86-84.318-168.938zM574.4 30.4c4.8 6.4 11.2 14.4 19.2 24l-12.8 6.4c-1.6-11.2-3.2-20.8-6.4-30.4zM657.6 129.6l86.4 174.4-52.8 25.6-86.4-174.4c0 0 0 0 0 0l52.8-25.6c0 0 0 0 0 0zM603.2 147.2c-3.2-14.4-11.2-46.4-19.2-78.4l16-8c19.2 22.4 41.6 49.6 52.8 62.4l-49.6 24zM342.4-9.6h246.4v-16h-246.4v16zM366.4 38.4c41.6 22.4 88 54.4 110.4 96 24 44.8-32 54.4-59.2 28.8-25.6-24-24-67.2-3.2-92.8 28.8-33.6 64 14.4 73.6 38.4 3.2 9.6-9.6 12.8-16 9.6-30.4-11.2-59.2-36.8-48-72 12.8-36.8 60.8-11.2 80 3.2 4.8 3.2 8 9.6 1.6 12.8-3.2 1.6-6.4 3.2-11.2 3.2-9.6 1.6-30.4-12.8-14.4-19.2 24-8 48-9.6 73.6-8 16 1.6 24 20.8 3.2 19.2-20.8-1.6-40 0-59.2 6.4-4.8-6.4-9.6-12.8-14.4-19.2 0 0 0 0 0 0 0 4.8 1.6 9.6 1.6 12.8-40-30.4-43.2 28.8-8 41.6-4.8 3.2-11.2 6.4-16 9.6-6.4-17.6-17.6-40-28.8-12.8-6.4 16-6.4 40 4.8 54.4 12.8-1.6 17.6-6.4 11.2-16-3.2-6.4-6.4-11.2-11.2-16-8-9.6-17.6-17.6-25.6-25.6-17.6-16-38.4-30.4-59.2-41.6-16-6.4 0-19.2 14.4-12.8v0z" horiz-adv-x="834" /> -<glyph unicode="" d="M260.8 342.4c-3.2 1.6-6.4 4.8-9.6 6.4-11.2-9.6-20.8-19.2-28.8-28.8 17.6-1.6 30.4-17.6 30.4-35.2v-246.4c0-19.2-16-35.2-35.2-35.2h-145.6c-19.2 0-35.2 16-35.2 35.2v246.4c0 19.2 16 35.2 35.2 35.2h56c3.2 11.2 8 24 12.8 35.2h-68.8c-40 1.6-72-30.4-72-70.4v-246.4c0-38.4 32-70.4 72-70.4h147.2c40 0 72 32 72 72v244.8c0 11.2-3.2 22.4-8 30.4-6.4 11.2-12.8 20.8-22.4 27.2zM113.6 283.2h60.8v-12.8h-60.8v12.8zM81.6 238.4h128v-12.8h-128v12.8zM81.6 193.6h128v-12.8h-128v12.8zM108.8 56h72v-27.2h-72v27.2zM552 356.8h-64l-9.6-28.8-1.6-6.4h76.8c19.2 0 35.2-16 35.2-35.2v-246.4c0-19.2-16-35.2-35.2-35.2h-147.2c-19.2 0-35.2 16-35.2 35.2v244.8c0 8 3.2 16 8 20.8l-38.4 3.2c-3.2-8-4.8-16-4.8-25.6v-246.4c0-40 32-72 72-72h147.2c40 0 72 32 72 72v248c-3.2 40-35.2 72-75.2 72zM448 283.2h60.8v-12.8h-60.8v12.8zM416 240h128v-12.8h-128v12.8zM416 198.4h128v-12.8h-128v12.8zM416 155.2h128v-12.8h-128v12.8zM416 113.6h128v-12.8h-128v12.8zM443.2 56h72v-27.2h-72v27.2zM379.2 464c-19.2 14.4-40 19.2-64 14.4-32-6.4-75.2-32-92.8-56-17.6-24-44.8-72-56-113.6 0 0 38.4 83.2 123.2 104 27.2 4.8 64 6.4 88-36.8l-35.2-25.6 97.6-9.6 32 91.2-40-20.8c-16 20.8-33.6 38.4-52.8 52.8z" horiz-adv-x="624" /> -<glyph unicode="" d="M204.8 152c0-1.6 0-1.6 0 0 0-1.6 0-1.6 0 0zM92.8 254.4v-19.2h73.6l17.6 19.2zM94.4 345.6h166.4v-17.6h-166.4v17.6zM228.8 299.2h-134.4v-17.6h116.8l3.2 3.2zM137.6 208h-43.2v-17.6h59.2l-16 16zM94.4 161.6v-17.6h105.6l-17.6 17.6zM38.4 84.8v270.4h86.4v86.4l41.6 1.6h132.8v-187.2l38.4-38.4v262.4h-337.6v-432h168l36.8 36.8h-166.4zM38.4 443.2h70.4l-70.4-70.4v70.4zM481.6 206.4l-49.6 49.6-94.4-96-96 96-48-49.6 96-94.4-96-94.4 48-49.6 96 94.4 94.4-94.4 49.6 49.6-94.4 94.4z" horiz-adv-x="482" /> -<glyph unicode="" d="M472 356.8v0 0c-6.4 9.6-9.6 17.6-9.6 30.4 0 14.4 3.2 24 11.2 32 6.4 8 16 11.2 27.2 11.2 12.8 0 22.4-4.8 28.8-12.8s11.2-20.8 9.6-36.8h-54.4c0-6.4 1.6-11.2 4.8-14.4s8-4.8 12.8-4.8c3.2 0 6.4 1.6 8 3.2 1.6 1.6 4.8 4.8 4.8 9.6l22.4-6.4c11.2-3.2 22.4-9.6 32-22.4 1.6 6.4 3.2 14.4 3.2 20.8v35.2c0 43.2-35.2 78.4-78.4 78.4h-416c-43.2 0-78.4-35.2-78.4-78.4v-33.6c0-44.8 35.2-80 78.4-80h368v19.2c0 19.2 11.2 38.4 25.6 49.6zM112 345.6h-19.2v12.8c-3.2-4.8-8-8-12.8-11.2s-9.6-3.2-16-3.2c-4.8 0-11.2 1.6-14.4 3.2-3.2 3.2-4.8 4.8-8 11.2-1.6 4.8-3.2 9.6-3.2 17.6v51.2h22.4v-38.4c0-11.2 0-19.2 1.6-20.8 1.6-3.2 1.6-4.8 4.8-6.4 1.6-1.6 4.8-1.6 8-1.6s6.4 0 9.6 3.2c3.2 3.2 3.2 4.8 4.8 8s1.6 9.6 1.6 22.4v33.6h20.8v-81.6zM204.8 355.2c-6.4-8-14.4-11.2-24-11.2-4.8 0-8 1.6-12.8 3.2-3.2 1.6-8 4.8-11.2 9.6v-41.6h-22.4v112h20.8v-11.2c3.2 4.8 6.4 8 11.2 9.6 4.8 3.2 9.6 3.2 14.4 3.2 9.6 0 17.6-3.2 24-11.2s9.6-17.6 9.6-32c0-11.2-3.2-22.4-9.6-30.4zM307.2 345.6h-20.8v12.8c-3.2-4.8-8-9.6-11.2-11.2-4.8-3.2-9.6-3.2-14.4-3.2-9.6 0-17.6 3.2-24 11.2s-9.6 17.6-9.6 32 3.2 24 9.6 32c6.4 8 14.4 11.2 25.6 11.2 9.6 0 17.6-3.2 24-11.2v40h22.4v-113.6h-1.6zM377.6 345.6c0 1.6-1.6 3.2-1.6 6.4 0 1.6 0 1.6 0 3.2-4.8-3.2-8-6.4-12.8-8s-8-3.2-12.8-3.2c-8 0-14.4 1.6-19.2 6.4-4.8 4.8-8 9.6-8 17.6 0 4.8 1.6 8 3.2 12.8 1.6 3.2 4.8 6.4 9.6 8 3.2 1.6 9.6 3.2 17.6 4.8 9.6 1.6 17.6 3.2 20.8 4.8v3.2c0 4.8-1.6 6.4-3.2 9.6-1.6 1.6-6.4 3.2-11.2 3.2-3.2 0-6.4 0-9.6-1.6-1.6-1.6-3.2-4.8-4.8-8l-19.2 3.2c1.6 8 6.4 14.4 11.2 17.6 4.8 3.2 12.8 6.4 24 6.4 9.6 0 17.6-1.6 22.4-3.2 4.8-1.6 8-4.8 9.6-8s3.2-9.6 3.2-19.2v-25.6c0-8 0-12.8 1.6-16 0-3.2 1.6-6.4 3.2-11.2l-22.4-6.4-1.6 3.2zM428.8 344c-3.2 1.6-4.8 4.8-6.4 6.4-1.6 1.6-3.2 4.8-3.2 8s0 8 0 16v36.8h-9.6v16h9.6v16l22.4 12.8v-28.8h14.4v-17.6h-14.4v-33.6c0-6.4 0-11.2 0-11.2 0-1.6 4.8-9.6 12.8-3.2l1.6-17.6c-4.8-1.6-9.6-4.8-17.6-3.2-4.8 1.6-4.8 0-9.6 3.2zM174.4 412.8c-4.8 0-9.6-1.6-12.8-6.4-3.2-3.2-6.4-9.6-6.4-17.6 0-9.6 1.6-16 4.8-20.8s8-6.4 12.8-6.4 8 1.6 12.8 6.4c4.8 4.8 6.4 9.6 6.4 19.2 0 8-1.6 14.4-4.8 19.2s-8 6.4-12.8 6.4zM267.2 412.8c-4.8 0-9.6-1.6-12.8-6.4s-4.8-9.6-4.8-17.6 1.6-14.4 3.2-19.2c3.2-6.4 8-8 14.4-8 4.8 0 9.6 1.6 12.8 6.4 3.2 4.8 4.8 11.2 4.8 19.2 0 9.6-1.6 16-4.8 20.8-3.2 3.2-8 4.8-12.8 4.8zM348.8 377.6c-3.2-1.6-4.8-4.8-4.8-8s1.6-6.4 3.2-8 4.8-3.2 8-3.2 8 1.6 11.2 3.2 4.8 4.8 4.8 6.4 1.6 4.8 1.6 11.2v6.4c-1.6-1.6-6.4-1.6-12.8-3.2-4.8-1.6-9.6-3.2-11.2-4.8zM513.6 408c-3.2 3.2-6.4 4.8-11.2 4.8s-8-1.6-11.2-4.8c-3.2-3.2-4.8-8-4.8-14.4h32c0 6.4-1.6 11.2-4.8 14.4zM684.8 174.4v0 0 38.4c-8 28.8-28.8 30.4-35.2 30.4-1.6 0-1.6 0-3.2 0h-1.6c-8 12.8-20.8 20.8-36.8 20.8-6.4 0-12.8-1.6-17.6-3.2-8 8-17.6 12.8-30.4 12.8-1.6 0-3.2 0-6.4 0v16c0 14.4 0 52.8-36.8 52.8h-3.2c-22.4 0-40-16-40-35.2v-88c-8 6.4-16 8-25.6 8-6.4 0-11.2-1.6-16-1.6-9.6-1.6-19.2-9.6-24-17.6-4.8-9.6-4.8-22.4 0-33.6l28.8-83.2 3.2-6.4 46.4-70.4 11.2-30.4 6.4-16h142.4l4.8 17.6 30.4 121.6c1.6 8 1.6 24 0 52.8 3.2 8 3.2 12.8 3.2 14.4zM660.8 113.6l-30.4-121.6h-108.8l-12.8 33.6-49.6 73.6-28.8 84.8c-3.2 8 0 17.6 6.4 19.2 4.8 1.6 8 1.6 11.2 1.6 4.8 0 9.6-1.6 14.4-8l22.4-49.6c0-1.6 3.2-3.2 4.8-3.2 3.2 0 6.4 1.6 6.4 4.8l-1.6 156.8c0 6.4 6.4 11.2 16 11.2 1.6 0 1.6 0 3.2 0 8 0 12.8-1.6 12.8-30.4v-104c0-3.2 3.2-3.2 6.4-3.2 3.2 0 6.4 1.6 6.4 3.2v54.4c0 6.4 6.4 11.2 16 11.2s16-4.8 16-11.2v-49.6c0-3.2 3.2-4.8 8-4.8s9.6 1.6 8 4.8v40c0 6.4 6.4 11.2 16 11.2v0c9.6 0 12.8-4.8 12.8-11.2v-51.2c0-3.2 3.2-4.8 4.8-4.8 3.2 0 6.4 1.6 6.4 4.8v30.4c0 6.4 4.8 12.8 12.8 12.8h1.6c6.4 0 9.6-4.8 12.8-12.8v-30.4c6.4-3.2 8-51.2 6.4-62.4z" horiz-adv-x="685" /> -</font></defs></svg> \ No newline at end of file diff --git a/unittests/example_labfolder_data/static/font/icons11.ttf b/unittests/example_labfolder_data/static/font/icons11.ttf deleted file mode 100644 index b956ee714be5bdfde6b4998de03bfc2b085ddeb0..0000000000000000000000000000000000000000 Binary files a/unittests/example_labfolder_data/static/font/icons11.ttf and /dev/null differ diff --git a/unittests/example_labfolder_data/static/font/icons11.woff b/unittests/example_labfolder_data/static/font/icons11.woff deleted file mode 100644 index 2f54cb21f8b7434e3ffd4f08f9a41b40e2cf68d7..0000000000000000000000000000000000000000 Binary files a/unittests/example_labfolder_data/static/font/icons11.woff and /dev/null differ diff --git a/unittests/example_labfolder_data/static/font/redactor-font.eot b/unittests/example_labfolder_data/static/font/redactor-font.eot deleted file mode 100644 index be2a55b38dea4c0522f935541adde23cd56b8ed4..0000000000000000000000000000000000000000 Binary files a/unittests/example_labfolder_data/static/font/redactor-font.eot and /dev/null differ diff --git a/unittests/example_labfolder_data/static/img/favicon2.ico b/unittests/example_labfolder_data/static/img/favicon2.ico deleted file mode 100644 index e5ae15465d3528a6eaf094b5401d93c3f07469ee..0000000000000000000000000000000000000000 Binary files a/unittests/example_labfolder_data/static/img/favicon2.ico and /dev/null differ diff --git a/unittests/example_labfolder_data/static/img/labfolder_icons.png b/unittests/example_labfolder_data/static/img/labfolder_icons.png deleted file mode 100644 index 7b42b63bf1e5c1056fa9df766e324f93cb93bae9..0000000000000000000000000000000000000000 Binary files a/unittests/example_labfolder_data/static/img/labfolder_icons.png and /dev/null differ diff --git a/unittests/example_labfolder_data/static/img/squares.png b/unittests/example_labfolder_data/static/img/squares.png deleted file mode 100644 index 84b9b012c7b9f50be7fe63243bce8ce7f4c83ae2..0000000000000000000000000000000000000000 Binary files a/unittests/example_labfolder_data/static/img/squares.png and /dev/null differ diff --git a/unittests/example_labfolder_data/static/js/jquery-1.8.2.min.js b/unittests/example_labfolder_data/static/js/jquery-1.8.2.min.js deleted file mode 100644 index f65cf1dc4573c51e54d7cf3772d06caf96726616..0000000000000000000000000000000000000000 --- a/unittests/example_labfolder_data/static/js/jquery-1.8.2.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! jQuery v1.8.2 jquery.com | jquery.org/license */ -(function(a,b){function G(a){var b=F[a]={};return p.each(a.split(s),function(a,c){b[c]=!0}),b}function J(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(I,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:+d+""===d?+d:H.test(d)?p.parseJSON(d):d}catch(f){}p.data(a,c,d)}else d=b}return d}function K(a){var b;for(b in a){if(b==="data"&&p.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function ba(){return!1}function bb(){return!0}function bh(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function bi(a,b){do a=a[b];while(a&&a.nodeType!==1);return a}function bj(a,b,c){b=b||0;if(p.isFunction(b))return p.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return p.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=p.grep(a,function(a){return a.nodeType===1});if(be.test(b))return p.filter(b,d,!c);b=p.filter(b,d)}return p.grep(a,function(a,d){return p.inArray(a,b)>=0===c})}function bk(a){var b=bl.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function bC(a,b){return a.getElementsByTagName(b)[0]||a.appendChild(a.ownerDocument.createElement(b))}function bD(a,b){if(b.nodeType!==1||!p.hasData(a))return;var c,d,e,f=p._data(a),g=p._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;d<e;d++)p.event.add(b,c,h[c][d])}g.data&&(g.data=p.extend({},g.data))}function bE(a,b){var c;if(b.nodeType!==1)return;b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase(),c==="object"?(b.parentNode&&(b.outerHTML=a.outerHTML),p.support.html5Clone&&a.innerHTML&&!p.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):c==="input"&&bv.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):c==="option"?b.selected=a.defaultSelected:c==="input"||c==="textarea"?b.defaultValue=a.defaultValue:c==="script"&&b.text!==a.text&&(b.text=a.text),b.removeAttribute(p.expando)}function bF(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bG(a){bv.test(a.type)&&(a.defaultChecked=a.checked)}function bY(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=bW.length;while(e--){b=bW[e]+c;if(b in a)return b}return d}function bZ(a,b){return a=b||a,p.css(a,"display")==="none"||!p.contains(a.ownerDocument,a)}function b$(a,b){var c,d,e=[],f=0,g=a.length;for(;f<g;f++){c=a[f];if(!c.style)continue;e[f]=p._data(c,"olddisplay"),b?(!e[f]&&c.style.display==="none"&&(c.style.display=""),c.style.display===""&&bZ(c)&&(e[f]=p._data(c,"olddisplay",cc(c.nodeName)))):(d=bH(c,"display"),!e[f]&&d!=="none"&&p._data(c,"olddisplay",d))}for(f=0;f<g;f++){c=a[f];if(!c.style)continue;if(!b||c.style.display==="none"||c.style.display==="")c.style.display=b?e[f]||"":"none"}return a}function b_(a,b,c){var d=bP.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function ca(a,b,c,d){var e=c===(d?"border":"content")?4:b==="width"?1:0,f=0;for(;e<4;e+=2)c==="margin"&&(f+=p.css(a,c+bV[e],!0)),d?(c==="content"&&(f-=parseFloat(bH(a,"padding"+bV[e]))||0),c!=="margin"&&(f-=parseFloat(bH(a,"border"+bV[e]+"Width"))||0)):(f+=parseFloat(bH(a,"padding"+bV[e]))||0,c!=="padding"&&(f+=parseFloat(bH(a,"border"+bV[e]+"Width"))||0));return f}function cb(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=!0,f=p.support.boxSizing&&p.css(a,"boxSizing")==="border-box";if(d<=0||d==null){d=bH(a,b);if(d<0||d==null)d=a.style[b];if(bQ.test(d))return d;e=f&&(p.support.boxSizingReliable||d===a.style[b]),d=parseFloat(d)||0}return d+ca(a,b,c||(f?"border":"content"),e)+"px"}function cc(a){if(bS[a])return bS[a];var b=p("<"+a+">").appendTo(e.body),c=b.css("display");b.remove();if(c==="none"||c===""){bI=e.body.appendChild(bI||p.extend(e.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!bJ||!bI.createElement)bJ=(bI.contentWindow||bI.contentDocument).document,bJ.write("<!doctype html><html><body>"),bJ.close();b=bJ.body.appendChild(bJ.createElement(a)),c=bH(b,"display"),e.body.removeChild(bI)}return bS[a]=c,c}function ci(a,b,c,d){var e;if(p.isArray(b))p.each(b,function(b,e){c||ce.test(a)?d(a,e):ci(a+"["+(typeof e=="object"?b:"")+"]",e,c,d)});else if(!c&&p.type(b)==="object")for(e in b)ci(a+"["+e+"]",b[e],c,d);else d(a,b)}function cz(a){return function(b,c){typeof b!="string"&&(c=b,b="*");var d,e,f,g=b.toLowerCase().split(s),h=0,i=g.length;if(p.isFunction(c))for(;h<i;h++)d=g[h],f=/^\+/.test(d),f&&(d=d.substr(1)||"*"),e=a[d]=a[d]||[],e[f?"unshift":"push"](c)}}function cA(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h,i=a[f],j=0,k=i?i.length:0,l=a===cv;for(;j<k&&(l||!h);j++)h=i[j](c,d,e),typeof h=="string"&&(!l||g[h]?h=b:(c.dataTypes.unshift(h),h=cA(a,c,d,e,h,g)));return(l||!h)&&!g["*"]&&(h=cA(a,c,d,e,"*",g)),h}function cB(a,c){var d,e,f=p.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((f[d]?a:e||(e={}))[d]=c[d]);e&&p.extend(!0,a,e)}function cC(a,c,d){var e,f,g,h,i=a.contents,j=a.dataTypes,k=a.responseFields;for(f in k)f in d&&(c[k[f]]=d[f]);while(j[0]==="*")j.shift(),e===b&&(e=a.mimeType||c.getResponseHeader("content-type"));if(e)for(f in i)if(i[f]&&i[f].test(e)){j.unshift(f);break}if(j[0]in d)g=j[0];else{for(f in d){if(!j[0]||a.converters[f+" "+j[0]]){g=f;break}h||(h=f)}g=g||h}if(g)return g!==j[0]&&j.unshift(g),d[g]}function cD(a,b){var c,d,e,f,g=a.dataTypes.slice(),h=g[0],i={},j=0;a.dataFilter&&(b=a.dataFilter(b,a.dataType));if(g[1])for(c in a.converters)i[c.toLowerCase()]=a.converters[c];for(;e=g[++j];)if(e!=="*"){if(h!=="*"&&h!==e){c=i[h+" "+e]||i["* "+e];if(!c)for(d in i){f=d.split(" ");if(f[1]===e){c=i[h+" "+f[0]]||i["* "+f[0]];if(c){c===!0?c=i[d]:i[d]!==!0&&(e=f[0],g.splice(j--,0,e));break}}}if(c!==!0)if(c&&a["throws"])b=c(b);else try{b=c(b)}catch(k){return{state:"parsererror",error:c?k:"No conversion from "+h+" to "+e}}}h=e}return{state:"success",data:b}}function cL(){try{return new a.XMLHttpRequest}catch(b){}}function cM(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function cU(){return setTimeout(function(){cN=b},0),cN=p.now()}function cV(a,b){p.each(b,function(b,c){var d=(cT[b]||[]).concat(cT["*"]),e=0,f=d.length;for(;e<f;e++)if(d[e].call(a,b,c))return})}function cW(a,b,c){var d,e=0,f=0,g=cS.length,h=p.Deferred().always(function(){delete i.elem}),i=function(){var b=cN||cU(),c=Math.max(0,j.startTime+j.duration-b),d=1-(c/j.duration||0),e=0,f=j.tweens.length;for(;e<f;e++)j.tweens[e].run(d);return h.notifyWith(a,[j,d,c]),d<1&&f?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:p.extend({},b),opts:p.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:cN||cU(),duration:c.duration,tweens:[],createTween:function(b,c,d){var e=p.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(e),e},stop:function(b){var c=0,d=b?j.tweens.length:0;for(;c<d;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;cX(k,j.opts.specialEasing);for(;e<g;e++){d=cS[e].call(j,a,k,j.opts);if(d)return d}return cV(j,k),p.isFunction(j.opts.start)&&j.opts.start.call(a,j),p.fx.timer(p.extend(i,{anim:j,queue:j.opts.queue,elem:a})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}function cX(a,b){var c,d,e,f,g;for(c in a){d=p.camelCase(c),e=b[d],f=a[c],p.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=p.cssHooks[d];if(g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}}function cY(a,b,c){var d,e,f,g,h,i,j,k,l=this,m=a.style,n={},o=[],q=a.nodeType&&bZ(a);c.queue||(j=p._queueHooks(a,"fx"),j.unqueued==null&&(j.unqueued=0,k=j.empty.fire,j.empty.fire=function(){j.unqueued||k()}),j.unqueued++,l.always(function(){l.always(function(){j.unqueued--,p.queue(a,"fx").length||j.empty.fire()})})),a.nodeType===1&&("height"in b||"width"in b)&&(c.overflow=[m.overflow,m.overflowX,m.overflowY],p.css(a,"display")==="inline"&&p.css(a,"float")==="none"&&(!p.support.inlineBlockNeedsLayout||cc(a.nodeName)==="inline"?m.display="inline-block":m.zoom=1)),c.overflow&&(m.overflow="hidden",p.support.shrinkWrapBlocks||l.done(function(){m.overflow=c.overflow[0],m.overflowX=c.overflow[1],m.overflowY=c.overflow[2]}));for(d in b){f=b[d];if(cP.exec(f)){delete b[d];if(f===(q?"hide":"show"))continue;o.push(d)}}g=o.length;if(g){h=p._data(a,"fxshow")||p._data(a,"fxshow",{}),q?p(a).show():l.done(function(){p(a).hide()}),l.done(function(){var b;p.removeData(a,"fxshow",!0);for(b in n)p.style(a,b,n[b])});for(d=0;d<g;d++)e=o[d],i=l.createTween(e,q?h[e]:0),n[e]=h[e]||p.style(a,e),e in h||(h[e]=i.start,q&&(i.end=i.start,i.start=e==="width"||e==="height"?1:0))}}function cZ(a,b,c,d,e){return new cZ.prototype.init(a,b,c,d,e)}function c$(a,b){var c,d={height:a},e=0;b=b?1:0;for(;e<4;e+=2-b)c=bV[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function da(a){return p.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}var c,d,e=a.document,f=a.location,g=a.navigator,h=a.jQuery,i=a.$,j=Array.prototype.push,k=Array.prototype.slice,l=Array.prototype.indexOf,m=Object.prototype.toString,n=Object.prototype.hasOwnProperty,o=String.prototype.trim,p=function(a,b){return new p.fn.init(a,b,c)},q=/[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source,r=/\S/,s=/\s+/,t=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,u=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,y=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,z=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,A=/^-ms-/,B=/-([\da-z])/gi,C=function(a,b){return(b+"").toUpperCase()},D=function(){e.addEventListener?(e.removeEventListener("DOMContentLoaded",D,!1),p.ready()):e.readyState==="complete"&&(e.detachEvent("onreadystatechange",D),p.ready())},E={};p.fn=p.prototype={constructor:p,init:function(a,c,d){var f,g,h,i;if(!a)return this;if(a.nodeType)return this.context=this[0]=a,this.length=1,this;if(typeof a=="string"){a.charAt(0)==="<"&&a.charAt(a.length-1)===">"&&a.length>=3?f=[null,a,null]:f=u.exec(a);if(f&&(f[1]||!c)){if(f[1])return c=c instanceof p?c[0]:c,i=c&&c.nodeType?c.ownerDocument||c:e,a=p.parseHTML(f[1],i,!0),v.test(f[1])&&p.isPlainObject(c)&&this.attr.call(a,c,!0),p.merge(this,a);g=e.getElementById(f[2]);if(g&&g.parentNode){if(g.id!==f[2])return d.find(a);this.length=1,this[0]=g}return this.context=e,this.selector=a,this}return!c||c.jquery?(c||d).find(a):this.constructor(c).find(a)}return p.isFunction(a)?d.ready(a):(a.selector!==b&&(this.selector=a.selector,this.context=a.context),p.makeArray(a,this))},selector:"",jquery:"1.8.2",length:0,size:function(){return this.length},toArray:function(){return k.call(this)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=p.merge(this.constructor(),a);return d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")"),d},each:function(a,b){return p.each(this,a,b)},ready:function(a){return p.ready.promise().done(a),this},eq:function(a){return a=+a,a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(k.apply(this,arguments),"slice",k.call(arguments).join(","))},map:function(a){return this.pushStack(p.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:j,sort:[].sort,splice:[].splice},p.fn.init.prototype=p.fn,p.extend=p.fn.extend=function(){var a,c,d,e,f,g,h=arguments[0]||{},i=1,j=arguments.length,k=!1;typeof h=="boolean"&&(k=h,h=arguments[1]||{},i=2),typeof h!="object"&&!p.isFunction(h)&&(h={}),j===i&&(h=this,--i);for(;i<j;i++)if((a=arguments[i])!=null)for(c in a){d=h[c],e=a[c];if(h===e)continue;k&&e&&(p.isPlainObject(e)||(f=p.isArray(e)))?(f?(f=!1,g=d&&p.isArray(d)?d:[]):g=d&&p.isPlainObject(d)?d:{},h[c]=p.extend(k,g,e)):e!==b&&(h[c]=e)}return h},p.extend({noConflict:function(b){return a.$===p&&(a.$=i),b&&a.jQuery===p&&(a.jQuery=h),p},isReady:!1,readyWait:1,holdReady:function(a){a?p.readyWait++:p.ready(!0)},ready:function(a){if(a===!0?--p.readyWait:p.isReady)return;if(!e.body)return setTimeout(p.ready,1);p.isReady=!0;if(a!==!0&&--p.readyWait>0)return;d.resolveWith(e,[p]),p.fn.trigger&&p(e).trigger("ready").off("ready")},isFunction:function(a){return p.type(a)==="function"},isArray:Array.isArray||function(a){return p.type(a)==="array"},isWindow:function(a){return a!=null&&a==a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):E[m.call(a)]||"object"},isPlainObject:function(a){if(!a||p.type(a)!=="object"||a.nodeType||p.isWindow(a))return!1;try{if(a.constructor&&!n.call(a,"constructor")&&!n.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||n.call(a,d)},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},error:function(a){throw new Error(a)},parseHTML:function(a,b,c){var d;return!a||typeof a!="string"?null:(typeof b=="boolean"&&(c=b,b=0),b=b||e,(d=v.exec(a))?[b.createElement(d[1])]:(d=p.buildFragment([a],b,c?null:[]),p.merge([],(d.cacheable?p.clone(d.fragment):d.fragment).childNodes)))},parseJSON:function(b){if(!b||typeof b!="string")return null;b=p.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(w.test(b.replace(y,"@").replace(z,"]").replace(x,"")))return(new Function("return "+b))();p.error("Invalid JSON: "+b)},parseXML:function(c){var d,e;if(!c||typeof c!="string")return null;try{a.DOMParser?(e=new DOMParser,d=e.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(f){d=b}return(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&p.error("Invalid XML: "+c),d},noop:function(){},globalEval:function(b){b&&r.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(A,"ms-").replace(B,C)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,c,d){var e,f=0,g=a.length,h=g===b||p.isFunction(a);if(d){if(h){for(e in a)if(c.apply(a[e],d)===!1)break}else for(;f<g;)if(c.apply(a[f++],d)===!1)break}else if(h){for(e in a)if(c.call(a[e],e,a[e])===!1)break}else for(;f<g;)if(c.call(a[f],f,a[f++])===!1)break;return a},trim:o&&!o.call(" ")?function(a){return a==null?"":o.call(a)}:function(a){return a==null?"":(a+"").replace(t,"")},makeArray:function(a,b){var c,d=b||[];return a!=null&&(c=p.type(a),a.length==null||c==="string"||c==="function"||c==="regexp"||p.isWindow(a)?j.call(d,a):p.merge(d,a)),d},inArray:function(a,b,c){var d;if(b){if(l)return l.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=c.length,e=a.length,f=0;if(typeof d=="number")for(;f<d;f++)a[e++]=c[f];else while(c[f]!==b)a[e++]=c[f++];return a.length=e,a},grep:function(a,b,c){var d,e=[],f=0,g=a.length;c=!!c;for(;f<g;f++)d=!!b(a[f],f),c!==d&&e.push(a[f]);return e},map:function(a,c,d){var e,f,g=[],h=0,i=a.length,j=a instanceof p||i!==b&&typeof i=="number"&&(i>0&&a[0]&&a[i-1]||i===0||p.isArray(a));if(j)for(;h<i;h++)e=c(a[h],h,d),e!=null&&(g[g.length]=e);else for(f in a)e=c(a[f],f,d),e!=null&&(g[g.length]=e);return g.concat.apply([],g)},guid:1,proxy:function(a,c){var d,e,f;return typeof c=="string"&&(d=a[c],c=a,a=d),p.isFunction(a)?(e=k.call(arguments,2),f=function(){return a.apply(c,e.concat(k.call(arguments)))},f.guid=a.guid=a.guid||p.guid++,f):b},access:function(a,c,d,e,f,g,h){var i,j=d==null,k=0,l=a.length;if(d&&typeof d=="object"){for(k in d)p.access(a,c,k,d[k],1,g,e);f=1}else if(e!==b){i=h===b&&p.isFunction(e),j&&(i?(i=c,c=function(a,b,c){return i.call(p(a),c)}):(c.call(a,e),c=null));if(c)for(;k<l;k++)c(a[k],d,i?e.call(a[k],k,c(a[k],d)):e,h);f=1}return f?a:j?c.call(a):l?c(a[0],d):g},now:function(){return(new Date).getTime()}}),p.ready.promise=function(b){if(!d){d=p.Deferred();if(e.readyState==="complete")setTimeout(p.ready,1);else if(e.addEventListener)e.addEventListener("DOMContentLoaded",D,!1),a.addEventListener("load",p.ready,!1);else{e.attachEvent("onreadystatechange",D),a.attachEvent("onload",p.ready);var c=!1;try{c=a.frameElement==null&&e.documentElement}catch(f){}c&&c.doScroll&&function g(){if(!p.isReady){try{c.doScroll("left")}catch(a){return setTimeout(g,50)}p.ready()}}()}}return d.promise(b)},p.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){E["[object "+b+"]"]=b.toLowerCase()}),c=p(e);var F={};p.Callbacks=function(a){a=typeof a=="string"?F[a]||G(a):p.extend({},a);var c,d,e,f,g,h,i=[],j=!a.once&&[],k=function(b){c=a.memory&&b,d=!0,h=f||0,f=0,g=i.length,e=!0;for(;i&&h<g;h++)if(i[h].apply(b[0],b[1])===!1&&a.stopOnFalse){c=!1;break}e=!1,i&&(j?j.length&&k(j.shift()):c?i=[]:l.disable())},l={add:function(){if(i){var b=i.length;(function d(b){p.each(b,function(b,c){var e=p.type(c);e==="function"&&(!a.unique||!l.has(c))?i.push(c):c&&c.length&&e!=="string"&&d(c)})})(arguments),e?g=i.length:c&&(f=b,k(c))}return this},remove:function(){return i&&p.each(arguments,function(a,b){var c;while((c=p.inArray(b,i,c))>-1)i.splice(c,1),e&&(c<=g&&g--,c<=h&&h--)}),this},has:function(a){return p.inArray(a,i)>-1},empty:function(){return i=[],this},disable:function(){return i=j=c=b,this},disabled:function(){return!i},lock:function(){return j=b,c||l.disable(),this},locked:function(){return!j},fireWith:function(a,b){return b=b||[],b=[a,b.slice?b.slice():b],i&&(!d||j)&&(e?j.push(b):k(b)),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!d}};return l},p.extend({Deferred:function(a){var b=[["resolve","done",p.Callbacks("once memory"),"resolved"],["reject","fail",p.Callbacks("once memory"),"rejected"],["notify","progress",p.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return p.Deferred(function(c){p.each(b,function(b,d){var f=d[0],g=a[b];e[d[1]](p.isFunction(g)?function(){var a=g.apply(this,arguments);a&&p.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f+"With"](this===e?c:this,[a])}:c[f])}),a=null}).promise()},promise:function(a){return a!=null?p.extend(a,d):d}},e={};return d.pipe=d.then,p.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[a^1][2].disable,b[2][2].lock),e[f[0]]=g.fire,e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=k.call(arguments),d=c.length,e=d!==1||a&&p.isFunction(a.promise)?d:0,f=e===1?a:p.Deferred(),g=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?k.call(arguments):d,c===h?f.notifyWith(b,c):--e||f.resolveWith(b,c)}},h,i,j;if(d>1){h=new Array(d),i=new Array(d),j=new Array(d);for(;b<d;b++)c[b]&&p.isFunction(c[b].promise)?c[b].promise().done(g(b,j,c)).fail(f.reject).progress(g(b,i,h)):--e}return e||f.resolveWith(j,c),f.promise()}}),p.support=function(){var b,c,d,f,g,h,i,j,k,l,m,n=e.createElement("div");n.setAttribute("className","t"),n.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",c=n.getElementsByTagName("*"),d=n.getElementsByTagName("a")[0],d.style.cssText="top:1px;float:left;opacity:.5";if(!c||!c.length)return{};f=e.createElement("select"),g=f.appendChild(e.createElement("option")),h=n.getElementsByTagName("input")[0],b={leadingWhitespace:n.firstChild.nodeType===3,tbody:!n.getElementsByTagName("tbody").length,htmlSerialize:!!n.getElementsByTagName("link").length,style:/top/.test(d.getAttribute("style")),hrefNormalized:d.getAttribute("href")==="/a",opacity:/^0.5/.test(d.style.opacity),cssFloat:!!d.style.cssFloat,checkOn:h.value==="on",optSelected:g.selected,getSetAttribute:n.className!=="t",enctype:!!e.createElement("form").enctype,html5Clone:e.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",boxModel:e.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},h.checked=!0,b.noCloneChecked=h.cloneNode(!0).checked,f.disabled=!0,b.optDisabled=!g.disabled;try{delete n.test}catch(o){b.deleteExpando=!1}!n.addEventListener&&n.attachEvent&&n.fireEvent&&(n.attachEvent("onclick",m=function(){b.noCloneEvent=!1}),n.cloneNode(!0).fireEvent("onclick"),n.detachEvent("onclick",m)),h=e.createElement("input"),h.value="t",h.setAttribute("type","radio"),b.radioValue=h.value==="t",h.setAttribute("checked","checked"),h.setAttribute("name","t"),n.appendChild(h),i=e.createDocumentFragment(),i.appendChild(n.lastChild),b.checkClone=i.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=h.checked,i.removeChild(h),i.appendChild(n);if(n.attachEvent)for(k in{submit:!0,change:!0,focusin:!0})j="on"+k,l=j in n,l||(n.setAttribute(j,"return;"),l=typeof n[j]=="function"),b[k+"Bubbles"]=l;return p(function(){var c,d,f,g,h="padding:0;margin:0;border:0;display:block;overflow:hidden;",i=e.getElementsByTagName("body")[0];if(!i)return;c=e.createElement("div"),c.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",i.insertBefore(c,i.firstChild),d=e.createElement("div"),c.appendChild(d),d.innerHTML="<table><tr><td></td><td>t</td></tr></table>",f=d.getElementsByTagName("td"),f[0].style.cssText="padding:0;margin:0;border:0;display:none",l=f[0].offsetHeight===0,f[0].style.display="",f[1].style.display="none",b.reliableHiddenOffsets=l&&f[0].offsetHeight===0,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",b.boxSizing=d.offsetWidth===4,b.doesNotIncludeMarginInBodyOffset=i.offsetTop!==1,a.getComputedStyle&&(b.pixelPosition=(a.getComputedStyle(d,null)||{}).top!=="1%",b.boxSizingReliable=(a.getComputedStyle(d,null)||{width:"4px"}).width==="4px",g=e.createElement("div"),g.style.cssText=d.style.cssText=h,g.style.marginRight=g.style.width="0",d.style.width="1px",d.appendChild(g),b.reliableMarginRight=!parseFloat((a.getComputedStyle(g,null)||{}).marginRight)),typeof d.style.zoom!="undefined"&&(d.innerHTML="",d.style.cssText=h+"width:1px;padding:1px;display:inline;zoom:1",b.inlineBlockNeedsLayout=d.offsetWidth===3,d.style.display="block",d.style.overflow="visible",d.innerHTML="<div></div>",d.firstChild.style.width="5px",b.shrinkWrapBlocks=d.offsetWidth!==3,c.style.zoom=1),i.removeChild(c),c=d=f=g=null}),i.removeChild(n),c=d=f=g=h=i=n=null,b}();var H=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,I=/([A-Z])/g;p.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(p.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){return a=a.nodeType?p.cache[a[p.expando]]:a[p.expando],!!a&&!K(a)},data:function(a,c,d,e){if(!p.acceptData(a))return;var f,g,h=p.expando,i=typeof c=="string",j=a.nodeType,k=j?p.cache:a,l=j?a[h]:a[h]&&h;if((!l||!k[l]||!e&&!k[l].data)&&i&&d===b)return;l||(j?a[h]=l=p.deletedIds.pop()||p.guid++:l=h),k[l]||(k[l]={},j||(k[l].toJSON=p.noop));if(typeof c=="object"||typeof c=="function")e?k[l]=p.extend(k[l],c):k[l].data=p.extend(k[l].data,c);return f=k[l],e||(f.data||(f.data={}),f=f.data),d!==b&&(f[p.camelCase(c)]=d),i?(g=f[c],g==null&&(g=f[p.camelCase(c)])):g=f,g},removeData:function(a,b,c){if(!p.acceptData(a))return;var d,e,f,g=a.nodeType,h=g?p.cache:a,i=g?a[p.expando]:p.expando;if(!h[i])return;if(b){d=c?h[i]:h[i].data;if(d){p.isArray(b)||(b in d?b=[b]:(b=p.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,f=b.length;e<f;e++)delete d[b[e]];if(!(c?K:p.isEmptyObject)(d))return}}if(!c){delete h[i].data;if(!K(h[i]))return}g?p.cleanData([a],!0):p.support.deleteExpando||h!=h.window?delete h[i]:h[i]=null},_data:function(a,b,c){return p.data(a,b,c,!0)},acceptData:function(a){var b=a.nodeName&&p.noData[a.nodeName.toLowerCase()];return!b||b!==!0&&a.getAttribute("classid")===b}}),p.fn.extend({data:function(a,c){var d,e,f,g,h,i=this[0],j=0,k=null;if(a===b){if(this.length){k=p.data(i);if(i.nodeType===1&&!p._data(i,"parsedAttrs")){f=i.attributes;for(h=f.length;j<h;j++)g=f[j].name,g.indexOf("data-")||(g=p.camelCase(g.substring(5)),J(i,g,k[g]));p._data(i,"parsedAttrs",!0)}}return k}return typeof a=="object"?this.each(function(){p.data(this,a)}):(d=a.split(".",2),d[1]=d[1]?"."+d[1]:"",e=d[1]+"!",p.access(this,function(c){if(c===b)return k=this.triggerHandler("getData"+e,[d[0]]),k===b&&i&&(k=p.data(i,a),k=J(i,a,k)),k===b&&d[1]?this.data(d[0]):k;d[1]=c,this.each(function(){var b=p(this);b.triggerHandler("setData"+e,d),p.data(this,a,c),b.triggerHandler("changeData"+e,d)})},null,c,arguments.length>1,null,!1))},removeData:function(a){return this.each(function(){p.removeData(this,a)})}}),p.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=p._data(a,b),c&&(!d||p.isArray(c)?d=p._data(a,b,p.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=p.queue(a,b),d=c.length,e=c.shift(),f=p._queueHooks(a,b),g=function(){p.dequeue(a,b)};e==="inprogress"&&(e=c.shift(),d--),e&&(b==="fx"&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return p._data(a,c)||p._data(a,c,{empty:p.Callbacks("once memory").add(function(){p.removeData(a,b+"queue",!0),p.removeData(a,c,!0)})})}}),p.fn.extend({queue:function(a,c){var d=2;return typeof a!="string"&&(c=a,a="fx",d--),arguments.length<d?p.queue(this[0],a):c===b?this:this.each(function(){var b=p.queue(this,a,c);p._queueHooks(this,a),a==="fx"&&b[0]!=="inprogress"&&p.dequeue(this,a)})},dequeue:function(a){return this.each(function(){p.dequeue(this,a)})},delay:function(a,b){return a=p.fx?p.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){var d,e=1,f=p.Deferred(),g=this,h=this.length,i=function(){--e||f.resolveWith(g,[g])};typeof a!="string"&&(c=a,a=b),a=a||"fx";while(h--)d=p._data(g[h],a+"queueHooks"),d&&d.empty&&(e++,d.empty.add(i));return i(),f.promise(c)}});var L,M,N,O=/[\t\r\n]/g,P=/\r/g,Q=/^(?:button|input)$/i,R=/^(?:button|input|object|select|textarea)$/i,S=/^a(?:rea|)$/i,T=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,U=p.support.getSetAttribute;p.fn.extend({attr:function(a,b){return p.access(this,p.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){p.removeAttr(this,a)})},prop:function(a,b){return p.access(this,p.prop,a,b,arguments.length>1)},removeProp:function(a){return a=p.propFix[a]||a,this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,f,g,h;if(p.isFunction(a))return this.each(function(b){p(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(s);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{f=" "+e.className+" ";for(g=0,h=b.length;g<h;g++)f.indexOf(" "+b[g]+" ")<0&&(f+=b[g]+" ");e.className=p.trim(f)}}}return this},removeClass:function(a){var c,d,e,f,g,h,i;if(p.isFunction(a))return this.each(function(b){p(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(s);for(h=0,i=this.length;h<i;h++){e=this[h];if(e.nodeType===1&&e.className){d=(" "+e.className+" ").replace(O," ");for(f=0,g=c.length;f<g;f++)while(d.indexOf(" "+c[f]+" ")>=0)d=d.replace(" "+c[f]+" "," ");e.className=a?p.trim(d):""}}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";return p.isFunction(a)?this.each(function(c){p(this).toggleClass(a.call(this,c,this.className,b),b)}):this.each(function(){if(c==="string"){var e,f=0,g=p(this),h=b,i=a.split(s);while(e=i[f++])h=d?h:!g.hasClass(e),g[h?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&p._data(this,"__className__",this.className),this.className=this.className||a===!1?"":p._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(O," ").indexOf(b)>=0)return!0;return!1},val:function(a){var c,d,e,f=this[0];if(!arguments.length){if(f)return c=p.valHooks[f.type]||p.valHooks[f.nodeName.toLowerCase()],c&&"get"in c&&(d=c.get(f,"value"))!==b?d:(d=f.value,typeof d=="string"?d.replace(P,""):d==null?"":d);return}return e=p.isFunction(a),this.each(function(d){var f,g=p(this);if(this.nodeType!==1)return;e?f=a.call(this,d,g.val()):f=a,f==null?f="":typeof f=="number"?f+="":p.isArray(f)&&(f=p.map(f,function(a){return a==null?"":a+""})),c=p.valHooks[this.type]||p.valHooks[this.nodeName.toLowerCase()];if(!c||!("set"in c)||c.set(this,f,"value")===b)this.value=f})}}),p.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,f=a.selectedIndex,g=[],h=a.options,i=a.type==="select-one";if(f<0)return null;c=i?f:0,d=i?f+1:h.length;for(;c<d;c++){e=h[c];if(e.selected&&(p.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!p.nodeName(e.parentNode,"optgroup"))){b=p(e).val();if(i)return b;g.push(b)}}return i&&!g.length&&h.length?p(h[f]).val():g},set:function(a,b){var c=p.makeArray(b);return p(a).find("option").each(function(){this.selected=p.inArray(p(this).val(),c)>=0}),c.length||(a.selectedIndex=-1),c}}},attrFn:{},attr:function(a,c,d,e){var f,g,h,i=a.nodeType;if(!a||i===3||i===8||i===2)return;if(e&&p.isFunction(p.fn[c]))return p(a)[c](d);if(typeof a.getAttribute=="undefined")return p.prop(a,c,d);h=i!==1||!p.isXMLDoc(a),h&&(c=c.toLowerCase(),g=p.attrHooks[c]||(T.test(c)?M:L));if(d!==b){if(d===null){p.removeAttr(a,c);return}return g&&"set"in g&&h&&(f=g.set(a,d,c))!==b?f:(a.setAttribute(c,d+""),d)}return g&&"get"in g&&h&&(f=g.get(a,c))!==null?f:(f=a.getAttribute(c),f===null?b:f)},removeAttr:function(a,b){var c,d,e,f,g=0;if(b&&a.nodeType===1){d=b.split(s);for(;g<d.length;g++)e=d[g],e&&(c=p.propFix[e]||e,f=T.test(e),f||p.attr(a,e,""),a.removeAttribute(U?e:c),f&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(Q.test(a.nodeName)&&a.parentNode)p.error("type property can't be changed");else if(!p.support.radioValue&&b==="radio"&&p.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}},value:{get:function(a,b){return L&&p.nodeName(a,"button")?L.get(a,b):b in a?a.value:null},set:function(a,b,c){if(L&&p.nodeName(a,"button"))return L.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,f,g,h=a.nodeType;if(!a||h===3||h===8||h===2)return;return g=h!==1||!p.isXMLDoc(a),g&&(c=p.propFix[c]||c,f=p.propHooks[c]),d!==b?f&&"set"in f&&(e=f.set(a,d,c))!==b?e:a[c]=d:f&&"get"in f&&(e=f.get(a,c))!==null?e:a[c]},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):R.test(a.nodeName)||S.test(a.nodeName)&&a.href?0:b}}}}),M={get:function(a,c){var d,e=p.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;return b===!1?p.removeAttr(a,c):(d=p.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase())),c}},U||(N={name:!0,id:!0,coords:!0},L=p.valHooks.button={get:function(a,c){var d;return d=a.getAttributeNode(c),d&&(N[c]?d.value!=="":d.specified)?d.value:b},set:function(a,b,c){var d=a.getAttributeNode(c);return d||(d=e.createAttribute(c),a.setAttributeNode(d)),d.value=b+""}},p.each(["width","height"],function(a,b){p.attrHooks[b]=p.extend(p.attrHooks[b],{set:function(a,c){if(c==="")return a.setAttribute(b,"auto"),c}})}),p.attrHooks.contenteditable={get:L.get,set:function(a,b,c){b===""&&(b="false"),L.set(a,b,c)}}),p.support.hrefNormalized||p.each(["href","src","width","height"],function(a,c){p.attrHooks[c]=p.extend(p.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),p.support.style||(p.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=b+""}}),p.support.optSelected||(p.propHooks.selected=p.extend(p.propHooks.selected,{get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}})),p.support.enctype||(p.propFix.enctype="encoding"),p.support.checkOn||p.each(["radio","checkbox"],function(){p.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),p.each(["radio","checkbox"],function(){p.valHooks[this]=p.extend(p.valHooks[this],{set:function(a,b){if(p.isArray(b))return a.checked=p.inArray(p(a).val(),b)>=0}})});var V=/^(?:textarea|input|select)$/i,W=/^([^\.]*|)(?:\.(.+)|)$/,X=/(?:^|\s)hover(\.\S+|)\b/,Y=/^key/,Z=/^(?:mouse|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=function(a){return p.event.special.hover?a:a.replace(X,"mouseenter$1 mouseleave$1")};p.event={add:function(a,c,d,e,f){var g,h,i,j,k,l,m,n,o,q,r;if(a.nodeType===3||a.nodeType===8||!c||!d||!(g=p._data(a)))return;d.handler&&(o=d,d=o.handler,f=o.selector),d.guid||(d.guid=p.guid++),i=g.events,i||(g.events=i={}),h=g.handle,h||(g.handle=h=function(a){return typeof p!="undefined"&&(!a||p.event.triggered!==a.type)?p.event.dispatch.apply(h.elem,arguments):b},h.elem=a),c=p.trim(_(c)).split(" ");for(j=0;j<c.length;j++){k=W.exec(c[j])||[],l=k[1],m=(k[2]||"").split(".").sort(),r=p.event.special[l]||{},l=(f?r.delegateType:r.bindType)||l,r=p.event.special[l]||{},n=p.extend({type:l,origType:k[1],data:e,handler:d,guid:d.guid,selector:f,needsContext:f&&p.expr.match.needsContext.test(f),namespace:m.join(".")},o),q=i[l];if(!q){q=i[l]=[],q.delegateCount=0;if(!r.setup||r.setup.call(a,e,m,h)===!1)a.addEventListener?a.addEventListener(l,h,!1):a.attachEvent&&a.attachEvent("on"+l,h)}r.add&&(r.add.call(a,n),n.handler.guid||(n.handler.guid=d.guid)),f?q.splice(q.delegateCount++,0,n):q.push(n),p.event.global[l]=!0}a=null},global:{},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,q,r=p.hasData(a)&&p._data(a);if(!r||!(m=r.events))return;b=p.trim(_(b||"")).split(" ");for(f=0;f<b.length;f++){g=W.exec(b[f])||[],h=i=g[1],j=g[2];if(!h){for(h in m)p.event.remove(a,h+b[f],c,d,!0);continue}n=p.event.special[h]||{},h=(d?n.delegateType:n.bindType)||h,o=m[h]||[],k=o.length,j=j?new RegExp("(^|\\.)"+j.split(".").sort().join("\\.(?:.*\\.|)")+"(\\.|$)"):null;for(l=0;l<o.length;l++)q=o[l],(e||i===q.origType)&&(!c||c.guid===q.guid)&&(!j||j.test(q.namespace))&&(!d||d===q.selector||d==="**"&&q.selector)&&(o.splice(l--,1),q.selector&&o.delegateCount--,n.remove&&n.remove.call(a,q));o.length===0&&k!==o.length&&((!n.teardown||n.teardown.call(a,j,r.handle)===!1)&&p.removeEvent(a,h,r.handle),delete m[h])}p.isEmptyObject(m)&&(delete r.handle,p.removeData(a,"events",!0))},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,f,g){if(!f||f.nodeType!==3&&f.nodeType!==8){var h,i,j,k,l,m,n,o,q,r,s=c.type||c,t=[];if($.test(s+p.event.triggered))return;s.indexOf("!")>=0&&(s=s.slice(0,-1),i=!0),s.indexOf(".")>=0&&(t=s.split("."),s=t.shift(),t.sort());if((!f||p.event.customEvent[s])&&!p.event.global[s])return;c=typeof c=="object"?c[p.expando]?c:new p.Event(s,c):new p.Event(s),c.type=s,c.isTrigger=!0,c.exclusive=i,c.namespace=t.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+t.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,m=s.indexOf(":")<0?"on"+s:"";if(!f){h=p.cache;for(j in h)h[j].events&&h[j].events[s]&&p.event.trigger(c,d,h[j].handle.elem,!0);return}c.result=b,c.target||(c.target=f),d=d!=null?p.makeArray(d):[],d.unshift(c),n=p.event.special[s]||{};if(n.trigger&&n.trigger.apply(f,d)===!1)return;q=[[f,n.bindType||s]];if(!g&&!n.noBubble&&!p.isWindow(f)){r=n.delegateType||s,k=$.test(r+s)?f:f.parentNode;for(l=f;k;k=k.parentNode)q.push([k,r]),l=k;l===(f.ownerDocument||e)&&q.push([l.defaultView||l.parentWindow||a,r])}for(j=0;j<q.length&&!c.isPropagationStopped();j++)k=q[j][0],c.type=q[j][1],o=(p._data(k,"events")||{})[c.type]&&p._data(k,"handle"),o&&o.apply(k,d),o=m&&k[m],o&&p.acceptData(k)&&o.apply&&o.apply(k,d)===!1&&c.preventDefault();return c.type=s,!g&&!c.isDefaultPrevented()&&(!n._default||n._default.apply(f.ownerDocument,d)===!1)&&(s!=="click"||!p.nodeName(f,"a"))&&p.acceptData(f)&&m&&f[s]&&(s!=="focus"&&s!=="blur"||c.target.offsetWidth!==0)&&!p.isWindow(f)&&(l=f[m],l&&(f[m]=null),p.event.triggered=s,f[s](),p.event.triggered=b,l&&(f[m]=l)),c.result}return},dispatch:function(c){c=p.event.fix(c||a.event);var d,e,f,g,h,i,j,l,m,n,o=(p._data(this,"events")||{})[c.type]||[],q=o.delegateCount,r=k.call(arguments),s=!c.exclusive&&!c.namespace,t=p.event.special[c.type]||{},u=[];r[0]=c,c.delegateTarget=this;if(t.preDispatch&&t.preDispatch.call(this,c)===!1)return;if(q&&(!c.button||c.type!=="click"))for(f=c.target;f!=this;f=f.parentNode||this)if(f.disabled!==!0||c.type!=="click"){h={},j=[];for(d=0;d<q;d++)l=o[d],m=l.selector,h[m]===b&&(h[m]=l.needsContext?p(m,this).index(f)>=0:p.find(m,this,null,[f]).length),h[m]&&j.push(l);j.length&&u.push({elem:f,matches:j})}o.length>q&&u.push({elem:this,matches:o.slice(q)});for(d=0;d<u.length&&!c.isPropagationStopped();d++){i=u[d],c.currentTarget=i.elem;for(e=0;e<i.matches.length&&!c.isImmediatePropagationStopped();e++){l=i.matches[e];if(s||!c.namespace&&!l.namespace||c.namespace_re&&c.namespace_re.test(l.namespace))c.data=l.data,c.handleObj=l,g=((p.event.special[l.origType]||{}).handle||l.handler).apply(i.elem,r),g!==b&&(c.result=g,g===!1&&(c.preventDefault(),c.stopPropagation()))}}return t.postDispatch&&t.postDispatch.call(this,c),c.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,c){var d,f,g,h=c.button,i=c.fromElement;return a.pageX==null&&c.clientX!=null&&(d=a.target.ownerDocument||e,f=d.documentElement,g=d.body,a.pageX=c.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=c.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?c.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0),a}},fix:function(a){if(a[p.expando])return a;var b,c,d=a,f=p.event.fixHooks[a.type]||{},g=f.props?this.props.concat(f.props):this.props;a=p.Event(d);for(b=g.length;b;)c=g[--b],a[c]=d[c];return a.target||(a.target=d.srcElement||e),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,f.filter?f.filter(a,d):a},special:{load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){p.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=p.extend(new p.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?p.event.trigger(e,null,b):p.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},p.event.handle=p.event.dispatch,p.removeEvent=e.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){var d="on"+b;a.detachEvent&&(typeof a[d]=="undefined"&&(a[d]=null),a.detachEvent(d,c))},p.Event=function(a,b){if(this instanceof p.Event)a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?bb:ba):this.type=a,b&&p.extend(this,b),this.timeStamp=a&&a.timeStamp||p.now(),this[p.expando]=!0;else return new p.Event(a,b)},p.Event.prototype={preventDefault:function(){this.isDefaultPrevented=bb;var a=this.originalEvent;if(!a)return;a.preventDefault?a.preventDefault():a.returnValue=!1},stopPropagation:function(){this.isPropagationStopped=bb;var a=this.originalEvent;if(!a)return;a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=bb,this.stopPropagation()},isDefaultPrevented:ba,isPropagationStopped:ba,isImmediatePropagationStopped:ba},p.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){p.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj,g=f.selector;if(!e||e!==d&&!p.contains(d,e))a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b;return c}}}),p.support.submitBubbles||(p.event.special.submit={setup:function(){if(p.nodeName(this,"form"))return!1;p.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=p.nodeName(c,"input")||p.nodeName(c,"button")?c.form:b;d&&!p._data(d,"_submit_attached")&&(p.event.add(d,"submit._submit",function(a){a._submit_bubble=!0}),p._data(d,"_submit_attached",!0))})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&p.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){if(p.nodeName(this,"form"))return!1;p.event.remove(this,"._submit")}}),p.support.changeBubbles||(p.event.special.change={setup:function(){if(V.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")p.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),p.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1),p.event.simulate("change",this,a,!0)});return!1}p.event.add(this,"beforeactivate._change",function(a){var b=a.target;V.test(b.nodeName)&&!p._data(b,"_change_attached")&&(p.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&p.event.simulate("change",this.parentNode,a,!0)}),p._data(b,"_change_attached",!0))})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){return p.event.remove(this,"._change"),!V.test(this.nodeName)}}),p.support.focusinBubbles||p.each({focus:"focusin",blur:"focusout"},function(a,b){var c=0,d=function(a){p.event.simulate(b,a.target,p.event.fix(a),!0)};p.event.special[b]={setup:function(){c++===0&&e.addEventListener(a,d,!0)},teardown:function(){--c===0&&e.removeEventListener(a,d,!0)}}}),p.fn.extend({on:function(a,c,d,e,f){var g,h;if(typeof a=="object"){typeof c!="string"&&(d=d||c,c=b);for(h in a)this.on(h,c,d,a[h],f);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=ba;else if(!e)return this;return f===1&&(g=e,e=function(a){return p().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=p.guid++)),this.each(function(){p.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,c,d){var e,f;if(a&&a.preventDefault&&a.handleObj)return e=a.handleObj,p(a.delegateTarget).off(e.namespace?e.origType+"."+e.namespace:e.origType,e.selector,e.handler),this;if(typeof a=="object"){for(f in a)this.off(f,c,a[f]);return this}if(c===!1||typeof c=="function")d=c,c=b;return d===!1&&(d=ba),this.each(function(){p.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){return p(this.context).on(a,this.selector,b,c),this},die:function(a,b){return p(this.context).off(a,this.selector||"**",b),this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length===1?this.off(a,"**"):this.off(b,a||"**",c)},trigger:function(a,b){return this.each(function(){p.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return p.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||p.guid++,d=0,e=function(c){var e=(p._data(this,"lastToggle"+a.guid)||0)%d;return p._data(this,"lastToggle"+a.guid,e+1),c.preventDefault(),b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),p.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){p.fn[b]=function(a,c){return c==null&&(c=a,a=null),arguments.length>0?this.on(b,null,a,c):this.trigger(b)},Y.test(b)&&(p.event.fixHooks[b]=p.event.keyHooks),Z.test(b)&&(p.event.fixHooks[b]=p.event.mouseHooks)}),function(a,b){function bc(a,b,c,d){c=c||[],b=b||r;var e,f,i,j,k=b.nodeType;if(!a||typeof a!="string")return c;if(k!==1&&k!==9)return[];i=g(b);if(!i&&!d)if(e=P.exec(a))if(j=e[1]){if(k===9){f=b.getElementById(j);if(!f||!f.parentNode)return c;if(f.id===j)return c.push(f),c}else if(b.ownerDocument&&(f=b.ownerDocument.getElementById(j))&&h(b,f)&&f.id===j)return c.push(f),c}else{if(e[2])return w.apply(c,x.call(b.getElementsByTagName(a),0)),c;if((j=e[3])&&_&&b.getElementsByClassName)return w.apply(c,x.call(b.getElementsByClassName(j),0)),c}return bp(a.replace(L,"$1"),b,c,d,i)}function bd(a){return function(b){var c=b.nodeName.toLowerCase();return c==="input"&&b.type===a}}function be(a){return function(b){var c=b.nodeName.toLowerCase();return(c==="input"||c==="button")&&b.type===a}}function bf(a){return z(function(b){return b=+b,z(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function bg(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}function bh(a,b){var c,d,f,g,h,i,j,k=C[o][a];if(k)return b?0:k.slice(0);h=a,i=[],j=e.preFilter;while(h){if(!c||(d=M.exec(h)))d&&(h=h.slice(d[0].length)),i.push(f=[]);c=!1;if(d=N.exec(h))f.push(c=new q(d.shift())),h=h.slice(c.length),c.type=d[0].replace(L," ");for(g in e.filter)(d=W[g].exec(h))&&(!j[g]||(d=j[g](d,r,!0)))&&(f.push(c=new q(d.shift())),h=h.slice(c.length),c.type=g,c.matches=d);if(!c)break}return b?h.length:h?bc.error(a):C(a,i).slice(0)}function bi(a,b,d){var e=b.dir,f=d&&b.dir==="parentNode",g=u++;return b.first?function(b,c,d){while(b=b[e])if(f||b.nodeType===1)return a(b,c,d)}:function(b,d,h){if(!h){var i,j=t+" "+g+" ",k=j+c;while(b=b[e])if(f||b.nodeType===1){if((i=b[o])===k)return b.sizset;if(typeof i=="string"&&i.indexOf(j)===0){if(b.sizset)return b}else{b[o]=k;if(a(b,d,h))return b.sizset=!0,b;b.sizset=!1}}}else while(b=b[e])if(f||b.nodeType===1)if(a(b,d,h))return b}}function bj(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function bk(a,b,c,d,e){var f,g=[],h=0,i=a.length,j=b!=null;for(;h<i;h++)if(f=a[h])if(!c||c(f,d,e))g.push(f),j&&b.push(h);return g}function bl(a,b,c,d,e,f){return d&&!d[o]&&(d=bl(d)),e&&!e[o]&&(e=bl(e,f)),z(function(f,g,h,i){if(f&&e)return;var j,k,l,m=[],n=[],o=g.length,p=f||bo(b||"*",h.nodeType?[h]:h,[],f),q=a&&(f||!b)?bk(p,m,a,h,i):p,r=c?e||(f?a:o||d)?[]:g:q;c&&c(q,r,h,i);if(d){l=bk(r,n),d(l,[],h,i),j=l.length;while(j--)if(k=l[j])r[n[j]]=!(q[n[j]]=k)}if(f){j=a&&r.length;while(j--)if(k=r[j])f[m[j]]=!(g[m[j]]=k)}else r=bk(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):w.apply(g,r)})}function bm(a){var b,c,d,f=a.length,g=e.relative[a[0].type],h=g||e.relative[" "],i=g?1:0,j=bi(function(a){return a===b},h,!0),k=bi(function(a){return y.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==l)||((b=c).nodeType?j(a,c,d):k(a,c,d))}];for(;i<f;i++)if(c=e.relative[a[i].type])m=[bi(bj(m),c)];else{c=e.filter[a[i].type].apply(null,a[i].matches);if(c[o]){d=++i;for(;d<f;d++)if(e.relative[a[d].type])break;return bl(i>1&&bj(m),i>1&&a.slice(0,i-1).join("").replace(L,"$1"),c,i<d&&bm(a.slice(i,d)),d<f&&bm(a=a.slice(d)),d<f&&a.join(""))}m.push(c)}return bj(m)}function bn(a,b){var d=b.length>0,f=a.length>0,g=function(h,i,j,k,m){var n,o,p,q=[],s=0,u="0",x=h&&[],y=m!=null,z=l,A=h||f&&e.find.TAG("*",m&&i.parentNode||i),B=t+=z==null?1:Math.E;y&&(l=i!==r&&i,c=g.el);for(;(n=A[u])!=null;u++){if(f&&n){for(o=0;p=a[o];o++)if(p(n,i,j)){k.push(n);break}y&&(t=B,c=++g.el)}d&&((n=!p&&n)&&s--,h&&x.push(n))}s+=u;if(d&&u!==s){for(o=0;p=b[o];o++)p(x,q,i,j);if(h){if(s>0)while(u--)!x[u]&&!q[u]&&(q[u]=v.call(k));q=bk(q)}w.apply(k,q),y&&!h&&q.length>0&&s+b.length>1&&bc.uniqueSort(k)}return y&&(t=B,l=z),x};return g.el=0,d?z(g):g}function bo(a,b,c,d){var e=0,f=b.length;for(;e<f;e++)bc(a,b[e],c,d);return c}function bp(a,b,c,d,f){var g,h,j,k,l,m=bh(a),n=m.length;if(!d&&m.length===1){h=m[0]=m[0].slice(0);if(h.length>2&&(j=h[0]).type==="ID"&&b.nodeType===9&&!f&&e.relative[h[1].type]){b=e.find.ID(j.matches[0].replace(V,""),b,f)[0];if(!b)return c;a=a.slice(h.shift().length)}for(g=W.POS.test(a)?-1:h.length-1;g>=0;g--){j=h[g];if(e.relative[k=j.type])break;if(l=e.find[k])if(d=l(j.matches[0].replace(V,""),R.test(h[0].type)&&b.parentNode||b,f)){h.splice(g,1),a=d.length&&h.join("");if(!a)return w.apply(c,x.call(d,0)),c;break}}}return i(a,m)(d,b,f,c,R.test(a)),c}function bq(){}var c,d,e,f,g,h,i,j,k,l,m=!0,n="undefined",o=("sizcache"+Math.random()).replace(".",""),q=String,r=a.document,s=r.documentElement,t=0,u=0,v=[].pop,w=[].push,x=[].slice,y=[].indexOf||function(a){var b=0,c=this.length;for(;b<c;b++)if(this[b]===a)return b;return-1},z=function(a,b){return a[o]=b==null||b,a},A=function(){var a={},b=[];return z(function(c,d){return b.push(c)>e.cacheLength&&delete a[b.shift()],a[c]=d},a)},B=A(),C=A(),D=A(),E="[\\x20\\t\\r\\n\\f]",F="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",G=F.replace("w","w#"),H="([*^$|!~]?=)",I="\\["+E+"*("+F+")"+E+"*(?:"+H+E+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+G+")|)|)"+E+"*\\]",J=":("+F+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:"+I+")|[^:]|\\\\.)*|.*))\\)|)",K=":(even|odd|eq|gt|lt|nth|first|last)(?:\\("+E+"*((?:-\\d)?\\d*)"+E+"*\\)|)(?=[^-]|$)",L=new RegExp("^"+E+"+|((?:^|[^\\\\])(?:\\\\.)*)"+E+"+$","g"),M=new RegExp("^"+E+"*,"+E+"*"),N=new RegExp("^"+E+"*([\\x20\\t\\r\\n\\f>+~])"+E+"*"),O=new RegExp(J),P=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,Q=/^:not/,R=/[\x20\t\r\n\f]*[+~]/,S=/:not\($/,T=/h\d/i,U=/input|select|textarea|button/i,V=/\\(?!\\)/g,W={ID:new RegExp("^#("+F+")"),CLASS:new RegExp("^\\.("+F+")"),NAME:new RegExp("^\\[name=['\"]?("+F+")['\"]?\\]"),TAG:new RegExp("^("+F.replace("w","w*")+")"),ATTR:new RegExp("^"+I),PSEUDO:new RegExp("^"+J),POS:new RegExp(K,"i"),CHILD:new RegExp("^:(only|nth|first|last)-child(?:\\("+E+"*(even|odd|(([+-]|)(\\d*)n|)"+E+"*(?:([+-]|)"+E+"*(\\d+)|))"+E+"*\\)|)","i"),needsContext:new RegExp("^"+E+"*[>+~]|"+K,"i")},X=function(a){var b=r.createElement("div");try{return a(b)}catch(c){return!1}finally{b=null}},Y=X(function(a){return a.appendChild(r.createComment("")),!a.getElementsByTagName("*").length}),Z=X(function(a){return a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!==n&&a.firstChild.getAttribute("href")==="#"}),$=X(function(a){a.innerHTML="<select></select>";var b=typeof a.lastChild.getAttribute("multiple");return b!=="boolean"&&b!=="string"}),_=X(function(a){return a.innerHTML="<div class='hidden e'></div><div class='hidden'></div>",!a.getElementsByClassName||!a.getElementsByClassName("e").length?!1:(a.lastChild.className="e",a.getElementsByClassName("e").length===2)}),ba=X(function(a){a.id=o+0,a.innerHTML="<a name='"+o+"'></a><div name='"+o+"'></div>",s.insertBefore(a,s.firstChild);var b=r.getElementsByName&&r.getElementsByName(o).length===2+r.getElementsByName(o+0).length;return d=!r.getElementById(o),s.removeChild(a),b});try{x.call(s.childNodes,0)[0].nodeType}catch(bb){x=function(a){var b,c=[];for(;b=this[a];a++)c.push(b);return c}}bc.matches=function(a,b){return bc(a,null,null,b)},bc.matchesSelector=function(a,b){return bc(b,null,null,[a]).length>0},f=bc.getText=function(a){var b,c="",d=0,e=a.nodeType;if(e){if(e===1||e===9||e===11){if(typeof a.textContent=="string")return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=f(a)}else if(e===3||e===4)return a.nodeValue}else for(;b=a[d];d++)c+=f(b);return c},g=bc.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?b.nodeName!=="HTML":!1},h=bc.contains=s.contains?function(a,b){var c=a.nodeType===9?a.documentElement:a,d=b&&b.parentNode;return a===d||!!(d&&d.nodeType===1&&c.contains&&c.contains(d))}:s.compareDocumentPosition?function(a,b){return b&&!!(a.compareDocumentPosition(b)&16)}:function(a,b){while(b=b.parentNode)if(b===a)return!0;return!1},bc.attr=function(a,b){var c,d=g(a);return d||(b=b.toLowerCase()),(c=e.attrHandle[b])?c(a):d||$?a.getAttribute(b):(c=a.getAttributeNode(b),c?typeof a[b]=="boolean"?a[b]?b:null:c.specified?c.value:null:null)},e=bc.selectors={cacheLength:50,createPseudo:z,match:W,attrHandle:Z?{}:{href:function(a){return a.getAttribute("href",2)},type:function(a){return a.getAttribute("type")}},find:{ID:d?function(a,b,c){if(typeof b.getElementById!==n&&!c){var d=b.getElementById(a);return d&&d.parentNode?[d]:[]}}:function(a,c,d){if(typeof c.getElementById!==n&&!d){var e=c.getElementById(a);return e?e.id===a||typeof e.getAttributeNode!==n&&e.getAttributeNode("id").value===a?[e]:b:[]}},TAG:Y?function(a,b){if(typeof b.getElementsByTagName!==n)return b.getElementsByTagName(a)}:function(a,b){var c=b.getElementsByTagName(a);if(a==="*"){var d,e=[],f=0;for(;d=c[f];f++)d.nodeType===1&&e.push(d);return e}return c},NAME:ba&&function(a,b){if(typeof b.getElementsByName!==n)return b.getElementsByName(name)},CLASS:_&&function(a,b,c){if(typeof b.getElementsByClassName!==n&&!c)return b.getElementsByClassName(a)}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(V,""),a[3]=(a[4]||a[5]||"").replace(V,""),a[2]==="~="&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),a[1]==="nth"?(a[2]||bc.error(a[0]),a[3]=+(a[3]?a[4]+(a[5]||1):2*(a[2]==="even"||a[2]==="odd")),a[4]=+(a[6]+a[7]||a[2]==="odd")):a[2]&&bc.error(a[0]),a},PSEUDO:function(a){var b,c;if(W.CHILD.test(a[0]))return null;if(a[3])a[2]=a[3];else if(b=a[4])O.test(b)&&(c=bh(b,!0))&&(c=b.indexOf(")",b.length-c)-b.length)&&(b=b.slice(0,c),a[0]=a[0].slice(0,c)),a[2]=b;return a.slice(0,3)}},filter:{ID:d?function(a){return a=a.replace(V,""),function(b){return b.getAttribute("id")===a}}:function(a){return a=a.replace(V,""),function(b){var c=typeof b.getAttributeNode!==n&&b.getAttributeNode("id");return c&&c.value===a}},TAG:function(a){return a==="*"?function(){return!0}:(a=a.replace(V,"").toLowerCase(),function(b){return b.nodeName&&b.nodeName.toLowerCase()===a})},CLASS:function(a){var b=B[o][a];return b||(b=B(a,new RegExp("(^|"+E+")"+a+"("+E+"|$)"))),function(a){return b.test(a.className||typeof a.getAttribute!==n&&a.getAttribute("class")||"")}},ATTR:function(a,b,c){return function(d,e){var f=bc.attr(d,a);return f==null?b==="!=":b?(f+="",b==="="?f===c:b==="!="?f!==c:b==="^="?c&&f.indexOf(c)===0:b==="*="?c&&f.indexOf(c)>-1:b==="$="?c&&f.substr(f.length-c.length)===c:b==="~="?(" "+f+" ").indexOf(c)>-1:b==="|="?f===c||f.substr(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d){return a==="nth"?function(a){var b,e,f=a.parentNode;if(c===1&&d===0)return!0;if(f){e=0;for(b=f.firstChild;b;b=b.nextSibling)if(b.nodeType===1){e++;if(a===b)break}}return e-=d,e===c||e%c===0&&e/c>=0}:function(b){var c=b;switch(a){case"only":case"first":while(c=c.previousSibling)if(c.nodeType===1)return!1;if(a==="first")return!0;c=b;case"last":while(c=c.nextSibling)if(c.nodeType===1)return!1;return!0}}},PSEUDO:function(a,b){var c,d=e.pseudos[a]||e.setFilters[a.toLowerCase()]||bc.error("unsupported pseudo: "+a);return d[o]?d(b):d.length>1?(c=[a,a,"",b],e.setFilters.hasOwnProperty(a.toLowerCase())?z(function(a,c){var e,f=d(a,b),g=f.length;while(g--)e=y.call(a,f[g]),a[e]=!(c[e]=f[g])}):function(a){return d(a,0,c)}):d}},pseudos:{not:z(function(a){var b=[],c=[],d=i(a.replace(L,"$1"));return d[o]?z(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)if(f=g[h])a[h]=!(b[h]=f)}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:z(function(a){return function(b){return bc(a,b).length>0}}),contains:z(function(a){return function(b){return(b.textContent||b.innerText||f(b)).indexOf(a)>-1}}),enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&!!a.checked||b==="option"&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},parent:function(a){return!e.pseudos.empty(a)},empty:function(a){var b;a=a.firstChild;while(a){if(a.nodeName>"@"||(b=a.nodeType)===3||b===4)return!1;a=a.nextSibling}return!0},header:function(a){return T.test(a.nodeName)},text:function(a){var b,c;return a.nodeName.toLowerCase()==="input"&&(b=a.type)==="text"&&((c=a.getAttribute("type"))==null||c.toLowerCase()===b)},radio:bd("radio"),checkbox:bd("checkbox"),file:bd("file"),password:bd("password"),image:bd("image"),submit:be("submit"),reset:be("reset"),button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&a.type==="button"||b==="button"},input:function(a){return U.test(a.nodeName)},focus:function(a){var b=a.ownerDocument;return a===b.activeElement&&(!b.hasFocus||b.hasFocus())&&(!!a.type||!!a.href)},active:function(a){return a===a.ownerDocument.activeElement},first:bf(function(a,b,c){return[0]}),last:bf(function(a,b,c){return[b-1]}),eq:bf(function(a,b,c){return[c<0?c+b:c]}),even:bf(function(a,b,c){for(var d=0;d<b;d+=2)a.push(d);return a}),odd:bf(function(a,b,c){for(var d=1;d<b;d+=2)a.push(d);return a}),lt:bf(function(a,b,c){for(var d=c<0?c+b:c;--d>=0;)a.push(d);return a}),gt:bf(function(a,b,c){for(var d=c<0?c+b:c;++d<b;)a.push(d);return a})}},j=s.compareDocumentPosition?function(a,b){return a===b?(k=!0,0):(!a.compareDocumentPosition||!b.compareDocumentPosition?a.compareDocumentPosition:a.compareDocumentPosition(b)&4)?-1:1}:function(a,b){if(a===b)return k=!0,0;if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],g=a.parentNode,h=b.parentNode,i=g;if(g===h)return bg(a,b);if(!g)return-1;if(!h)return 1;while(i)e.unshift(i),i=i.parentNode;i=h;while(i)f.unshift(i),i=i.parentNode;c=e.length,d=f.length;for(var j=0;j<c&&j<d;j++)if(e[j]!==f[j])return bg(e[j],f[j]);return j===c?bg(a,f[j],-1):bg(e[j],b,1)},[0,0].sort(j),m=!k,bc.uniqueSort=function(a){var b,c=1;k=m,a.sort(j);if(k)for(;b=a[c];c++)b===a[c-1]&&a.splice(c--,1);return a},bc.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},i=bc.compile=function(a,b){var c,d=[],e=[],f=D[o][a];if(!f){b||(b=bh(a)),c=b.length;while(c--)f=bm(b[c]),f[o]?d.push(f):e.push(f);f=D(a,bn(e,d))}return f},r.querySelectorAll&&function(){var a,b=bp,c=/'|\\/g,d=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,e=[":focus"],f=[":active",":focus"],h=s.matchesSelector||s.mozMatchesSelector||s.webkitMatchesSelector||s.oMatchesSelector||s.msMatchesSelector;X(function(a){a.innerHTML="<select><option selected=''></option></select>",a.querySelectorAll("[selected]").length||e.push("\\["+E+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),a.querySelectorAll(":checked").length||e.push(":checked")}),X(function(a){a.innerHTML="<p test=''></p>",a.querySelectorAll("[test^='']").length&&e.push("[*^$]="+E+"*(?:\"\"|'')"),a.innerHTML="<input type='hidden'/>",a.querySelectorAll(":enabled").length||e.push(":enabled",":disabled")}),e=new RegExp(e.join("|")),bp=function(a,d,f,g,h){if(!g&&!h&&(!e||!e.test(a))){var i,j,k=!0,l=o,m=d,n=d.nodeType===9&&a;if(d.nodeType===1&&d.nodeName.toLowerCase()!=="object"){i=bh(a),(k=d.getAttribute("id"))?l=k.replace(c,"\\$&"):d.setAttribute("id",l),l="[id='"+l+"'] ",j=i.length;while(j--)i[j]=l+i[j].join("");m=R.test(a)&&d.parentNode||d,n=i.join(",")}if(n)try{return w.apply(f,x.call(m.querySelectorAll(n),0)),f}catch(p){}finally{k||d.removeAttribute("id")}}return b(a,d,f,g,h)},h&&(X(function(b){a=h.call(b,"div");try{h.call(b,"[test!='']:sizzle"),f.push("!=",J)}catch(c){}}),f=new RegExp(f.join("|")),bc.matchesSelector=function(b,c){c=c.replace(d,"='$1']");if(!g(b)&&!f.test(c)&&(!e||!e.test(c)))try{var i=h.call(b,c);if(i||a||b.document&&b.document.nodeType!==11)return i}catch(j){}return bc(c,null,null,[b]).length>0})}(),e.pseudos.nth=e.pseudos.eq,e.filters=bq.prototype=e.pseudos,e.setFilters=new bq,bc.attr=p.attr,p.find=bc,p.expr=bc.selectors,p.expr[":"]=p.expr.pseudos,p.unique=bc.uniqueSort,p.text=bc.getText,p.isXMLDoc=bc.isXML,p.contains=bc.contains}(a);var bc=/Until$/,bd=/^(?:parents|prev(?:Until|All))/,be=/^.[^:#\[\.,]*$/,bf=p.expr.match.needsContext,bg={children:!0,contents:!0,next:!0,prev:!0};p.fn.extend({find:function(a){var b,c,d,e,f,g,h=this;if(typeof a!="string")return p(a).filter(function(){for(b=0,c=h.length;b<c;b++)if(p.contains(h[b],this))return!0});g=this.pushStack("","find",a);for(b=0,c=this.length;b<c;b++){d=g.length,p.find(a,this[b],g);if(b>0)for(e=d;e<g.length;e++)for(f=0;f<d;f++)if(g[f]===g[e]){g.splice(e--,1);break}}return g},has:function(a){var b,c=p(a,this),d=c.length;return this.filter(function(){for(b=0;b<d;b++)if(p.contains(this,c[b]))return!0})},not:function(a){return this.pushStack(bj(this,a,!1),"not",a)},filter:function(a){return this.pushStack(bj(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?bf.test(a)?p(a,this.context).index(this[0])>=0:p.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c,d=0,e=this.length,f=[],g=bf.test(a)||typeof a!="string"?p(a,b||this.context):0;for(;d<e;d++){c=this[d];while(c&&c.ownerDocument&&c!==b&&c.nodeType!==11){if(g?g.index(c)>-1:p.find.matchesSelector(c,a)){f.push(c);break}c=c.parentNode}}return f=f.length>1?p.unique(f):f,this.pushStack(f,"closest",a)},index:function(a){return a?typeof a=="string"?p.inArray(this[0],p(a)):p.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(a,b){var c=typeof a=="string"?p(a,b):p.makeArray(a&&a.nodeType?[a]:a),d=p.merge(this.get(),c);return this.pushStack(bh(c[0])||bh(d[0])?d:p.unique(d))},addBack:function(a){return this.add(a==null?this.prevObject:this.prevObject.filter(a))}}),p.fn.andSelf=p.fn.addBack,p.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return p.dir(a,"parentNode")},parentsUntil:function(a,b,c){return p.dir(a,"parentNode",c)},next:function(a){return bi(a,"nextSibling")},prev:function(a){return bi(a,"previousSibling")},nextAll:function(a){return p.dir(a,"nextSibling")},prevAll:function(a){return p.dir(a,"previousSibling")},nextUntil:function(a,b,c){return p.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return p.dir(a,"previousSibling",c)},siblings:function(a){return p.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return p.sibling(a.firstChild)},contents:function(a){return p.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:p.merge([],a.childNodes)}},function(a,b){p.fn[a]=function(c,d){var e=p.map(this,b,c);return bc.test(a)||(d=c),d&&typeof d=="string"&&(e=p.filter(d,e)),e=this.length>1&&!bg[a]?p.unique(e):e,this.length>1&&bd.test(a)&&(e=e.reverse()),this.pushStack(e,a,k.call(arguments).join(","))}}),p.extend({filter:function(a,b,c){return c&&(a=":not("+a+")"),b.length===1?p.find.matchesSelector(b[0],a)?[b[0]]:[]:p.find.matches(a,b)},dir:function(a,c,d){var e=[],f=a[c];while(f&&f.nodeType!==9&&(d===b||f.nodeType!==1||!p(f).is(d)))f.nodeType===1&&e.push(f),f=f[c];return e},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var bl="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",bm=/ jQuery\d+="(?:null|\d+)"/g,bn=/^\s+/,bo=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bp=/<([\w:]+)/,bq=/<tbody/i,br=/<|&#?\w+;/,bs=/<(?:script|style|link)/i,bt=/<(?:script|object|embed|option|style)/i,bu=new RegExp("<(?:"+bl+")[\\s/>]","i"),bv=/^(?:checkbox|radio)$/,bw=/checked\s*(?:[^=]|=\s*.checked.)/i,bx=/\/(java|ecma)script/i,by=/^\s*<!(?:\[CDATA\[|\-\-)|[\]\-]{2}>\s*$/g,bz={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},bA=bk(e),bB=bA.appendChild(e.createElement("div"));bz.optgroup=bz.option,bz.tbody=bz.tfoot=bz.colgroup=bz.caption=bz.thead,bz.th=bz.td,p.support.htmlSerialize||(bz._default=[1,"X<div>","</div>"]),p.fn.extend({text:function(a){return p.access(this,function(a){return a===b?p.text(this):this.empty().append((this[0]&&this[0].ownerDocument||e).createTextNode(a))},null,a,arguments.length)},wrapAll:function(a){if(p.isFunction(a))return this.each(function(b){p(this).wrapAll(a.call(this,b))});if(this[0]){var b=p(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return p.isFunction(a)?this.each(function(b){p(this).wrapInner(a.call(this,b))}):this.each(function(){var b=p(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=p.isFunction(a);return this.each(function(c){p(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){p.nodeName(this,"body")||p(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){(this.nodeType===1||this.nodeType===11)&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(a,this.firstChild)})},before:function(){if(!bh(this[0]))return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=p.clean(arguments);return this.pushStack(p.merge(a,this),"before",this.selector)}},after:function(){if(!bh(this[0]))return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=p.clean(arguments);return this.pushStack(p.merge(this,a),"after",this.selector)}},remove:function(a,b){var c,d=0;for(;(c=this[d])!=null;d++)if(!a||p.filter(a,[c]).length)!b&&c.nodeType===1&&(p.cleanData(c.getElementsByTagName("*")),p.cleanData([c])),c.parentNode&&c.parentNode.removeChild(c);return this},empty:function(){var a,b=0;for(;(a=this[b])!=null;b++){a.nodeType===1&&p.cleanData(a.getElementsByTagName("*"));while(a.firstChild)a.removeChild(a.firstChild)}return this},clone:function(a,b){return a=a==null?!1:a,b=b==null?a:b,this.map(function(){return p.clone(this,a,b)})},html:function(a){return p.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return c.nodeType===1?c.innerHTML.replace(bm,""):b;if(typeof a=="string"&&!bs.test(a)&&(p.support.htmlSerialize||!bu.test(a))&&(p.support.leadingWhitespace||!bn.test(a))&&!bz[(bp.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(bo,"<$1></$2>");try{for(;d<e;d++)c=this[d]||{},c.nodeType===1&&(p.cleanData(c.getElementsByTagName("*")),c.innerHTML=a);c=0}catch(f){}}c&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(a){return bh(this[0])?this.length?this.pushStack(p(p.isFunction(a)?a():a),"replaceWith",a):this:p.isFunction(a)?this.each(function(b){var c=p(this),d=c.html();c.replaceWith(a.call(this,b,d))}):(typeof a!="string"&&(a=p(a).detach()),this.each(function(){var b=this.nextSibling,c=this.parentNode;p(this).remove(),b?p(b).before(a):p(c).append(a)}))},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){a=[].concat.apply([],a);var e,f,g,h,i=0,j=a[0],k=[],l=this.length;if(!p.support.checkClone&&l>1&&typeof j=="string"&&bw.test(j))return this.each(function(){p(this).domManip(a,c,d)});if(p.isFunction(j))return this.each(function(e){var f=p(this);a[0]=j.call(this,e,c?f.html():b),f.domManip(a,c,d)});if(this[0]){e=p.buildFragment(a,this,k),g=e.fragment,f=g.firstChild,g.childNodes.length===1&&(g=f);if(f){c=c&&p.nodeName(f,"tr");for(h=e.cacheable||l-1;i<l;i++)d.call(c&&p.nodeName(this[i],"table")?bC(this[i],"tbody"):this[i],i===h?g:p.clone(g,!0,!0))}g=f=null,k.length&&p.each(k,function(a,b){b.src?p.ajax?p.ajax({url:b.src,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0}):p.error("no ajax"):p.globalEval((b.text||b.textContent||b.innerHTML||"").replace(by,"")),b.parentNode&&b.parentNode.removeChild(b)})}return this}}),p.buildFragment=function(a,c,d){var f,g,h,i=a[0];return c=c||e,c=!c.nodeType&&c[0]||c,c=c.ownerDocument||c,a.length===1&&typeof i=="string"&&i.length<512&&c===e&&i.charAt(0)==="<"&&!bt.test(i)&&(p.support.checkClone||!bw.test(i))&&(p.support.html5Clone||!bu.test(i))&&(g=!0,f=p.fragments[i],h=f!==b),f||(f=c.createDocumentFragment(),p.clean(a,c,f,d),g&&(p.fragments[i]=h&&f)),{fragment:f,cacheable:g}},p.fragments={},p.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){p.fn[a]=function(c){var d,e=0,f=[],g=p(c),h=g.length,i=this.length===1&&this[0].parentNode;if((i==null||i&&i.nodeType===11&&i.childNodes.length===1)&&h===1)return g[b](this[0]),this;for(;e<h;e++)d=(e>0?this.clone(!0):this).get(),p(g[e])[b](d),f=f.concat(d);return this.pushStack(f,a,g.selector)}}),p.extend({clone:function(a,b,c){var d,e,f,g;p.support.html5Clone||p.isXMLDoc(a)||!bu.test("<"+a.nodeName+">")?g=a.cloneNode(!0):(bB.innerHTML=a.outerHTML,bB.removeChild(g=bB.firstChild));if((!p.support.noCloneEvent||!p.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!p.isXMLDoc(a)){bE(a,g),d=bF(a),e=bF(g);for(f=0;d[f];++f)e[f]&&bE(d[f],e[f])}if(b){bD(a,g);if(c){d=bF(a),e=bF(g);for(f=0;d[f];++f)bD(d[f],e[f])}}return d=e=null,g},clean:function(a,b,c,d){var f,g,h,i,j,k,l,m,n,o,q,r,s=b===e&&bA,t=[];if(!b||typeof b.createDocumentFragment=="undefined")b=e;for(f=0;(h=a[f])!=null;f++){typeof h=="number"&&(h+="");if(!h)continue;if(typeof h=="string")if(!br.test(h))h=b.createTextNode(h);else{s=s||bk(b),l=b.createElement("div"),s.appendChild(l),h=h.replace(bo,"<$1></$2>"),i=(bp.exec(h)||["",""])[1].toLowerCase(),j=bz[i]||bz._default,k=j[0],l.innerHTML=j[1]+h+j[2];while(k--)l=l.lastChild;if(!p.support.tbody){m=bq.test(h),n=i==="table"&&!m?l.firstChild&&l.firstChild.childNodes:j[1]==="<table>"&&!m?l.childNodes:[];for(g=n.length-1;g>=0;--g)p.nodeName(n[g],"tbody")&&!n[g].childNodes.length&&n[g].parentNode.removeChild(n[g])}!p.support.leadingWhitespace&&bn.test(h)&&l.insertBefore(b.createTextNode(bn.exec(h)[0]),l.firstChild),h=l.childNodes,l.parentNode.removeChild(l)}h.nodeType?t.push(h):p.merge(t,h)}l&&(h=l=s=null);if(!p.support.appendChecked)for(f=0;(h=t[f])!=null;f++)p.nodeName(h,"input")?bG(h):typeof h.getElementsByTagName!="undefined"&&p.grep(h.getElementsByTagName("input"),bG);if(c){q=function(a){if(!a.type||bx.test(a.type))return d?d.push(a.parentNode?a.parentNode.removeChild(a):a):c.appendChild(a)};for(f=0;(h=t[f])!=null;f++)if(!p.nodeName(h,"script")||!q(h))c.appendChild(h),typeof h.getElementsByTagName!="undefined"&&(r=p.grep(p.merge([],h.getElementsByTagName("script")),q),t.splice.apply(t,[f+1,0].concat(r)),f+=r.length)}return t},cleanData:function(a,b){var c,d,e,f,g=0,h=p.expando,i=p.cache,j=p.support.deleteExpando,k=p.event.special;for(;(e=a[g])!=null;g++)if(b||p.acceptData(e)){d=e[h],c=d&&i[d];if(c){if(c.events)for(f in c.events)k[f]?p.event.remove(e,f):p.removeEvent(e,f,c.handle);i[d]&&(delete i[d],j?delete e[h]:e.removeAttribute?e.removeAttribute(h):e[h]=null,p.deletedIds.push(d))}}}}),function(){var a,b;p.uaMatch=function(a){a=a.toLowerCase();var b=/(chrome)[ \/]([\w.]+)/.exec(a)||/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||a.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},a=p.uaMatch(g.userAgent),b={},a.browser&&(b[a.browser]=!0,b.version=a.version),b.chrome?b.webkit=!0:b.webkit&&(b.safari=!0),p.browser=b,p.sub=function(){function a(b,c){return new a.fn.init(b,c)}p.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function c(c,d){return d&&d instanceof p&&!(d instanceof a)&&(d=a(d)),p.fn.init.call(this,c,d,b)},a.fn.init.prototype=a.fn;var b=a(e);return a}}();var bH,bI,bJ,bK=/alpha\([^)]*\)/i,bL=/opacity=([^)]*)/,bM=/^(top|right|bottom|left)$/,bN=/^(none|table(?!-c[ea]).+)/,bO=/^margin/,bP=new RegExp("^("+q+")(.*)$","i"),bQ=new RegExp("^("+q+")(?!px)[a-z%]+$","i"),bR=new RegExp("^([-+])=("+q+")","i"),bS={},bT={position:"absolute",visibility:"hidden",display:"block"},bU={letterSpacing:0,fontWeight:400},bV=["Top","Right","Bottom","Left"],bW=["Webkit","O","Moz","ms"],bX=p.fn.toggle;p.fn.extend({css:function(a,c){return p.access(this,function(a,c,d){return d!==b?p.style(a,c,d):p.css(a,c)},a,c,arguments.length>1)},show:function(){return b$(this,!0)},hide:function(){return b$(this)},toggle:function(a,b){var c=typeof a=="boolean";return p.isFunction(a)&&p.isFunction(b)?bX.apply(this,arguments):this.each(function(){(c?a:bZ(this))?p(this).show():p(this).hide()})}}),p.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bH(a,"opacity");return c===""?"1":c}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":p.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!a||a.nodeType===3||a.nodeType===8||!a.style)return;var f,g,h,i=p.camelCase(c),j=a.style;c=p.cssProps[i]||(p.cssProps[i]=bY(j,i)),h=p.cssHooks[c]||p.cssHooks[i];if(d===b)return h&&"get"in h&&(f=h.get(a,!1,e))!==b?f:j[c];g=typeof d,g==="string"&&(f=bR.exec(d))&&(d=(f[1]+1)*f[2]+parseFloat(p.css(a,c)),g="number");if(d==null||g==="number"&&isNaN(d))return;g==="number"&&!p.cssNumber[i]&&(d+="px");if(!h||!("set"in h)||(d=h.set(a,d,e))!==b)try{j[c]=d}catch(k){}},css:function(a,c,d,e){var f,g,h,i=p.camelCase(c);return c=p.cssProps[i]||(p.cssProps[i]=bY(a.style,i)),h=p.cssHooks[c]||p.cssHooks[i],h&&"get"in h&&(f=h.get(a,!0,e)),f===b&&(f=bH(a,c)),f==="normal"&&c in bU&&(f=bU[c]),d||e!==b?(g=parseFloat(f),d||p.isNumeric(g)?g||0:f):f},swap:function(a,b,c){var d,e,f={};for(e in b)f[e]=a.style[e],a.style[e]=b[e];d=c.call(a);for(e in b)a.style[e]=f[e];return d}}),a.getComputedStyle?bH=function(b,c){var d,e,f,g,h=a.getComputedStyle(b,null),i=b.style;return h&&(d=h[c],d===""&&!p.contains(b.ownerDocument,b)&&(d=p.style(b,c)),bQ.test(d)&&bO.test(c)&&(e=i.width,f=i.minWidth,g=i.maxWidth,i.minWidth=i.maxWidth=i.width=d,d=h.width,i.width=e,i.minWidth=f,i.maxWidth=g)),d}:e.documentElement.currentStyle&&(bH=function(a,b){var c,d,e=a.currentStyle&&a.currentStyle[b],f=a.style;return e==null&&f&&f[b]&&(e=f[b]),bQ.test(e)&&!bM.test(b)&&(c=f.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":e,e=f.pixelLeft+"px",f.left=c,d&&(a.runtimeStyle.left=d)),e===""?"auto":e}),p.each(["height","width"],function(a,b){p.cssHooks[b]={get:function(a,c,d){if(c)return a.offsetWidth===0&&bN.test(bH(a,"display"))?p.swap(a,bT,function(){return cb(a,b,d)}):cb(a,b,d)},set:function(a,c,d){return b_(a,c,d?ca(a,b,d,p.support.boxSizing&&p.css(a,"boxSizing")==="border-box"):0)}}}),p.support.opacity||(p.cssHooks.opacity={get:function(a,b){return bL.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=p.isNumeric(b)?"alpha(opacity="+b*100+")":"",f=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&p.trim(f.replace(bK,""))===""&&c.removeAttribute){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bK.test(f)?f.replace(bK,e):f+" "+e}}),p(function(){p.support.reliableMarginRight||(p.cssHooks.marginRight={get:function(a,b){return p.swap(a,{display:"inline-block"},function(){if(b)return bH(a,"marginRight")})}}),!p.support.pixelPosition&&p.fn.position&&p.each(["top","left"],function(a,b){p.cssHooks[b]={get:function(a,c){if(c){var d=bH(a,b);return bQ.test(d)?p(a).position()[b]+"px":d}}}})}),p.expr&&p.expr.filters&&(p.expr.filters.hidden=function(a){return a.offsetWidth===0&&a.offsetHeight===0||!p.support.reliableHiddenOffsets&&(a.style&&a.style.display||bH(a,"display"))==="none"},p.expr.filters.visible=function(a){return!p.expr.filters.hidden(a)}),p.each({margin:"",padding:"",border:"Width"},function(a,b){p.cssHooks[a+b]={expand:function(c){var d,e=typeof c=="string"?c.split(" "):[c],f={};for(d=0;d<4;d++)f[a+bV[d]+b]=e[d]||e[d-2]||e[0];return f}},bO.test(a)||(p.cssHooks[a+b].set=b_)});var cd=/%20/g,ce=/\[\]$/,cf=/\r?\n/g,cg=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,ch=/^(?:select|textarea)/i;p.fn.extend({serialize:function(){return p.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?p.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ch.test(this.nodeName)||cg.test(this.type))}).map(function(a,b){var c=p(this).val();return c==null?null:p.isArray(c)?p.map(c,function(a,c){return{name:b.name,value:a.replace(cf,"\r\n")}}):{name:b.name,value:c.replace(cf,"\r\n")}}).get()}}),p.param=function(a,c){var d,e=[],f=function(a,b){b=p.isFunction(b)?b():b==null?"":b,e[e.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=p.ajaxSettings&&p.ajaxSettings.traditional);if(p.isArray(a)||a.jquery&&!p.isPlainObject(a))p.each(a,function(){f(this.name,this.value)});else for(d in a)ci(d,a[d],c,f);return e.join("&").replace(cd,"+")};var cj,ck,cl=/#.*$/,cm=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,cn=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,co=/^(?:GET|HEAD)$/,cp=/^\/\//,cq=/\?/,cr=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,cs=/([?&])_=[^&]*/,ct=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,cu=p.fn.load,cv={},cw={},cx=["*/"]+["*"];try{ck=f.href}catch(cy){ck=e.createElement("a"),ck.href="",ck=ck.href}cj=ct.exec(ck.toLowerCase())||[],p.fn.load=function(a,c,d){if(typeof a!="string"&&cu)return cu.apply(this,arguments);if(!this.length)return this;var e,f,g,h=this,i=a.indexOf(" ");return i>=0&&(e=a.slice(i,a.length),a=a.slice(0,i)),p.isFunction(c)?(d=c,c=b):c&&typeof c=="object"&&(f="POST"),p.ajax({url:a,type:f,dataType:"html",data:c,complete:function(a,b){d&&h.each(d,g||[a.responseText,b,a])}}).done(function(a){g=arguments,h.html(e?p("<div>").append(a.replace(cr,"")).find(e):a)}),this},p.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){p.fn[b]=function(a){return this.on(b,a)}}),p.each(["get","post"],function(a,c){p[c]=function(a,d,e,f){return p.isFunction(d)&&(f=f||e,e=d,d=b),p.ajax({type:c,url:a,data:d,success:e,dataType:f})}}),p.extend({getScript:function(a,c){return p.get(a,b,c,"script")},getJSON:function(a,b,c){return p.get(a,b,c,"json")},ajaxSetup:function(a,b){return b?cB(a,p.ajaxSettings):(b=a,a=p.ajaxSettings),cB(a,b),a},ajaxSettings:{url:ck,isLocal:cn.test(cj[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":cx},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":p.parseJSON,"text xml":p.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:cz(cv),ajaxTransport:cz(cw),ajax:function(a,c){function y(a,c,f,i){var k,s,t,u,w,y=c;if(v===2)return;v=2,h&&clearTimeout(h),g=b,e=i||"",x.readyState=a>0?4:0,f&&(u=cC(l,x,f));if(a>=200&&a<300||a===304)l.ifModified&&(w=x.getResponseHeader("Last-Modified"),w&&(p.lastModified[d]=w),w=x.getResponseHeader("Etag"),w&&(p.etag[d]=w)),a===304?(y="notmodified",k=!0):(k=cD(l,u),y=k.state,s=k.data,t=k.error,k=!t);else{t=y;if(!y||a)y="error",a<0&&(a=0)}x.status=a,x.statusText=(c||y)+"",k?o.resolveWith(m,[s,y,x]):o.rejectWith(m,[x,y,t]),x.statusCode(r),r=b,j&&n.trigger("ajax"+(k?"Success":"Error"),[x,l,k?s:t]),q.fireWith(m,[x,y]),j&&(n.trigger("ajaxComplete",[x,l]),--p.active||p.event.trigger("ajaxStop"))}typeof a=="object"&&(c=a,a=b),c=c||{};var d,e,f,g,h,i,j,k,l=p.ajaxSetup({},c),m=l.context||l,n=m!==l&&(m.nodeType||m instanceof p)?p(m):p.event,o=p.Deferred(),q=p.Callbacks("once memory"),r=l.statusCode||{},t={},u={},v=0,w="canceled",x={readyState:0,setRequestHeader:function(a,b){if(!v){var c=a.toLowerCase();a=u[c]=u[c]||a,t[a]=b}return this},getAllResponseHeaders:function(){return v===2?e:null},getResponseHeader:function(a){var c;if(v===2){if(!f){f={};while(c=cm.exec(e))f[c[1].toLowerCase()]=c[2]}c=f[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){return v||(l.mimeType=a),this},abort:function(a){return a=a||w,g&&g.abort(a),y(0,a),this}};o.promise(x),x.success=x.done,x.error=x.fail,x.complete=q.add,x.statusCode=function(a){if(a){var b;if(v<2)for(b in a)r[b]=[r[b],a[b]];else b=a[x.status],x.always(b)}return this},l.url=((a||l.url)+"").replace(cl,"").replace(cp,cj[1]+"//"),l.dataTypes=p.trim(l.dataType||"*").toLowerCase().split(s),l.crossDomain==null&&(i=ct.exec(l.url.toLowerCase())||!1,l.crossDomain=i&&i.join(":")+(i[3]?"":i[1]==="http:"?80:443)!==cj.join(":")+(cj[3]?"":cj[1]==="http:"?80:443)),l.data&&l.processData&&typeof l.data!="string"&&(l.data=p.param(l.data,l.traditional)),cA(cv,l,c,x);if(v===2)return x;j=l.global,l.type=l.type.toUpperCase(),l.hasContent=!co.test(l.type),j&&p.active++===0&&p.event.trigger("ajaxStart");if(!l.hasContent){l.data&&(l.url+=(cq.test(l.url)?"&":"?")+l.data,delete l.data),d=l.url;if(l.cache===!1){var z=p.now(),A=l.url.replace(cs,"$1_="+z);l.url=A+(A===l.url?(cq.test(l.url)?"&":"?")+"_="+z:"")}}(l.data&&l.hasContent&&l.contentType!==!1||c.contentType)&&x.setRequestHeader("Content-Type",l.contentType),l.ifModified&&(d=d||l.url,p.lastModified[d]&&x.setRequestHeader("If-Modified-Since",p.lastModified[d]),p.etag[d]&&x.setRequestHeader("If-None-Match",p.etag[d])),x.setRequestHeader("Accept",l.dataTypes[0]&&l.accepts[l.dataTypes[0]]?l.accepts[l.dataTypes[0]]+(l.dataTypes[0]!=="*"?", "+cx+"; q=0.01":""):l.accepts["*"]);for(k in l.headers)x.setRequestHeader(k,l.headers[k]);if(!l.beforeSend||l.beforeSend.call(m,x,l)!==!1&&v!==2){w="abort";for(k in{success:1,error:1,complete:1})x[k](l[k]);g=cA(cw,l,c,x);if(!g)y(-1,"No Transport");else{x.readyState=1,j&&n.trigger("ajaxSend",[x,l]),l.async&&l.timeout>0&&(h=setTimeout(function(){x.abort("timeout")},l.timeout));try{v=1,g.send(t,y)}catch(B){if(v<2)y(-1,B);else throw B}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var cE=[],cF=/\?/,cG=/(=)\?(?=&|$)|\?\?/,cH=p.now();p.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=cE.pop()||p.expando+"_"+cH++;return this[a]=!0,a}}),p.ajaxPrefilter("json jsonp",function(c,d,e){var f,g,h,i=c.data,j=c.url,k=c.jsonp!==!1,l=k&&cG.test(j),m=k&&!l&&typeof i=="string"&&!(c.contentType||"").indexOf("application/x-www-form-urlencoded")&&cG.test(i);if(c.dataTypes[0]==="jsonp"||l||m)return f=c.jsonpCallback=p.isFunction(c.jsonpCallback)?c.jsonpCallback():c.jsonpCallback,g=a[f],l?c.url=j.replace(cG,"$1"+f):m?c.data=i.replace(cG,"$1"+f):k&&(c.url+=(cF.test(j)?"&":"?")+c.jsonp+"="+f),c.converters["script json"]=function(){return h||p.error(f+" was not called"),h[0]},c.dataTypes[0]="json",a[f]=function(){h=arguments},e.always(function(){a[f]=g,c[f]&&(c.jsonpCallback=d.jsonpCallback,cE.push(f)),h&&p.isFunction(g)&&g(h[0]),h=g=b}),"script"}),p.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){return p.globalEval(a),a}}}),p.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),p.ajaxTransport("script",function(a){if(a.crossDomain){var c,d=e.head||e.getElementsByTagName("head")[0]||e.documentElement;return{send:function(f,g){c=e.createElement("script"),c.async="async",a.scriptCharset&&(c.charset=a.scriptCharset),c.src=a.url,c.onload=c.onreadystatechange=function(a,e){if(e||!c.readyState||/loaded|complete/.test(c.readyState))c.onload=c.onreadystatechange=null,d&&c.parentNode&&d.removeChild(c),c=b,e||g(200,"success")},d.insertBefore(c,d.firstChild)},abort:function(){c&&c.onload(0,1)}}}});var cI,cJ=a.ActiveXObject?function(){for(var a in cI)cI[a](0,1)}:!1,cK=0;p.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&cL()||cM()}:cL,function(a){p.extend(p.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(p.ajaxSettings.xhr()),p.support.ajax&&p.ajaxTransport(function(c){if(!c.crossDomain||p.support.cors){var d;return{send:function(e,f){var g,h,i=c.xhr();c.username?i.open(c.type,c.url,c.async,c.username,c.password):i.open(c.type,c.url,c.async);if(c.xhrFields)for(h in c.xhrFields)i[h]=c.xhrFields[h];c.mimeType&&i.overrideMimeType&&i.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(h in e)i.setRequestHeader(h,e[h])}catch(j){}i.send(c.hasContent&&c.data||null),d=function(a,e){var h,j,k,l,m;try{if(d&&(e||i.readyState===4)){d=b,g&&(i.onreadystatechange=p.noop,cJ&&delete cI[g]);if(e)i.readyState!==4&&i.abort();else{h=i.status,k=i.getAllResponseHeaders(),l={},m=i.responseXML,m&&m.documentElement&&(l.xml=m);try{l.text=i.responseText}catch(a){}try{j=i.statusText}catch(n){j=""}!h&&c.isLocal&&!c.crossDomain?h=l.text?200:404:h===1223&&(h=204)}}}catch(o){e||f(-1,o)}l&&f(h,j,l,k)},c.async?i.readyState===4?setTimeout(d,0):(g=++cK,cJ&&(cI||(cI={},p(a).unload(cJ)),cI[g]=d),i.onreadystatechange=d):d()},abort:function(){d&&d(0,1)}}}});var cN,cO,cP=/^(?:toggle|show|hide)$/,cQ=new RegExp("^(?:([-+])=|)("+q+")([a-z%]*)$","i"),cR=/queueHooks$/,cS=[cY],cT={"*":[function(a,b){var c,d,e=this.createTween(a,b),f=cQ.exec(b),g=e.cur(),h=+g||0,i=1,j=20;if(f){c=+f[2],d=f[3]||(p.cssNumber[a]?"":"px");if(d!=="px"&&h){h=p.css(e.elem,a,!0)||c||1;do i=i||".5",h=h/i,p.style(e.elem,a,h+d);while(i!==(i=e.cur()/g)&&i!==1&&--j)}e.unit=d,e.start=h,e.end=f[1]?h+(f[1]+1)*c:c}return e}]};p.Animation=p.extend(cW,{tweener:function(a,b){p.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");var c,d=0,e=a.length;for(;d<e;d++)c=a[d],cT[c]=cT[c]||[],cT[c].unshift(b)},prefilter:function(a,b){b?cS.unshift(a):cS.push(a)}}),p.Tween=cZ,cZ.prototype={constructor:cZ,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(p.cssNumber[c]?"":"px")},cur:function(){var a=cZ.propHooks[this.prop];return a&&a.get?a.get(this):cZ.propHooks._default.get(this)},run:function(a){var b,c=cZ.propHooks[this.prop];return this.options.duration?this.pos=b=p.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):cZ.propHooks._default.set(this),this}},cZ.prototype.init.prototype=cZ.prototype,cZ.propHooks={_default:{get:function(a){var b;return a.elem[a.prop]==null||!!a.elem.style&&a.elem.style[a.prop]!=null?(b=p.css(a.elem,a.prop,!1,""),!b||b==="auto"?0:b):a.elem[a.prop]},set:function(a){p.fx.step[a.prop]?p.fx.step[a.prop](a):a.elem.style&&(a.elem.style[p.cssProps[a.prop]]!=null||p.cssHooks[a.prop])?p.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},cZ.propHooks.scrollTop=cZ.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},p.each(["toggle","show","hide"],function(a,b){var c=p.fn[b];p.fn[b]=function(d,e,f){return d==null||typeof d=="boolean"||!a&&p.isFunction(d)&&p.isFunction(e)?c.apply(this,arguments):this.animate(c$(b,!0),d,e,f)}}),p.fn.extend({fadeTo:function(a,b,c,d){return this.filter(bZ).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=p.isEmptyObject(a),f=p.speed(b,c,d),g=function(){var b=cW(this,p.extend({},a),f);e&&b.stop(!0)};return e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,c,d){var e=function(a){var b=a.stop;delete a.stop,b(d)};return typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,c=a!=null&&a+"queueHooks",f=p.timers,g=p._data(this);if(c)g[c]&&g[c].stop&&e(g[c]);else for(c in g)g[c]&&g[c].stop&&cR.test(c)&&e(g[c]);for(c=f.length;c--;)f[c].elem===this&&(a==null||f[c].queue===a)&&(f[c].anim.stop(d),b=!1,f.splice(c,1));(b||!d)&&p.dequeue(this,a)})}}),p.each({slideDown:c$("show"),slideUp:c$("hide"),slideToggle:c$("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){p.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),p.speed=function(a,b,c){var d=a&&typeof a=="object"?p.extend({},a):{complete:c||!c&&b||p.isFunction(a)&&a,duration:a,easing:c&&b||b&&!p.isFunction(b)&&b};d.duration=p.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in p.fx.speeds?p.fx.speeds[d.duration]:p.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";return d.old=d.complete,d.complete=function(){p.isFunction(d.old)&&d.old.call(this),d.queue&&p.dequeue(this,d.queue)},d},p.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},p.timers=[],p.fx=cZ.prototype.init,p.fx.tick=function(){var a,b=p.timers,c=0;for(;c<b.length;c++)a=b[c],!a()&&b[c]===a&&b.splice(c--,1);b.length||p.fx.stop()},p.fx.timer=function(a){a()&&p.timers.push(a)&&!cO&&(cO=setInterval(p.fx.tick,p.fx.interval))},p.fx.interval=13,p.fx.stop=function(){clearInterval(cO),cO=null},p.fx.speeds={slow:600,fast:200,_default:400},p.fx.step={},p.expr&&p.expr.filters&&(p.expr.filters.animated=function(a){return p.grep(p.timers,function(b){return a===b.elem}).length});var c_=/^(?:body|html)$/i;p.fn.offset=function(a){if(arguments.length)return a===b?this:this.each(function(b){p.offset.setOffset(this,a,b)});var c,d,e,f,g,h,i,j={top:0,left:0},k=this[0],l=k&&k.ownerDocument;if(!l)return;return(d=l.body)===k?p.offset.bodyOffset(k):(c=l.documentElement,p.contains(c,k)?(typeof k.getBoundingClientRect!="undefined"&&(j=k.getBoundingClientRect()),e=da(l),f=c.clientTop||d.clientTop||0,g=c.clientLeft||d.clientLeft||0,h=e.pageYOffset||c.scrollTop,i=e.pageXOffset||c.scrollLeft,{top:j.top+h-f,left:j.left+i-g}):j)},p.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;return p.support.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(p.css(a,"marginTop"))||0,c+=parseFloat(p.css(a,"marginLeft"))||0),{top:b,left:c}},setOffset:function(a,b,c){var d=p.css(a,"position");d==="static"&&(a.style.position="relative");var e=p(a),f=e.offset(),g=p.css(a,"top"),h=p.css(a,"left"),i=(d==="absolute"||d==="fixed")&&p.inArray("auto",[g,h])>-1,j={},k={},l,m;i?(k=e.position(),l=k.top,m=k.left):(l=parseFloat(g)||0,m=parseFloat(h)||0),p.isFunction(b)&&(b=b.call(a,c,f)),b.top!=null&&(j.top=b.top-f.top+l),b.left!=null&&(j.left=b.left-f.left+m),"using"in b?b.using.call(a,j):e.css(j)}},p.fn.extend({position:function(){if(!this[0])return;var a=this[0],b=this.offsetParent(),c=this.offset(),d=c_.test(b[0].nodeName)?{top:0,left:0}:b.offset();return c.top-=parseFloat(p.css(a,"marginTop"))||0,c.left-=parseFloat(p.css(a,"marginLeft"))||0,d.top+=parseFloat(p.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(p.css(b[0],"borderLeftWidth"))||0,{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||e.body;while(a&&!c_.test(a.nodeName)&&p.css(a,"position")==="static")a=a.offsetParent;return a||e.body})}}),p.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,c){var d=/Y/.test(c);p.fn[a]=function(e){return p.access(this,function(a,e,f){var g=da(a);if(f===b)return g?c in g?g[c]:g.document.documentElement[e]:a[e];g?g.scrollTo(d?p(g).scrollLeft():f,d?f:p(g).scrollTop()):a[e]=f},a,e,arguments.length,null)}}),p.each({Height:"height",Width:"width"},function(a,c){p.each({padding:"inner"+a,content:c,"":"outer"+a},function(d,e){p.fn[e]=function(e,f){var g=arguments.length&&(d||typeof e!="boolean"),h=d||(e===!0||f===!0?"margin":"border");return p.access(this,function(c,d,e){var f;return p.isWindow(c)?c.document.documentElement["client"+a]:c.nodeType===9?(f=c.documentElement,Math.max(c.body["scroll"+a],f["scroll"+a],c.body["offset"+a],f["offset"+a],f["client"+a])):e===b?p.css(c,d,e,h):p.style(c,d,e,h)},c,g?e:b,g,null)}})}),a.jQuery=a.$=p,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return p})})(window); \ No newline at end of file diff --git a/unittests/example_labfolder_data/static/js/jquery-ui.js b/unittests/example_labfolder_data/static/js/jquery-ui.js deleted file mode 100644 index 9a7ea59f1ef40f1063d7127a35903203f4703ea7..0000000000000000000000000000000000000000 --- a/unittests/example_labfolder_data/static/js/jquery-ui.js +++ /dev/null @@ -1,14912 +0,0 @@ -/*! jQuery UI - v1.9.2 - 2012-11-23 -* http://jqueryui.com -* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.effect.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js, jquery.ui.menu.js, jquery.ui.position.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js -* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ - -(function( $, undefined ) { - -var uuid = 0, - runiqueId = /^ui-id-\d+$/; - -// prevent duplicate loading -// this is only a problem because we proxy existing functions -// and we don't want to double proxy them -$.ui = $.ui || {}; -if ( $.ui.version ) { - return; -} - -$.extend( $.ui, { - version: "1.9.2", - - keyCode: { - BACKSPACE: 8, - COMMA: 188, - DELETE: 46, - DOWN: 40, - END: 35, - ENTER: 13, - ESCAPE: 27, - HOME: 36, - LEFT: 37, - NUMPAD_ADD: 107, - NUMPAD_DECIMAL: 110, - NUMPAD_DIVIDE: 111, - NUMPAD_ENTER: 108, - NUMPAD_MULTIPLY: 106, - NUMPAD_SUBTRACT: 109, - PAGE_DOWN: 34, - PAGE_UP: 33, - PERIOD: 190, - RIGHT: 39, - SPACE: 32, - TAB: 9, - UP: 38 - } -}); - -// plugins -$.fn.extend({ - _focus: $.fn.focus, - focus: function( delay, fn ) { - return typeof delay === "number" ? - this.each(function() { - var elem = this; - setTimeout(function() { - $( elem ).focus(); - if ( fn ) { - fn.call( elem ); - } - }, delay ); - }) : - this._focus.apply( this, arguments ); - }, - - scrollParent: function() { - var scrollParent; - if (($.ui.ie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) { - scrollParent = this.parents().filter(function() { - return (/(relative|absolute|fixed)/).test($.css(this,'position')) && (/(auto|scroll)/).test($.css(this,'overflow')+$.css(this,'overflow-y')+$.css(this,'overflow-x')); - }).eq(0); - } else { - scrollParent = this.parents().filter(function() { - return (/(auto|scroll)/).test($.css(this,'overflow')+$.css(this,'overflow-y')+$.css(this,'overflow-x')); - }).eq(0); - } - - return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent; - }, - - zIndex: function( zIndex ) { - if ( zIndex !== undefined ) { - return this.css( "zIndex", zIndex ); - } - - if ( this.length ) { - var elem = $( this[ 0 ] ), position, value; - while ( elem.length && elem[ 0 ] !== document ) { - // Ignore z-index if position is set to a value where z-index is ignored by the browser - // This makes behavior of this function consistent across browsers - // WebKit always returns auto if the element is positioned - position = elem.css( "position" ); - if ( position === "absolute" || position === "relative" || position === "fixed" ) { - // IE returns 0 when zIndex is not specified - // other browsers return a string - // we ignore the case of nested elements with an explicit value of 0 - // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> - value = parseInt( elem.css( "zIndex" ), 31 ); - if ( !isNaN( value ) && value !== 0 ) { - return value; - } - } - elem = elem.parent(); - } - } - - return 0; - }, - - uniqueId: function() { - return this.each(function() { - if ( !this.id ) { - this.id = "ui-id-" + (++uuid); - } - }); - }, - - removeUniqueId: function() { - return this.each(function() { - if ( runiqueId.test( this.id ) ) { - $( this ).removeAttr( "id" ); - } - }); - } -}); - -// selectors -function focusable( element, isTabIndexNotNaN ) { - var map, mapName, img, - nodeName = element.nodeName.toLowerCase(); - if ( "area" === nodeName ) { - map = element.parentNode; - mapName = map.name; - if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { - return false; - } - img = $( "img[usemap=#" + mapName + "]" )[0]; - return !!img && visible( img ); - } - return ( /input|select|textarea|button|object/.test( nodeName ) ? - !element.disabled : - "a" === nodeName ? - element.href || isTabIndexNotNaN : - isTabIndexNotNaN) && - // the element and all of its ancestors must be visible - visible( element ); -} - -function visible( element ) { - return $.expr.filters.visible( element ) && - !$( element ).parents().andSelf().filter(function() { - return $.css( this, "visibility" ) === "hidden"; - }).length; -} - -$.extend( $.expr[ ":" ], { - data: $.expr.createPseudo ? - $.expr.createPseudo(function( dataName ) { - return function( elem ) { - return !!$.data( elem, dataName ); - }; - }) : - // support: jQuery <1.8 - function( elem, i, match ) { - return !!$.data( elem, match[ 3 ] ); - }, - - focusable: function( element ) { - return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) ); - }, - - tabbable: function( element ) { - var tabIndex = $.attr( element, "tabindex" ), - isTabIndexNaN = isNaN( tabIndex ); - return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN ); - } -}); - -// support -$(function() { - var body = document.body, - div = body.appendChild( div = document.createElement( "div" ) ); - - // access offsetHeight before setting the style to prevent a layout bug - // in IE 9 which causes the element to continue to take up space even - // after it is removed from the DOM (#8026) - div.offsetHeight; - - $.extend( div.style, { - minHeight: "100px", - height: "auto", - padding: 0, - borderWidth: 0 - }); - - $.support.minHeight = div.offsetHeight === 100; - $.support.selectstart = "onselectstart" in div; - - // set display to none to avoid a layout bug in IE - // http://dev.jquery.com/ticket/4014 - body.removeChild( div ).style.display = "none"; -}); - -// support: jQuery <1.8 -if ( !$( "<a>" ).outerWidth( 1 ).jquery ) { - $.each( [ "Width", "Height" ], function( i, name ) { - var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], - type = name.toLowerCase(), - orig = { - innerWidth: $.fn.innerWidth, - innerHeight: $.fn.innerHeight, - outerWidth: $.fn.outerWidth, - outerHeight: $.fn.outerHeight - }; - - function reduce( elem, size, border, margin ) { - $.each( side, function() { - size -= parseFloat( $.css( elem, "padding" + this ) ) || 0; - if ( border ) { - size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; - } - if ( margin ) { - size -= parseFloat( $.css( elem, "margin" + this ) ) || 0; - } - }); - return size; - } - - $.fn[ "inner" + name ] = function( size ) { - if ( size === undefined ) { - return orig[ "inner" + name ].call( this ); - } - - return this.each(function() { - $( this ).css( type, reduce( this, size ) + "px" ); - }); - }; - - $.fn[ "outer" + name] = function( size, margin ) { - if ( typeof size !== "number" ) { - return orig[ "outer" + name ].call( this, size ); - } - - return this.each(function() { - $( this).css( type, reduce( this, size, true, margin ) + "px" ); - }); - }; - }); -} - -// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413) -if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) { - $.fn.removeData = (function( removeData ) { - return function( key ) { - if ( arguments.length ) { - return removeData.call( this, $.camelCase( key ) ); - } else { - return removeData.call( this ); - } - }; - })( $.fn.removeData ); -} - - - - - -// deprecated - -(function() { - var uaMatch = /msie ([\w.]+)/.exec( navigator.userAgent.toLowerCase() ) || []; - $.ui.ie = uaMatch.length ? true : false; - $.ui.ie6 = parseFloat( uaMatch[ 1 ], 10 ) === 6; -})(); - -$.fn.extend({ - disableSelection: function() { - return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) + - ".ui-disableSelection", function( event ) { - event.preventDefault(); - }); - }, - - enableSelection: function() { - return this.unbind( ".ui-disableSelection" ); - } -}); - -$.extend( $.ui, { - // $.ui.plugin is deprecated. Use the proxy pattern instead. - plugin: { - add: function( module, option, set ) { - var i, - proto = $.ui[ module ].prototype; - for ( i in set ) { - proto.plugins[ i ] = proto.plugins[ i ] || []; - proto.plugins[ i ].push( [ option, set[ i ] ] ); - } - }, - call: function( instance, name, args ) { - var i, - set = instance.plugins[ name ]; - if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) { - return; - } - - for ( i = 0; i < set.length; i++ ) { - if ( instance.options[ set[ i ][ 0 ] ] ) { - set[ i ][ 1 ].apply( instance.element, args ); - } - } - } - }, - - contains: $.contains, - - // only used by resizable - hasScroll: function( el, a ) { - - //If overflow is hidden, the element might have extra content, but the user wants to hide it - if ( $( el ).css( "overflow" ) === "hidden") { - return false; - } - - var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", - has = false; - - if ( el[ scroll ] > 0 ) { - return true; - } - - // TODO: determine which cases actually cause this to happen - // if the element doesn't have the scroll set, see if it's possible to - // set the scroll - el[ scroll ] = 1; - has = ( el[ scroll ] > 0 ); - el[ scroll ] = 0; - return has; - }, - - // these are odd functions, fix the API or move into individual plugins - isOverAxis: function( x, reference, size ) { - //Determines when x coordinate is over "b" element axis - return ( x > reference ) && ( x < ( reference + size ) ); - }, - isOver: function( y, x, top, left, height, width ) { - //Determines when x, y coordinates is over "b" element - return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width ); - } -}); - -})( jQuery ); - -(function( $, undefined ) { - -var uuid = 0, - slice = Array.prototype.slice, - _cleanData = $.cleanData; -$.cleanData = function( elems ) { - for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { - try { - $( elem ).triggerHandler( "remove" ); - // http://bugs.jquery.com/ticket/8235 - } catch( e ) {} - } - _cleanData( elems ); -}; - -$.widget = function( name, base, prototype ) { - var fullName, existingConstructor, constructor, basePrototype, - namespace = name.split( "." )[ 0 ]; - - name = name.split( "." )[ 1 ]; - fullName = namespace + "-" + name; - - if ( !prototype ) { - prototype = base; - base = $.Widget; - } - - // create selector for plugin - $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { - return !!$.data( elem, fullName ); - }; - - $[ namespace ] = $[ namespace ] || {}; - existingConstructor = $[ namespace ][ name ]; - constructor = $[ namespace ][ name ] = function( options, element ) { - // allow instantiation without "new" keyword - if ( !this._createWidget ) { - return new constructor( options, element ); - } - - // allow instantiation without initializing for simple inheritance - // must use "new" keyword (the code above always passes args) - if ( arguments.length ) { - this._createWidget( options, element ); - } - }; - // extend with the existing constructor to carry over any static properties - $.extend( constructor, existingConstructor, { - version: prototype.version, - // copy the object used to create the prototype in case we need to - // redefine the widget later - _proto: $.extend( {}, prototype ), - // track widgets that inherit from this widget in case this widget is - // redefined after a widget inherits from it - _childConstructors: [] - }); - - basePrototype = new base(); - // we need to make the options hash a property directly on the new instance - // otherwise we'll modify the options hash on the prototype that we're - // inheriting from - basePrototype.options = $.widget.extend( {}, basePrototype.options ); - $.each( prototype, function( prop, value ) { - if ( $.isFunction( value ) ) { - prototype[ prop ] = (function() { - var _super = function() { - return base.prototype[ prop ].apply( this, arguments ); - }, - _superApply = function( args ) { - return base.prototype[ prop ].apply( this, args ); - }; - return function() { - var __super = this._super, - __superApply = this._superApply, - returnValue; - - this._super = _super; - this._superApply = _superApply; - - returnValue = value.apply( this, arguments ); - - this._super = __super; - this._superApply = __superApply; - - return returnValue; - }; - })(); - } - }); - constructor.prototype = $.widget.extend( basePrototype, { - // TODO: remove support for widgetEventPrefix - // always use the name + a colon as the prefix, e.g., draggable:start - // don't prefix for widgets that aren't DOM-based - widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name - }, prototype, { - constructor: constructor, - namespace: namespace, - widgetName: name, - // TODO remove widgetBaseClass, see #8155 - widgetBaseClass: fullName, - widgetFullName: fullName - }); - - // If this widget is being redefined then we need to find all widgets that - // are inheriting from it and redefine all of them so that they inherit from - // the new version of this widget. We're essentially trying to replace one - // level in the prototype chain. - if ( existingConstructor ) { - $.each( existingConstructor._childConstructors, function( i, child ) { - var childPrototype = child.prototype; - - // redefine the child widget using the same prototype that was - // originally used, but inherit from the new version of the base - $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); - }); - // remove the list of existing child constructors from the old constructor - // so the old child constructors can be garbage collected - delete existingConstructor._childConstructors; - } else { - base._childConstructors.push( constructor ); - } - - $.widget.bridge( name, constructor ); -}; - -$.widget.extend = function( target ) { - var input = slice.call( arguments, 1 ), - inputIndex = 0, - inputLength = input.length, - key, - value; - for ( ; inputIndex < inputLength; inputIndex++ ) { - for ( key in input[ inputIndex ] ) { - value = input[ inputIndex ][ key ]; - if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { - // Clone objects - if ( $.isPlainObject( value ) ) { - target[ key ] = $.isPlainObject( target[ key ] ) ? - $.widget.extend( {}, target[ key ], value ) : - // Don't extend strings, arrays, etc. with objects - $.widget.extend( {}, value ); - // Copy everything else by reference - } else { - target[ key ] = value; - } - } - } - } - return target; -}; - -$.widget.bridge = function( name, object ) { - var fullName = object.prototype.widgetFullName || name; - $.fn[ name ] = function( options ) { - var isMethodCall = typeof options === "string", - args = slice.call( arguments, 1 ), - returnValue = this; - - // allow multiple hashes to be passed on init - options = !isMethodCall && args.length ? - $.widget.extend.apply( null, [ options ].concat(args) ) : - options; - - if ( isMethodCall ) { - this.each(function() { - var methodValue, - instance = $.data( this, fullName ); - if ( !instance ) { - return $.error( "cannot call methods on " + name + " prior to initialization; " + - "attempted to call method '" + options + "'" ); - } - if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { - return $.error( "no such method '" + options + "' for " + name + " widget instance" ); - } - methodValue = instance[ options ].apply( instance, args ); - if ( methodValue !== instance && methodValue !== undefined ) { - returnValue = methodValue && methodValue.jquery ? - returnValue.pushStack( methodValue.get() ) : - methodValue; - return false; - } - }); - } else { - this.each(function() { - var instance = $.data( this, fullName ); - if ( instance ) { - instance.option( options || {} )._init(); - } else { - $.data( this, fullName, new object( options, this ) ); - } - }); - } - - return returnValue; - }; -}; - -$.Widget = function( /* options, element */ ) {}; -$.Widget._childConstructors = []; - -$.Widget.prototype = { - widgetName: "widget", - widgetEventPrefix: "", - defaultElement: "<div>", - options: { - disabled: false, - - // callbacks - create: null - }, - _createWidget: function( options, element ) { - element = $( element || this.defaultElement || this )[ 0 ]; - this.element = $( element ); - this.uuid = uuid++; - this.eventNamespace = "." + this.widgetName + this.uuid; - this.options = $.widget.extend( {}, - this.options, - this._getCreateOptions(), - options ); - - this.bindings = $(); - this.hoverable = $(); - this.focusable = $(); - - if ( element !== this ) { - // 1.9 BC for #7810 - // TODO remove dual storage - $.data( element, this.widgetName, this ); - $.data( element, this.widgetFullName, this ); - this._on( true, this.element, { - remove: function( event ) { - if ( event.target === element ) { - this.destroy(); - } - } - }); - this.document = $( element.style ? - // element within the document - element.ownerDocument : - // element is window or document - element.document || element ); - this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); - } - - this._create(); - this._trigger( "create", null, this._getCreateEventData() ); - this._init(); - }, - _getCreateOptions: $.noop, - _getCreateEventData: $.noop, - _create: $.noop, - _init: $.noop, - - destroy: function() { - this._destroy(); - // we can probably remove the unbind calls in 2.0 - // all event bindings should go through this._on() - this.element - .unbind( this.eventNamespace ) - // 1.9 BC for #7810 - // TODO remove dual storage - .removeData( this.widgetName ) - .removeData( this.widgetFullName ) - // support: jquery <1.6.3 - // http://bugs.jquery.com/ticket/9413 - .removeData( $.camelCase( this.widgetFullName ) ); - this.widget() - .unbind( this.eventNamespace ) - .removeAttr( "aria-disabled" ) - .removeClass( - this.widgetFullName + "-disabled " + - "ui-state-disabled" ); - - // clean up events and states - this.bindings.unbind( this.eventNamespace ); - this.hoverable.removeClass( "ui-state-hover" ); - this.focusable.removeClass( "ui-state-focus" ); - }, - _destroy: $.noop, - - widget: function() { - return this.element; - }, - - option: function( key, value ) { - var options = key, - parts, - curOption, - i; - - if ( arguments.length === 0 ) { - // don't return a reference to the internal hash - return $.widget.extend( {}, this.options ); - } - - if ( typeof key === "string" ) { - // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } - options = {}; - parts = key.split( "." ); - key = parts.shift(); - if ( parts.length ) { - curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); - for ( i = 0; i < parts.length - 1; i++ ) { - curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; - curOption = curOption[ parts[ i ] ]; - } - key = parts.pop(); - if ( value === undefined ) { - return curOption[ key ] === undefined ? null : curOption[ key ]; - } - curOption[ key ] = value; - } else { - if ( value === undefined ) { - return this.options[ key ] === undefined ? null : this.options[ key ]; - } - options[ key ] = value; - } - } - - this._setOptions( options ); - - return this; - }, - _setOptions: function( options ) { - var key; - - for ( key in options ) { - this._setOption( key, options[ key ] ); - } - - return this; - }, - _setOption: function( key, value ) { - this.options[ key ] = value; - - if ( key === "disabled" ) { - this.widget() - .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value ) - .attr( "aria-disabled", value ); - this.hoverable.removeClass( "ui-state-hover" ); - this.focusable.removeClass( "ui-state-focus" ); - } - - return this; - }, - - enable: function() { - return this._setOption( "disabled", false ); - }, - disable: function() { - return this._setOption( "disabled", true ); - }, - - _on: function( suppressDisabledCheck, element, handlers ) { - var delegateElement, - instance = this; - - // no suppressDisabledCheck flag, shuffle arguments - if ( typeof suppressDisabledCheck !== "boolean" ) { - handlers = element; - element = suppressDisabledCheck; - suppressDisabledCheck = false; - } - - // no element argument, shuffle and use this.element - if ( !handlers ) { - handlers = element; - element = this.element; - delegateElement = this.widget(); - } else { - // accept selectors, DOM elements - element = delegateElement = $( element ); - this.bindings = this.bindings.add( element ); - } - - $.each( handlers, function( event, handler ) { - function handlerProxy() { - // allow widgets to customize the disabled handling - // - disabled as an array instead of boolean - // - disabled class as method for disabling individual parts - if ( !suppressDisabledCheck && - ( instance.options.disabled === true || - $( this ).hasClass( "ui-state-disabled" ) ) ) { - return; - } - return ( typeof handler === "string" ? instance[ handler ] : handler ) - .apply( instance, arguments ); - } - - // copy the guid so direct unbinding works - if ( typeof handler !== "string" ) { - handlerProxy.guid = handler.guid = - handler.guid || handlerProxy.guid || $.guid++; - } - - var match = event.match( /^(\w+)\s*(.*)$/ ), - eventName = match[1] + instance.eventNamespace, - selector = match[2]; - if ( selector ) { - delegateElement.delegate( selector, eventName, handlerProxy ); - } else { - element.bind( eventName, handlerProxy ); - } - }); - }, - - _off: function( element, eventName ) { - eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; - element.unbind( eventName ).undelegate( eventName ); - }, - - _delay: function( handler, delay ) { - function handlerProxy() { - return ( typeof handler === "string" ? instance[ handler ] : handler ) - .apply( instance, arguments ); - } - var instance = this; - return setTimeout( handlerProxy, delay || 0 ); - }, - - _hoverable: function( element ) { - this.hoverable = this.hoverable.add( element ); - this._on( element, { - mouseenter: function( event ) { - $( event.currentTarget ).addClass( "ui-state-hover" ); - }, - mouseleave: function( event ) { - $( event.currentTarget ).removeClass( "ui-state-hover" ); - } - }); - }, - - _focusable: function( element ) { - this.focusable = this.focusable.add( element ); - this._on( element, { - focusin: function( event ) { - $( event.currentTarget ).addClass( "ui-state-focus" ); - }, - focusout: function( event ) { - $( event.currentTarget ).removeClass( "ui-state-focus" ); - } - }); - }, - - _trigger: function( type, event, data ) { - var prop, orig, - callback = this.options[ type ]; - - data = data || {}; - event = $.Event( event ); - event.type = ( type === this.widgetEventPrefix ? - type : - this.widgetEventPrefix + type ).toLowerCase(); - // the original event may come from any element - // so we need to reset the target on the new event - event.target = this.element[ 0 ]; - - // copy original event properties over to the new event - orig = event.originalEvent; - if ( orig ) { - for ( prop in orig ) { - if ( !( prop in event ) ) { - event[ prop ] = orig[ prop ]; - } - } - } - - this.element.trigger( event, data ); - return !( $.isFunction( callback ) && - callback.apply( this.element[0], [ event ].concat( data ) ) === false || - event.isDefaultPrevented() ); - } -}; - -$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { - $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { - if ( typeof options === "string" ) { - options = { effect: options }; - } - var hasOptions, - effectName = !options ? - method : - options === true || typeof options === "number" ? - defaultEffect : - options.effect || defaultEffect; - options = options || {}; - if ( typeof options === "number" ) { - options = { duration: options }; - } - hasOptions = !$.isEmptyObject( options ); - options.complete = callback; - if ( options.delay ) { - element.delay( options.delay ); - } - if ( hasOptions && $.effects && ( $.effects.effect[ effectName ] || $.uiBackCompat !== false && $.effects[ effectName ] ) ) { - element[ method ]( options ); - } else if ( effectName !== method && element[ effectName ] ) { - element[ effectName ]( options.duration, options.easing, callback ); - } else { - element.queue(function( next ) { - $( this )[ method ](); - if ( callback ) { - callback.call( element[ 0 ] ); - } - next(); - }); - } - }; -}); - -// DEPRECATED -if ( $.uiBackCompat !== false ) { - $.Widget.prototype._getCreateOptions = function() { - return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ]; - }; -} - -})( jQuery ); - -(function( $, undefined ) { - -var mouseHandled = false; -$( document ).mouseup( function( e ) { - mouseHandled = false; -}); - -$.widget("ui.mouse", { - version: "1.9.2", - options: { - cancel: 'input,textarea,button,select,option', - distance: 1, - delay: 0 - }, - _mouseInit: function() { - var that = this; - - this.element - .bind('mousedown.'+this.widgetName, function(event) { - return that._mouseDown(event); - }) - .bind('click.'+this.widgetName, function(event) { - if (true === $.data(event.target, that.widgetName + '.preventClickEvent')) { - $.removeData(event.target, that.widgetName + '.preventClickEvent'); - event.stopImmediatePropagation(); - return false; - } - }); - - this.started = false; - }, - - // TODO: make sure destroying one instance of mouse doesn't mess with - // other instances of mouse - _mouseDestroy: function() { - this.element.unbind('.'+this.widgetName); - if ( this._mouseMoveDelegate ) { - $(document) - .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate) - .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate); - } - }, - - _mouseDown: function(event) { - // don't let more than one widget handle mouseStart - if( mouseHandled ) { return; } - - // we may have missed mouseup (out of window) - (this._mouseStarted && this._mouseUp(event)); - - this._mouseDownEvent = event; - - var that = this, - btnIsLeft = (event.which === 1), - // event.target.nodeName works around a bug in IE 8 with - // disabled inputs (#7620) - elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false); - if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { - return true; - } - - this.mouseDelayMet = !this.options.delay; - if (!this.mouseDelayMet) { - this._mouseDelayTimer = setTimeout(function() { - that.mouseDelayMet = true; - }, this.options.delay); - } - - if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { - this._mouseStarted = (this._mouseStart(event) !== false); - if (!this._mouseStarted) { - event.preventDefault(); - return true; - } - } - - // Click event may never have fired (Gecko & Opera) - if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) { - $.removeData(event.target, this.widgetName + '.preventClickEvent'); - } - - // these delegates are required to keep context - this._mouseMoveDelegate = function(event) { - return that._mouseMove(event); - }; - this._mouseUpDelegate = function(event) { - return that._mouseUp(event); - }; - $(document) - .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate) - .bind('mouseup.'+this.widgetName, this._mouseUpDelegate); - - event.preventDefault(); - - mouseHandled = true; - return true; - }, - - _mouseMove: function(event) { - // IE mouseup check - mouseup happened when mouse was out of window - if ($.ui.ie && !(document.documentMode >= 9) && !event.button) { - return this._mouseUp(event); - } - - if (this._mouseStarted) { - this._mouseDrag(event); - return event.preventDefault(); - } - - if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { - this._mouseStarted = - (this._mouseStart(this._mouseDownEvent, event) !== false); - (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); - } - - return !this._mouseStarted; - }, - - _mouseUp: function(event) { - $(document) - .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate) - .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate); - - if (this._mouseStarted) { - this._mouseStarted = false; - - if (event.target === this._mouseDownEvent.target) { - $.data(event.target, this.widgetName + '.preventClickEvent', true); - } - - this._mouseStop(event); - } - - return false; - }, - - _mouseDistanceMet: function(event) { - return (Math.max( - Math.abs(this._mouseDownEvent.pageX - event.pageX), - Math.abs(this._mouseDownEvent.pageY - event.pageY) - ) >= this.options.distance - ); - }, - - _mouseDelayMet: function(event) { - return this.mouseDelayMet; - }, - - // These are placeholder methods, to be overriden by extending plugin - _mouseStart: function(event) {}, - _mouseDrag: function(event) {}, - _mouseStop: function(event) {}, - _mouseCapture: function(event) { return true; } -}); - -})(jQuery); - -(function( $, undefined ) { - -$.widget("ui.draggable", $.ui.mouse, { - version: "1.9.2", - widgetEventPrefix: "drag", - options: { - addClasses: true, - appendTo: "parent", - axis: false, - connectToSortable: false, - containment: false, - cursor: "auto", - cursorAt: false, - grid: false, - handle: false, - helper: "original", - iframeFix: false, - opacity: false, - refreshPositions: false, - revert: false, - revertDuration: 500, - scope: "default", - scroll: true, - scrollSensitivity: 20, - scrollSpeed: 20, - snap: false, - snapMode: "both", - snapTolerance: 20, - stack: false, - zIndex: false - }, - _create: function() { - - if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position"))) - this.element[0].style.position = 'relative'; - - (this.options.addClasses && this.element.addClass("ui-draggable")); - (this.options.disabled && this.element.addClass("ui-draggable-disabled")); - - this._mouseInit(); - - }, - - _destroy: function() { - this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" ); - this._mouseDestroy(); - }, - - _mouseCapture: function(event) { - - var o = this.options; - - // among others, prevent a drag on a resizable-handle - if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle')) - return false; - - //Quit if we're not on a valid handle - this.handle = this._getHandle(event); - if (!this.handle) - return false; - - $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() { - $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>') - .css({ - width: this.offsetWidth+"px", height: this.offsetHeight+"px", - position: "absolute", opacity: "0.001", zIndex: 1000 - }) - .css($(this).offset()) - .appendTo("body"); - }); - - return true; - - }, - - _mouseStart: function(event) { - - var o = this.options; - - //Create and append the visible helper - this.helper = this._createHelper(event); - - this.helper.addClass("ui-draggable-dragging"); - - //Cache the helper size - this._cacheHelperProportions(); - - //If ddmanager is used for droppables, set the global draggable - if($.ui.ddmanager) - $.ui.ddmanager.current = this; - - /* - * - Position generation - - * This block generates everything position related - it's the core of draggables. - */ - - //Cache the margins of the original element - this._cacheMargins(); - - //Store the helper's css position - this.cssPosition = this.helper.css("position"); - this.scrollParent = this.helper.scrollParent(); - - //The element's absolute position on the page minus margins - this.offset = this.positionAbs = this.element.offset(); - this.offset = { - top: this.offset.top - this.margins.top, - left: this.offset.left - this.margins.left - }; - - $.extend(this.offset, { - click: { //Where the click happened, relative to the element - left: event.pageX - this.offset.left, - top: event.pageY - this.offset.top - }, - parent: this._getParentOffset(), - relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper - }); - - //Generate the original position - this.originalPosition = this.position = this._generatePosition(event); - this.originalPageX = event.pageX; - this.originalPageY = event.pageY; - - //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied - (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); - - //Set a containment if given in the options - if(o.containment) - this._setContainment(); - - //Trigger event + callbacks - if(this._trigger("start", event) === false) { - this._clear(); - return false; - } - - //Recache the helper size - this._cacheHelperProportions(); - - //Prepare the droppable offsets - if ($.ui.ddmanager && !o.dropBehaviour) - $.ui.ddmanager.prepareOffsets(this, event); - - - this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position - - //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) - if ( $.ui.ddmanager ) $.ui.ddmanager.dragStart(this, event); - - return true; - }, - - _mouseDrag: function(event, noPropagation) { - - //Compute the helpers position - this.position = this._generatePosition(event); - this.positionAbs = this._convertPositionTo("absolute"); - - //Call plugins and callbacks and use the resulting position if something is returned - if (!noPropagation) { - var ui = this._uiHash(); - if(this._trigger('drag', event, ui) === false) { - this._mouseUp({}); - return false; - } - this.position = ui.position; - } - - if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px'; - if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px'; - if($.ui.ddmanager) $.ui.ddmanager.drag(this, event); - - return false; - }, - - _mouseStop: function(event) { - - //If we are using droppables, inform the manager about the drop - var dropped = false; - if ($.ui.ddmanager && !this.options.dropBehaviour) - dropped = $.ui.ddmanager.drop(this, event); - - //if a drop comes from outside (a sortable) - if(this.dropped) { - dropped = this.dropped; - this.dropped = false; - } - - //if the original element is no longer in the DOM don't bother to continue (see #8269) - var element = this.element[0], elementInDom = false; - while ( element && (element = element.parentNode) ) { - if (element == document ) { - elementInDom = true; - } - } - if ( !elementInDom && this.options.helper === "original" ) - return false; - - if((this.options.revert == "invalid" && !dropped) || (this.options.revert == "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) { - var that = this; - $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { - if(that._trigger("stop", event) !== false) { - that._clear(); - } - }); - } else { - if(this._trigger("stop", event) !== false) { - this._clear(); - } - } - - return false; - }, - - _mouseUp: function(event) { - //Remove frame helpers - $("div.ui-draggable-iframeFix").each(function() { - this.parentNode.removeChild(this); - }); - - //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) - if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event); - - return $.ui.mouse.prototype._mouseUp.call(this, event); - }, - - cancel: function() { - - if(this.helper.is(".ui-draggable-dragging")) { - this._mouseUp({}); - } else { - this._clear(); - } - - return this; - - }, - - _getHandle: function(event) { - - var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false; - $(this.options.handle, this.element) - .find("*") - .andSelf() - .each(function() { - if(this == event.target) handle = true; - }); - - return handle; - - }, - - _createHelper: function(event) { - - var o = this.options; - var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone().removeAttr('id') : this.element); - - if(!helper.parents('body').length) - helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo)); - - if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) - helper.css("position", "absolute"); - - return helper; - - }, - - _adjustOffsetFromHelper: function(obj) { - if (typeof obj == 'string') { - obj = obj.split(' '); - } - if ($.isArray(obj)) { - obj = {left: +obj[0], top: +obj[1] || 0}; - } - if ('left' in obj) { - this.offset.click.left = obj.left + this.margins.left; - } - if ('right' in obj) { - this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; - } - if ('top' in obj) { - this.offset.click.top = obj.top + this.margins.top; - } - if ('bottom' in obj) { - this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; - } - }, - - _getParentOffset: function() { - - //Get the offsetParent and cache its position - this.offsetParent = this.helper.offsetParent(); - var po = this.offsetParent.offset(); - - // This is a special case where we need to modify a offset calculated on start, since the following happened: - // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent - // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that - // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag - if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) { - po.left += this.scrollParent.scrollLeft(); - po.top += this.scrollParent.scrollTop(); - } - - if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information - || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.ui.ie)) //Ugly IE fix - po = { top: 0, left: 0 }; - - return { - top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), - left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) - }; - - }, - - _getRelativeOffset: function() { - - if(this.cssPosition == "relative") { - var p = this.element.position(); - return { - top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), - left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() - }; - } else { - return { top: 0, left: 0 }; - } - - }, - - _cacheMargins: function() { - this.margins = { - left: (parseInt(this.element.css("marginLeft"),10) || 0), - top: (parseInt(this.element.css("marginTop"),10) || 0), - right: (parseInt(this.element.css("marginRight"),10) || 0), - bottom: (parseInt(this.element.css("marginBottom"),10) || 0) - }; - }, - - _cacheHelperProportions: function() { - this.helperProportions = { - width: this.helper.outerWidth(), - height: this.helper.outerHeight() - }; - }, - - _setContainment: function() { - - var o = this.options; - if(o.containment == 'parent') o.containment = this.helper[0].parentNode; - if(o.containment == 'document' || o.containment == 'window') this.containment = [ - o.containment == 'document' ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left, - o.containment == 'document' ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top, - (o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left, - (o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top - ]; - - if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) { - var c = $(o.containment); - var ce = c[0]; if(!ce) return; - var co = c.offset(); - var over = ($(ce).css("overflow") != 'hidden'); - - this.containment = [ - (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0), - (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0), - (over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left - this.margins.right, - (over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top - this.margins.bottom - ]; - this.relative_container = c; - - } else if(o.containment.constructor == Array) { - this.containment = o.containment; - } - - }, - - _convertPositionTo: function(d, pos) { - - if(!pos) pos = this.position; - var mod = d == "absolute" ? 1 : -1; - var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); - - return { - top: ( - pos.top // The absolute mouse position - + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent - + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border) - - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) - ), - left: ( - pos.left // The absolute mouse position - + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent - + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border) - - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) - ) - }; - - }, - - _generatePosition: function(event) { - - var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); - var pageX = event.pageX; - var pageY = event.pageY; - - /* - * - Position constraining - - * Constrain the position to a mix of grid, containment. - */ - - if(this.originalPosition) { //If we are not dragging yet, we won't check for options - var containment; - if(this.containment) { - if (this.relative_container){ - var co = this.relative_container.offset(); - containment = [ this.containment[0] + co.left, - this.containment[1] + co.top, - this.containment[2] + co.left, - this.containment[3] + co.top ]; - } - else { - containment = this.containment; - } - - if(event.pageX - this.offset.click.left < containment[0]) pageX = containment[0] + this.offset.click.left; - if(event.pageY - this.offset.click.top < containment[1]) pageY = containment[1] + this.offset.click.top; - if(event.pageX - this.offset.click.left > containment[2]) pageX = containment[2] + this.offset.click.left; - if(event.pageY - this.offset.click.top > containment[3]) pageY = containment[3] + this.offset.click.top; - } - - if(o.grid) { - //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950) - var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY; - pageY = containment ? (!(top - this.offset.click.top < containment[1] || top - this.offset.click.top > containment[3]) ? top : (!(top - this.offset.click.top < containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top; - - var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX; - pageX = containment ? (!(left - this.offset.click.left < containment[0] || left - this.offset.click.left > containment[2]) ? left : (!(left - this.offset.click.left < containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left; - } - - } - - return { - top: ( - pageY // The absolute mouse position - - this.offset.click.top // Click offset (relative to the element) - - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent - - this.offset.parent.top // The offsetParent's offset without borders (offset + border) - + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) - ), - left: ( - pageX // The absolute mouse position - - this.offset.click.left // Click offset (relative to the element) - - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent - - this.offset.parent.left // The offsetParent's offset without borders (offset + border) - + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) - ) - }; - - }, - - _clear: function() { - this.helper.removeClass("ui-draggable-dragging"); - if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove(); - //if($.ui.ddmanager) $.ui.ddmanager.current = null; - this.helper = null; - this.cancelHelperRemoval = false; - }, - - // From now on bulk stuff - mainly helpers - - _trigger: function(type, event, ui) { - ui = ui || this._uiHash(); - $.ui.plugin.call(this, type, [event, ui]); - if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins - return $.Widget.prototype._trigger.call(this, type, event, ui); - }, - - plugins: {}, - - _uiHash: function(event) { - return { - helper: this.helper, - position: this.position, - originalPosition: this.originalPosition, - offset: this.positionAbs - }; - } - -}); - -$.ui.plugin.add("draggable", "connectToSortable", { - start: function(event, ui) { - - var inst = $(this).data("draggable"), o = inst.options, - uiSortable = $.extend({}, ui, { item: inst.element }); - inst.sortables = []; - $(o.connectToSortable).each(function() { - var sortable = $.data(this, 'sortable'); - if (sortable && !sortable.options.disabled) { - inst.sortables.push({ - instance: sortable, - shouldRevert: sortable.options.revert - }); - sortable.refreshPositions(); // Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page). - sortable._trigger("activate", event, uiSortable); - } - }); - - }, - stop: function(event, ui) { - - //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper - var inst = $(this).data("draggable"), - uiSortable = $.extend({}, ui, { item: inst.element }); - - $.each(inst.sortables, function() { - if(this.instance.isOver) { - - this.instance.isOver = 0; - - inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance - this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work) - - //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid' - if(this.shouldRevert) this.instance.options.revert = true; - - //Trigger the stop of the sortable - this.instance._mouseStop(event); - - this.instance.options.helper = this.instance.options._helper; - - //If the helper has been the original item, restore properties in the sortable - if(inst.options.helper == 'original') - this.instance.currentItem.css({ top: 'auto', left: 'auto' }); - - } else { - this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance - this.instance._trigger("deactivate", event, uiSortable); - } - - }); - - }, - drag: function(event, ui) { - - var inst = $(this).data("draggable"), that = this; - - var checkPos = function(o) { - var dyClick = this.offset.click.top, dxClick = this.offset.click.left; - var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left; - var itemHeight = o.height, itemWidth = o.width; - var itemTop = o.top, itemLeft = o.left; - - return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth); - }; - - $.each(inst.sortables, function(i) { - - var innermostIntersecting = false; - var thisSortable = this; - //Copy over some variables to allow calling the sortable's native _intersectsWith - this.instance.positionAbs = inst.positionAbs; - this.instance.helperProportions = inst.helperProportions; - this.instance.offset.click = inst.offset.click; - - if(this.instance._intersectsWith(this.instance.containerCache)) { - innermostIntersecting = true; - $.each(inst.sortables, function () { - this.instance.positionAbs = inst.positionAbs; - this.instance.helperProportions = inst.helperProportions; - this.instance.offset.click = inst.offset.click; - if (this != thisSortable - && this.instance._intersectsWith(this.instance.containerCache) - && $.ui.contains(thisSortable.instance.element[0], this.instance.element[0])) - innermostIntersecting = false; - return innermostIntersecting; - }); - } - - - if(innermostIntersecting) { - //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once - if(!this.instance.isOver) { - - this.instance.isOver = 1; - //Now we fake the start of dragging for the sortable instance, - //by cloning the list group item, appending it to the sortable and using it as inst.currentItem - //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one) - this.instance.currentItem = $(that).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true); - this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it - this.instance.options.helper = function() { return ui.helper[0]; }; - - event.target = this.instance.currentItem[0]; - this.instance._mouseCapture(event, true); - this.instance._mouseStart(event, true, true); - - //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes - this.instance.offset.click.top = inst.offset.click.top; - this.instance.offset.click.left = inst.offset.click.left; - this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left; - this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top; - - inst._trigger("toSortable", event); - inst.dropped = this.instance.element; //draggable revert needs that - //hack so receive/update callbacks work (mostly) - inst.currentItem = inst.element; - this.instance.fromOutside = inst; - - } - - //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable - if(this.instance.currentItem) this.instance._mouseDrag(event); - - } else { - - //If it doesn't intersect with the sortable, and it intersected before, - //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval - if(this.instance.isOver) { - - this.instance.isOver = 0; - this.instance.cancelHelperRemoval = true; - - //Prevent reverting on this forced stop - this.instance.options.revert = false; - - // The out event needs to be triggered independently - this.instance._trigger('out', event, this.instance._uiHash(this.instance)); - - this.instance._mouseStop(event, true); - this.instance.options.helper = this.instance.options._helper; - - //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size - this.instance.currentItem.remove(); - if(this.instance.placeholder) this.instance.placeholder.remove(); - - inst._trigger("fromSortable", event); - inst.dropped = false; //draggable revert needs that - } - - }; - - }); - - } -}); - -$.ui.plugin.add("draggable", "cursor", { - start: function(event, ui) { - var t = $('body'), o = $(this).data('draggable').options; - if (t.css("cursor")) o._cursor = t.css("cursor"); - t.css("cursor", o.cursor); - }, - stop: function(event, ui) { - var o = $(this).data('draggable').options; - if (o._cursor) $('body').css("cursor", o._cursor); - } -}); - -$.ui.plugin.add("draggable", "opacity", { - start: function(event, ui) { - var t = $(ui.helper), o = $(this).data('draggable').options; - if(t.css("opacity")) o._opacity = t.css("opacity"); - t.css('opacity', o.opacity); - }, - stop: function(event, ui) { - var o = $(this).data('draggable').options; - if(o._opacity) $(ui.helper).css('opacity', o._opacity); - } -}); - -$.ui.plugin.add("draggable", "scroll", { - start: function(event, ui) { - var i = $(this).data("draggable"); - if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset(); - }, - drag: function(event, ui) { - - var i = $(this).data("draggable"), o = i.options, scrolled = false; - - if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') { - - if(!o.axis || o.axis != 'x') { - if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) - i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed; - else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) - i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed; - } - - if(!o.axis || o.axis != 'y') { - if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) - i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed; - else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) - i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed; - } - - } else { - - if(!o.axis || o.axis != 'x') { - if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) - scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); - else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) - scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); - } - - if(!o.axis || o.axis != 'y') { - if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) - scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); - else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) - scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); - } - - } - - if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) - $.ui.ddmanager.prepareOffsets(i, event); - - } -}); - -$.ui.plugin.add("draggable", "snap", { - start: function(event, ui) { - - var i = $(this).data("draggable"), o = i.options; - i.snapElements = []; - - $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() { - var $t = $(this); var $o = $t.offset(); - if(this != i.element[0]) i.snapElements.push({ - item: this, - width: $t.outerWidth(), height: $t.outerHeight(), - top: $o.top, left: $o.left - }); - }); - - }, - drag: function(event, ui) { - - var inst = $(this).data("draggable"), o = inst.options; - var d = o.snapTolerance; - - var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, - y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; - - for (var i = inst.snapElements.length - 1; i >= 0; i--){ - - var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width, - t = inst.snapElements[i].top, b = t + inst.snapElements[i].height; - - //Yes, I know, this is insane ;) - if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) { - if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); - inst.snapElements[i].snapping = false; - continue; - } - - if(o.snapMode != 'inner') { - var ts = Math.abs(t - y2) <= d; - var bs = Math.abs(b - y1) <= d; - var ls = Math.abs(l - x2) <= d; - var rs = Math.abs(r - x1) <= d; - if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top; - if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top; - if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left; - if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left; - } - - var first = (ts || bs || ls || rs); - - if(o.snapMode != 'outer') { - var ts = Math.abs(t - y1) <= d; - var bs = Math.abs(b - y2) <= d; - var ls = Math.abs(l - x1) <= d; - var rs = Math.abs(r - x2) <= d; - if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top; - if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top; - if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left; - if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left; - } - - if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) - (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); - inst.snapElements[i].snapping = (ts || bs || ls || rs || first); - - }; - - } -}); - -$.ui.plugin.add("draggable", "stack", { - start: function(event, ui) { - - var o = $(this).data("draggable").options; - - var group = $.makeArray($(o.stack)).sort(function(a,b) { - return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0); - }); - if (!group.length) { return; } - - var min = parseInt(group[0].style.zIndex) || 0; - $(group).each(function(i) { - this.style.zIndex = min + i; - }); - - this[0].style.zIndex = min + group.length; - - } -}); - -$.ui.plugin.add("draggable", "zIndex", { - start: function(event, ui) { - var t = $(ui.helper), o = $(this).data("draggable").options; - if(t.css("zIndex")) o._zIndex = t.css("zIndex"); - t.css('zIndex', o.zIndex); - }, - stop: function(event, ui) { - var o = $(this).data("draggable").options; - if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex); - } -}); - -})(jQuery); - -(function( $, undefined ) { - -$.widget("ui.droppable", { - version: "1.9.2", - widgetEventPrefix: "drop", - options: { - accept: '*', - activeClass: false, - addClasses: true, - greedy: false, - hoverClass: false, - scope: 'default', - tolerance: 'intersect' - }, - _create: function() { - - var o = this.options, accept = o.accept; - this.isover = 0; this.isout = 1; - - this.accept = $.isFunction(accept) ? accept : function(d) { - return d.is(accept); - }; - - //Store the droppable's proportions - this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight }; - - // Add the reference and positions to the manager - $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || []; - $.ui.ddmanager.droppables[o.scope].push(this); - - (o.addClasses && this.element.addClass("ui-droppable")); - - }, - - _destroy: function() { - var drop = $.ui.ddmanager.droppables[this.options.scope]; - for ( var i = 0; i < drop.length; i++ ) - if ( drop[i] == this ) - drop.splice(i, 1); - - this.element.removeClass("ui-droppable ui-droppable-disabled"); - }, - - _setOption: function(key, value) { - - if(key == 'accept') { - this.accept = $.isFunction(value) ? value : function(d) { - return d.is(value); - }; - } - $.Widget.prototype._setOption.apply(this, arguments); - }, - - _activate: function(event) { - var draggable = $.ui.ddmanager.current; - if(this.options.activeClass) this.element.addClass(this.options.activeClass); - (draggable && this._trigger('activate', event, this.ui(draggable))); - }, - - _deactivate: function(event) { - var draggable = $.ui.ddmanager.current; - if(this.options.activeClass) this.element.removeClass(this.options.activeClass); - (draggable && this._trigger('deactivate', event, this.ui(draggable))); - }, - - _over: function(event) { - - var draggable = $.ui.ddmanager.current; - if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element - - if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { - if(this.options.hoverClass) this.element.addClass(this.options.hoverClass); - this._trigger('over', event, this.ui(draggable)); - } - - }, - - _out: function(event) { - - var draggable = $.ui.ddmanager.current; - if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element - - if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { - if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass); - this._trigger('out', event, this.ui(draggable)); - } - - }, - - _drop: function(event,custom) { - - var draggable = custom || $.ui.ddmanager.current; - if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element - - var childrenIntersection = false; - this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() { - var inst = $.data(this, 'droppable'); - if( - inst.options.greedy - && !inst.options.disabled - && inst.options.scope == draggable.options.scope - && inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) - && $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance) - ) { childrenIntersection = true; return false; } - }); - if(childrenIntersection) return false; - - if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { - if(this.options.activeClass) this.element.removeClass(this.options.activeClass); - if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass); - this._trigger('drop', event, this.ui(draggable)); - return this.element; - } - - return false; - - }, - - ui: function(c) { - return { - draggable: (c.currentItem || c.element), - helper: c.helper, - position: c.position, - offset: c.positionAbs - }; - } - -}); - -$.ui.intersect = function(draggable, droppable, toleranceMode) { - - if (!droppable.offset) return false; - - var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width, - y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height; - var l = droppable.offset.left, r = l + droppable.proportions.width, - t = droppable.offset.top, b = t + droppable.proportions.height; - - switch (toleranceMode) { - case 'fit': - return (l <= x1 && x2 <= r - && t <= y1 && y2 <= b); - break; - case 'intersect': - return (l < x1 + (draggable.helperProportions.width / 2) // Right Half - && x2 - (draggable.helperProportions.width / 2) < r // Left Half - && t < y1 + (draggable.helperProportions.height / 2) // Bottom Half - && y2 - (draggable.helperProportions.height / 2) < b ); // Top Half - break; - case 'pointer': - var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left), - draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top), - isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width); - return isOver; - break; - case 'touch': - return ( - (y1 >= t && y1 <= b) || // Top edge touching - (y2 >= t && y2 <= b) || // Bottom edge touching - (y1 < t && y2 > b) // Surrounded vertically - ) && ( - (x1 >= l && x1 <= r) || // Left edge touching - (x2 >= l && x2 <= r) || // Right edge touching - (x1 < l && x2 > r) // Surrounded horizontally - ); - break; - default: - return false; - break; - } - -}; - -/* - This manager tracks offsets of draggables and droppables -*/ -$.ui.ddmanager = { - current: null, - droppables: { 'default': [] }, - prepareOffsets: function(t, event) { - - var m = $.ui.ddmanager.droppables[t.options.scope] || []; - var type = event ? event.type : null; // workaround for #2317 - var list = (t.currentItem || t.element).find(":data(droppable)").andSelf(); - - droppablesLoop: for (var i = 0; i < m.length; i++) { - - if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue; //No disabled and non-accepted - for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item - m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; //If the element is not visible, continue - - if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables - - m[i].offset = m[i].element.offset(); - m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight }; - - } - - }, - drop: function(draggable, event) { - - var dropped = false; - $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() { - - if(!this.options) return; - if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) - dropped = this._drop.call(this, event) || dropped; - - if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { - this.isout = 1; this.isover = 0; - this._deactivate.call(this, event); - } - - }); - return dropped; - - }, - dragStart: function( draggable, event ) { - //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003) - draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() { - if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event ); - }); - }, - drag: function(draggable, event) { - - //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse. - if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event); - - //Run through all droppables and check their positions based on specific tolerance options - $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() { - - if(this.options.disabled || this.greedyChild || !this.visible) return; - var intersects = $.ui.intersect(draggable, this, this.options.tolerance); - - var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null); - if(!c) return; - - var parentInstance; - if (this.options.greedy) { - // find droppable parents with same scope - var scope = this.options.scope; - var parent = this.element.parents(':data(droppable)').filter(function () { - return $.data(this, 'droppable').options.scope === scope; - }); - - if (parent.length) { - parentInstance = $.data(parent[0], 'droppable'); - parentInstance.greedyChild = (c == 'isover' ? 1 : 0); - } - } - - // we just moved into a greedy child - if (parentInstance && c == 'isover') { - parentInstance['isover'] = 0; - parentInstance['isout'] = 1; - parentInstance._out.call(parentInstance, event); - } - - this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0; - this[c == "isover" ? "_over" : "_out"].call(this, event); - - // we just moved out of a greedy child - if (parentInstance && c == 'isout') { - parentInstance['isout'] = 0; - parentInstance['isover'] = 1; - parentInstance._over.call(parentInstance, event); - } - }); - - }, - dragStop: function( draggable, event ) { - draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" ); - //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003) - if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event ); - } -}; - -})(jQuery); - -(function( $, undefined ) { - -$.widget("ui.resizable", $.ui.mouse, { - version: "1.9.2", - widgetEventPrefix: "resize", - options: { - alsoResize: false, - animate: false, - animateDuration: "slow", - animateEasing: "swing", - aspectRatio: false, - autoHide: false, - containment: false, - ghost: false, - grid: false, - handles: "e,s,se", - helper: false, - maxHeight: null, - maxWidth: null, - minHeight: 10, - minWidth: 10, - zIndex: 1000 - }, - _create: function() { - - var that = this, o = this.options; - this.element.addClass("ui-resizable"); - - $.extend(this, { - _aspectRatio: !!(o.aspectRatio), - aspectRatio: o.aspectRatio, - originalElement: this.element, - _proportionallyResizeElements: [], - _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null - }); - - //Wrap the element if it cannot hold child nodes - if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) { - - //Create a wrapper element and set the wrapper to the new current internal element - this.element.wrap( - $('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({ - position: this.element.css('position'), - width: this.element.outerWidth(), - height: this.element.outerHeight(), - top: this.element.css('top'), - left: this.element.css('left') - }) - ); - - //Overwrite the original this.element - this.element = this.element.parent().data( - "resizable", this.element.data('resizable') - ); - - this.elementIsWrapper = true; - - //Move margins to the wrapper - this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") }); - this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0}); - - //Prevent Safari textarea resize - this.originalResizeStyle = this.originalElement.css('resize'); - this.originalElement.css('resize', 'none'); - - //Push the actual element to our proportionallyResize internal array - this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' })); - - // avoid IE jump (hard set the margin) - this.originalElement.css({ margin: this.originalElement.css('margin') }); - - // fix handlers offset - this._proportionallyResize(); - - } - - this.handles = o.handles || (!$('.ui-resizable-handle', this.element).length ? "e,s,se" : { n: '.ui-resizable-n', e: '.ui-resizable-e', s: '.ui-resizable-s', w: '.ui-resizable-w', se: '.ui-resizable-se', sw: '.ui-resizable-sw', ne: '.ui-resizable-ne', nw: '.ui-resizable-nw' }); - if(this.handles.constructor == String) { - - if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw'; - var n = this.handles.split(","); this.handles = {}; - - for(var i = 0; i < n.length; i++) { - - var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle; - var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>'); - - // Apply zIndex to all handles - see #7960 - axis.css({ zIndex: o.zIndex }); - - //TODO : What's going on here? - if ('se' == handle) { - axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se'); - }; - - //Insert into internal handles object and append to element - this.handles[handle] = '.ui-resizable-'+handle; - this.element.append(axis); - } - - } - - this._renderAxis = function(target) { - - target = target || this.element; - - for(var i in this.handles) { - - if(this.handles[i].constructor == String) - this.handles[i] = $(this.handles[i], this.element).show(); - - //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls) - if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) { - - var axis = $(this.handles[i], this.element), padWrapper = 0; - - //Checking the correct pad and border - padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); - - //The padding type i have to apply... - var padPos = [ 'padding', - /ne|nw|n/.test(i) ? 'Top' : - /se|sw|s/.test(i) ? 'Bottom' : - /^e$/.test(i) ? 'Right' : 'Left' ].join(""); - - target.css(padPos, padWrapper); - - this._proportionallyResize(); - - } - - //TODO: What's that good for? There's not anything to be executed left - if(!$(this.handles[i]).length) - continue; - - } - }; - - //TODO: make renderAxis a prototype function - this._renderAxis(this.element); - - this._handles = $('.ui-resizable-handle', this.element) - .disableSelection(); - - //Matching axis name - this._handles.mouseover(function() { - if (!that.resizing) { - if (this.className) - var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); - //Axis, default = se - that.axis = axis && axis[1] ? axis[1] : 'se'; - } - }); - - //If we want to auto hide the elements - if (o.autoHide) { - this._handles.hide(); - $(this.element) - .addClass("ui-resizable-autohide") - .mouseenter(function() { - if (o.disabled) return; - $(this).removeClass("ui-resizable-autohide"); - that._handles.show(); - }) - .mouseleave(function(){ - if (o.disabled) return; - if (!that.resizing) { - $(this).addClass("ui-resizable-autohide"); - that._handles.hide(); - } - }); - } - - //Initialize the mouse interaction - this._mouseInit(); - - }, - - _destroy: function() { - - this._mouseDestroy(); - - var _destroy = function(exp) { - $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") - .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find('.ui-resizable-handle').remove(); - }; - - //TODO: Unwrap at same DOM position - if (this.elementIsWrapper) { - _destroy(this.element); - var wrapper = this.element; - this.originalElement.css({ - position: wrapper.css('position'), - width: wrapper.outerWidth(), - height: wrapper.outerHeight(), - top: wrapper.css('top'), - left: wrapper.css('left') - }).insertAfter( wrapper ); - wrapper.remove(); - } - - this.originalElement.css('resize', this.originalResizeStyle); - _destroy(this.originalElement); - - return this; - }, - - _mouseCapture: function(event) { - var handle = false; - for (var i in this.handles) { - if ($(this.handles[i])[0] == event.target) { - handle = true; - } - } - - return !this.options.disabled && handle; - }, - - _mouseStart: function(event) { - - var o = this.options, iniPos = this.element.position(), el = this.element; - - this.resizing = true; - this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() }; - - // bugfix for http://dev.jquery.com/ticket/1749 - if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) { - el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left }); - } - - this._renderProxy(); - - var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top')); - - if (o.containment) { - curleft += $(o.containment).scrollLeft() || 0; - curtop += $(o.containment).scrollTop() || 0; - } - - //Store needed variables - this.offset = this.helper.offset(); - this.position = { left: curleft, top: curtop }; - this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; - this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; - this.originalPosition = { left: curleft, top: curtop }; - this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() }; - this.originalMousePosition = { left: event.pageX, top: event.pageY }; - - //Aspect Ratio - this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1); - - var cursor = $('.ui-resizable-' + this.axis).css('cursor'); - $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor); - - el.addClass("ui-resizable-resizing"); - this._propagate("start", event); - return true; - }, - - _mouseDrag: function(event) { - - //Increase performance, avoid regex - var el = this.helper, o = this.options, props = {}, - that = this, smp = this.originalMousePosition, a = this.axis; - - var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0; - var trigger = this._change[a]; - if (!trigger) return false; - - // Calculate the attrs that will be change - var data = trigger.apply(this, [event, dx, dy]); - - // Put this in the mouseDrag handler since the user can start pressing shift while resizing - this._updateVirtualBoundaries(event.shiftKey); - if (this._aspectRatio || event.shiftKey) - data = this._updateRatio(data, event); - - data = this._respectSize(data, event); - - // plugins callbacks need to be called first - this._propagate("resize", event); - - el.css({ - top: this.position.top + "px", left: this.position.left + "px", - width: this.size.width + "px", height: this.size.height + "px" - }); - - if (!this._helper && this._proportionallyResizeElements.length) - this._proportionallyResize(); - - this._updateCache(data); - - // calling the user callback at the end - this._trigger('resize', event, this.ui()); - - return false; - }, - - _mouseStop: function(event) { - - this.resizing = false; - var o = this.options, that = this; - - if(this._helper) { - var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName), - soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height, - soffsetw = ista ? 0 : that.sizeDiff.width; - - var s = { width: (that.helper.width() - soffsetw), height: (that.helper.height() - soffseth) }, - left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null, - top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null; - - if (!o.animate) - this.element.css($.extend(s, { top: top, left: left })); - - that.helper.height(that.size.height); - that.helper.width(that.size.width); - - if (this._helper && !o.animate) this._proportionallyResize(); - } - - $('body').css('cursor', 'auto'); - - this.element.removeClass("ui-resizable-resizing"); - - this._propagate("stop", event); - - if (this._helper) this.helper.remove(); - return false; - - }, - - _updateVirtualBoundaries: function(forceAspectRatio) { - var o = this.options, pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b; - - b = { - minWidth: isNumber(o.minWidth) ? o.minWidth : 0, - maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity, - minHeight: isNumber(o.minHeight) ? o.minHeight : 0, - maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity - }; - - if(this._aspectRatio || forceAspectRatio) { - // We want to create an enclosing box whose aspect ration is the requested one - // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension - pMinWidth = b.minHeight * this.aspectRatio; - pMinHeight = b.minWidth / this.aspectRatio; - pMaxWidth = b.maxHeight * this.aspectRatio; - pMaxHeight = b.maxWidth / this.aspectRatio; - - if(pMinWidth > b.minWidth) b.minWidth = pMinWidth; - if(pMinHeight > b.minHeight) b.minHeight = pMinHeight; - if(pMaxWidth < b.maxWidth) b.maxWidth = pMaxWidth; - if(pMaxHeight < b.maxHeight) b.maxHeight = pMaxHeight; - } - this._vBoundaries = b; - }, - - _updateCache: function(data) { - var o = this.options; - this.offset = this.helper.offset(); - if (isNumber(data.left)) this.position.left = data.left; - if (isNumber(data.top)) this.position.top = data.top; - if (isNumber(data.height)) this.size.height = data.height; - if (isNumber(data.width)) this.size.width = data.width; - }, - - _updateRatio: function(data, event) { - - var o = this.options, cpos = this.position, csize = this.size, a = this.axis; - - if (isNumber(data.height)) data.width = (data.height * this.aspectRatio); - else if (isNumber(data.width)) data.height = (data.width / this.aspectRatio); - - if (a == 'sw') { - data.left = cpos.left + (csize.width - data.width); - data.top = null; - } - if (a == 'nw') { - data.top = cpos.top + (csize.height - data.height); - data.left = cpos.left + (csize.width - data.width); - } - - return data; - }, - - _respectSize: function(data, event) { - - var el = this.helper, o = this._vBoundaries, pRatio = this._aspectRatio || event.shiftKey, a = this.axis, - ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), - isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height); - - if (isminw) data.width = o.minWidth; - if (isminh) data.height = o.minHeight; - if (ismaxw) data.width = o.maxWidth; - if (ismaxh) data.height = o.maxHeight; - - var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height; - var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); - - if (isminw && cw) data.left = dw - o.minWidth; - if (ismaxw && cw) data.left = dw - o.maxWidth; - if (isminh && ch) data.top = dh - o.minHeight; - if (ismaxh && ch) data.top = dh - o.maxHeight; - - // fixing jump error on top/left - bug #2330 - var isNotwh = !data.width && !data.height; - if (isNotwh && !data.left && data.top) data.top = null; - else if (isNotwh && !data.top && data.left) data.left = null; - - return data; - }, - - _proportionallyResize: function() { - - var o = this.options; - if (!this._proportionallyResizeElements.length) return; - var element = this.helper || this.element; - - for (var i=0; i < this._proportionallyResizeElements.length; i++) { - - var prel = this._proportionallyResizeElements[i]; - - if (!this.borderDif) { - var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')], - p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')]; - - this.borderDif = $.map(b, function(v, i) { - var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0; - return border + padding; - }); - } - - prel.css({ - height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0, - width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0 - }); - - }; - - }, - - _renderProxy: function() { - - var el = this.element, o = this.options; - this.elementOffset = el.offset(); - - if(this._helper) { - - this.helper = this.helper || $('<div style="overflow:hidden;"></div>'); - - // fix ie6 offset TODO: This seems broken - var ie6offset = ($.ui.ie6 ? 1 : 0), - pxyoffset = ( $.ui.ie6 ? 2 : -1 ); - - this.helper.addClass(this._helper).css({ - width: this.element.outerWidth() + pxyoffset, - height: this.element.outerHeight() + pxyoffset, - position: 'absolute', - left: this.elementOffset.left - ie6offset +'px', - top: this.elementOffset.top - ie6offset +'px', - zIndex: ++o.zIndex //TODO: Don't modify option - }); - - this.helper - .appendTo("body") - .disableSelection(); - - } else { - this.helper = this.element; - } - - }, - - _change: { - e: function(event, dx, dy) { - return { width: this.originalSize.width + dx }; - }, - w: function(event, dx, dy) { - var o = this.options, cs = this.originalSize, sp = this.originalPosition; - return { left: sp.left + dx, width: cs.width - dx }; - }, - n: function(event, dx, dy) { - var o = this.options, cs = this.originalSize, sp = this.originalPosition; - return { top: sp.top + dy, height: cs.height - dy }; - }, - s: function(event, dx, dy) { - return { height: this.originalSize.height + dy }; - }, - se: function(event, dx, dy) { - return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); - }, - sw: function(event, dx, dy) { - return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); - }, - ne: function(event, dx, dy) { - return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); - }, - nw: function(event, dx, dy) { - return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); - } - }, - - _propagate: function(n, event) { - $.ui.plugin.call(this, n, [event, this.ui()]); - (n != "resize" && this._trigger(n, event, this.ui())); - }, - - plugins: {}, - - ui: function() { - return { - originalElement: this.originalElement, - element: this.element, - helper: this.helper, - position: this.position, - size: this.size, - originalSize: this.originalSize, - originalPosition: this.originalPosition - }; - } - -}); - -/* - * Resizable Extensions - */ - -$.ui.plugin.add("resizable", "alsoResize", { - - start: function (event, ui) { - var that = $(this).data("resizable"), o = that.options; - - var _store = function (exp) { - $(exp).each(function() { - var el = $(this); - el.data("resizable-alsoresize", { - width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), - left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10) - }); - }); - }; - - if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) { - if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); } - else { $.each(o.alsoResize, function (exp) { _store(exp); }); } - }else{ - _store(o.alsoResize); - } - }, - - resize: function (event, ui) { - var that = $(this).data("resizable"), o = that.options, os = that.originalSize, op = that.originalPosition; - - var delta = { - height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0, - top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0 - }, - - _alsoResize = function (exp, c) { - $(exp).each(function() { - var el = $(this), start = $(this).data("resizable-alsoresize"), style = {}, - css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left']; - - $.each(css, function (i, prop) { - var sum = (start[prop]||0) + (delta[prop]||0); - if (sum && sum >= 0) - style[prop] = sum || null; - }); - - el.css(style); - }); - }; - - if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) { - $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); }); - }else{ - _alsoResize(o.alsoResize); - } - }, - - stop: function (event, ui) { - $(this).removeData("resizable-alsoresize"); - } -}); - -$.ui.plugin.add("resizable", "animate", { - - stop: function(event, ui) { - var that = $(this).data("resizable"), o = that.options; - - var pr = that._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName), - soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height, - soffsetw = ista ? 0 : that.sizeDiff.width; - - var style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) }, - left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null, - top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null; - - that.element.animate( - $.extend(style, top && left ? { top: top, left: left } : {}), { - duration: o.animateDuration, - easing: o.animateEasing, - step: function() { - - var data = { - width: parseInt(that.element.css('width'), 10), - height: parseInt(that.element.css('height'), 10), - top: parseInt(that.element.css('top'), 10), - left: parseInt(that.element.css('left'), 10) - }; - - if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height }); - - // propagating resize, and updating values for each animation step - that._updateCache(data); - that._propagate("resize", event); - - } - } - ); - } - -}); - -$.ui.plugin.add("resizable", "containment", { - - start: function(event, ui) { - var that = $(this).data("resizable"), o = that.options, el = that.element; - var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc; - if (!ce) return; - - that.containerElement = $(ce); - - if (/document/.test(oc) || oc == document) { - that.containerOffset = { left: 0, top: 0 }; - that.containerPosition = { left: 0, top: 0 }; - - that.parentData = { - element: $(document), left: 0, top: 0, - width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight - }; - } - - // i'm a node, so compute top, left, right, bottom - else { - var element = $(ce), p = []; - $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); }); - - that.containerOffset = element.offset(); - that.containerPosition = element.position(); - that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) }; - - var co = that.containerOffset, ch = that.containerSize.height, cw = that.containerSize.width, - width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch); - - that.parentData = { - element: ce, left: co.left, top: co.top, width: width, height: height - }; - } - }, - - resize: function(event, ui) { - var that = $(this).data("resizable"), o = that.options, - ps = that.containerSize, co = that.containerOffset, cs = that.size, cp = that.position, - pRatio = that._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = that.containerElement; - - if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co; - - if (cp.left < (that._helper ? co.left : 0)) { - that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left)); - if (pRatio) that.size.height = that.size.width / that.aspectRatio; - that.position.left = o.helper ? co.left : 0; - } - - if (cp.top < (that._helper ? co.top : 0)) { - that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top); - if (pRatio) that.size.width = that.size.height * that.aspectRatio; - that.position.top = that._helper ? co.top : 0; - } - - that.offset.left = that.parentData.left+that.position.left; - that.offset.top = that.parentData.top+that.position.top; - - var woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width ), - hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height ); - - var isParent = that.containerElement.get(0) == that.element.parent().get(0), - isOffsetRelative = /relative|absolute/.test(that.containerElement.css('position')); - - if(isParent && isOffsetRelative) woset -= that.parentData.left; - - if (woset + that.size.width >= that.parentData.width) { - that.size.width = that.parentData.width - woset; - if (pRatio) that.size.height = that.size.width / that.aspectRatio; - } - - if (hoset + that.size.height >= that.parentData.height) { - that.size.height = that.parentData.height - hoset; - if (pRatio) that.size.width = that.size.height * that.aspectRatio; - } - }, - - stop: function(event, ui){ - var that = $(this).data("resizable"), o = that.options, cp = that.position, - co = that.containerOffset, cop = that.containerPosition, ce = that.containerElement; - - var helper = $(that.helper), ho = helper.offset(), w = helper.outerWidth() - that.sizeDiff.width, h = helper.outerHeight() - that.sizeDiff.height; - - if (that._helper && !o.animate && (/relative/).test(ce.css('position'))) - $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); - - if (that._helper && !o.animate && (/static/).test(ce.css('position'))) - $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); - - } -}); - -$.ui.plugin.add("resizable", "ghost", { - - start: function(event, ui) { - - var that = $(this).data("resizable"), o = that.options, cs = that.size; - - that.ghost = that.originalElement.clone(); - that.ghost - .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 }) - .addClass('ui-resizable-ghost') - .addClass(typeof o.ghost == 'string' ? o.ghost : ''); - - that.ghost.appendTo(that.helper); - - }, - - resize: function(event, ui){ - var that = $(this).data("resizable"), o = that.options; - if (that.ghost) that.ghost.css({ position: 'relative', height: that.size.height, width: that.size.width }); - }, - - stop: function(event, ui){ - var that = $(this).data("resizable"), o = that.options; - if (that.ghost && that.helper) that.helper.get(0).removeChild(that.ghost.get(0)); - } - -}); - -$.ui.plugin.add("resizable", "grid", { - - resize: function(event, ui) { - var that = $(this).data("resizable"), o = that.options, cs = that.size, os = that.originalSize, op = that.originalPosition, a = that.axis, ratio = o._aspectRatio || event.shiftKey; - o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid; - var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1); - - if (/^(se|s|e)$/.test(a)) { - that.size.width = os.width + ox; - that.size.height = os.height + oy; - } - else if (/^(ne)$/.test(a)) { - that.size.width = os.width + ox; - that.size.height = os.height + oy; - that.position.top = op.top - oy; - } - else if (/^(sw)$/.test(a)) { - that.size.width = os.width + ox; - that.size.height = os.height + oy; - that.position.left = op.left - ox; - } - else { - that.size.width = os.width + ox; - that.size.height = os.height + oy; - that.position.top = op.top - oy; - that.position.left = op.left - ox; - } - } - -}); - -var num = function(v) { - return parseInt(v, 10) || 0; -}; - -var isNumber = function(value) { - return !isNaN(parseInt(value, 10)); -}; - -})(jQuery); - -(function( $, undefined ) { - -$.widget("ui.selectable", $.ui.mouse, { - version: "1.9.2", - options: { - appendTo: 'body', - autoRefresh: true, - distance: 0, - filter: '*', - tolerance: 'touch' - }, - _create: function() { - var that = this; - - this.element.addClass("ui-selectable"); - - this.dragged = false; - - // cache selectee children based on filter - var selectees; - this.refresh = function() { - selectees = $(that.options.filter, that.element[0]); - selectees.addClass("ui-selectee"); - selectees.each(function() { - var $this = $(this); - var pos = $this.offset(); - $.data(this, "selectable-item", { - element: this, - $element: $this, - left: pos.left, - top: pos.top, - right: pos.left + $this.outerWidth(), - bottom: pos.top + $this.outerHeight(), - startselected: false, - selected: $this.hasClass('ui-selected'), - selecting: $this.hasClass('ui-selecting'), - unselecting: $this.hasClass('ui-unselecting') - }); - }); - }; - this.refresh(); - - this.selectees = selectees.addClass("ui-selectee"); - - this._mouseInit(); - - this.helper = $("<div class='ui-selectable-helper'></div>"); - }, - - _destroy: function() { - this.selectees - .removeClass("ui-selectee") - .removeData("selectable-item"); - this.element - .removeClass("ui-selectable ui-selectable-disabled"); - this._mouseDestroy(); - }, - - _mouseStart: function(event) { - var that = this; - - this.opos = [event.pageX, event.pageY]; - - if (this.options.disabled) - return; - - var options = this.options; - - this.selectees = $(options.filter, this.element[0]); - - this._trigger("start", event); - - $(options.appendTo).append(this.helper); - // position helper (lasso) - this.helper.css({ - "left": event.clientX, - "top": event.clientY, - "width": 0, - "height": 0 - }); - - if (options.autoRefresh) { - this.refresh(); - } - - this.selectees.filter('.ui-selected').each(function() { - var selectee = $.data(this, "selectable-item"); - selectee.startselected = true; - if (!event.metaKey && !event.ctrlKey) { - selectee.$element.removeClass('ui-selected'); - selectee.selected = false; - selectee.$element.addClass('ui-unselecting'); - selectee.unselecting = true; - // selectable UNSELECTING callback - that._trigger("unselecting", event, { - unselecting: selectee.element - }); - } - }); - - $(event.target).parents().andSelf().each(function() { - var selectee = $.data(this, "selectable-item"); - if (selectee) { - var doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass('ui-selected'); - selectee.$element - .removeClass(doSelect ? "ui-unselecting" : "ui-selected") - .addClass(doSelect ? "ui-selecting" : "ui-unselecting"); - selectee.unselecting = !doSelect; - selectee.selecting = doSelect; - selectee.selected = doSelect; - // selectable (UN)SELECTING callback - if (doSelect) { - that._trigger("selecting", event, { - selecting: selectee.element - }); - } else { - that._trigger("unselecting", event, { - unselecting: selectee.element - }); - } - return false; - } - }); - - }, - - _mouseDrag: function(event) { - var that = this; - this.dragged = true; - - if (this.options.disabled) - return; - - var options = this.options; - - var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY; - if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; } - if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; } - this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1}); - - this.selectees.each(function() { - var selectee = $.data(this, "selectable-item"); - //prevent helper from being selected if appendTo: selectable - if (!selectee || selectee.element == that.element[0]) - return; - var hit = false; - if (options.tolerance == 'touch') { - hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) ); - } else if (options.tolerance == 'fit') { - hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); - } - - if (hit) { - // SELECT - if (selectee.selected) { - selectee.$element.removeClass('ui-selected'); - selectee.selected = false; - } - if (selectee.unselecting) { - selectee.$element.removeClass('ui-unselecting'); - selectee.unselecting = false; - } - if (!selectee.selecting) { - selectee.$element.addClass('ui-selecting'); - selectee.selecting = true; - // selectable SELECTING callback - that._trigger("selecting", event, { - selecting: selectee.element - }); - } - } else { - // UNSELECT - if (selectee.selecting) { - if ((event.metaKey || event.ctrlKey) && selectee.startselected) { - selectee.$element.removeClass('ui-selecting'); - selectee.selecting = false; - selectee.$element.addClass('ui-selected'); - selectee.selected = true; - } else { - selectee.$element.removeClass('ui-selecting'); - selectee.selecting = false; - if (selectee.startselected) { - selectee.$element.addClass('ui-unselecting'); - selectee.unselecting = true; - } - // selectable UNSELECTING callback - that._trigger("unselecting", event, { - unselecting: selectee.element - }); - } - } - if (selectee.selected) { - if (!event.metaKey && !event.ctrlKey && !selectee.startselected) { - selectee.$element.removeClass('ui-selected'); - selectee.selected = false; - - selectee.$element.addClass('ui-unselecting'); - selectee.unselecting = true; - // selectable UNSELECTING callback - that._trigger("unselecting", event, { - unselecting: selectee.element - }); - } - } - } - }); - - return false; - }, - - _mouseStop: function(event) { - var that = this; - - this.dragged = false; - - var options = this.options; - - $('.ui-unselecting', this.element[0]).each(function() { - var selectee = $.data(this, "selectable-item"); - selectee.$element.removeClass('ui-unselecting'); - selectee.unselecting = false; - selectee.startselected = false; - that._trigger("unselected", event, { - unselected: selectee.element - }); - }); - $('.ui-selecting', this.element[0]).each(function() { - var selectee = $.data(this, "selectable-item"); - selectee.$element.removeClass('ui-selecting').addClass('ui-selected'); - selectee.selecting = false; - selectee.selected = true; - selectee.startselected = true; - that._trigger("selected", event, { - selected: selectee.element - }); - }); - this._trigger("stop", event); - - this.helper.remove(); - - return false; - } - -}); - -})(jQuery); - -(function( $, undefined ) { - -$.widget("ui.sortable", $.ui.mouse, { - version: "1.9.2", - widgetEventPrefix: "sort", - ready: false, - options: { - appendTo: "parent", - axis: false, - connectWith: false, - containment: false, - cursor: 'auto', - cursorAt: false, - dropOnEmpty: true, - forcePlaceholderSize: false, - forceHelperSize: false, - grid: false, - handle: false, - helper: "original", - items: '> *', - opacity: false, - placeholder: false, - revert: false, - scroll: true, - scrollSensitivity: 20, - scrollSpeed: 20, - scope: "default", - tolerance: "intersect", - zIndex: 1000 - }, - _create: function() { - - var o = this.options; - this.containerCache = {}; - this.element.addClass("ui-sortable"); - - //Get the items - this.refresh(); - - //Let's determine if the items are being displayed horizontally - this.floating = this.items.length ? o.axis === 'x' || (/left|right/).test(this.items[0].item.css('float')) || (/inline|table-cell/).test(this.items[0].item.css('display')) : false; - - //Let's determine the parent's offset - this.offset = this.element.offset(); - - //Initialize mouse events for interaction - this._mouseInit(); - - //We're ready to go - this.ready = true - - }, - - _destroy: function() { - this.element - .removeClass("ui-sortable ui-sortable-disabled"); - this._mouseDestroy(); - - for ( var i = this.items.length - 1; i >= 0; i-- ) - this.items[i].item.removeData(this.widgetName + "-item"); - - return this; - }, - - _setOption: function(key, value){ - if ( key === "disabled" ) { - this.options[ key ] = value; - - this.widget().toggleClass( "ui-sortable-disabled", !!value ); - } else { - // Don't call widget base _setOption for disable as it adds ui-state-disabled class - $.Widget.prototype._setOption.apply(this, arguments); - } - }, - - _mouseCapture: function(event, overrideHandle) { - var that = this; - - if (this.reverting) { - return false; - } - - if(this.options.disabled || this.options.type == 'static') return false; - - //We have to refresh the items data once first - this._refreshItems(event); - - //Find out if the clicked node (or one of its parents) is a actual item in this.items - var currentItem = null, nodes = $(event.target).parents().each(function() { - if($.data(this, that.widgetName + '-item') == that) { - currentItem = $(this); - return false; - } - }); - if($.data(event.target, that.widgetName + '-item') == that) currentItem = $(event.target); - - if(!currentItem) return false; - if(this.options.handle && !overrideHandle) { - var validHandle = false; - - $(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; }); - if(!validHandle) return false; - } - - this.currentItem = currentItem; - this._removeCurrentsFromItems(); - return true; - - }, - - _mouseStart: function(event, overrideHandle, noActivation) { - - var o = this.options; - this.currentContainer = this; - - //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture - this.refreshPositions(); - - //Create and append the visible helper - this.helper = this._createHelper(event); - - //Cache the helper size - this._cacheHelperProportions(); - - /* - * - Position generation - - * This block generates everything position related - it's the core of draggables. - */ - - //Cache the margins of the original element - this._cacheMargins(); - - //Get the next scrolling parent - this.scrollParent = this.helper.scrollParent(); - - //The element's absolute position on the page minus margins - this.offset = this.currentItem.offset(); - this.offset = { - top: this.offset.top - this.margins.top, - left: this.offset.left - this.margins.left - }; - - $.extend(this.offset, { - click: { //Where the click happened, relative to the element - left: event.pageX - this.offset.left, - top: event.pageY - this.offset.top - }, - parent: this._getParentOffset(), - relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper - }); - - // Only after we got the offset, we can change the helper's position to absolute - // TODO: Still need to figure out a way to make relative sorting possible - this.helper.css("position", "absolute"); - this.cssPosition = this.helper.css("position"); - - //Generate the original position - this.originalPosition = this._generatePosition(event); - this.originalPageX = event.pageX; - this.originalPageY = event.pageY; - - //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied - (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); - - //Cache the former DOM position - this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; - - //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way - if(this.helper[0] != this.currentItem[0]) { - this.currentItem.hide(); - } - - //Create the placeholder - this._createPlaceholder(); - - //Set a containment if given in the options - if(o.containment) - this._setContainment(); - - if(o.cursor) { // cursor option - if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor"); - $('body').css("cursor", o.cursor); - } - - if(o.opacity) { // opacity option - if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity"); - this.helper.css("opacity", o.opacity); - } - - if(o.zIndex) { // zIndex option - if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex"); - this.helper.css("zIndex", o.zIndex); - } - - //Prepare scrolling - if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') - this.overflowOffset = this.scrollParent.offset(); - - //Call callbacks - this._trigger("start", event, this._uiHash()); - - //Recache the helper size - if(!this._preserveHelperProportions) - this._cacheHelperProportions(); - - - //Post 'activate' events to possible containers - if(!noActivation) { - for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, this._uiHash(this)); } - } - - //Prepare possible droppables - if($.ui.ddmanager) - $.ui.ddmanager.current = this; - - if ($.ui.ddmanager && !o.dropBehaviour) - $.ui.ddmanager.prepareOffsets(this, event); - - this.dragging = true; - - this.helper.addClass("ui-sortable-helper"); - this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position - return true; - - }, - - _mouseDrag: function(event) { - - //Compute the helpers position - this.position = this._generatePosition(event); - this.positionAbs = this._convertPositionTo("absolute"); - - if (!this.lastPositionAbs) { - this.lastPositionAbs = this.positionAbs; - } - - //Do scrolling - if(this.options.scroll) { - var o = this.options, scrolled = false; - if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') { - - if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) - this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed; - else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) - this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed; - - if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) - this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed; - else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) - this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed; - - } else { - - if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) - scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); - else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) - scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); - - if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) - scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); - else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) - scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); - - } - - if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) - $.ui.ddmanager.prepareOffsets(this, event); - } - - //Regenerate the absolute position used for position checks - this.positionAbs = this._convertPositionTo("absolute"); - - //Set the helper position - if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px'; - if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px'; - - //Rearrange - for (var i = this.items.length - 1; i >= 0; i--) { - - //Cache variables and intersection, continue if no intersection - var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item); - if (!intersection) continue; - - // Only put the placeholder inside the current Container, skip all - // items form other containers. This works because when moving - // an item from one container to another the - // currentContainer is switched before the placeholder is moved. - // - // Without this moving items in "sub-sortables" can cause the placeholder to jitter - // beetween the outer and inner container. - if (item.instance !== this.currentContainer) continue; - - if (itemElement != this.currentItem[0] //cannot intersect with itself - && this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before - && !$.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked - && (this.options.type == 'semi-dynamic' ? !$.contains(this.element[0], itemElement) : true) - //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container - ) { - - this.direction = intersection == 1 ? "down" : "up"; - - if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) { - this._rearrange(event, item); - } else { - break; - } - - this._trigger("change", event, this._uiHash()); - break; - } - } - - //Post events to containers - this._contactContainers(event); - - //Interconnect with droppables - if($.ui.ddmanager) $.ui.ddmanager.drag(this, event); - - //Call callbacks - this._trigger('sort', event, this._uiHash()); - - this.lastPositionAbs = this.positionAbs; - return false; - - }, - - _mouseStop: function(event, noPropagation) { - - if(!event) return; - - //If we are using droppables, inform the manager about the drop - if ($.ui.ddmanager && !this.options.dropBehaviour) - $.ui.ddmanager.drop(this, event); - - if(this.options.revert) { - var that = this; - var cur = this.placeholder.offset(); - - this.reverting = true; - - $(this.helper).animate({ - left: cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft), - top: cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop) - }, parseInt(this.options.revert, 10) || 500, function() { - that._clear(event); - }); - } else { - this._clear(event, noPropagation); - } - - return false; - - }, - - cancel: function() { - - if(this.dragging) { - - this._mouseUp({ target: null }); - - if(this.options.helper == "original") - this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); - else - this.currentItem.show(); - - //Post deactivating events to containers - for (var i = this.containers.length - 1; i >= 0; i--){ - this.containers[i]._trigger("deactivate", null, this._uiHash(this)); - if(this.containers[i].containerCache.over) { - this.containers[i]._trigger("out", null, this._uiHash(this)); - this.containers[i].containerCache.over = 0; - } - } - - } - - if (this.placeholder) { - //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! - if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]); - if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove(); - - $.extend(this, { - helper: null, - dragging: false, - reverting: false, - _noFinalSort: null - }); - - if(this.domPosition.prev) { - $(this.domPosition.prev).after(this.currentItem); - } else { - $(this.domPosition.parent).prepend(this.currentItem); - } - } - - return this; - - }, - - serialize: function(o) { - - var items = this._getItemsAsjQuery(o && o.connected); - var str = []; o = o || {}; - - $(items).each(function() { - var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/)); - if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2])); - }); - - if(!str.length && o.key) { - str.push(o.key + '='); - } - - return str.join('&'); - - }, - - toArray: function(o) { - - var items = this._getItemsAsjQuery(o && o.connected); - var ret = []; o = o || {}; - - items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); }); - return ret; - - }, - - /* Be careful with the following core functions */ - _intersectsWith: function(item) { - - var x1 = this.positionAbs.left, - x2 = x1 + this.helperProportions.width, - y1 = this.positionAbs.top, - y2 = y1 + this.helperProportions.height; - - var l = item.left, - r = l + item.width, - t = item.top, - b = t + item.height; - - var dyClick = this.offset.click.top, - dxClick = this.offset.click.left; - - var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r; - - if( this.options.tolerance == "pointer" - || this.options.forcePointerForContainers - || (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height']) - ) { - return isOverElement; - } else { - - return (l < x1 + (this.helperProportions.width / 2) // Right Half - && x2 - (this.helperProportions.width / 2) < r // Left Half - && t < y1 + (this.helperProportions.height / 2) // Bottom Half - && y2 - (this.helperProportions.height / 2) < b ); // Top Half - - } - }, - - _intersectsWithPointer: function(item) { - - var isOverElementHeight = (this.options.axis === 'x') || $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), - isOverElementWidth = (this.options.axis === 'y') || $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), - isOverElement = isOverElementHeight && isOverElementWidth, - verticalDirection = this._getDragVerticalDirection(), - horizontalDirection = this._getDragHorizontalDirection(); - - if (!isOverElement) - return false; - - return this.floating ? - ( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 ) - : ( verticalDirection && (verticalDirection == "down" ? 2 : 1) ); - - }, - - _intersectsWithSides: function(item) { - - var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), - isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), - verticalDirection = this._getDragVerticalDirection(), - horizontalDirection = this._getDragHorizontalDirection(); - - if (this.floating && horizontalDirection) { - return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf)); - } else { - return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf)); - } - - }, - - _getDragVerticalDirection: function() { - var delta = this.positionAbs.top - this.lastPositionAbs.top; - return delta != 0 && (delta > 0 ? "down" : "up"); - }, - - _getDragHorizontalDirection: function() { - var delta = this.positionAbs.left - this.lastPositionAbs.left; - return delta != 0 && (delta > 0 ? "right" : "left"); - }, - - refresh: function(event) { - this._refreshItems(event); - this.refreshPositions(); - return this; - }, - - _connectWith: function() { - var options = this.options; - return options.connectWith.constructor == String - ? [options.connectWith] - : options.connectWith; - }, - - _getItemsAsjQuery: function(connected) { - - var items = []; - var queries = []; - var connectWith = this._connectWith(); - - if(connectWith && connected) { - for (var i = connectWith.length - 1; i >= 0; i--){ - var cur = $(connectWith[i]); - for (var j = cur.length - 1; j >= 0; j--){ - var inst = $.data(cur[j], this.widgetName); - if(inst && inst != this && !inst.options.disabled) { - queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), inst]); - } - }; - }; - } - - queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), this]); - - for (var i = queries.length - 1; i >= 0; i--){ - queries[i][0].each(function() { - items.push(this); - }); - }; - - return $(items); - - }, - - _removeCurrentsFromItems: function() { - - var list = this.currentItem.find(":data(" + this.widgetName + "-item)"); - - this.items = $.grep(this.items, function (item) { - for (var j=0; j < list.length; j++) { - if(list[j] == item.item[0]) - return false; - }; - return true; - }); - - }, - - _refreshItems: function(event) { - - this.items = []; - this.containers = [this]; - var items = this.items; - var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]]; - var connectWith = this._connectWith(); - - if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down - for (var i = connectWith.length - 1; i >= 0; i--){ - var cur = $(connectWith[i]); - for (var j = cur.length - 1; j >= 0; j--){ - var inst = $.data(cur[j], this.widgetName); - if(inst && inst != this && !inst.options.disabled) { - queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]); - this.containers.push(inst); - } - }; - }; - } - - for (var i = queries.length - 1; i >= 0; i--) { - var targetData = queries[i][1]; - var _queries = queries[i][0]; - - for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) { - var item = $(_queries[j]); - - item.data(this.widgetName + '-item', targetData); // Data for target checking (mouse manager) - - items.push({ - item: item, - instance: targetData, - width: 0, height: 0, - left: 0, top: 0 - }); - }; - }; - - }, - - refreshPositions: function(fast) { - - //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change - if(this.offsetParent && this.helper) { - this.offset.parent = this._getParentOffset(); - } - - for (var i = this.items.length - 1; i >= 0; i--){ - var item = this.items[i]; - - //We ignore calculating positions of all connected containers when we're not over them - if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0]) - continue; - - var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item; - - if (!fast) { - item.width = t.outerWidth(); - item.height = t.outerHeight(); - } - - var p = t.offset(); - item.left = p.left; - item.top = p.top; - }; - - if(this.options.custom && this.options.custom.refreshContainers) { - this.options.custom.refreshContainers.call(this); - } else { - for (var i = this.containers.length - 1; i >= 0; i--){ - var p = this.containers[i].element.offset(); - this.containers[i].containerCache.left = p.left; - this.containers[i].containerCache.top = p.top; - this.containers[i].containerCache.width = this.containers[i].element.outerWidth(); - this.containers[i].containerCache.height = this.containers[i].element.outerHeight(); - }; - } - - return this; - }, - - _createPlaceholder: function(that) { - that = that || this; - var o = that.options; - - if(!o.placeholder || o.placeholder.constructor == String) { - var className = o.placeholder; - o.placeholder = { - element: function() { - - var el = $(document.createElement(that.currentItem[0].nodeName)) - .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder") - .removeClass("ui-sortable-helper")[0]; - - if(!className) - el.style.visibility = "hidden"; - - return el; - }, - update: function(container, p) { - - // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that - // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified - if(className && !o.forcePlaceholderSize) return; - - //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item - if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css('paddingTop')||0, 10) - parseInt(that.currentItem.css('paddingBottom')||0, 10)); }; - if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css('paddingLeft')||0, 10) - parseInt(that.currentItem.css('paddingRight')||0, 10)); }; - } - }; - } - - //Create the placeholder - that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem)); - - //Append it after the actual current item - that.currentItem.after(that.placeholder); - - //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) - o.placeholder.update(that, that.placeholder); - - }, - - _contactContainers: function(event) { - - // get innermost container that intersects with item - var innermostContainer = null, innermostIndex = null; - - - for (var i = this.containers.length - 1; i >= 0; i--){ - - // never consider a container that's located within the item itself - if($.contains(this.currentItem[0], this.containers[i].element[0])) - continue; - - if(this._intersectsWith(this.containers[i].containerCache)) { - - // if we've already found a container and it's more "inner" than this, then continue - if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) - continue; - - innermostContainer = this.containers[i]; - innermostIndex = i; - - } else { - // container doesn't intersect. trigger "out" event if necessary - if(this.containers[i].containerCache.over) { - this.containers[i]._trigger("out", event, this._uiHash(this)); - this.containers[i].containerCache.over = 0; - } - } - - } - - // if no intersecting containers found, return - if(!innermostContainer) return; - - // move the item into the container if it's not there already - if(this.containers.length === 1) { - this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); - this.containers[innermostIndex].containerCache.over = 1; - } else { - - //When entering a new container, we will find the item with the least distance and append our item near it - var dist = 10000; var itemWithLeastDistance = null; - var posProperty = this.containers[innermostIndex].floating ? 'left' : 'top'; - var sizeProperty = this.containers[innermostIndex].floating ? 'width' : 'height'; - var base = this.positionAbs[posProperty] + this.offset.click[posProperty]; - for (var j = this.items.length - 1; j >= 0; j--) { - if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue; - if(this.items[j].item[0] == this.currentItem[0]) continue; - var cur = this.items[j].item.offset()[posProperty]; - var nearBottom = false; - if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){ - nearBottom = true; - cur += this.items[j][sizeProperty]; - } - - if(Math.abs(cur - base) < dist) { - dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; - this.direction = nearBottom ? "up": "down"; - } - } - - if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled - return; - - this.currentContainer = this.containers[innermostIndex]; - itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); - this._trigger("change", event, this._uiHash()); - this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); - - //Update the placeholder - this.options.placeholder.update(this.currentContainer, this.placeholder); - - this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); - this.containers[innermostIndex].containerCache.over = 1; - } - - - }, - - _createHelper: function(event) { - - var o = this.options; - var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem); - - if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already - $(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]); - - if(helper[0] == this.currentItem[0]) - this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") }; - - if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width()); - if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height()); - - return helper; - - }, - - _adjustOffsetFromHelper: function(obj) { - if (typeof obj == 'string') { - obj = obj.split(' '); - } - if ($.isArray(obj)) { - obj = {left: +obj[0], top: +obj[1] || 0}; - } - if ('left' in obj) { - this.offset.click.left = obj.left + this.margins.left; - } - if ('right' in obj) { - this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; - } - if ('top' in obj) { - this.offset.click.top = obj.top + this.margins.top; - } - if ('bottom' in obj) { - this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; - } - }, - - _getParentOffset: function() { - - - //Get the offsetParent and cache its position - this.offsetParent = this.helper.offsetParent(); - var po = this.offsetParent.offset(); - - // This is a special case where we need to modify a offset calculated on start, since the following happened: - // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent - // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that - // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag - if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) { - po.left += this.scrollParent.scrollLeft(); - po.top += this.scrollParent.scrollTop(); - } - - if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information - || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.ui.ie)) //Ugly IE fix - po = { top: 0, left: 0 }; - - return { - top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), - left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) - }; - - }, - - _getRelativeOffset: function() { - - if(this.cssPosition == "relative") { - var p = this.currentItem.position(); - return { - top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), - left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() - }; - } else { - return { top: 0, left: 0 }; - } - - }, - - _cacheMargins: function() { - this.margins = { - left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), - top: (parseInt(this.currentItem.css("marginTop"),10) || 0) - }; - }, - - _cacheHelperProportions: function() { - this.helperProportions = { - width: this.helper.outerWidth(), - height: this.helper.outerHeight() - }; - }, - - _setContainment: function() { - - var o = this.options; - if(o.containment == 'parent') o.containment = this.helper[0].parentNode; - if(o.containment == 'document' || o.containment == 'window') this.containment = [ - 0 - this.offset.relative.left - this.offset.parent.left, - 0 - this.offset.relative.top - this.offset.parent.top, - $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left, - ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top - ]; - - if(!(/^(document|window|parent)$/).test(o.containment)) { - var ce = $(o.containment)[0]; - var co = $(o.containment).offset(); - var over = ($(ce).css("overflow") != 'hidden'); - - this.containment = [ - co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left, - co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top, - co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left, - co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top - ]; - } - - }, - - _convertPositionTo: function(d, pos) { - - if(!pos) pos = this.position; - var mod = d == "absolute" ? 1 : -1; - var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); - - return { - top: ( - pos.top // The absolute mouse position - + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent - + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border) - - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) - ), - left: ( - pos.left // The absolute mouse position - + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent - + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border) - - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) - ) - }; - - }, - - _generatePosition: function(event) { - - var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); - - // This is another very weird special case that only happens for relative elements: - // 1. If the css position is relative - // 2. and the scroll parent is the document or similar to the offset parent - // we have to refresh the relative offset during the scroll so there are no jumps - if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) { - this.offset.relative = this._getRelativeOffset(); - } - - var pageX = event.pageX; - var pageY = event.pageY; - - /* - * - Position constraining - - * Constrain the position to a mix of grid, containment. - */ - - if(this.originalPosition) { //If we are not dragging yet, we won't check for options - - if(this.containment) { - if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left; - if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top; - if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left; - if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top; - } - - if(o.grid) { - var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; - pageY = this.containment ? (!(top - this.offset.click.top < this.containment[1] || top - this.offset.click.top > this.containment[3]) ? top : (!(top - this.offset.click.top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top; - - var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; - pageX = this.containment ? (!(left - this.offset.click.left < this.containment[0] || left - this.offset.click.left > this.containment[2]) ? left : (!(left - this.offset.click.left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left; - } - - } - - return { - top: ( - pageY // The absolute mouse position - - this.offset.click.top // Click offset (relative to the element) - - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent - - this.offset.parent.top // The offsetParent's offset without borders (offset + border) - + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) - ), - left: ( - pageX // The absolute mouse position - - this.offset.click.left // Click offset (relative to the element) - - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent - - this.offset.parent.left // The offsetParent's offset without borders (offset + border) - + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) - ) - }; - - }, - - _rearrange: function(event, i, a, hardRefresh) { - - a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction == 'down' ? i.item[0] : i.item[0].nextSibling)); - - //Various things done here to improve the performance: - // 1. we create a setTimeout, that calls refreshPositions - // 2. on the instance, we have a counter variable, that get's higher after every append - // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same - // 4. this lets only the last addition to the timeout stack through - this.counter = this.counter ? ++this.counter : 1; - var counter = this.counter; - - this._delay(function() { - if(counter == this.counter) this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove - }); - - }, - - _clear: function(event, noPropagation) { - - this.reverting = false; - // We delay all events that have to be triggered to after the point where the placeholder has been removed and - // everything else normalized again - var delayedTriggers = []; - - // We first have to update the dom position of the actual currentItem - // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088) - if(!this._noFinalSort && this.currentItem.parent().length) this.placeholder.before(this.currentItem); - this._noFinalSort = null; - - if(this.helper[0] == this.currentItem[0]) { - for(var i in this._storedCSS) { - if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = ''; - } - this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); - } else { - this.currentItem.show(); - } - - if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); }); - if((this.fromOutside || this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) && !noPropagation) delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed - - // Check if the items Container has Changed and trigger appropriate - // events. - if (this !== this.currentContainer) { - if(!noPropagation) { - delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); }); - delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); - delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); - } - } - - - //Post events to containers - for (var i = this.containers.length - 1; i >= 0; i--){ - if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i])); - if(this.containers[i].containerCache.over) { - delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i])); - this.containers[i].containerCache.over = 0; - } - } - - //Do what was originally in plugins - if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor - if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity - if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index - - this.dragging = false; - if(this.cancelHelperRemoval) { - if(!noPropagation) { - this._trigger("beforeStop", event, this._uiHash()); - for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events - this._trigger("stop", event, this._uiHash()); - } - - this.fromOutside = false; - return false; - } - - if(!noPropagation) this._trigger("beforeStop", event, this._uiHash()); - - //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! - this.placeholder[0].parentNode.removeChild(this.placeholder[0]); - - if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null; - - if(!noPropagation) { - for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events - this._trigger("stop", event, this._uiHash()); - } - - this.fromOutside = false; - return true; - - }, - - _trigger: function() { - if ($.Widget.prototype._trigger.apply(this, arguments) === false) { - this.cancel(); - } - }, - - _uiHash: function(_inst) { - var inst = _inst || this; - return { - helper: inst.helper, - placeholder: inst.placeholder || $([]), - position: inst.position, - originalPosition: inst.originalPosition, - offset: inst.positionAbs, - item: inst.currentItem, - sender: _inst ? _inst.element : null - }; - } - -}); - -})(jQuery); - -;(jQuery.effects || (function($, undefined) { - -var backCompat = $.uiBackCompat !== false, - // prefix used for storing data on .data() - dataSpace = "ui-effects-"; - -$.effects = { - effect: {} -}; - -/*! - * jQuery Color Animations v2.0.0 - * http://jquery.com/ - * - * Copyright 2012 jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * Date: Mon Aug 13 13:41:02 2012 -0500 - */ -(function( jQuery, undefined ) { - - var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor".split(" "), - - // plusequals test for += 100 -= 100 - rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, - // a set of RE's that can match strings and generate color tuples. - stringParsers = [{ - re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/, - parse: function( execResult ) { - return [ - execResult[ 1 ], - execResult[ 2 ], - execResult[ 3 ], - execResult[ 4 ] - ]; - } - }, { - re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/, - parse: function( execResult ) { - return [ - execResult[ 1 ] * 2.55, - execResult[ 2 ] * 2.55, - execResult[ 3 ] * 2.55, - execResult[ 4 ] - ]; - } - }, { - // this regex ignores A-F because it's compared against an already lowercased string - re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/, - parse: function( execResult ) { - return [ - parseInt( execResult[ 1 ], 16 ), - parseInt( execResult[ 2 ], 16 ), - parseInt( execResult[ 3 ], 16 ) - ]; - } - }, { - // this regex ignores A-F because it's compared against an already lowercased string - re: /#([a-f0-9])([a-f0-9])([a-f0-9])/, - parse: function( execResult ) { - return [ - parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), - parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), - parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ) - ]; - } - }, { - re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/, - space: "hsla", - parse: function( execResult ) { - return [ - execResult[ 1 ], - execResult[ 2 ] / 100, - execResult[ 3 ] / 100, - execResult[ 4 ] - ]; - } - }], - - // jQuery.Color( ) - color = jQuery.Color = function( color, green, blue, alpha ) { - return new jQuery.Color.fn.parse( color, green, blue, alpha ); - }, - spaces = { - rgba: { - props: { - red: { - idx: 0, - type: "byte" - }, - green: { - idx: 1, - type: "byte" - }, - blue: { - idx: 2, - type: "byte" - } - } - }, - - hsla: { - props: { - hue: { - idx: 0, - type: "degrees" - }, - saturation: { - idx: 1, - type: "percent" - }, - lightness: { - idx: 2, - type: "percent" - } - } - } - }, - propTypes = { - "byte": { - floor: true, - max: 255 - }, - "percent": { - max: 1 - }, - "degrees": { - mod: 360, - floor: true - } - }, - support = color.support = {}, - - // element for support tests - supportElem = jQuery( "<p>" )[ 0 ], - - // colors = jQuery.Color.names - colors, - - // local aliases of functions called often - each = jQuery.each; - -// determine rgba support immediately -supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; -support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; - -// define cache name and alpha properties -// for rgba and hsla spaces -each( spaces, function( spaceName, space ) { - space.cache = "_" + spaceName; - space.props.alpha = { - idx: 3, - type: "percent", - def: 1 - }; -}); - -function clamp( value, prop, allowEmpty ) { - var type = propTypes[ prop.type ] || {}; - - if ( value == null ) { - return (allowEmpty || !prop.def) ? null : prop.def; - } - - // ~~ is an short way of doing floor for positive numbers - value = type.floor ? ~~value : parseFloat( value ); - - // IE will pass in empty strings as value for alpha, - // which will hit this case - if ( isNaN( value ) ) { - return prop.def; - } - - if ( type.mod ) { - // we add mod before modding to make sure that negatives values - // get converted properly: -10 -> 350 - return (value + type.mod) % type.mod; - } - - // for now all property types without mod have min and max - return 0 > value ? 0 : type.max < value ? type.max : value; -} - -function stringParse( string ) { - var inst = color(), - rgba = inst._rgba = []; - - string = string.toLowerCase(); - - each( stringParsers, function( i, parser ) { - var parsed, - match = parser.re.exec( string ), - values = match && parser.parse( match ), - spaceName = parser.space || "rgba"; - - if ( values ) { - parsed = inst[ spaceName ]( values ); - - // if this was an rgba parse the assignment might happen twice - // oh well.... - inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; - rgba = inst._rgba = parsed._rgba; - - // exit each( stringParsers ) here because we matched - return false; - } - }); - - // Found a stringParser that handled it - if ( rgba.length ) { - - // if this came from a parsed string, force "transparent" when alpha is 0 - // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) - if ( rgba.join() === "0,0,0,0" ) { - jQuery.extend( rgba, colors.transparent ); - } - return inst; - } - - // named colors - return colors[ string ]; -} - -color.fn = jQuery.extend( color.prototype, { - parse: function( red, green, blue, alpha ) { - if ( red === undefined ) { - this._rgba = [ null, null, null, null ]; - return this; - } - if ( red.jquery || red.nodeType ) { - red = jQuery( red ).css( green ); - green = undefined; - } - - var inst = this, - type = jQuery.type( red ), - rgba = this._rgba = []; - - // more than 1 argument specified - assume ( red, green, blue, alpha ) - if ( green !== undefined ) { - red = [ red, green, blue, alpha ]; - type = "array"; - } - - if ( type === "string" ) { - return this.parse( stringParse( red ) || colors._default ); - } - - if ( type === "array" ) { - each( spaces.rgba.props, function( key, prop ) { - rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); - }); - return this; - } - - if ( type === "object" ) { - if ( red instanceof color ) { - each( spaces, function( spaceName, space ) { - if ( red[ space.cache ] ) { - inst[ space.cache ] = red[ space.cache ].slice(); - } - }); - } else { - each( spaces, function( spaceName, space ) { - var cache = space.cache; - each( space.props, function( key, prop ) { - - // if the cache doesn't exist, and we know how to convert - if ( !inst[ cache ] && space.to ) { - - // if the value was null, we don't need to copy it - // if the key was alpha, we don't need to copy it either - if ( key === "alpha" || red[ key ] == null ) { - return; - } - inst[ cache ] = space.to( inst._rgba ); - } - - // this is the only case where we allow nulls for ALL properties. - // call clamp with alwaysAllowEmpty - inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); - }); - - // everything defined but alpha? - if ( inst[ cache ] && $.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { - // use the default of 1 - inst[ cache ][ 3 ] = 1; - if ( space.from ) { - inst._rgba = space.from( inst[ cache ] ); - } - } - }); - } - return this; - } - }, - is: function( compare ) { - var is = color( compare ), - same = true, - inst = this; - - each( spaces, function( _, space ) { - var localCache, - isCache = is[ space.cache ]; - if (isCache) { - localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; - each( space.props, function( _, prop ) { - if ( isCache[ prop.idx ] != null ) { - same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); - return same; - } - }); - } - return same; - }); - return same; - }, - _space: function() { - var used = [], - inst = this; - each( spaces, function( spaceName, space ) { - if ( inst[ space.cache ] ) { - used.push( spaceName ); - } - }); - return used.pop(); - }, - transition: function( other, distance ) { - var end = color( other ), - spaceName = end._space(), - space = spaces[ spaceName ], - startColor = this.alpha() === 0 ? color( "transparent" ) : this, - start = startColor[ space.cache ] || space.to( startColor._rgba ), - result = start.slice(); - - end = end[ space.cache ]; - each( space.props, function( key, prop ) { - var index = prop.idx, - startValue = start[ index ], - endValue = end[ index ], - type = propTypes[ prop.type ] || {}; - - // if null, don't override start value - if ( endValue === null ) { - return; - } - // if null - use end - if ( startValue === null ) { - result[ index ] = endValue; - } else { - if ( type.mod ) { - if ( endValue - startValue > type.mod / 2 ) { - startValue += type.mod; - } else if ( startValue - endValue > type.mod / 2 ) { - startValue -= type.mod; - } - } - result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); - } - }); - return this[ spaceName ]( result ); - }, - blend: function( opaque ) { - // if we are already opaque - return ourself - if ( this._rgba[ 3 ] === 1 ) { - return this; - } - - var rgb = this._rgba.slice(), - a = rgb.pop(), - blend = color( opaque )._rgba; - - return color( jQuery.map( rgb, function( v, i ) { - return ( 1 - a ) * blend[ i ] + a * v; - })); - }, - toRgbaString: function() { - var prefix = "rgba(", - rgba = jQuery.map( this._rgba, function( v, i ) { - return v == null ? ( i > 2 ? 1 : 0 ) : v; - }); - - if ( rgba[ 3 ] === 1 ) { - rgba.pop(); - prefix = "rgb("; - } - - return prefix + rgba.join() + ")"; - }, - toHslaString: function() { - var prefix = "hsla(", - hsla = jQuery.map( this.hsla(), function( v, i ) { - if ( v == null ) { - v = i > 2 ? 1 : 0; - } - - // catch 1 and 2 - if ( i && i < 3 ) { - v = Math.round( v * 100 ) + "%"; - } - return v; - }); - - if ( hsla[ 3 ] === 1 ) { - hsla.pop(); - prefix = "hsl("; - } - return prefix + hsla.join() + ")"; - }, - toHexString: function( includeAlpha ) { - var rgba = this._rgba.slice(), - alpha = rgba.pop(); - - if ( includeAlpha ) { - rgba.push( ~~( alpha * 255 ) ); - } - - return "#" + jQuery.map( rgba, function( v ) { - - // default to 0 when nulls exist - v = ( v || 0 ).toString( 16 ); - return v.length === 1 ? "0" + v : v; - }).join(""); - }, - toString: function() { - return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); - } -}); -color.fn.parse.prototype = color.fn; - -// hsla conversions adapted from: -// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 - -function hue2rgb( p, q, h ) { - h = ( h + 1 ) % 1; - if ( h * 6 < 1 ) { - return p + (q - p) * h * 6; - } - if ( h * 2 < 1) { - return q; - } - if ( h * 3 < 2 ) { - return p + (q - p) * ((2/3) - h) * 6; - } - return p; -} - -spaces.hsla.to = function ( rgba ) { - if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { - return [ null, null, null, rgba[ 3 ] ]; - } - var r = rgba[ 0 ] / 255, - g = rgba[ 1 ] / 255, - b = rgba[ 2 ] / 255, - a = rgba[ 3 ], - max = Math.max( r, g, b ), - min = Math.min( r, g, b ), - diff = max - min, - add = max + min, - l = add * 0.5, - h, s; - - if ( min === max ) { - h = 0; - } else if ( r === max ) { - h = ( 60 * ( g - b ) / diff ) + 360; - } else if ( g === max ) { - h = ( 60 * ( b - r ) / diff ) + 120; - } else { - h = ( 60 * ( r - g ) / diff ) + 240; - } - - if ( l === 0 || l === 1 ) { - s = l; - } else if ( l <= 0.5 ) { - s = diff / add; - } else { - s = diff / ( 2 - add ); - } - return [ Math.round(h) % 360, s, l, a == null ? 1 : a ]; -}; - -spaces.hsla.from = function ( hsla ) { - if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { - return [ null, null, null, hsla[ 3 ] ]; - } - var h = hsla[ 0 ] / 360, - s = hsla[ 1 ], - l = hsla[ 2 ], - a = hsla[ 3 ], - q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, - p = 2 * l - q; - - return [ - Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), - Math.round( hue2rgb( p, q, h ) * 255 ), - Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), - a - ]; -}; - - -each( spaces, function( spaceName, space ) { - var props = space.props, - cache = space.cache, - to = space.to, - from = space.from; - - // makes rgba() and hsla() - color.fn[ spaceName ] = function( value ) { - - // generate a cache for this space if it doesn't exist - if ( to && !this[ cache ] ) { - this[ cache ] = to( this._rgba ); - } - if ( value === undefined ) { - return this[ cache ].slice(); - } - - var ret, - type = jQuery.type( value ), - arr = ( type === "array" || type === "object" ) ? value : arguments, - local = this[ cache ].slice(); - - each( props, function( key, prop ) { - var val = arr[ type === "object" ? key : prop.idx ]; - if ( val == null ) { - val = local[ prop.idx ]; - } - local[ prop.idx ] = clamp( val, prop ); - }); - - if ( from ) { - ret = color( from( local ) ); - ret[ cache ] = local; - return ret; - } else { - return color( local ); - } - }; - - // makes red() green() blue() alpha() hue() saturation() lightness() - each( props, function( key, prop ) { - // alpha is included in more than one space - if ( color.fn[ key ] ) { - return; - } - color.fn[ key ] = function( value ) { - var vtype = jQuery.type( value ), - fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), - local = this[ fn ](), - cur = local[ prop.idx ], - match; - - if ( vtype === "undefined" ) { - return cur; - } - - if ( vtype === "function" ) { - value = value.call( this, cur ); - vtype = jQuery.type( value ); - } - if ( value == null && prop.empty ) { - return this; - } - if ( vtype === "string" ) { - match = rplusequals.exec( value ); - if ( match ) { - value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); - } - } - local[ prop.idx ] = value; - return this[ fn ]( local ); - }; - }); -}); - -// add .fx.step functions -each( stepHooks, function( i, hook ) { - jQuery.cssHooks[ hook ] = { - set: function( elem, value ) { - var parsed, curElem, - backgroundColor = ""; - - if ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) { - value = color( parsed || value ); - if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { - curElem = hook === "backgroundColor" ? elem.parentNode : elem; - while ( - (backgroundColor === "" || backgroundColor === "transparent") && - curElem && curElem.style - ) { - try { - backgroundColor = jQuery.css( curElem, "backgroundColor" ); - curElem = curElem.parentNode; - } catch ( e ) { - } - } - - value = value.blend( backgroundColor && backgroundColor !== "transparent" ? - backgroundColor : - "_default" ); - } - - value = value.toRgbaString(); - } - try { - elem.style[ hook ] = value; - } catch( error ) { - // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' - } - } - }; - jQuery.fx.step[ hook ] = function( fx ) { - if ( !fx.colorInit ) { - fx.start = color( fx.elem, hook ); - fx.end = color( fx.end ); - fx.colorInit = true; - } - jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); - }; -}); - -jQuery.cssHooks.borderColor = { - expand: function( value ) { - var expanded = {}; - - each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) { - expanded[ "border" + part + "Color" ] = value; - }); - return expanded; - } -}; - -// Basic color names only. -// Usage of any of the other color names requires adding yourself or including -// jquery.color.svg-names.js. -colors = jQuery.Color.names = { - // 4.1. Basic color keywords - aqua: "#00ffff", - black: "#000000", - blue: "#0000ff", - fuchsia: "#ff00ff", - gray: "#808080", - green: "#008000", - lime: "#00ff00", - maroon: "#800000", - navy: "#000080", - olive: "#808000", - purple: "#800080", - red: "#ff0000", - silver: "#c0c0c0", - teal: "#008080", - white: "#ffffff", - yellow: "#ffff00", - - // 4.2.3. "transparent" color keyword - transparent: [ null, null, null, 0 ], - - _default: "#ffffff" -}; - -})( jQuery ); - - - -/******************************************************************************/ -/****************************** CLASS ANIMATIONS ******************************/ -/******************************************************************************/ -(function() { - -var classAnimationActions = [ "add", "remove", "toggle" ], - shorthandStyles = { - border: 1, - borderBottom: 1, - borderColor: 1, - borderLeft: 1, - borderRight: 1, - borderTop: 1, - borderWidth: 1, - margin: 1, - padding: 1 - }; - -$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) { - $.fx.step[ prop ] = function( fx ) { - if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { - jQuery.style( fx.elem, prop, fx.end ); - fx.setAttr = true; - } - }; -}); - -function getElementStyles() { - var style = this.ownerDocument.defaultView ? - this.ownerDocument.defaultView.getComputedStyle( this, null ) : - this.currentStyle, - newStyle = {}, - key, - len; - - // webkit enumerates style porperties - if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { - len = style.length; - while ( len-- ) { - key = style[ len ]; - if ( typeof style[ key ] === "string" ) { - newStyle[ $.camelCase( key ) ] = style[ key ]; - } - } - } else { - for ( key in style ) { - if ( typeof style[ key ] === "string" ) { - newStyle[ key ] = style[ key ]; - } - } - } - - return newStyle; -} - - -function styleDifference( oldStyle, newStyle ) { - var diff = {}, - name, value; - - for ( name in newStyle ) { - value = newStyle[ name ]; - if ( oldStyle[ name ] !== value ) { - if ( !shorthandStyles[ name ] ) { - if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { - diff[ name ] = value; - } - } - } - } - - return diff; -} - -$.effects.animateClass = function( value, duration, easing, callback ) { - var o = $.speed( duration, easing, callback ); - - return this.queue( function() { - var animated = $( this ), - baseClass = animated.attr( "class" ) || "", - applyClassChange, - allAnimations = o.children ? animated.find( "*" ).andSelf() : animated; - - // map the animated objects to store the original styles. - allAnimations = allAnimations.map(function() { - var el = $( this ); - return { - el: el, - start: getElementStyles.call( this ) - }; - }); - - // apply class change - applyClassChange = function() { - $.each( classAnimationActions, function(i, action) { - if ( value[ action ] ) { - animated[ action + "Class" ]( value[ action ] ); - } - }); - }; - applyClassChange(); - - // map all animated objects again - calculate new styles and diff - allAnimations = allAnimations.map(function() { - this.end = getElementStyles.call( this.el[ 0 ] ); - this.diff = styleDifference( this.start, this.end ); - return this; - }); - - // apply original class - animated.attr( "class", baseClass ); - - // map all animated objects again - this time collecting a promise - allAnimations = allAnimations.map(function() { - var styleInfo = this, - dfd = $.Deferred(), - opts = jQuery.extend({}, o, { - queue: false, - complete: function() { - dfd.resolve( styleInfo ); - } - }); - - this.el.animate( this.diff, opts ); - return dfd.promise(); - }); - - // once all animations have completed: - $.when.apply( $, allAnimations.get() ).done(function() { - - // set the final class - applyClassChange(); - - // for each animated element, - // clear all css properties that were animated - $.each( arguments, function() { - var el = this.el; - $.each( this.diff, function(key) { - el.css( key, '' ); - }); - }); - - // this is guarnteed to be there if you use jQuery.speed() - // it also handles dequeuing the next anim... - o.complete.call( animated[ 0 ] ); - }); - }); -}; - -$.fn.extend({ - _addClass: $.fn.addClass, - addClass: function( classNames, speed, easing, callback ) { - return speed ? - $.effects.animateClass.call( this, - { add: classNames }, speed, easing, callback ) : - this._addClass( classNames ); - }, - - _removeClass: $.fn.removeClass, - removeClass: function( classNames, speed, easing, callback ) { - return speed ? - $.effects.animateClass.call( this, - { remove: classNames }, speed, easing, callback ) : - this._removeClass( classNames ); - }, - - _toggleClass: $.fn.toggleClass, - toggleClass: function( classNames, force, speed, easing, callback ) { - if ( typeof force === "boolean" || force === undefined ) { - if ( !speed ) { - // without speed parameter - return this._toggleClass( classNames, force ); - } else { - return $.effects.animateClass.call( this, - (force ? { add: classNames } : { remove: classNames }), - speed, easing, callback ); - } - } else { - // without force parameter - return $.effects.animateClass.call( this, - { toggle: classNames }, force, speed, easing ); - } - }, - - switchClass: function( remove, add, speed, easing, callback) { - return $.effects.animateClass.call( this, { - add: add, - remove: remove - }, speed, easing, callback ); - } -}); - -})(); - -/******************************************************************************/ -/*********************************** EFFECTS **********************************/ -/******************************************************************************/ - -(function() { - -$.extend( $.effects, { - version: "1.9.2", - - // Saves a set of properties in a data storage - save: function( element, set ) { - for( var i=0; i < set.length; i++ ) { - if ( set[ i ] !== null ) { - element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); - } - } - }, - - // Restores a set of previously saved properties from a data storage - restore: function( element, set ) { - var val, i; - for( i=0; i < set.length; i++ ) { - if ( set[ i ] !== null ) { - val = element.data( dataSpace + set[ i ] ); - // support: jQuery 1.6.2 - // http://bugs.jquery.com/ticket/9917 - // jQuery 1.6.2 incorrectly returns undefined for any falsy value. - // We can't differentiate between "" and 0 here, so we just assume - // empty string since it's likely to be a more common value... - if ( val === undefined ) { - val = ""; - } - element.css( set[ i ], val ); - } - } - }, - - setMode: function( el, mode ) { - if (mode === "toggle") { - mode = el.is( ":hidden" ) ? "show" : "hide"; - } - return mode; - }, - - // Translates a [top,left] array into a baseline value - // this should be a little more flexible in the future to handle a string & hash - getBaseline: function( origin, original ) { - var y, x; - switch ( origin[ 0 ] ) { - case "top": y = 0; break; - case "middle": y = 0.5; break; - case "bottom": y = 1; break; - default: y = origin[ 0 ] / original.height; - } - switch ( origin[ 1 ] ) { - case "left": x = 0; break; - case "center": x = 0.5; break; - case "right": x = 1; break; - default: x = origin[ 1 ] / original.width; - } - return { - x: x, - y: y - }; - }, - - // Wraps the element around a wrapper that copies position properties - createWrapper: function( element ) { - - // if the element is already wrapped, return it - if ( element.parent().is( ".ui-effects-wrapper" )) { - return element.parent(); - } - - // wrap the element - var props = { - width: element.outerWidth(true), - height: element.outerHeight(true), - "float": element.css( "float" ) - }, - wrapper = $( "<div></div>" ) - .addClass( "ui-effects-wrapper" ) - .css({ - fontSize: "100%", - background: "transparent", - border: "none", - margin: 0, - padding: 0 - }), - // Store the size in case width/height are defined in % - Fixes #5245 - size = { - width: element.width(), - height: element.height() - }, - active = document.activeElement; - - // support: Firefox - // Firefox incorrectly exposes anonymous content - // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 - try { - active.id; - } catch( e ) { - active = document.body; - } - - element.wrap( wrapper ); - - // Fixes #7595 - Elements lose focus when wrapped. - if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { - $( active ).focus(); - } - - wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element - - // transfer positioning properties to the wrapper - if ( element.css( "position" ) === "static" ) { - wrapper.css({ position: "relative" }); - element.css({ position: "relative" }); - } else { - $.extend( props, { - position: element.css( "position" ), - zIndex: element.css( "z-index" ) - }); - $.each([ "top", "left", "bottom", "right" ], function(i, pos) { - props[ pos ] = element.css( pos ); - if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { - props[ pos ] = "auto"; - } - }); - element.css({ - position: "relative", - top: 0, - left: 0, - right: "auto", - bottom: "auto" - }); - } - element.css(size); - - return wrapper.css( props ).show(); - }, - - removeWrapper: function( element ) { - var active = document.activeElement; - - if ( element.parent().is( ".ui-effects-wrapper" ) ) { - element.parent().replaceWith( element ); - - // Fixes #7595 - Elements lose focus when wrapped. - if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { - $( active ).focus(); - } - } - - - return element; - }, - - setTransition: function( element, list, factor, value ) { - value = value || {}; - $.each( list, function( i, x ) { - var unit = element.cssUnit( x ); - if ( unit[ 0 ] > 0 ) { - value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; - } - }); - return value; - } -}); - -// return an effect options object for the given parameters: -function _normalizeArguments( effect, options, speed, callback ) { - - // allow passing all options as the first parameter - if ( $.isPlainObject( effect ) ) { - options = effect; - effect = effect.effect; - } - - // convert to an object - effect = { effect: effect }; - - // catch (effect, null, ...) - if ( options == null ) { - options = {}; - } - - // catch (effect, callback) - if ( $.isFunction( options ) ) { - callback = options; - speed = null; - options = {}; - } - - // catch (effect, speed, ?) - if ( typeof options === "number" || $.fx.speeds[ options ] ) { - callback = speed; - speed = options; - options = {}; - } - - // catch (effect, options, callback) - if ( $.isFunction( speed ) ) { - callback = speed; - speed = null; - } - - // add options to effect - if ( options ) { - $.extend( effect, options ); - } - - speed = speed || options.duration; - effect.duration = $.fx.off ? 0 : - typeof speed === "number" ? speed : - speed in $.fx.speeds ? $.fx.speeds[ speed ] : - $.fx.speeds._default; - - effect.complete = callback || options.complete; - - return effect; -} - -function standardSpeed( speed ) { - // valid standard speeds - if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) { - return true; - } - - // invalid strings - treat as "normal" speed - if ( typeof speed === "string" && !$.effects.effect[ speed ] ) { - // TODO: remove in 2.0 (#7115) - if ( backCompat && $.effects[ speed ] ) { - return false; - } - return true; - } - - return false; -} - -$.fn.extend({ - effect: function( /* effect, options, speed, callback */ ) { - var args = _normalizeArguments.apply( this, arguments ), - mode = args.mode, - queue = args.queue, - effectMethod = $.effects.effect[ args.effect ], - - // DEPRECATED: remove in 2.0 (#7115) - oldEffectMethod = !effectMethod && backCompat && $.effects[ args.effect ]; - - if ( $.fx.off || !( effectMethod || oldEffectMethod ) ) { - // delegate to the original method (e.g., .show()) if possible - if ( mode ) { - return this[ mode ]( args.duration, args.complete ); - } else { - return this.each( function() { - if ( args.complete ) { - args.complete.call( this ); - } - }); - } - } - - function run( next ) { - var elem = $( this ), - complete = args.complete, - mode = args.mode; - - function done() { - if ( $.isFunction( complete ) ) { - complete.call( elem[0] ); - } - if ( $.isFunction( next ) ) { - next(); - } - } - - // if the element is hiddden and mode is hide, - // or element is visible and mode is show - if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { - done(); - } else { - effectMethod.call( elem[0], args, done ); - } - } - - // TODO: remove this check in 2.0, effectMethod will always be true - if ( effectMethod ) { - return queue === false ? this.each( run ) : this.queue( queue || "fx", run ); - } else { - // DEPRECATED: remove in 2.0 (#7115) - return oldEffectMethod.call(this, { - options: args, - duration: args.duration, - callback: args.complete, - mode: args.mode - }); - } - }, - - _show: $.fn.show, - show: function( speed ) { - if ( standardSpeed( speed ) ) { - return this._show.apply( this, arguments ); - } else { - var args = _normalizeArguments.apply( this, arguments ); - args.mode = "show"; - return this.effect.call( this, args ); - } - }, - - _hide: $.fn.hide, - hide: function( speed ) { - if ( standardSpeed( speed ) ) { - return this._hide.apply( this, arguments ); - } else { - var args = _normalizeArguments.apply( this, arguments ); - args.mode = "hide"; - return this.effect.call( this, args ); - } - }, - - // jQuery core overloads toggle and creates _toggle - __toggle: $.fn.toggle, - toggle: function( speed ) { - if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) { - return this.__toggle.apply( this, arguments ); - } else { - var args = _normalizeArguments.apply( this, arguments ); - args.mode = "toggle"; - return this.effect.call( this, args ); - } - }, - - // helper functions - cssUnit: function(key) { - var style = this.css( key ), - val = []; - - $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { - if ( style.indexOf( unit ) > 0 ) { - val = [ parseFloat( style ), unit ]; - } - }); - return val; - } -}); - -})(); - -/******************************************************************************/ -/*********************************** EASING ***********************************/ -/******************************************************************************/ - -(function() { - -// based on easing equations from Robert Penner (http://www.robertpenner.com/easing) - -var baseEasings = {}; - -$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { - baseEasings[ name ] = function( p ) { - return Math.pow( p, i + 2 ); - }; -}); - -$.extend( baseEasings, { - Sine: function ( p ) { - return 1 - Math.cos( p * Math.PI / 2 ); - }, - Circ: function ( p ) { - return 1 - Math.sqrt( 1 - p * p ); - }, - Elastic: function( p ) { - return p === 0 || p === 1 ? p : - -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 ); - }, - Back: function( p ) { - return p * p * ( 3 * p - 2 ); - }, - Bounce: function ( p ) { - var pow2, - bounce = 4; - - while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} - return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); - } -}); - -$.each( baseEasings, function( name, easeIn ) { - $.easing[ "easeIn" + name ] = easeIn; - $.easing[ "easeOut" + name ] = function( p ) { - return 1 - easeIn( 1 - p ); - }; - $.easing[ "easeInOut" + name ] = function( p ) { - return p < 0.5 ? - easeIn( p * 2 ) / 2 : - 1 - easeIn( p * -2 + 2 ) / 2; - }; -}); - -})(); - -})(jQuery)); - -(function( $, undefined ) { - -var uid = 0, - hideProps = {}, - showProps = {}; - -hideProps.height = hideProps.paddingTop = hideProps.paddingBottom = - hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide"; -showProps.height = showProps.paddingTop = showProps.paddingBottom = - showProps.borderTopWidth = showProps.borderBottomWidth = "show"; - -$.widget( "ui.accordion", { - version: "1.9.2", - options: { - active: 0, - animate: {}, - collapsible: false, - event: "click", - header: "> li > :first-child,> :not(li):even", - heightStyle: "auto", - icons: { - activeHeader: "ui-icon-triangle-1-s", - header: "ui-icon-triangle-1-e" - }, - - // callbacks - activate: null, - beforeActivate: null - }, - - _create: function() { - var accordionId = this.accordionId = "ui-accordion-" + - (this.element.attr( "id" ) || ++uid), - options = this.options; - - this.prevShow = this.prevHide = $(); - this.element.addClass( "ui-accordion ui-widget ui-helper-reset" ); - - this.headers = this.element.find( options.header ) - .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" ); - this._hoverable( this.headers ); - this._focusable( this.headers ); - - this.headers.next() - .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ) - .hide(); - - // don't allow collapsible: false and active: false / null - if ( !options.collapsible && (options.active === false || options.active == null) ) { - options.active = 0; - } - // handle negative values - if ( options.active < 0 ) { - options.active += this.headers.length; - } - this.active = this._findActive( options.active ) - .addClass( "ui-accordion-header-active ui-state-active" ) - .toggleClass( "ui-corner-all ui-corner-top" ); - this.active.next() - .addClass( "ui-accordion-content-active" ) - .show(); - - this._createIcons(); - this.refresh(); - - // ARIA - this.element.attr( "role", "tablist" ); - - this.headers - .attr( "role", "tab" ) - .each(function( i ) { - var header = $( this ), - headerId = header.attr( "id" ), - panel = header.next(), - panelId = panel.attr( "id" ); - if ( !headerId ) { - headerId = accordionId + "-header-" + i; - header.attr( "id", headerId ); - } - if ( !panelId ) { - panelId = accordionId + "-panel-" + i; - panel.attr( "id", panelId ); - } - header.attr( "aria-controls", panelId ); - panel.attr( "aria-labelledby", headerId ); - }) - .next() - .attr( "role", "tabpanel" ); - - this.headers - .not( this.active ) - .attr({ - "aria-selected": "false", - tabIndex: -1 - }) - .next() - .attr({ - "aria-expanded": "false", - "aria-hidden": "true" - }) - .hide(); - - // make sure at least one header is in the tab order - if ( !this.active.length ) { - this.headers.eq( 0 ).attr( "tabIndex", 0 ); - } else { - this.active.attr({ - "aria-selected": "true", - tabIndex: 0 - }) - .next() - .attr({ - "aria-expanded": "true", - "aria-hidden": "false" - }); - } - - this._on( this.headers, { keydown: "_keydown" }); - this._on( this.headers.next(), { keydown: "_panelKeyDown" }); - this._setupEvents( options.event ); - }, - - _getCreateEventData: function() { - return { - header: this.active, - content: !this.active.length ? $() : this.active.next() - }; - }, - - _createIcons: function() { - var icons = this.options.icons; - if ( icons ) { - $( "<span>" ) - .addClass( "ui-accordion-header-icon ui-icon " + icons.header ) - .prependTo( this.headers ); - this.active.children( ".ui-accordion-header-icon" ) - .removeClass( icons.header ) - .addClass( icons.activeHeader ); - this.headers.addClass( "ui-accordion-icons" ); - } - }, - - _destroyIcons: function() { - this.headers - .removeClass( "ui-accordion-icons" ) - .children( ".ui-accordion-header-icon" ) - .remove(); - }, - - _destroy: function() { - var contents; - - // clean up main element - this.element - .removeClass( "ui-accordion ui-widget ui-helper-reset" ) - .removeAttr( "role" ); - - // clean up headers - this.headers - .removeClass( "ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" ) - .removeAttr( "role" ) - .removeAttr( "aria-selected" ) - .removeAttr( "aria-controls" ) - .removeAttr( "tabIndex" ) - .each(function() { - if ( /^ui-accordion/.test( this.id ) ) { - this.removeAttribute( "id" ); - } - }); - this._destroyIcons(); - - // clean up content panels - contents = this.headers.next() - .css( "display", "" ) - .removeAttr( "role" ) - .removeAttr( "aria-expanded" ) - .removeAttr( "aria-hidden" ) - .removeAttr( "aria-labelledby" ) - .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" ) - .each(function() { - if ( /^ui-accordion/.test( this.id ) ) { - this.removeAttribute( "id" ); - } - }); - if ( this.options.heightStyle !== "content" ) { - contents.css( "height", "" ); - } - }, - - _setOption: function( key, value ) { - if ( key === "active" ) { - // _activate() will handle invalid values and update this.options - this._activate( value ); - return; - } - - if ( key === "event" ) { - if ( this.options.event ) { - this._off( this.headers, this.options.event ); - } - this._setupEvents( value ); - } - - this._super( key, value ); - - // setting collapsible: false while collapsed; open first panel - if ( key === "collapsible" && !value && this.options.active === false ) { - this._activate( 0 ); - } - - if ( key === "icons" ) { - this._destroyIcons(); - if ( value ) { - this._createIcons(); - } - } - - // #5332 - opacity doesn't cascade to positioned elements in IE - // so we need to add the disabled class to the headers and panels - if ( key === "disabled" ) { - this.headers.add( this.headers.next() ) - .toggleClass( "ui-state-disabled", !!value ); - } - }, - - _keydown: function( event ) { - if ( event.altKey || event.ctrlKey ) { - return; - } - - var keyCode = $.ui.keyCode, - length = this.headers.length, - currentIndex = this.headers.index( event.target ), - toFocus = false; - - switch ( event.keyCode ) { - case keyCode.RIGHT: - case keyCode.DOWN: - toFocus = this.headers[ ( currentIndex + 1 ) % length ]; - break; - case keyCode.LEFT: - case keyCode.UP: - toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; - break; - case keyCode.SPACE: - case keyCode.ENTER: - this._eventHandler( event ); - break; - case keyCode.HOME: - toFocus = this.headers[ 0 ]; - break; - case keyCode.END: - toFocus = this.headers[ length - 1 ]; - break; - } - - if ( toFocus ) { - $( event.target ).attr( "tabIndex", -1 ); - $( toFocus ).attr( "tabIndex", 0 ); - toFocus.focus(); - event.preventDefault(); - } - }, - - _panelKeyDown : function( event ) { - if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { - $( event.currentTarget ).prev().focus(); - } - }, - - refresh: function() { - var maxHeight, overflow, - heightStyle = this.options.heightStyle, - parent = this.element.parent(); - - - if ( heightStyle === "fill" ) { - // IE 6 treats height like minHeight, so we need to turn off overflow - // in order to get a reliable height - // we use the minHeight support test because we assume that only - // browsers that don't support minHeight will treat height as minHeight - if ( !$.support.minHeight ) { - overflow = parent.css( "overflow" ); - parent.css( "overflow", "hidden"); - } - maxHeight = parent.height(); - this.element.siblings( ":visible" ).each(function() { - var elem = $( this ), - position = elem.css( "position" ); - - if ( position === "absolute" || position === "fixed" ) { - return; - } - maxHeight -= elem.outerHeight( true ); - }); - if ( overflow ) { - parent.css( "overflow", overflow ); - } - - this.headers.each(function() { - maxHeight -= $( this ).outerHeight( true ); - }); - - this.headers.next() - .each(function() { - $( this ).height( Math.max( 0, maxHeight - - $( this ).innerHeight() + $( this ).height() ) ); - }) - .css( "overflow", "auto" ); - } else if ( heightStyle === "auto" ) { - maxHeight = 0; - this.headers.next() - .each(function() { - maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); - }) - .height( maxHeight ); - } - }, - - _activate: function( index ) { - var active = this._findActive( index )[ 0 ]; - - // trying to activate the already active panel - if ( active === this.active[ 0 ] ) { - return; - } - - // trying to collapse, simulate a click on the currently active header - active = active || this.active[ 0 ]; - - this._eventHandler({ - target: active, - currentTarget: active, - preventDefault: $.noop - }); - }, - - _findActive: function( selector ) { - return typeof selector === "number" ? this.headers.eq( selector ) : $(); - }, - - _setupEvents: function( event ) { - var events = {}; - if ( !event ) { - return; - } - $.each( event.split(" "), function( index, eventName ) { - events[ eventName ] = "_eventHandler"; - }); - this._on( this.headers, events ); - }, - - _eventHandler: function( event ) { - var options = this.options, - active = this.active, - clicked = $( event.currentTarget ), - clickedIsActive = clicked[ 0 ] === active[ 0 ], - collapsing = clickedIsActive && options.collapsible, - toShow = collapsing ? $() : clicked.next(), - toHide = active.next(), - eventData = { - oldHeader: active, - oldPanel: toHide, - newHeader: collapsing ? $() : clicked, - newPanel: toShow - }; - - event.preventDefault(); - - if ( - // click on active header, but not collapsible - ( clickedIsActive && !options.collapsible ) || - // allow canceling activation - ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { - return; - } - - options.active = collapsing ? false : this.headers.index( clicked ); - - // when the call to ._toggle() comes after the class changes - // it causes a very odd bug in IE 8 (see #6720) - this.active = clickedIsActive ? $() : clicked; - this._toggle( eventData ); - - // switch classes - // corner classes on the previously active header stay after the animation - active.removeClass( "ui-accordion-header-active ui-state-active" ); - if ( options.icons ) { - active.children( ".ui-accordion-header-icon" ) - .removeClass( options.icons.activeHeader ) - .addClass( options.icons.header ); - } - - if ( !clickedIsActive ) { - clicked - .removeClass( "ui-corner-all" ) - .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ); - if ( options.icons ) { - clicked.children( ".ui-accordion-header-icon" ) - .removeClass( options.icons.header ) - .addClass( options.icons.activeHeader ); - } - - clicked - .next() - .addClass( "ui-accordion-content-active" ); - } - }, - - _toggle: function( data ) { - var toShow = data.newPanel, - toHide = this.prevShow.length ? this.prevShow : data.oldPanel; - - // handle activating a panel during the animation for another activation - this.prevShow.add( this.prevHide ).stop( true, true ); - this.prevShow = toShow; - this.prevHide = toHide; - - if ( this.options.animate ) { - this._animate( toShow, toHide, data ); - } else { - toHide.hide(); - toShow.show(); - this._toggleComplete( data ); - } - - toHide.attr({ - "aria-expanded": "false", - "aria-hidden": "true" - }); - toHide.prev().attr( "aria-selected", "false" ); - // if we're switching panels, remove the old header from the tab order - // if we're opening from collapsed state, remove the previous header from the tab order - // if we're collapsing, then keep the collapsing header in the tab order - if ( toShow.length && toHide.length ) { - toHide.prev().attr( "tabIndex", -1 ); - } else if ( toShow.length ) { - this.headers.filter(function() { - return $( this ).attr( "tabIndex" ) === 0; - }) - .attr( "tabIndex", -1 ); - } - - toShow - .attr({ - "aria-expanded": "true", - "aria-hidden": "false" - }) - .prev() - .attr({ - "aria-selected": "true", - tabIndex: 0 - }); - }, - - _animate: function( toShow, toHide, data ) { - var total, easing, duration, - that = this, - adjust = 0, - down = toShow.length && - ( !toHide.length || ( toShow.index() < toHide.index() ) ), - animate = this.options.animate || {}, - options = down && animate.down || animate, - complete = function() { - that._toggleComplete( data ); - }; - - if ( typeof options === "number" ) { - duration = options; - } - if ( typeof options === "string" ) { - easing = options; - } - // fall back from options to animation in case of partial down settings - easing = easing || options.easing || animate.easing; - duration = duration || options.duration || animate.duration; - - if ( !toHide.length ) { - return toShow.animate( showProps, duration, easing, complete ); - } - if ( !toShow.length ) { - return toHide.animate( hideProps, duration, easing, complete ); - } - - total = toShow.show().outerHeight(); - toHide.animate( hideProps, { - duration: duration, - easing: easing, - step: function( now, fx ) { - fx.now = Math.round( now ); - } - }); - toShow - .hide() - .animate( showProps, { - duration: duration, - easing: easing, - complete: complete, - step: function( now, fx ) { - fx.now = Math.round( now ); - if ( fx.prop !== "height" ) { - adjust += fx.now; - } else if ( that.options.heightStyle !== "content" ) { - fx.now = Math.round( total - toHide.outerHeight() - adjust ); - adjust = 0; - } - } - }); - }, - - _toggleComplete: function( data ) { - var toHide = data.oldPanel; - - toHide - .removeClass( "ui-accordion-content-active" ) - .prev() - .removeClass( "ui-corner-top" ) - .addClass( "ui-corner-all" ); - - // Work around for rendering bug in IE (#5421) - if ( toHide.length ) { - toHide.parent()[0].className = toHide.parent()[0].className; - } - - this._trigger( "activate", null, data ); - } -}); - - - -// DEPRECATED -if ( $.uiBackCompat !== false ) { - // navigation options - (function( $, prototype ) { - $.extend( prototype.options, { - navigation: false, - navigationFilter: function() { - return this.href.toLowerCase() === location.href.toLowerCase(); - } - }); - - var _create = prototype._create; - prototype._create = function() { - if ( this.options.navigation ) { - var that = this, - headers = this.element.find( this.options.header ), - content = headers.next(), - current = headers.add( content ) - .find( "a" ) - .filter( this.options.navigationFilter ) - [ 0 ]; - if ( current ) { - headers.add( content ).each( function( index ) { - if ( $.contains( this, current ) ) { - that.options.active = Math.floor( index / 2 ); - return false; - } - }); - } - } - _create.call( this ); - }; - }( jQuery, jQuery.ui.accordion.prototype ) ); - - // height options - (function( $, prototype ) { - $.extend( prototype.options, { - heightStyle: null, // remove default so we fall back to old values - autoHeight: true, // use heightStyle: "auto" - clearStyle: false, // use heightStyle: "content" - fillSpace: false // use heightStyle: "fill" - }); - - var _create = prototype._create, - _setOption = prototype._setOption; - - $.extend( prototype, { - _create: function() { - this.options.heightStyle = this.options.heightStyle || - this._mergeHeightStyle(); - - _create.call( this ); - }, - - _setOption: function( key ) { - if ( key === "autoHeight" || key === "clearStyle" || key === "fillSpace" ) { - this.options.heightStyle = this._mergeHeightStyle(); - } - _setOption.apply( this, arguments ); - }, - - _mergeHeightStyle: function() { - var options = this.options; - - if ( options.fillSpace ) { - return "fill"; - } - - if ( options.clearStyle ) { - return "content"; - } - - if ( options.autoHeight ) { - return "auto"; - } - } - }); - }( jQuery, jQuery.ui.accordion.prototype ) ); - - // icon options - (function( $, prototype ) { - $.extend( prototype.options.icons, { - activeHeader: null, // remove default so we fall back to old values - headerSelected: "ui-icon-triangle-1-s" - }); - - var _createIcons = prototype._createIcons; - prototype._createIcons = function() { - if ( this.options.icons ) { - this.options.icons.activeHeader = this.options.icons.activeHeader || - this.options.icons.headerSelected; - } - _createIcons.call( this ); - }; - }( jQuery, jQuery.ui.accordion.prototype ) ); - - // expanded active option, activate method - (function( $, prototype ) { - prototype.activate = prototype._activate; - - var _findActive = prototype._findActive; - prototype._findActive = function( index ) { - if ( index === -1 ) { - index = false; - } - if ( index && typeof index !== "number" ) { - index = this.headers.index( this.headers.filter( index ) ); - if ( index === -1 ) { - index = false; - } - } - return _findActive.call( this, index ); - }; - }( jQuery, jQuery.ui.accordion.prototype ) ); - - // resize method - jQuery.ui.accordion.prototype.resize = jQuery.ui.accordion.prototype.refresh; - - // change events - (function( $, prototype ) { - $.extend( prototype.options, { - change: null, - changestart: null - }); - - var _trigger = prototype._trigger; - prototype._trigger = function( type, event, data ) { - var ret = _trigger.apply( this, arguments ); - if ( !ret ) { - return false; - } - - if ( type === "beforeActivate" ) { - ret = _trigger.call( this, "changestart", event, { - oldHeader: data.oldHeader, - oldContent: data.oldPanel, - newHeader: data.newHeader, - newContent: data.newPanel - }); - } else if ( type === "activate" ) { - ret = _trigger.call( this, "change", event, { - oldHeader: data.oldHeader, - oldContent: data.oldPanel, - newHeader: data.newHeader, - newContent: data.newPanel - }); - } - return ret; - }; - }( jQuery, jQuery.ui.accordion.prototype ) ); - - // animated option - // NOTE: this only provides support for "slide", "bounceslide", and easings - // not the full $.ui.accordion.animations API - (function( $, prototype ) { - $.extend( prototype.options, { - animate: null, - animated: "slide" - }); - - var _create = prototype._create; - prototype._create = function() { - var options = this.options; - if ( options.animate === null ) { - if ( !options.animated ) { - options.animate = false; - } else if ( options.animated === "slide" ) { - options.animate = 300; - } else if ( options.animated === "bounceslide" ) { - options.animate = { - duration: 200, - down: { - easing: "easeOutBounce", - duration: 1000 - } - }; - } else { - options.animate = options.animated; - } - } - - _create.call( this ); - }; - }( jQuery, jQuery.ui.accordion.prototype ) ); -} - -})( jQuery ); - -(function( $, undefined ) { - -// used to prevent race conditions with remote data sources -var requestIndex = 0; - -$.widget( "ui.autocomplete", { - version: "1.9.2", - defaultElement: "<input>", - options: { - appendTo: "body", - autoFocus: false, - delay: 300, - minLength: 1, - position: { - my: "left top", - at: "left bottom", - collision: "none" - }, - source: null, - - // callbacks - change: null, - close: null, - focus: null, - open: null, - response: null, - search: null, - select: null - }, - - pending: 0, - - _create: function() { - // Some browsers only repeat keydown events, not keypress events, - // so we use the suppressKeyPress flag to determine if we've already - // handled the keydown event. #7269 - // Unfortunately the code for & in keypress is the same as the up arrow, - // so we use the suppressKeyPressRepeat flag to avoid handling keypress - // events when we know the keydown event was used to modify the - // search term. #7799 - var suppressKeyPress, suppressKeyPressRepeat, suppressInput; - - this.isMultiLine = this._isMultiLine(); - this.valueMethod = this.element[ this.element.is( "input,textarea" ) ? "val" : "text" ]; - this.isNewMenu = true; - - this.element - .addClass( "ui-autocomplete-input" ) - .attr( "autocomplete", "off" ); - - this._on( this.element, { - keydown: function( event ) { - if ( this.element.prop( "readOnly" ) ) { - suppressKeyPress = true; - suppressInput = true; - suppressKeyPressRepeat = true; - return; - } - - suppressKeyPress = false; - suppressInput = false; - suppressKeyPressRepeat = false; - var keyCode = $.ui.keyCode; - switch( event.keyCode ) { - case keyCode.PAGE_UP: - suppressKeyPress = true; - this._move( "previousPage", event ); - break; - case keyCode.PAGE_DOWN: - suppressKeyPress = true; - this._move( "nextPage", event ); - break; - case keyCode.UP: - suppressKeyPress = true; - this._keyEvent( "previous", event ); - break; - case keyCode.DOWN: - suppressKeyPress = true; - this._keyEvent( "next", event ); - break; - case keyCode.ENTER: - case keyCode.NUMPAD_ENTER: - // when menu is open and has focus - if ( this.menu.active ) { - // #6055 - Opera still allows the keypress to occur - // which causes forms to submit - suppressKeyPress = true; - event.preventDefault(); - this.menu.select( event ); - } - break; - case keyCode.TAB: - if ( this.menu.active ) { - this.menu.select( event ); - } - break; - case keyCode.ESCAPE: - if ( this.menu.element.is( ":visible" ) ) { - this._value( this.term ); - this.close( event ); - // Different browsers have different default behavior for escape - // Single press can mean undo or clear - // Double press in IE means clear the whole form - event.preventDefault(); - } - break; - default: - suppressKeyPressRepeat = true; - // search timeout should be triggered before the input value is changed - this._searchTimeout( event ); - break; - } - }, - keypress: function( event ) { - if ( suppressKeyPress ) { - suppressKeyPress = false; - event.preventDefault(); - return; - } - if ( suppressKeyPressRepeat ) { - return; - } - - // replicate some key handlers to allow them to repeat in Firefox and Opera - var keyCode = $.ui.keyCode; - switch( event.keyCode ) { - case keyCode.PAGE_UP: - this._move( "previousPage", event ); - break; - case keyCode.PAGE_DOWN: - this._move( "nextPage", event ); - break; - case keyCode.UP: - this._keyEvent( "previous", event ); - break; - case keyCode.DOWN: - this._keyEvent( "next", event ); - break; - } - }, - input: function( event ) { - if ( suppressInput ) { - suppressInput = false; - event.preventDefault(); - return; - } - this._searchTimeout( event ); - }, - focus: function() { - this.selectedItem = null; - this.previous = this._value(); - }, - blur: function( event ) { - if ( this.cancelBlur ) { - delete this.cancelBlur; - return; - } - - clearTimeout( this.searching ); - this.close( event ); - this._change( event ); - } - }); - - this._initSource(); - this.menu = $( "<ul>" ) - .addClass( "ui-autocomplete" ) - .appendTo( this.document.find( this.options.appendTo || "body" )[ 0 ] ) - .menu({ - // custom key handling for now - input: $(), - // disable ARIA support, the live region takes care of that - role: null - }) - .zIndex( this.element.zIndex() + 1 ) - .hide() - .data( "menu" ); - - this._on( this.menu.element, { - mousedown: function( event ) { - // prevent moving focus out of the text field - event.preventDefault(); - - // IE doesn't prevent moving focus even with event.preventDefault() - // so we set a flag to know when we should ignore the blur event - this.cancelBlur = true; - this._delay(function() { - delete this.cancelBlur; - }); - - // clicking on the scrollbar causes focus to shift to the body - // but we can't detect a mouseup or a click immediately afterward - // so we have to track the next mousedown and close the menu if - // the user clicks somewhere outside of the autocomplete - var menuElement = this.menu.element[ 0 ]; - if ( !$( event.target ).closest( ".ui-menu-item" ).length ) { - this._delay(function() { - var that = this; - this.document.one( "mousedown", function( event ) { - if ( event.target !== that.element[ 0 ] && - event.target !== menuElement && - !$.contains( menuElement, event.target ) ) { - that.close(); - } - }); - }); - } - }, - menufocus: function( event, ui ) { - // #7024 - Prevent accidental activation of menu items in Firefox - if ( this.isNewMenu ) { - this.isNewMenu = false; - if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { - this.menu.blur(); - - this.document.one( "mousemove", function() { - $( event.target ).trigger( event.originalEvent ); - }); - - return; - } - } - - // back compat for _renderItem using item.autocomplete, via #7810 - // TODO remove the fallback, see #8156 - var item = ui.item.data( "ui-autocomplete-item" ) || ui.item.data( "item.autocomplete" ); - if ( false !== this._trigger( "focus", event, { item: item } ) ) { - // use value to match what will end up in the input, if it was a key event - if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { - this._value( item.value ); - } - } else { - // Normally the input is populated with the item's value as the - // menu is navigated, causing screen readers to notice a change and - // announce the item. Since the focus event was canceled, this doesn't - // happen, so we update the live region so that screen readers can - // still notice the change and announce it. - this.liveRegion.text( item.value ); - } - }, - menuselect: function( event, ui ) { - // back compat for _renderItem using item.autocomplete, via #7810 - // TODO remove the fallback, see #8156 - var item = ui.item.data( "ui-autocomplete-item" ) || ui.item.data( "item.autocomplete" ), - previous = this.previous; - - // only trigger when focus was lost (click on menu) - if ( this.element[0] !== this.document[0].activeElement ) { - this.element.focus(); - this.previous = previous; - // #6109 - IE triggers two focus events and the second - // is asynchronous, so we need to reset the previous - // term synchronously and asynchronously :-( - this._delay(function() { - this.previous = previous; - this.selectedItem = item; - }); - } - - if ( false !== this._trigger( "select", event, { item: item } ) ) { - this._value( item.value ); - } - // reset the term after the select event - // this allows custom select handling to work properly - this.term = this._value(); - - this.close( event ); - this.selectedItem = item; - } - }); - - this.liveRegion = $( "<span>", { - role: "status", - "aria-live": "polite" - }) - .addClass( "ui-helper-hidden-accessible" ) - .insertAfter( this.element ); - - if ( $.fn.bgiframe ) { - this.menu.element.bgiframe(); - } - - // turning off autocomplete prevents the browser from remembering the - // value when navigating through history, so we re-enable autocomplete - // if the page is unloaded before the widget is destroyed. #7790 - this._on( this.window, { - beforeunload: function() { - this.element.removeAttr( "autocomplete" ); - } - }); - }, - - _destroy: function() { - clearTimeout( this.searching ); - this.element - .removeClass( "ui-autocomplete-input" ) - .removeAttr( "autocomplete" ); - this.menu.element.remove(); - this.liveRegion.remove(); - }, - - _setOption: function( key, value ) { - this._super( key, value ); - if ( key === "source" ) { - this._initSource(); - } - if ( key === "appendTo" ) { - this.menu.element.appendTo( this.document.find( value || "body" )[0] ); - } - if ( key === "disabled" && value && this.xhr ) { - this.xhr.abort(); - } - }, - - _isMultiLine: function() { - // Textareas are always multi-line - if ( this.element.is( "textarea" ) ) { - return true; - } - // Inputs are always single-line, even if inside a contentEditable element - // IE also treats inputs as contentEditable - if ( this.element.is( "input" ) ) { - return false; - } - // All other element types are determined by whether or not they're contentEditable - return this.element.prop( "isContentEditable" ); - }, - - _initSource: function() { - var array, url, - that = this; - if ( $.isArray(this.options.source) ) { - array = this.options.source; - this.source = function( request, response ) { - response( $.ui.autocomplete.filter( array, request.term ) ); - }; - } else if ( typeof this.options.source === "string" ) { - url = this.options.source; - this.source = function( request, response ) { - if ( that.xhr ) { - that.xhr.abort(); - } - that.xhr = $.ajax({ - url: url, - data: request, - dataType: "json", - success: function( data ) { - response( data ); - }, - error: function() { - response( [] ); - } - }); - }; - } else { - this.source = this.options.source; - } - }, - - _searchTimeout: function( event ) { - clearTimeout( this.searching ); - this.searching = this._delay(function() { - // only search if the value has changed - if ( this.term !== this._value() ) { - this.selectedItem = null; - this.search( null, event ); - } - }, this.options.delay ); - }, - - search: function( value, event ) { - value = value != null ? value : this._value(); - - // always save the actual value, not the one passed as an argument - this.term = this._value(); - - if ( value.length < this.options.minLength ) { - return this.close( event ); - } - - if ( this._trigger( "search", event ) === false ) { - return; - } - - return this._search( value ); - }, - - _search: function( value ) { - this.pending++; - this.element.addClass( "ui-autocomplete-loading" ); - this.cancelSearch = false; - - this.source( { term: value }, this._response() ); - }, - - _response: function() { - var that = this, - index = ++requestIndex; - - return function( content ) { - if ( index === requestIndex ) { - that.__response( content ); - } - - that.pending--; - if ( !that.pending ) { - that.element.removeClass( "ui-autocomplete-loading" ); - } - }; - }, - - __response: function( content ) { - if ( content ) { - content = this._normalize( content ); - } - this._trigger( "response", null, { content: content } ); - if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { - this._suggest( content ); - this._trigger( "open" ); - } else { - // use ._close() instead of .close() so we don't cancel future searches - this._close(); - } - }, - - close: function( event ) { - this.cancelSearch = true; - this._close( event ); - }, - - _close: function( event ) { - if ( this.menu.element.is( ":visible" ) ) { - this.menu.element.hide(); - this.menu.blur(); - this.isNewMenu = true; - this._trigger( "close", event ); - } - }, - - _change: function( event ) { - if ( this.previous !== this._value() ) { - this._trigger( "change", event, { item: this.selectedItem } ); - } - }, - - _normalize: function( items ) { - // assume all items have the right format when the first item is complete - if ( items.length && items[0].label && items[0].value ) { - return items; - } - return $.map( items, function( item ) { - if ( typeof item === "string" ) { - return { - label: item, - value: item - }; - } - return $.extend({ - label: item.label || item.value, - value: item.value || item.label - }, item ); - }); - }, - - _suggest: function( items ) { - var ul = this.menu.element - .empty() - .zIndex( this.element.zIndex() + 1 ); - this._renderMenu( ul, items ); - this.menu.refresh(); - - // size and position menu - ul.show(); - this._resizeMenu(); - ul.position( $.extend({ - of: this.element - }, this.options.position )); - - if ( this.options.autoFocus ) { - this.menu.next(); - } - }, - - _resizeMenu: function() { - var ul = this.menu.element; - ul.outerWidth( Math.max( - // Firefox wraps long text (possibly a rounding bug) - // so we add 1px to avoid the wrapping (#7513) - ul.width( "" ).outerWidth() + 1, - this.element.outerWidth() - ) ); - }, - - _renderMenu: function( ul, items ) { - var that = this; - $.each( items, function( index, item ) { - that._renderItemData( ul, item ); - }); - }, - - _renderItemData: function( ul, item ) { - return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); - }, - - _renderItem: function( ul, item ) { - return $( "<li>" ) - .append( $( "<a>" ).text( item.label ) ) - .appendTo( ul ); - }, - - _move: function( direction, event ) { - if ( !this.menu.element.is( ":visible" ) ) { - this.search( null, event ); - return; - } - if ( this.menu.isFirstItem() && /^previous/.test( direction ) || - this.menu.isLastItem() && /^next/.test( direction ) ) { - this._value( this.term ); - this.menu.blur(); - return; - } - this.menu[ direction ]( event ); - }, - - widget: function() { - return this.menu.element; - }, - - _value: function() { - return this.valueMethod.apply( this.element, arguments ); - }, - - _keyEvent: function( keyEvent, event ) { - if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { - this._move( keyEvent, event ); - - // prevents moving cursor to beginning/end of the text field in some browsers - event.preventDefault(); - } - } -}); - -$.extend( $.ui.autocomplete, { - escapeRegex: function( value ) { - return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&"); - }, - filter: function(array, term) { - var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" ); - return $.grep( array, function(value) { - return matcher.test( value.label || value.value || value ); - }); - } -}); - - -// live region extension, adding a `messages` option -// NOTE: This is an experimental API. We are still investigating -// a full solution for string manipulation and internationalization. -$.widget( "ui.autocomplete", $.ui.autocomplete, { - options: { - messages: { - noResults: "No search results.", - results: function( amount ) { - return amount + ( amount > 1 ? " results are" : " result is" ) + - " available, use up and down arrow keys to navigate."; - } - } - }, - - __response: function( content ) { - var message; - this._superApply( arguments ); - if ( this.options.disabled || this.cancelSearch ) { - return; - } - if ( content && content.length ) { - message = this.options.messages.results( content.length ); - } else { - message = this.options.messages.noResults; - } - this.liveRegion.text( message ); - } -}); - - -}( jQuery )); - -(function( $, undefined ) { - -var lastActive, startXPos, startYPos, clickDragged, - baseClasses = "ui-button ui-widget ui-state-default ui-corner-all", - stateClasses = "ui-state-hover ui-state-active ", - typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only", - formResetHandler = function() { - var buttons = $( this ).find( ":ui-button" ); - setTimeout(function() { - buttons.button( "refresh" ); - }, 1 ); - }, - radioGroup = function( radio ) { - var name = radio.name, - form = radio.form, - radios = $( [] ); - if ( name ) { - if ( form ) { - radios = $( form ).find( "[name='" + name + "']" ); - } else { - radios = $( "[name='" + name + "']", radio.ownerDocument ) - .filter(function() { - return !this.form; - }); - } - } - return radios; - }; - -$.widget( "ui.button", { - version: "1.9.2", - defaultElement: "<button>", - options: { - disabled: null, - text: true, - label: null, - icons: { - primary: null, - secondary: null - } - }, - _create: function() { - this.element.closest( "form" ) - .unbind( "reset" + this.eventNamespace ) - .bind( "reset" + this.eventNamespace, formResetHandler ); - - if ( typeof this.options.disabled !== "boolean" ) { - this.options.disabled = !!this.element.prop( "disabled" ); - } else { - this.element.prop( "disabled", this.options.disabled ); - } - - this._determineButtonType(); - this.hasTitle = !!this.buttonElement.attr( "title" ); - - var that = this, - options = this.options, - toggleButton = this.type === "checkbox" || this.type === "radio", - activeClass = !toggleButton ? "ui-state-active" : "", - focusClass = "ui-state-focus"; - - if ( options.label === null ) { - options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html()); - } - - this._hoverable( this.buttonElement ); - - this.buttonElement - .addClass( baseClasses ) - .attr( "role", "button" ) - .bind( "mouseenter" + this.eventNamespace, function() { - if ( options.disabled ) { - return; - } - if ( this === lastActive ) { - $( this ).addClass( "ui-state-active" ); - } - }) - .bind( "mouseleave" + this.eventNamespace, function() { - if ( options.disabled ) { - return; - } - $( this ).removeClass( activeClass ); - }) - .bind( "click" + this.eventNamespace, function( event ) { - if ( options.disabled ) { - event.preventDefault(); - event.stopImmediatePropagation(); - } - }); - - this.element - .bind( "focus" + this.eventNamespace, function() { - // no need to check disabled, focus won't be triggered anyway - that.buttonElement.addClass( focusClass ); - }) - .bind( "blur" + this.eventNamespace, function() { - that.buttonElement.removeClass( focusClass ); - }); - - if ( toggleButton ) { - this.element.bind( "change" + this.eventNamespace, function() { - if ( clickDragged ) { - return; - } - that.refresh(); - }); - // if mouse moves between mousedown and mouseup (drag) set clickDragged flag - // prevents issue where button state changes but checkbox/radio checked state - // does not in Firefox (see ticket #6970) - this.buttonElement - .bind( "mousedown" + this.eventNamespace, function( event ) { - if ( options.disabled ) { - return; - } - clickDragged = false; - startXPos = event.pageX; - startYPos = event.pageY; - }) - .bind( "mouseup" + this.eventNamespace, function( event ) { - if ( options.disabled ) { - return; - } - if ( startXPos !== event.pageX || startYPos !== event.pageY ) { - clickDragged = true; - } - }); - } - - if ( this.type === "checkbox" ) { - this.buttonElement.bind( "click" + this.eventNamespace, function() { - if ( options.disabled || clickDragged ) { - return false; - } - $( this ).toggleClass( "ui-state-active" ); - that.buttonElement.attr( "aria-pressed", that.element[0].checked ); - }); - } else if ( this.type === "radio" ) { - this.buttonElement.bind( "click" + this.eventNamespace, function() { - if ( options.disabled || clickDragged ) { - return false; - } - $( this ).addClass( "ui-state-active" ); - that.buttonElement.attr( "aria-pressed", "true" ); - - var radio = that.element[ 0 ]; - radioGroup( radio ) - .not( radio ) - .map(function() { - return $( this ).button( "widget" )[ 0 ]; - }) - .removeClass( "ui-state-active" ) - .attr( "aria-pressed", "false" ); - }); - } else { - this.buttonElement - .bind( "mousedown" + this.eventNamespace, function() { - if ( options.disabled ) { - return false; - } - $( this ).addClass( "ui-state-active" ); - lastActive = this; - that.document.one( "mouseup", function() { - lastActive = null; - }); - }) - .bind( "mouseup" + this.eventNamespace, function() { - if ( options.disabled ) { - return false; - } - $( this ).removeClass( "ui-state-active" ); - }) - .bind( "keydown" + this.eventNamespace, function(event) { - if ( options.disabled ) { - return false; - } - if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) { - $( this ).addClass( "ui-state-active" ); - } - }) - .bind( "keyup" + this.eventNamespace, function() { - $( this ).removeClass( "ui-state-active" ); - }); - - if ( this.buttonElement.is("a") ) { - this.buttonElement.keyup(function(event) { - if ( event.keyCode === $.ui.keyCode.SPACE ) { - // TODO pass through original event correctly (just as 2nd argument doesn't work) - $( this ).click(); - } - }); - } - } - - // TODO: pull out $.Widget's handling for the disabled option into - // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can - // be overridden by individual plugins - this._setOption( "disabled", options.disabled ); - this._resetButton(); - }, - - _determineButtonType: function() { - var ancestor, labelSelector, checked; - - if ( this.element.is("[type=checkbox]") ) { - this.type = "checkbox"; - } else if ( this.element.is("[type=radio]") ) { - this.type = "radio"; - } else if ( this.element.is("input") ) { - this.type = "input"; - } else { - this.type = "button"; - } - - if ( this.type === "checkbox" || this.type === "radio" ) { - // we don't search against the document in case the element - // is disconnected from the DOM - ancestor = this.element.parents().last(); - labelSelector = "label[for='" + this.element.attr("id") + "']"; - this.buttonElement = ancestor.find( labelSelector ); - if ( !this.buttonElement.length ) { - ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings(); - this.buttonElement = ancestor.filter( labelSelector ); - if ( !this.buttonElement.length ) { - this.buttonElement = ancestor.find( labelSelector ); - } - } - this.element.addClass( "ui-helper-hidden-accessible" ); - - checked = this.element.is( ":checked" ); - if ( checked ) { - this.buttonElement.addClass( "ui-state-active" ); - } - this.buttonElement.prop( "aria-pressed", checked ); - } else { - this.buttonElement = this.element; - } - }, - - widget: function() { - return this.buttonElement; - }, - - _destroy: function() { - this.element - .removeClass( "ui-helper-hidden-accessible" ); - this.buttonElement - .removeClass( baseClasses + " " + stateClasses + " " + typeClasses ) - .removeAttr( "role" ) - .removeAttr( "aria-pressed" ) - .html( this.buttonElement.find(".ui-button-text").html() ); - - if ( !this.hasTitle ) { - this.buttonElement.removeAttr( "title" ); - } - }, - - _setOption: function( key, value ) { - this._super( key, value ); - if ( key === "disabled" ) { - if ( value ) { - this.element.prop( "disabled", true ); - } else { - this.element.prop( "disabled", false ); - } - return; - } - this._resetButton(); - }, - - refresh: function() { - //See #8237 & #8828 - var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" ); - - if ( isDisabled !== this.options.disabled ) { - this._setOption( "disabled", isDisabled ); - } - if ( this.type === "radio" ) { - radioGroup( this.element[0] ).each(function() { - if ( $( this ).is( ":checked" ) ) { - $( this ).button( "widget" ) - .addClass( "ui-state-active" ) - .attr( "aria-pressed", "true" ); - } else { - $( this ).button( "widget" ) - .removeClass( "ui-state-active" ) - .attr( "aria-pressed", "false" ); - } - }); - } else if ( this.type === "checkbox" ) { - if ( this.element.is( ":checked" ) ) { - this.buttonElement - .addClass( "ui-state-active" ) - .attr( "aria-pressed", "true" ); - } else { - this.buttonElement - .removeClass( "ui-state-active" ) - .attr( "aria-pressed", "false" ); - } - } - }, - - _resetButton: function() { - if ( this.type === "input" ) { - if ( this.options.label ) { - this.element.val( this.options.label ); - } - return; - } - var buttonElement = this.buttonElement.removeClass( typeClasses ), - buttonText = $( "<span></span>", this.document[0] ) - .addClass( "ui-button-text" ) - .html( this.options.label ) - .appendTo( buttonElement.empty() ) - .text(), - icons = this.options.icons, - multipleIcons = icons.primary && icons.secondary, - buttonClasses = []; - - if ( icons.primary || icons.secondary ) { - if ( this.options.text ) { - buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) ); - } - - if ( icons.primary ) { - buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" ); - } - - if ( icons.secondary ) { - buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" ); - } - - if ( !this.options.text ) { - buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" ); - - if ( !this.hasTitle ) { - buttonElement.attr( "title", $.trim( buttonText ) ); - } - } - } else { - buttonClasses.push( "ui-button-text-only" ); - } - buttonElement.addClass( buttonClasses.join( " " ) ); - } -}); - -$.widget( "ui.buttonset", { - version: "1.9.2", - options: { - items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(button)" - }, - - _create: function() { - this.element.addClass( "ui-buttonset" ); - }, - - _init: function() { - this.refresh(); - }, - - _setOption: function( key, value ) { - if ( key === "disabled" ) { - this.buttons.button( "option", key, value ); - } - - this._super( key, value ); - }, - - refresh: function() { - var rtl = this.element.css( "direction" ) === "rtl"; - - this.buttons = this.element.find( this.options.items ) - .filter( ":ui-button" ) - .button( "refresh" ) - .end() - .not( ":ui-button" ) - .button() - .end() - .map(function() { - return $( this ).button( "widget" )[ 0 ]; - }) - .removeClass( "ui-corner-all ui-corner-left ui-corner-right" ) - .filter( ":first" ) - .addClass( rtl ? "ui-corner-right" : "ui-corner-left" ) - .end() - .filter( ":last" ) - .addClass( rtl ? "ui-corner-left" : "ui-corner-right" ) - .end() - .end(); - }, - - _destroy: function() { - this.element.removeClass( "ui-buttonset" ); - this.buttons - .map(function() { - return $( this ).button( "widget" )[ 0 ]; - }) - .removeClass( "ui-corner-left ui-corner-right" ) - .end() - .button( "destroy" ); - } -}); - -}( jQuery ) ); - -(function( $, undefined ) { - -$.extend($.ui, { datepicker: { version: "1.9.2" } }); - -var PROP_NAME = 'datepicker'; -var dpuuid = new Date().getTime(); -var instActive; - -/* Date picker manager. - Use the singleton instance of this class, $.datepicker, to interact with the date picker. - Settings for (groups of) date pickers are maintained in an instance object, - allowing multiple different settings on the same page. */ - -function Datepicker() { - this.debug = false; // Change this to true to start debugging - this._curInst = null; // The current instance in use - this._keyEvent = false; // If the last event was a key event - this._disabledInputs = []; // List of date picker inputs that have been disabled - this._datepickerShowing = false; // True if the popup picker is showing , false if not - this._inDialog = false; // True if showing within a "dialog", false if not - this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division - this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class - this._appendClass = 'ui-datepicker-append'; // The name of the append marker class - this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class - this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class - this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class - this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class - this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class - this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class - this.regional = []; // Available regional settings, indexed by language code - this.regional[''] = { // Default regional settings - closeText: 'Done', // Display text for close link - prevText: 'Prev', // Display text for previous month link - nextText: 'Next', // Display text for next month link - currentText: 'Today', // Display text for current month link - monthNames: ['January','February','March','April','May','June', - 'July','August','September','October','November','December'], // Names of months for drop-down and formatting - monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting - dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting - dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting - dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday - weekHeader: 'Wk', // Column header for week of the year - dateFormat: 'mm/dd/yy', // See format options on parseDate - firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... - isRTL: false, // True if right-to-left language, false if left-to-right - showMonthAfterYear: false, // True if the year select precedes month, false for month then year - yearSuffix: '' // Additional text to append to the year in the month headers - }; - this._defaults = { // Global defaults for all the date picker instances - showOn: 'focus', // 'focus' for popup on focus, - // 'button' for trigger button, or 'both' for either - showAnim: 'fadeIn', // Name of jQuery animation for popup - showOptions: {}, // Options for enhanced animations - defaultDate: null, // Used when field is blank: actual date, - // +/-number for offset from today, null for today - appendText: '', // Display text following the input box, e.g. showing the format - buttonText: '...', // Text for trigger button - buttonImage: '', // URL for trigger button image - buttonImageOnly: false, // True if the image appears alone, false if it appears on a button - hideIfNoPrevNext: false, // True to hide next/previous month links - // if not applicable, false to just disable them - navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links - gotoCurrent: false, // True if today link goes back to current selection instead - changeMonth: false, // True if month can be selected directly, false if only prev/next - changeYear: false, // True if year can be selected directly, false if only prev/next - yearRange: 'c-10:c+10', // Range of years to display in drop-down, - // either relative to today's year (-nn:+nn), relative to currently displayed year - // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) - showOtherMonths: false, // True to show dates in other months, false to leave blank - selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable - showWeek: false, // True to show week of the year, false to not show it - calculateWeek: this.iso8601Week, // How to calculate the week of the year, - // takes a Date and returns the number of the week for it - shortYearCutoff: '+10', // Short year values < this are in the current century, - // > this are in the previous century, - // string value starting with '+' for current year + value - minDate: null, // The earliest selectable date, or null for no limit - maxDate: null, // The latest selectable date, or null for no limit - duration: 'fast', // Duration of display/closure - beforeShowDay: null, // Function that takes a date and returns an array with - // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '', - // [2] = cell title (optional), e.g. $.datepicker.noWeekends - beforeShow: null, // Function that takes an input field and - // returns a set of custom settings for the date picker - onSelect: null, // Define a callback function when a date is selected - onChangeMonthYear: null, // Define a callback function when the month or year is changed - onClose: null, // Define a callback function when the datepicker is closed - numberOfMonths: 1, // Number of months to show at a time - showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) - stepMonths: 1, // Number of months to step back/forward - stepBigMonths: 12, // Number of months to step back/forward for the big links - altField: '', // Selector for an alternate field to store selected dates into - altFormat: '', // The date format to use for the alternate field - constrainInput: true, // The input is constrained by the current date format - showButtonPanel: false, // True to show button panel, false to not show it - autoSize: false, // True to size the input for the date format, false to leave as is - disabled: false // The initial disabled state - }; - $.extend(this._defaults, this.regional['']); - this.dpDiv = bindHover($('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')); -} - -$.extend(Datepicker.prototype, { - /* Class name added to elements to indicate already configured with a date picker. */ - markerClassName: 'hasDatepicker', - - //Keep track of the maximum number of rows displayed (see #7043) - maxRows: 4, - - /* Debug logging (if enabled). */ - log: function () { - if (this.debug) - console.log.apply('', arguments); - }, - - // TODO rename to "widget" when switching to widget factory - _widgetDatepicker: function() { - return this.dpDiv; - }, - - /* Override the default settings for all instances of the date picker. - @param settings object - the new settings to use as defaults (anonymous object) - @return the manager object */ - setDefaults: function(settings) { - extendRemove(this._defaults, settings || {}); - return this; - }, - - /* Attach the date picker to a jQuery selection. - @param target element - the target input field or division or span - @param settings object - the new settings to use for this date picker instance (anonymous) */ - _attachDatepicker: function(target, settings) { - // check for settings on the control itself - in namespace 'date:' - var inlineSettings = null; - for (var attrName in this._defaults) { - var attrValue = target.getAttribute('date:' + attrName); - if (attrValue) { - inlineSettings = inlineSettings || {}; - try { - inlineSettings[attrName] = eval(attrValue); - } catch (err) { - inlineSettings[attrName] = attrValue; - } - } - } - var nodeName = target.nodeName.toLowerCase(); - var inline = (nodeName == 'div' || nodeName == 'span'); - if (!target.id) { - this.uuid += 1; - target.id = 'dp' + this.uuid; - } - var inst = this._newInst($(target), inline); - inst.settings = $.extend({}, settings || {}, inlineSettings || {}); - if (nodeName == 'input') { - this._connectDatepicker(target, inst); - } else if (inline) { - this._inlineDatepicker(target, inst); - } - }, - - /* Create a new instance object. */ - _newInst: function(target, inline) { - var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars - return {id: id, input: target, // associated target - selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection - drawMonth: 0, drawYear: 0, // month being drawn - inline: inline, // is datepicker inline or not - dpDiv: (!inline ? this.dpDiv : // presentation div - bindHover($('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')))}; - }, - - /* Attach the date picker to an input field. */ - _connectDatepicker: function(target, inst) { - var input = $(target); - inst.append = $([]); - inst.trigger = $([]); - if (input.hasClass(this.markerClassName)) - return; - this._attachments(input, inst); - input.addClass(this.markerClassName).keydown(this._doKeyDown). - keypress(this._doKeyPress).keyup(this._doKeyUp). - bind("setData.datepicker", function(event, key, value) { - inst.settings[key] = value; - }).bind("getData.datepicker", function(event, key) { - return this._get(inst, key); - }); - this._autoSize(inst); - $.data(target, PROP_NAME, inst); - //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) - if( inst.settings.disabled ) { - this._disableDatepicker( target ); - } - }, - - /* Make attachments based on settings. */ - _attachments: function(input, inst) { - var appendText = this._get(inst, 'appendText'); - var isRTL = this._get(inst, 'isRTL'); - if (inst.append) - inst.append.remove(); - if (appendText) { - inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>'); - input[isRTL ? 'before' : 'after'](inst.append); - } - input.unbind('focus', this._showDatepicker); - if (inst.trigger) - inst.trigger.remove(); - var showOn = this._get(inst, 'showOn'); - if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field - input.focus(this._showDatepicker); - if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked - var buttonText = this._get(inst, 'buttonText'); - var buttonImage = this._get(inst, 'buttonImage'); - inst.trigger = $(this._get(inst, 'buttonImageOnly') ? - $('<img/>').addClass(this._triggerClass). - attr({ src: buttonImage, alt: buttonText, title: buttonText }) : - $('<button type="button"></button>').addClass(this._triggerClass). - html(buttonImage == '' ? buttonText : $('<img/>').attr( - { src:buttonImage, alt:buttonText, title:buttonText }))); - input[isRTL ? 'before' : 'after'](inst.trigger); - inst.trigger.click(function() { - if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0]) - $.datepicker._hideDatepicker(); - else if ($.datepicker._datepickerShowing && $.datepicker._lastInput != input[0]) { - $.datepicker._hideDatepicker(); - $.datepicker._showDatepicker(input[0]); - } else - $.datepicker._showDatepicker(input[0]); - return false; - }); - } - }, - - /* Apply the maximum length for the date format. */ - _autoSize: function(inst) { - if (this._get(inst, 'autoSize') && !inst.inline) { - var date = new Date(2009, 12 - 1, 20); // Ensure double digits - var dateFormat = this._get(inst, 'dateFormat'); - if (dateFormat.match(/[DM]/)) { - var findMax = function(names) { - var max = 0; - var maxI = 0; - for (var i = 0; i < names.length; i++) { - if (names[i].length > max) { - max = names[i].length; - maxI = i; - } - } - return maxI; - }; - date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ? - 'monthNames' : 'monthNamesShort')))); - date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ? - 'dayNames' : 'dayNamesShort'))) + 20 - date.getDay()); - } - inst.input.attr('size', this._formatDate(inst, date).length); - } - }, - - /* Attach an inline date picker to a div. */ - _inlineDatepicker: function(target, inst) { - var divSpan = $(target); - if (divSpan.hasClass(this.markerClassName)) - return; - divSpan.addClass(this.markerClassName).append(inst.dpDiv). - bind("setData.datepicker", function(event, key, value){ - inst.settings[key] = value; - }).bind("getData.datepicker", function(event, key){ - return this._get(inst, key); - }); - $.data(target, PROP_NAME, inst); - this._setDate(inst, this._getDefaultDate(inst), true); - this._updateDatepicker(inst); - this._updateAlternate(inst); - //If disabled option is true, disable the datepicker before showing it (see ticket #5665) - if( inst.settings.disabled ) { - this._disableDatepicker( target ); - } - // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements - // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height - inst.dpDiv.css( "display", "block" ); - }, - - /* Pop-up the date picker in a "dialog" box. - @param input element - ignored - @param date string or Date - the initial date to display - @param onSelect function - the function to call when a date is selected - @param settings object - update the dialog date picker instance's settings (anonymous object) - @param pos int[2] - coordinates for the dialog's position within the screen or - event - with x/y coordinates or - leave empty for default (screen centre) - @return the manager object */ - _dialogDatepicker: function(input, date, onSelect, settings, pos) { - var inst = this._dialogInst; // internal instance - if (!inst) { - this.uuid += 1; - var id = 'dp' + this.uuid; - this._dialogInput = $('<input type="text" id="' + id + - '" style="position: absolute; top: -100px; width: 0px;"/>'); - this._dialogInput.keydown(this._doKeyDown); - $('body').append(this._dialogInput); - inst = this._dialogInst = this._newInst(this._dialogInput, false); - inst.settings = {}; - $.data(this._dialogInput[0], PROP_NAME, inst); - } - extendRemove(inst.settings, settings || {}); - date = (date && date.constructor == Date ? this._formatDate(inst, date) : date); - this._dialogInput.val(date); - - this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); - if (!this._pos) { - var browserWidth = document.documentElement.clientWidth; - var browserHeight = document.documentElement.clientHeight; - var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; - var scrollY = document.documentElement.scrollTop || document.body.scrollTop; - this._pos = // should use actual width/height below - [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; - } - - // move input on screen for focus, but hidden behind dialog - this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px'); - inst.settings.onSelect = onSelect; - this._inDialog = true; - this.dpDiv.addClass(this._dialogClass); - this._showDatepicker(this._dialogInput[0]); - if ($.blockUI) - $.blockUI(this.dpDiv); - $.data(this._dialogInput[0], PROP_NAME, inst); - return this; - }, - - /* Detach a datepicker from its control. - @param target element - the target input field or division or span */ - _destroyDatepicker: function(target) { - var $target = $(target); - var inst = $.data(target, PROP_NAME); - if (!$target.hasClass(this.markerClassName)) { - return; - } - var nodeName = target.nodeName.toLowerCase(); - $.removeData(target, PROP_NAME); - if (nodeName == 'input') { - inst.append.remove(); - inst.trigger.remove(); - $target.removeClass(this.markerClassName). - unbind('focus', this._showDatepicker). - unbind('keydown', this._doKeyDown). - unbind('keypress', this._doKeyPress). - unbind('keyup', this._doKeyUp); - } else if (nodeName == 'div' || nodeName == 'span') - $target.removeClass(this.markerClassName).empty(); - }, - - /* Enable the date picker to a jQuery selection. - @param target element - the target input field or division or span */ - _enableDatepicker: function(target) { - var $target = $(target); - var inst = $.data(target, PROP_NAME); - if (!$target.hasClass(this.markerClassName)) { - return; - } - var nodeName = target.nodeName.toLowerCase(); - if (nodeName == 'input') { - target.disabled = false; - inst.trigger.filter('button'). - each(function() { this.disabled = false; }).end(). - filter('img').css({opacity: '1.0', cursor: ''}); - } - else if (nodeName == 'div' || nodeName == 'span') { - var inline = $target.children('.' + this._inlineClass); - inline.children().removeClass('ui-state-disabled'); - inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). - prop("disabled", false); - } - this._disabledInputs = $.map(this._disabledInputs, - function(value) { return (value == target ? null : value); }); // delete entry - }, - - /* Disable the date picker to a jQuery selection. - @param target element - the target input field or division or span */ - _disableDatepicker: function(target) { - var $target = $(target); - var inst = $.data(target, PROP_NAME); - if (!$target.hasClass(this.markerClassName)) { - return; - } - var nodeName = target.nodeName.toLowerCase(); - if (nodeName == 'input') { - target.disabled = true; - inst.trigger.filter('button'). - each(function() { this.disabled = true; }).end(). - filter('img').css({opacity: '0.5', cursor: 'default'}); - } - else if (nodeName == 'div' || nodeName == 'span') { - var inline = $target.children('.' + this._inlineClass); - inline.children().addClass('ui-state-disabled'); - inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). - prop("disabled", true); - } - this._disabledInputs = $.map(this._disabledInputs, - function(value) { return (value == target ? null : value); }); // delete entry - this._disabledInputs[this._disabledInputs.length] = target; - }, - - /* Is the first field in a jQuery collection disabled as a datepicker? - @param target element - the target input field or division or span - @return boolean - true if disabled, false if enabled */ - _isDisabledDatepicker: function(target) { - if (!target) { - return false; - } - for (var i = 0; i < this._disabledInputs.length; i++) { - if (this._disabledInputs[i] == target) - return true; - } - return false; - }, - - /* Retrieve the instance data for the target control. - @param target element - the target input field or division or span - @return object - the associated instance data - @throws error if a jQuery problem getting data */ - _getInst: function(target) { - try { - return $.data(target, PROP_NAME); - } - catch (err) { - throw 'Missing instance data for this datepicker'; - } - }, - - /* Update or retrieve the settings for a date picker attached to an input field or division. - @param target element - the target input field or division or span - @param name object - the new settings to update or - string - the name of the setting to change or retrieve, - when retrieving also 'all' for all instance settings or - 'defaults' for all global defaults - @param value any - the new value for the setting - (omit if above is an object or to retrieve a value) */ - _optionDatepicker: function(target, name, value) { - var inst = this._getInst(target); - if (arguments.length == 2 && typeof name == 'string') { - return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) : - (inst ? (name == 'all' ? $.extend({}, inst.settings) : - this._get(inst, name)) : null)); - } - var settings = name || {}; - if (typeof name == 'string') { - settings = {}; - settings[name] = value; - } - if (inst) { - if (this._curInst == inst) { - this._hideDatepicker(); - } - var date = this._getDateDatepicker(target, true); - var minDate = this._getMinMaxDate(inst, 'min'); - var maxDate = this._getMinMaxDate(inst, 'max'); - extendRemove(inst.settings, settings); - // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided - if (minDate !== null && settings['dateFormat'] !== undefined && settings['minDate'] === undefined) - inst.settings.minDate = this._formatDate(inst, minDate); - if (maxDate !== null && settings['dateFormat'] !== undefined && settings['maxDate'] === undefined) - inst.settings.maxDate = this._formatDate(inst, maxDate); - this._attachments($(target), inst); - this._autoSize(inst); - this._setDate(inst, date); - this._updateAlternate(inst); - this._updateDatepicker(inst); - } - }, - - // change method deprecated - _changeDatepicker: function(target, name, value) { - this._optionDatepicker(target, name, value); - }, - - /* Redraw the date picker attached to an input field or division. - @param target element - the target input field or division or span */ - _refreshDatepicker: function(target) { - var inst = this._getInst(target); - if (inst) { - this._updateDatepicker(inst); - } - }, - - /* Set the dates for a jQuery selection. - @param target element - the target input field or division or span - @param date Date - the new date */ - _setDateDatepicker: function(target, date) { - var inst = this._getInst(target); - if (inst) { - this._setDate(inst, date); - this._updateDatepicker(inst); - this._updateAlternate(inst); - } - }, - - /* Get the date(s) for the first entry in a jQuery selection. - @param target element - the target input field or division or span - @param noDefault boolean - true if no default date is to be used - @return Date - the current date */ - _getDateDatepicker: function(target, noDefault) { - var inst = this._getInst(target); - if (inst && !inst.inline) - this._setDateFromField(inst, noDefault); - return (inst ? this._getDate(inst) : null); - }, - - /* Handle keystrokes. */ - _doKeyDown: function(event) { - var inst = $.datepicker._getInst(event.target); - var handled = true; - var isRTL = inst.dpDiv.is('.ui-datepicker-rtl'); - inst._keyEvent = true; - if ($.datepicker._datepickerShowing) - switch (event.keyCode) { - case 9: $.datepicker._hideDatepicker(); - handled = false; - break; // hide on tab out - case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' + - $.datepicker._currentClass + ')', inst.dpDiv); - if (sel[0]) - $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); - var onSelect = $.datepicker._get(inst, 'onSelect'); - if (onSelect) { - var dateStr = $.datepicker._formatDate(inst); - - // trigger custom callback - onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); - } - else - $.datepicker._hideDatepicker(); - return false; // don't submit the form - break; // select the value on enter - case 27: $.datepicker._hideDatepicker(); - break; // hide on escape - case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? - -$.datepicker._get(inst, 'stepBigMonths') : - -$.datepicker._get(inst, 'stepMonths')), 'M'); - break; // previous month/year on page up/+ ctrl - case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? - +$.datepicker._get(inst, 'stepBigMonths') : - +$.datepicker._get(inst, 'stepMonths')), 'M'); - break; // next month/year on page down/+ ctrl - case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target); - handled = event.ctrlKey || event.metaKey; - break; // clear on ctrl or command +end - case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target); - handled = event.ctrlKey || event.metaKey; - break; // current on ctrl or command +home - case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D'); - handled = event.ctrlKey || event.metaKey; - // -1 day on ctrl or command +left - if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ? - -$.datepicker._get(inst, 'stepBigMonths') : - -$.datepicker._get(inst, 'stepMonths')), 'M'); - // next month/year on alt +left on Mac - break; - case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D'); - handled = event.ctrlKey || event.metaKey; - break; // -1 week on ctrl or command +up - case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D'); - handled = event.ctrlKey || event.metaKey; - // +1 day on ctrl or command +right - if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ? - +$.datepicker._get(inst, 'stepBigMonths') : - +$.datepicker._get(inst, 'stepMonths')), 'M'); - // next month/year on alt +right - break; - case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D'); - handled = event.ctrlKey || event.metaKey; - break; // +1 week on ctrl or command +down - default: handled = false; - } - else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home - $.datepicker._showDatepicker(this); - else { - handled = false; - } - if (handled) { - event.preventDefault(); - event.stopPropagation(); - } - }, - - /* Filter entered characters - based on date format. */ - _doKeyPress: function(event) { - var inst = $.datepicker._getInst(event.target); - if ($.datepicker._get(inst, 'constrainInput')) { - var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat')); - var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode); - return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1); - } - }, - - /* Synchronise manual entry and field/alternate field. */ - _doKeyUp: function(event) { - var inst = $.datepicker._getInst(event.target); - if (inst.input.val() != inst.lastVal) { - try { - var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'), - (inst.input ? inst.input.val() : null), - $.datepicker._getFormatConfig(inst)); - if (date) { // only if valid - $.datepicker._setDateFromField(inst); - $.datepicker._updateAlternate(inst); - $.datepicker._updateDatepicker(inst); - } - } - catch (err) { - $.datepicker.log(err); - } - } - return true; - }, - - /* Pop-up the date picker for a given input field. - If false returned from beforeShow event handler do not show. - @param input element - the input field attached to the date picker or - event - if triggered by focus */ - _showDatepicker: function(input) { - input = input.target || input; - if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger - input = $('input', input.parentNode)[0]; - if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here - return; - var inst = $.datepicker._getInst(input); - if ($.datepicker._curInst && $.datepicker._curInst != inst) { - $.datepicker._curInst.dpDiv.stop(true, true); - if ( inst && $.datepicker._datepickerShowing ) { - $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] ); - } - } - var beforeShow = $.datepicker._get(inst, 'beforeShow'); - var beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; - if(beforeShowSettings === false){ - //false - return; - } - extendRemove(inst.settings, beforeShowSettings); - inst.lastVal = null; - $.datepicker._lastInput = input; - $.datepicker._setDateFromField(inst); - if ($.datepicker._inDialog) // hide cursor - input.value = ''; - if (!$.datepicker._pos) { // position below input - $.datepicker._pos = $.datepicker._findPos(input); - $.datepicker._pos[1] += input.offsetHeight; // add the height - } - var isFixed = false; - $(input).parents().each(function() { - isFixed |= $(this).css('position') == 'fixed'; - return !isFixed; - }); - var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; - $.datepicker._pos = null; - //to avoid flashes on Firefox - inst.dpDiv.empty(); - // determine sizing offscreen - inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'}); - $.datepicker._updateDatepicker(inst); - // fix width for dynamic number of date pickers - // and adjust position before showing - offset = $.datepicker._checkOffset(inst, offset, isFixed); - inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? - 'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none', - left: offset.left + 'px', top: offset.top + 'px'}); - if (!inst.inline) { - var showAnim = $.datepicker._get(inst, 'showAnim'); - var duration = $.datepicker._get(inst, 'duration'); - var postProcess = function() { - var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only - if( !! cover.length ){ - var borders = $.datepicker._getBorders(inst.dpDiv); - cover.css({left: -borders[0], top: -borders[1], - width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()}); - } - }; - inst.dpDiv.zIndex($(input).zIndex()+1); - $.datepicker._datepickerShowing = true; - - // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed - if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) - inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess); - else - inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess); - if (!showAnim || !duration) - postProcess(); - if (inst.input.is(':visible') && !inst.input.is(':disabled')) - inst.input.focus(); - $.datepicker._curInst = inst; - } - }, - - /* Generate the date picker content. */ - _updateDatepicker: function(inst) { - this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) - var borders = $.datepicker._getBorders(inst.dpDiv); - instActive = inst; // for delegate hover events - inst.dpDiv.empty().append(this._generateHTML(inst)); - this._attachHandlers(inst); - var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only - if( !!cover.length ){ //avoid call to outerXXXX() when not in IE6 - cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()}) - } - inst.dpDiv.find('.' + this._dayOverClass + ' a').mouseover(); - var numMonths = this._getNumberOfMonths(inst); - var cols = numMonths[1]; - var width = 17; - inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width(''); - if (cols > 1) - inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em'); - inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') + - 'Class']('ui-datepicker-multi'); - inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') + - 'Class']('ui-datepicker-rtl'); - if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input && - // #6694 - don't focus the input if it's already focused - // this breaks the change event in IE - inst.input.is(':visible') && !inst.input.is(':disabled') && inst.input[0] != document.activeElement) - inst.input.focus(); - // deffered render of the years select (to avoid flashes on Firefox) - if( inst.yearshtml ){ - var origyearshtml = inst.yearshtml; - setTimeout(function(){ - //assure that inst.yearshtml didn't change. - if( origyearshtml === inst.yearshtml && inst.yearshtml ){ - inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml); - } - origyearshtml = inst.yearshtml = null; - }, 0); - } - }, - - /* Retrieve the size of left and top borders for an element. - @param elem (jQuery object) the element of interest - @return (number[2]) the left and top borders */ - _getBorders: function(elem) { - var convert = function(value) { - return {thin: 1, medium: 2, thick: 3}[value] || value; - }; - return [parseFloat(convert(elem.css('border-left-width'))), - parseFloat(convert(elem.css('border-top-width')))]; - }, - - /* Check positioning to remain on screen. */ - _checkOffset: function(inst, offset, isFixed) { - var dpWidth = inst.dpDiv.outerWidth(); - var dpHeight = inst.dpDiv.outerHeight(); - var inputWidth = inst.input ? inst.input.outerWidth() : 0; - var inputHeight = inst.input ? inst.input.outerHeight() : 0; - var viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()); - var viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop()); - - offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0); - offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0; - offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0; - - // now check if datepicker is showing outside window viewport - move to a better place if so. - offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? - Math.abs(offset.left + dpWidth - viewWidth) : 0); - offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? - Math.abs(dpHeight + inputHeight) : 0); - - return offset; - }, - - /* Find an object's position on the screen. */ - _findPos: function(obj) { - var inst = this._getInst(obj); - var isRTL = this._get(inst, 'isRTL'); - while (obj && (obj.type == 'hidden' || obj.nodeType != 1 || $.expr.filters.hidden(obj))) { - obj = obj[isRTL ? 'previousSibling' : 'nextSibling']; - } - var position = $(obj).offset(); - return [position.left, position.top]; - }, - - /* Hide the date picker from view. - @param input element - the input field attached to the date picker */ - _hideDatepicker: function(input) { - var inst = this._curInst; - if (!inst || (input && inst != $.data(input, PROP_NAME))) - return; - if (this._datepickerShowing) { - var showAnim = this._get(inst, 'showAnim'); - var duration = this._get(inst, 'duration'); - var postProcess = function() { - $.datepicker._tidyDialog(inst); - }; - - // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed - if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) - inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess); - else - inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' : - (showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess); - if (!showAnim) - postProcess(); - this._datepickerShowing = false; - var onClose = this._get(inst, 'onClose'); - if (onClose) - onClose.apply((inst.input ? inst.input[0] : null), - [(inst.input ? inst.input.val() : ''), inst]); - this._lastInput = null; - if (this._inDialog) { - this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' }); - if ($.blockUI) { - $.unblockUI(); - $('body').append(this.dpDiv); - } - } - this._inDialog = false; - } - }, - - /* Tidy up after a dialog display. */ - _tidyDialog: function(inst) { - inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar'); - }, - - /* Close date picker if clicked elsewhere. */ - _checkExternalClick: function(event) { - if (!$.datepicker._curInst) - return; - - var $target = $(event.target), - inst = $.datepicker._getInst($target[0]); - - if ( ( ( $target[0].id != $.datepicker._mainDivId && - $target.parents('#' + $.datepicker._mainDivId).length == 0 && - !$target.hasClass($.datepicker.markerClassName) && - !$target.closest("." + $.datepicker._triggerClass).length && - $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) || - ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst != inst ) ) - $.datepicker._hideDatepicker(); - }, - - /* Adjust one of the date sub-fields. */ - _adjustDate: function(id, offset, period) { - var target = $(id); - var inst = this._getInst(target[0]); - if (this._isDisabledDatepicker(target[0])) { - return; - } - this._adjustInstDate(inst, offset + - (period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning - period); - this._updateDatepicker(inst); - }, - - /* Action for current link. */ - _gotoToday: function(id) { - var target = $(id); - var inst = this._getInst(target[0]); - if (this._get(inst, 'gotoCurrent') && inst.currentDay) { - inst.selectedDay = inst.currentDay; - inst.drawMonth = inst.selectedMonth = inst.currentMonth; - inst.drawYear = inst.selectedYear = inst.currentYear; - } - else { - var date = new Date(); - inst.selectedDay = date.getDate(); - inst.drawMonth = inst.selectedMonth = date.getMonth(); - inst.drawYear = inst.selectedYear = date.getFullYear(); - } - this._notifyChange(inst); - this._adjustDate(target); - }, - - /* Action for selecting a new month/year. */ - _selectMonthYear: function(id, select, period) { - var target = $(id); - var inst = this._getInst(target[0]); - inst['selected' + (period == 'M' ? 'Month' : 'Year')] = - inst['draw' + (period == 'M' ? 'Month' : 'Year')] = - parseInt(select.options[select.selectedIndex].value,10); - this._notifyChange(inst); - this._adjustDate(target); - }, - - /* Action for selecting a day. */ - _selectDay: function(id, month, year, td) { - var target = $(id); - if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) { - return; - } - var inst = this._getInst(target[0]); - inst.selectedDay = inst.currentDay = $('a', td).html(); - inst.selectedMonth = inst.currentMonth = month; - inst.selectedYear = inst.currentYear = year; - this._selectDate(id, this._formatDate(inst, - inst.currentDay, inst.currentMonth, inst.currentYear)); - }, - - /* Erase the input field and hide the date picker. */ - _clearDate: function(id) { - var target = $(id); - var inst = this._getInst(target[0]); - this._selectDate(target, ''); - }, - - /* Update the input field with the selected date. */ - _selectDate: function(id, dateStr) { - var target = $(id); - var inst = this._getInst(target[0]); - dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); - if (inst.input) - inst.input.val(dateStr); - this._updateAlternate(inst); - var onSelect = this._get(inst, 'onSelect'); - if (onSelect) - onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback - else if (inst.input) - inst.input.trigger('change'); // fire the change event - if (inst.inline) - this._updateDatepicker(inst); - else { - this._hideDatepicker(); - this._lastInput = inst.input[0]; - if (typeof(inst.input[0]) != 'object') - inst.input.focus(); // restore focus - this._lastInput = null; - } - }, - - /* Update any alternate field to synchronise with the main field. */ - _updateAlternate: function(inst) { - var altField = this._get(inst, 'altField'); - if (altField) { // update alternate field too - var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat'); - var date = this._getDate(inst); - var dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); - $(altField).each(function() { $(this).val(dateStr); }); - } - }, - - /* Set as beforeShowDay function to prevent selection of weekends. - @param date Date - the date to customise - @return [boolean, string] - is this date selectable?, what is its CSS class? */ - noWeekends: function(date) { - var day = date.getDay(); - return [(day > 0 && day < 6), '']; - }, - - /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. - @param date Date - the date to get the week for - @return number - the number of the week within the year that contains this date */ - iso8601Week: function(date) { - var checkDate = new Date(date.getTime()); - // Find Thursday of this week starting on Monday - checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); - var time = checkDate.getTime(); - checkDate.setMonth(0); // Compare with Jan 1 - checkDate.setDate(1); - return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; - }, - - /* Parse a string value into a date object. - See formatDate below for the possible formats. - - @param format string - the expected format of the date - @param value string - the date in the above format - @param settings Object - attributes include: - shortYearCutoff number - the cutoff year for determining the century (optional) - dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) - dayNames string[7] - names of the days from Sunday (optional) - monthNamesShort string[12] - abbreviated names of the months (optional) - monthNames string[12] - names of the months (optional) - @return Date - the extracted date value or null if value is blank */ - parseDate: function (format, value, settings) { - if (format == null || value == null) - throw 'Invalid arguments'; - value = (typeof value == 'object' ? value.toString() : value + ''); - if (value == '') - return null; - var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff; - shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff : - new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); - var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort; - var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames; - var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort; - var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames; - var year = -1; - var month = -1; - var day = -1; - var doy = -1; - var literal = false; - // Check whether a format character is doubled - var lookAhead = function(match) { - var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); - if (matches) - iFormat++; - return matches; - }; - // Extract a number from the string value - var getNumber = function(match) { - var isDoubled = lookAhead(match); - var size = (match == '@' ? 14 : (match == '!' ? 20 : - (match == 'y' && isDoubled ? 4 : (match == 'o' ? 3 : 2)))); - var digits = new RegExp('^\\d{1,' + size + '}'); - var num = value.substring(iValue).match(digits); - if (!num) - throw 'Missing number at position ' + iValue; - iValue += num[0].length; - return parseInt(num[0], 10); - }; - // Extract a name from the string value and convert to an index - var getName = function(match, shortNames, longNames) { - var names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { - return [ [k, v] ]; - }).sort(function (a, b) { - return -(a[1].length - b[1].length); - }); - var index = -1; - $.each(names, function (i, pair) { - var name = pair[1]; - if (value.substr(iValue, name.length).toLowerCase() == name.toLowerCase()) { - index = pair[0]; - iValue += name.length; - return false; - } - }); - if (index != -1) - return index + 1; - else - throw 'Unknown name at position ' + iValue; - }; - // Confirm that a literal character matches the string value - var checkLiteral = function() { - if (value.charAt(iValue) != format.charAt(iFormat)) - throw 'Unexpected literal at position ' + iValue; - iValue++; - }; - var iValue = 0; - for (var iFormat = 0; iFormat < format.length; iFormat++) { - if (literal) - if (format.charAt(iFormat) == "'" && !lookAhead("'")) - literal = false; - else - checkLiteral(); - else - switch (format.charAt(iFormat)) { - case 'd': - day = getNumber('d'); - break; - case 'D': - getName('D', dayNamesShort, dayNames); - break; - case 'o': - doy = getNumber('o'); - break; - case 'm': - month = getNumber('m'); - break; - case 'M': - month = getName('M', monthNamesShort, monthNames); - break; - case 'y': - year = getNumber('y'); - break; - case '@': - var date = new Date(getNumber('@')); - year = date.getFullYear(); - month = date.getMonth() + 1; - day = date.getDate(); - break; - case '!': - var date = new Date((getNumber('!') - this._ticksTo1970) / 10000); - year = date.getFullYear(); - month = date.getMonth() + 1; - day = date.getDate(); - break; - case "'": - if (lookAhead("'")) - checkLiteral(); - else - literal = true; - break; - default: - checkLiteral(); - } - } - if (iValue < value.length){ - var extra = value.substr(iValue); - if (!/^\s+/.test(extra)) { - throw "Extra/unparsed characters found in date: " + extra; - } - } - if (year == -1) - year = new Date().getFullYear(); - else if (year < 100) - year += new Date().getFullYear() - new Date().getFullYear() % 100 + - (year <= shortYearCutoff ? 0 : -100); - if (doy > -1) { - month = 1; - day = doy; - do { - var dim = this._getDaysInMonth(year, month - 1); - if (day <= dim) - break; - month++; - day -= dim; - } while (true); - } - var date = this._daylightSavingAdjust(new Date(year, month - 1, day)); - if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day) - throw 'Invalid date'; // E.g. 31/02/00 - return date; - }, - - /* Standard date formats. */ - ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601) - COOKIE: 'D, dd M yy', - ISO_8601: 'yy-mm-dd', - RFC_822: 'D, d M y', - RFC_850: 'DD, dd-M-y', - RFC_1036: 'D, d M y', - RFC_1123: 'D, d M yy', - RFC_2822: 'D, d M yy', - RSS: 'D, d M y', // RFC 822 - TICKS: '!', - TIMESTAMP: '@', - W3C: 'yy-mm-dd', // ISO 8601 - - _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + - Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000), - - /* Format a date object into a string value. - The format can be combinations of the following: - d - day of month (no leading zero) - dd - day of month (two digit) - o - day of year (no leading zeros) - oo - day of year (three digit) - D - day name short - DD - day name long - m - month of year (no leading zero) - mm - month of year (two digit) - M - month name short - MM - month name long - y - year (two digit) - yy - year (four digit) - @ - Unix timestamp (ms since 01/01/1970) - ! - Windows ticks (100ns since 01/01/0001) - '...' - literal text - '' - single quote - - @param format string - the desired format of the date - @param date Date - the date value to format - @param settings Object - attributes include: - dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) - dayNames string[7] - names of the days from Sunday (optional) - monthNamesShort string[12] - abbreviated names of the months (optional) - monthNames string[12] - names of the months (optional) - @return string - the date in the above format */ - formatDate: function (format, date, settings) { - if (!date) - return ''; - var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort; - var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames; - var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort; - var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames; - // Check whether a format character is doubled - var lookAhead = function(match) { - var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); - if (matches) - iFormat++; - return matches; - }; - // Format a number, with leading zero if necessary - var formatNumber = function(match, value, len) { - var num = '' + value; - if (lookAhead(match)) - while (num.length < len) - num = '0' + num; - return num; - }; - // Format a name, short or long as requested - var formatName = function(match, value, shortNames, longNames) { - return (lookAhead(match) ? longNames[value] : shortNames[value]); - }; - var output = ''; - var literal = false; - if (date) - for (var iFormat = 0; iFormat < format.length; iFormat++) { - if (literal) - if (format.charAt(iFormat) == "'" && !lookAhead("'")) - literal = false; - else - output += format.charAt(iFormat); - else - switch (format.charAt(iFormat)) { - case 'd': - output += formatNumber('d', date.getDate(), 2); - break; - case 'D': - output += formatName('D', date.getDay(), dayNamesShort, dayNames); - break; - case 'o': - output += formatNumber('o', - Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3); - break; - case 'm': - output += formatNumber('m', date.getMonth() + 1, 2); - break; - case 'M': - output += formatName('M', date.getMonth(), monthNamesShort, monthNames); - break; - case 'y': - output += (lookAhead('y') ? date.getFullYear() : - (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100); - break; - case '@': - output += date.getTime(); - break; - case '!': - output += date.getTime() * 10000 + this._ticksTo1970; - break; - case "'": - if (lookAhead("'")) - output += "'"; - else - literal = true; - break; - default: - output += format.charAt(iFormat); - } - } - return output; - }, - - /* Extract all possible characters from the date format. */ - _possibleChars: function (format) { - var chars = ''; - var literal = false; - // Check whether a format character is doubled - var lookAhead = function(match) { - var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); - if (matches) - iFormat++; - return matches; - }; - for (var iFormat = 0; iFormat < format.length; iFormat++) - if (literal) - if (format.charAt(iFormat) == "'" && !lookAhead("'")) - literal = false; - else - chars += format.charAt(iFormat); - else - switch (format.charAt(iFormat)) { - case 'd': case 'm': case 'y': case '@': - chars += '0123456789'; - break; - case 'D': case 'M': - return null; // Accept anything - case "'": - if (lookAhead("'")) - chars += "'"; - else - literal = true; - break; - default: - chars += format.charAt(iFormat); - } - return chars; - }, - - /* Get a setting value, defaulting if necessary. */ - _get: function(inst, name) { - return inst.settings[name] !== undefined ? - inst.settings[name] : this._defaults[name]; - }, - - /* Parse existing date and initialise date picker. */ - _setDateFromField: function(inst, noDefault) { - if (inst.input.val() == inst.lastVal) { - return; - } - var dateFormat = this._get(inst, 'dateFormat'); - var dates = inst.lastVal = inst.input ? inst.input.val() : null; - var date, defaultDate; - date = defaultDate = this._getDefaultDate(inst); - var settings = this._getFormatConfig(inst); - try { - date = this.parseDate(dateFormat, dates, settings) || defaultDate; - } catch (event) { - this.log(event); - dates = (noDefault ? '' : dates); - } - inst.selectedDay = date.getDate(); - inst.drawMonth = inst.selectedMonth = date.getMonth(); - inst.drawYear = inst.selectedYear = date.getFullYear(); - inst.currentDay = (dates ? date.getDate() : 0); - inst.currentMonth = (dates ? date.getMonth() : 0); - inst.currentYear = (dates ? date.getFullYear() : 0); - this._adjustInstDate(inst); - }, - - /* Retrieve the default date shown on opening. */ - _getDefaultDate: function(inst) { - return this._restrictMinMax(inst, - this._determineDate(inst, this._get(inst, 'defaultDate'), new Date())); - }, - - /* A date may be specified as an exact value or a relative one. */ - _determineDate: function(inst, date, defaultDate) { - var offsetNumeric = function(offset) { - var date = new Date(); - date.setDate(date.getDate() + offset); - return date; - }; - var offsetString = function(offset) { - try { - return $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'), - offset, $.datepicker._getFormatConfig(inst)); - } - catch (e) { - // Ignore - } - var date = (offset.toLowerCase().match(/^c/) ? - $.datepicker._getDate(inst) : null) || new Date(); - var year = date.getFullYear(); - var month = date.getMonth(); - var day = date.getDate(); - var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g; - var matches = pattern.exec(offset); - while (matches) { - switch (matches[2] || 'd') { - case 'd' : case 'D' : - day += parseInt(matches[1],10); break; - case 'w' : case 'W' : - day += parseInt(matches[1],10) * 7; break; - case 'm' : case 'M' : - month += parseInt(matches[1],10); - day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); - break; - case 'y': case 'Y' : - year += parseInt(matches[1],10); - day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); - break; - } - matches = pattern.exec(offset); - } - return new Date(year, month, day); - }; - var newDate = (date == null || date === '' ? defaultDate : (typeof date == 'string' ? offsetString(date) : - (typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime())))); - newDate = (newDate && newDate.toString() == 'Invalid Date' ? defaultDate : newDate); - if (newDate) { - newDate.setHours(0); - newDate.setMinutes(0); - newDate.setSeconds(0); - newDate.setMilliseconds(0); - } - return this._daylightSavingAdjust(newDate); - }, - - /* Handle switch to/from daylight saving. - Hours may be non-zero on daylight saving cut-over: - > 12 when midnight changeover, but then cannot generate - midnight datetime, so jump to 1AM, otherwise reset. - @param date (Date) the date to check - @return (Date) the corrected date */ - _daylightSavingAdjust: function(date) { - if (!date) return null; - date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); - return date; - }, - - /* Set the date(s) directly. */ - _setDate: function(inst, date, noChange) { - var clear = !date; - var origMonth = inst.selectedMonth; - var origYear = inst.selectedYear; - var newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); - inst.selectedDay = inst.currentDay = newDate.getDate(); - inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); - inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); - if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange) - this._notifyChange(inst); - this._adjustInstDate(inst); - if (inst.input) { - inst.input.val(clear ? '' : this._formatDate(inst)); - } - }, - - /* Retrieve the date(s) directly. */ - _getDate: function(inst) { - var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null : - this._daylightSavingAdjust(new Date( - inst.currentYear, inst.currentMonth, inst.currentDay))); - return startDate; - }, - - /* Attach the onxxx handlers. These are declared statically so - * they work with static code transformers like Caja. - */ - _attachHandlers: function(inst) { - var stepMonths = this._get(inst, 'stepMonths'); - var id = '#' + inst.id.replace( /\\\\/g, "\\" ); - inst.dpDiv.find('[data-handler]').map(function () { - var handler = { - prev: function () { - window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, -stepMonths, 'M'); - }, - next: function () { - window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, +stepMonths, 'M'); - }, - hide: function () { - window['DP_jQuery_' + dpuuid].datepicker._hideDatepicker(); - }, - today: function () { - window['DP_jQuery_' + dpuuid].datepicker._gotoToday(id); - }, - selectDay: function () { - window['DP_jQuery_' + dpuuid].datepicker._selectDay(id, +this.getAttribute('data-month'), +this.getAttribute('data-year'), this); - return false; - }, - selectMonth: function () { - window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'M'); - return false; - }, - selectYear: function () { - window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'Y'); - return false; - } - }; - $(this).bind(this.getAttribute('data-event'), handler[this.getAttribute('data-handler')]); - }); - }, - - /* Generate the HTML for the current state of the date picker. */ - _generateHTML: function(inst) { - var today = new Date(); - today = this._daylightSavingAdjust( - new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time - var isRTL = this._get(inst, 'isRTL'); - var showButtonPanel = this._get(inst, 'showButtonPanel'); - var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext'); - var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat'); - var numMonths = this._getNumberOfMonths(inst); - var showCurrentAtPos = this._get(inst, 'showCurrentAtPos'); - var stepMonths = this._get(inst, 'stepMonths'); - var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1); - var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : - new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); - var minDate = this._getMinMaxDate(inst, 'min'); - var maxDate = this._getMinMaxDate(inst, 'max'); - var drawMonth = inst.drawMonth - showCurrentAtPos; - var drawYear = inst.drawYear; - if (drawMonth < 0) { - drawMonth += 12; - drawYear--; - } - if (maxDate) { - var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), - maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate())); - maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); - while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { - drawMonth--; - if (drawMonth < 0) { - drawMonth = 11; - drawYear--; - } - } - } - inst.drawMonth = drawMonth; - inst.drawYear = drawYear; - var prevText = this._get(inst, 'prevText'); - prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, - this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), - this._getFormatConfig(inst))); - var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? - '<a class="ui-datepicker-prev ui-corner-all" data-handler="prev" data-event="click"' + - ' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' : - (hideIfNoPrevNext ? '' : '<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+ prevText +'"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>')); - var nextText = this._get(inst, 'nextText'); - nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, - this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), - this._getFormatConfig(inst))); - var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? - '<a class="ui-datepicker-next ui-corner-all" data-handler="next" data-event="click"' + - ' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' : - (hideIfNoPrevNext ? '' : '<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+ nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>')); - var currentText = this._get(inst, 'currentText'); - var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today); - currentText = (!navigationAsDateFormat ? currentText : - this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); - var controls = (!inst.inline ? '<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" data-handler="hide" data-event="click">' + - this._get(inst, 'closeText') + '</button>' : ''); - var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') + - (this._isInRange(inst, gotoDate) ? '<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" data-handler="today" data-event="click"' + - '>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : ''; - var firstDay = parseInt(this._get(inst, 'firstDay'),10); - firstDay = (isNaN(firstDay) ? 0 : firstDay); - var showWeek = this._get(inst, 'showWeek'); - var dayNames = this._get(inst, 'dayNames'); - var dayNamesShort = this._get(inst, 'dayNamesShort'); - var dayNamesMin = this._get(inst, 'dayNamesMin'); - var monthNames = this._get(inst, 'monthNames'); - var monthNamesShort = this._get(inst, 'monthNamesShort'); - var beforeShowDay = this._get(inst, 'beforeShowDay'); - var showOtherMonths = this._get(inst, 'showOtherMonths'); - var selectOtherMonths = this._get(inst, 'selectOtherMonths'); - var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week; - var defaultDate = this._getDefaultDate(inst); - var html = ''; - for (var row = 0; row < numMonths[0]; row++) { - var group = ''; - this.maxRows = 4; - for (var col = 0; col < numMonths[1]; col++) { - var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); - var cornerClass = ' ui-corner-all'; - var calender = ''; - if (isMultiMonth) { - calender += '<div class="ui-datepicker-group'; - if (numMonths[1] > 1) - switch (col) { - case 0: calender += ' ui-datepicker-group-first'; - cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break; - case numMonths[1]-1: calender += ' ui-datepicker-group-last'; - cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break; - default: calender += ' ui-datepicker-group-middle'; cornerClass = ''; break; - } - calender += '">'; - } - calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' + - (/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') + - (/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') + - this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, - row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers - '</div><table class="ui-datepicker-calendar"><thead>' + - '<tr>'; - var thead = (showWeek ? '<th class="ui-datepicker-week-col">' + this._get(inst, 'weekHeader') + '</th>' : ''); - for (var dow = 0; dow < 7; dow++) { // days of the week - var day = (dow + firstDay) % 7; - thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>' + - '<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>'; - } - calender += thead + '</tr></thead><tbody>'; - var daysInMonth = this._getDaysInMonth(drawYear, drawMonth); - if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth) - inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); - var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; - var curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate - var numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) - this.maxRows = numRows; - var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); - for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows - calender += '<tr>'; - var tbody = (!showWeek ? '' : '<td class="ui-datepicker-week-col">' + - this._get(inst, 'calculateWeek')(printDate) + '</td>'); - for (var dow = 0; dow < 7; dow++) { // create date picker days - var daySettings = (beforeShowDay ? - beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']); - var otherMonth = (printDate.getMonth() != drawMonth); - var unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || - (minDate && printDate < minDate) || (maxDate && printDate > maxDate); - tbody += '<td class="' + - ((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends - (otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months - ((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key - (defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ? - // or defaultDate is current printedDate and defaultDate is selectedDate - ' ' + this._dayOverClass : '') + // highlight selected day - (unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') + // highlight unselectable days - (otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates - (printDate.getTime() == currentDate.getTime() ? ' ' + this._currentClass : '') + // highlight selected day - (printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different) - ((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title - (unselectable ? '' : ' data-handler="selectDay" data-event="click" data-month="' + printDate.getMonth() + '" data-year="' + printDate.getFullYear() + '"') + '>' + // actions - (otherMonth && !showOtherMonths ? ' ' : // display for other months - (unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' + - (printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') + - (printDate.getTime() == currentDate.getTime() ? ' ui-state-active' : '') + // highlight selected day - (otherMonth ? ' ui-priority-secondary' : '') + // distinguish dates from other months - '" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display selectable date - printDate.setDate(printDate.getDate() + 1); - printDate = this._daylightSavingAdjust(printDate); - } - calender += tbody + '</tr>'; - } - drawMonth++; - if (drawMonth > 11) { - drawMonth = 0; - drawYear++; - } - calender += '</tbody></table>' + (isMultiMonth ? '</div>' + - ((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : ''); - group += calender; - } - html += group; - } - html += buttonPanel + ($.ui.ie6 && !inst.inline ? - '<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : ''); - inst._keyEvent = false; - return html; - }, - - /* Generate the month and year header. */ - _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, - secondary, monthNames, monthNamesShort) { - var changeMonth = this._get(inst, 'changeMonth'); - var changeYear = this._get(inst, 'changeYear'); - var showMonthAfterYear = this._get(inst, 'showMonthAfterYear'); - var html = '<div class="ui-datepicker-title">'; - var monthHtml = ''; - // month selection - if (secondary || !changeMonth) - monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span>'; - else { - var inMinYear = (minDate && minDate.getFullYear() == drawYear); - var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear); - monthHtml += '<select class="ui-datepicker-month" data-handler="selectMonth" data-event="change">'; - for (var month = 0; month < 12; month++) { - if ((!inMinYear || month >= minDate.getMonth()) && - (!inMaxYear || month <= maxDate.getMonth())) - monthHtml += '<option value="' + month + '"' + - (month == drawMonth ? ' selected="selected"' : '') + - '>' + monthNamesShort[month] + '</option>'; - } - monthHtml += '</select>'; - } - if (!showMonthAfterYear) - html += monthHtml + (secondary || !(changeMonth && changeYear) ? ' ' : ''); - // year selection - if ( !inst.yearshtml ) { - inst.yearshtml = ''; - if (secondary || !changeYear) - html += '<span class="ui-datepicker-year">' + drawYear + '</span>'; - else { - // determine range of years to display - var years = this._get(inst, 'yearRange').split(':'); - var thisYear = new Date().getFullYear(); - var determineYear = function(value) { - var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) : - (value.match(/[+-].*/) ? thisYear + parseInt(value, 10) : - parseInt(value, 10))); - return (isNaN(year) ? thisYear : year); - }; - var year = determineYear(years[0]); - var endYear = Math.max(year, determineYear(years[1] || '')); - year = (minDate ? Math.max(year, minDate.getFullYear()) : year); - endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); - inst.yearshtml += '<select class="ui-datepicker-year" data-handler="selectYear" data-event="change">'; - for (; year <= endYear; year++) { - inst.yearshtml += '<option value="' + year + '"' + - (year == drawYear ? ' selected="selected"' : '') + - '>' + year + '</option>'; - } - inst.yearshtml += '</select>'; - - html += inst.yearshtml; - inst.yearshtml = null; - } - } - html += this._get(inst, 'yearSuffix'); - if (showMonthAfterYear) - html += (secondary || !(changeMonth && changeYear) ? ' ' : '') + monthHtml; - html += '</div>'; // Close datepicker_header - return html; - }, - - /* Adjust one of the date sub-fields. */ - _adjustInstDate: function(inst, offset, period) { - var year = inst.drawYear + (period == 'Y' ? offset : 0); - var month = inst.drawMonth + (period == 'M' ? offset : 0); - var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + - (period == 'D' ? offset : 0); - var date = this._restrictMinMax(inst, - this._daylightSavingAdjust(new Date(year, month, day))); - inst.selectedDay = date.getDate(); - inst.drawMonth = inst.selectedMonth = date.getMonth(); - inst.drawYear = inst.selectedYear = date.getFullYear(); - if (period == 'M' || period == 'Y') - this._notifyChange(inst); - }, - - /* Ensure a date is within any min/max bounds. */ - _restrictMinMax: function(inst, date) { - var minDate = this._getMinMaxDate(inst, 'min'); - var maxDate = this._getMinMaxDate(inst, 'max'); - var newDate = (minDate && date < minDate ? minDate : date); - newDate = (maxDate && newDate > maxDate ? maxDate : newDate); - return newDate; - }, - - /* Notify change of month/year. */ - _notifyChange: function(inst) { - var onChange = this._get(inst, 'onChangeMonthYear'); - if (onChange) - onChange.apply((inst.input ? inst.input[0] : null), - [inst.selectedYear, inst.selectedMonth + 1, inst]); - }, - - /* Determine the number of months to show. */ - _getNumberOfMonths: function(inst) { - var numMonths = this._get(inst, 'numberOfMonths'); - return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths)); - }, - - /* Determine the current maximum date - ensure no time components are set. */ - _getMinMaxDate: function(inst, minMax) { - return this._determineDate(inst, this._get(inst, minMax + 'Date'), null); - }, - - /* Find the number of days in a given month. */ - _getDaysInMonth: function(year, month) { - return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); - }, - - /* Find the day of the week of the first of a month. */ - _getFirstDayOfMonth: function(year, month) { - return new Date(year, month, 1).getDay(); - }, - - /* Determines if we should allow a "next/prev" month display change. */ - _canAdjustMonth: function(inst, offset, curYear, curMonth) { - var numMonths = this._getNumberOfMonths(inst); - var date = this._daylightSavingAdjust(new Date(curYear, - curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); - if (offset < 0) - date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); - return this._isInRange(inst, date); - }, - - /* Is the given date in the accepted range? */ - _isInRange: function(inst, date) { - var minDate = this._getMinMaxDate(inst, 'min'); - var maxDate = this._getMinMaxDate(inst, 'max'); - return ((!minDate || date.getTime() >= minDate.getTime()) && - (!maxDate || date.getTime() <= maxDate.getTime())); - }, - - /* Provide the configuration settings for formatting/parsing. */ - _getFormatConfig: function(inst) { - var shortYearCutoff = this._get(inst, 'shortYearCutoff'); - shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff : - new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); - return {shortYearCutoff: shortYearCutoff, - dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'), - monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')}; - }, - - /* Format the given date for display. */ - _formatDate: function(inst, day, month, year) { - if (!day) { - inst.currentDay = inst.selectedDay; - inst.currentMonth = inst.selectedMonth; - inst.currentYear = inst.selectedYear; - } - var date = (day ? (typeof day == 'object' ? day : - this._daylightSavingAdjust(new Date(year, month, day))) : - this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); - return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst)); - } -}); - -/* - * Bind hover events for datepicker elements. - * Done via delegate so the binding only occurs once in the lifetime of the parent div. - * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. - */ -function bindHover(dpDiv) { - var selector = 'button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a'; - return dpDiv.delegate(selector, 'mouseout', function() { - $(this).removeClass('ui-state-hover'); - if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover'); - if (this.className.indexOf('ui-datepicker-next') != -1) $(this).removeClass('ui-datepicker-next-hover'); - }) - .delegate(selector, 'mouseover', function(){ - if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) { - $(this).parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover'); - $(this).addClass('ui-state-hover'); - if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).addClass('ui-datepicker-prev-hover'); - if (this.className.indexOf('ui-datepicker-next') != -1) $(this).addClass('ui-datepicker-next-hover'); - } - }); -} - -/* jQuery extend now ignores nulls! */ -function extendRemove(target, props) { - $.extend(target, props); - for (var name in props) - if (props[name] == null || props[name] == undefined) - target[name] = props[name]; - return target; -}; - -/* Invoke the datepicker functionality. - @param options string - a command, optionally followed by additional parameters or - Object - settings for attaching new datepicker functionality - @return jQuery object */ -$.fn.datepicker = function(options){ - - /* Verify an empty collection wasn't passed - Fixes #6976 */ - if ( !this.length ) { - return this; - } - - /* Initialise the date picker. */ - if (!$.datepicker.initialized) { - $(document).mousedown($.datepicker._checkExternalClick). - find(document.body).append($.datepicker.dpDiv); - $.datepicker.initialized = true; - } - - var otherArgs = Array.prototype.slice.call(arguments, 1); - if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget')) - return $.datepicker['_' + options + 'Datepicker']. - apply($.datepicker, [this[0]].concat(otherArgs)); - if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string') - return $.datepicker['_' + options + 'Datepicker']. - apply($.datepicker, [this[0]].concat(otherArgs)); - return this.each(function() { - typeof options == 'string' ? - $.datepicker['_' + options + 'Datepicker']. - apply($.datepicker, [this].concat(otherArgs)) : - $.datepicker._attachDatepicker(this, options); - }); -}; - -$.datepicker = new Datepicker(); // singleton instance -$.datepicker.initialized = false; -$.datepicker.uuid = new Date().getTime(); -$.datepicker.version = "1.9.2"; - -// Workaround for #4055 -// Add another global to avoid noConflict issues with inline event handlers -window['DP_jQuery_' + dpuuid] = $; - -})(jQuery); - -(function( $, undefined ) { - -var uiDialogClasses = "ui-dialog ui-widget ui-widget-content ui-corner-all ", - sizeRelatedOptions = { - buttons: true, - height: true, - maxHeight: true, - maxWidth: true, - minHeight: true, - minWidth: true, - width: true - }, - resizableRelatedOptions = { - maxHeight: true, - maxWidth: true, - minHeight: true, - minWidth: true - }; - -$.widget("ui.dialog", { - version: "1.9.2", - options: { - autoOpen: true, - buttons: {}, - closeOnEscape: true, - closeText: "close", - dialogClass: "", - draggable: true, - hide: null, - height: "auto", - maxHeight: false, - maxWidth: false, - minHeight: 150, - minWidth: 150, - modal: false, - position: { - my: "center", - at: "center", - of: window, - collision: "fit", - // ensure that the titlebar is never outside the document - using: function( pos ) { - var topOffset = $( this ).css( pos ).offset().top; - if ( topOffset < 0 ) { - $( this ).css( "top", pos.top - topOffset ); - } - } - }, - resizable: true, - show: null, - stack: true, - title: "", - width: 300, - zIndex: 1000 - }, - - _create: function() { - this.originalTitle = this.element.attr( "title" ); - // #5742 - .attr() might return a DOMElement - if ( typeof this.originalTitle !== "string" ) { - this.originalTitle = ""; - } - this.oldPosition = { - parent: this.element.parent(), - index: this.element.parent().children().index( this.element ) - }; - this.options.title = this.options.title || this.originalTitle; - var that = this, - options = this.options, - - title = options.title || " ", - uiDialog, - uiDialogTitlebar, - uiDialogTitlebarClose, - uiDialogTitle, - uiDialogButtonPane; - - uiDialog = ( this.uiDialog = $( "<div>" ) ) - .addClass( uiDialogClasses + options.dialogClass ) - .css({ - display: "none", - outline: 0, // TODO: move to stylesheet - zIndex: options.zIndex - }) - // setting tabIndex makes the div focusable - .attr( "tabIndex", -1) - .keydown(function( event ) { - if ( options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && - event.keyCode === $.ui.keyCode.ESCAPE ) { - that.close( event ); - event.preventDefault(); - } - }) - .mousedown(function( event ) { - that.moveToTop( false, event ); - }) - .appendTo( "body" ); - - this.element - .show() - .removeAttr( "title" ) - .addClass( "ui-dialog-content ui-widget-content" ) - .appendTo( uiDialog ); - - uiDialogTitlebar = ( this.uiDialogTitlebar = $( "<div>" ) ) - .addClass( "ui-dialog-titlebar ui-widget-header " + - "ui-corner-all ui-helper-clearfix" ) - .bind( "mousedown", function() { - // Dialog isn't getting focus when dragging (#8063) - uiDialog.focus(); - }) - .prependTo( uiDialog ); - - uiDialogTitlebarClose = $( "<a href='#'></a>" ) - .addClass( "ui-dialog-titlebar-close ui-corner-all" ) - .attr( "role", "button" ) - .click(function( event ) { - event.preventDefault(); - that.close( event ); - }) - .appendTo( uiDialogTitlebar ); - - ( this.uiDialogTitlebarCloseText = $( "<span>" ) ) - .addClass( "ui-icon ui-icon-closethick" ) - .text( options.closeText ) - .appendTo( uiDialogTitlebarClose ); - - uiDialogTitle = $( "<span>" ) - .uniqueId() - .addClass( "ui-dialog-title" ) - .html( title ) - .prependTo( uiDialogTitlebar ); - - uiDialogButtonPane = ( this.uiDialogButtonPane = $( "<div>" ) ) - .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" ); - - ( this.uiButtonSet = $( "<div>" ) ) - .addClass( "ui-dialog-buttonset" ) - .appendTo( uiDialogButtonPane ); - - uiDialog.attr({ - role: "dialog", - "aria-labelledby": uiDialogTitle.attr( "id" ) - }); - - uiDialogTitlebar.find( "*" ).add( uiDialogTitlebar ).disableSelection(); - this._hoverable( uiDialogTitlebarClose ); - this._focusable( uiDialogTitlebarClose ); - - if ( options.draggable && $.fn.draggable ) { - this._makeDraggable(); - } - if ( options.resizable && $.fn.resizable ) { - this._makeResizable(); - } - - this._createButtons( options.buttons ); - this._isOpen = false; - - if ( $.fn.bgiframe ) { - uiDialog.bgiframe(); - } - - // prevent tabbing out of modal dialogs - this._on( uiDialog, { keydown: function( event ) { - if ( !options.modal || event.keyCode !== $.ui.keyCode.TAB ) { - return; - } - - var tabbables = $( ":tabbable", uiDialog ), - first = tabbables.filter( ":first" ), - last = tabbables.filter( ":last" ); - - if ( event.target === last[0] && !event.shiftKey ) { - first.focus( 1 ); - return false; - } else if ( event.target === first[0] && event.shiftKey ) { - last.focus( 1 ); - return false; - } - }}); - }, - - _init: function() { - if ( this.options.autoOpen ) { - this.open(); - } - }, - - _destroy: function() { - var next, - oldPosition = this.oldPosition; - - if ( this.overlay ) { - this.overlay.destroy(); - } - this.uiDialog.hide(); - this.element - .removeClass( "ui-dialog-content ui-widget-content" ) - .hide() - .appendTo( "body" ); - this.uiDialog.remove(); - - if ( this.originalTitle ) { - this.element.attr( "title", this.originalTitle ); - } - - next = oldPosition.parent.children().eq( oldPosition.index ); - // Don't try to place the dialog next to itself (#8613) - if ( next.length && next[ 0 ] !== this.element[ 0 ] ) { - next.before( this.element ); - } else { - oldPosition.parent.append( this.element ); - } - }, - - widget: function() { - return this.uiDialog; - }, - - close: function( event ) { - var that = this, - maxZ, thisZ; - - if ( !this._isOpen ) { - return; - } - - if ( false === this._trigger( "beforeClose", event ) ) { - return; - } - - this._isOpen = false; - - if ( this.overlay ) { - this.overlay.destroy(); - } - - if ( this.options.hide ) { - this._hide( this.uiDialog, this.options.hide, function() { - that._trigger( "close", event ); - }); - } else { - this.uiDialog.hide(); - this._trigger( "close", event ); - } - - $.ui.dialog.overlay.resize(); - - // adjust the maxZ to allow other modal dialogs to continue to work (see #4309) - if ( this.options.modal ) { - maxZ = 0; - $( ".ui-dialog" ).each(function() { - if ( this !== that.uiDialog[0] ) { - thisZ = $( this ).css( "z-index" ); - if ( !isNaN( thisZ ) ) { - maxZ = Math.max( maxZ, thisZ ); - } - } - }); - $.ui.dialog.maxZ = maxZ; - } - - return this; - }, - - isOpen: function() { - return this._isOpen; - }, - - // the force parameter allows us to move modal dialogs to their correct - // position on open - moveToTop: function( force, event ) { - var options = this.options, - saveScroll; - - if ( ( options.modal && !force ) || - ( !options.stack && !options.modal ) ) { - return this._trigger( "focus", event ); - } - - if ( options.zIndex > $.ui.dialog.maxZ ) { - $.ui.dialog.maxZ = options.zIndex; - } - if ( this.overlay ) { - $.ui.dialog.maxZ += 1; - $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ; - this.overlay.$el.css( "z-index", $.ui.dialog.overlay.maxZ ); - } - - // Save and then restore scroll - // Opera 9.5+ resets when parent z-index is changed. - // http://bugs.jqueryui.com/ticket/3193 - saveScroll = { - scrollTop: this.element.scrollTop(), - scrollLeft: this.element.scrollLeft() - }; - $.ui.dialog.maxZ += 1; - this.uiDialog.css( "z-index", $.ui.dialog.maxZ ); - this.element.attr( saveScroll ); - this._trigger( "focus", event ); - - return this; - }, - - open: function() { - if ( this._isOpen ) { - return; - } - - var hasFocus, - options = this.options, - uiDialog = this.uiDialog; - - this._size(); - this._position( options.position ); - uiDialog.show( options.show ); - this.overlay = options.modal ? new $.ui.dialog.overlay( this ) : null; - this.moveToTop( true ); - - // set focus to the first tabbable element in the content area or the first button - // if there are no tabbable elements, set focus on the dialog itself - hasFocus = this.element.find( ":tabbable" ); - if ( !hasFocus.length ) { - hasFocus = this.uiDialogButtonPane.find( ":tabbable" ); - if ( !hasFocus.length ) { - hasFocus = uiDialog; - } - } - hasFocus.eq( 0 ).focus(); - - this._isOpen = true; - this._trigger( "open" ); - - return this; - }, - - _createButtons: function( buttons ) { - var that = this, - hasButtons = false; - - // if we already have a button pane, remove it - this.uiDialogButtonPane.remove(); - this.uiButtonSet.empty(); - - if ( typeof buttons === "object" && buttons !== null ) { - $.each( buttons, function() { - return !(hasButtons = true); - }); - } - if ( hasButtons ) { - $.each( buttons, function( name, props ) { - var button, click; - props = $.isFunction( props ) ? - { click: props, text: name } : - props; - // Default to a non-submitting button - props = $.extend( { type: "button" }, props ); - // Change the context for the click callback to be the main element - click = props.click; - props.click = function() { - click.apply( that.element[0], arguments ); - }; - button = $( "<button></button>", props ) - .appendTo( that.uiButtonSet ); - if ( $.fn.button ) { - button.button(); - } - }); - this.uiDialog.addClass( "ui-dialog-buttons" ); - this.uiDialogButtonPane.appendTo( this.uiDialog ); - } else { - this.uiDialog.removeClass( "ui-dialog-buttons" ); - } - }, - - _makeDraggable: function() { - var that = this, - options = this.options; - - function filteredUi( ui ) { - return { - position: ui.position, - offset: ui.offset - }; - } - - this.uiDialog.draggable({ - cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", - handle: ".ui-dialog-titlebar", - containment: "document", - start: function( event, ui ) { - $( this ) - .addClass( "ui-dialog-dragging" ); - that._trigger( "dragStart", event, filteredUi( ui ) ); - }, - drag: function( event, ui ) { - that._trigger( "drag", event, filteredUi( ui ) ); - }, - stop: function( event, ui ) { - options.position = [ - ui.position.left - that.document.scrollLeft(), - ui.position.top - that.document.scrollTop() - ]; - $( this ) - .removeClass( "ui-dialog-dragging" ); - that._trigger( "dragStop", event, filteredUi( ui ) ); - $.ui.dialog.overlay.resize(); - } - }); - }, - - _makeResizable: function( handles ) { - handles = (handles === undefined ? this.options.resizable : handles); - var that = this, - options = this.options, - // .ui-resizable has position: relative defined in the stylesheet - // but dialogs have to use absolute or fixed positioning - position = this.uiDialog.css( "position" ), - resizeHandles = typeof handles === 'string' ? - handles : - "n,e,s,w,se,sw,ne,nw"; - - function filteredUi( ui ) { - return { - originalPosition: ui.originalPosition, - originalSize: ui.originalSize, - position: ui.position, - size: ui.size - }; - } - - this.uiDialog.resizable({ - cancel: ".ui-dialog-content", - containment: "document", - alsoResize: this.element, - maxWidth: options.maxWidth, - maxHeight: options.maxHeight, - minWidth: options.minWidth, - minHeight: this._minHeight(), - handles: resizeHandles, - start: function( event, ui ) { - $( this ).addClass( "ui-dialog-resizing" ); - that._trigger( "resizeStart", event, filteredUi( ui ) ); - }, - resize: function( event, ui ) { - that._trigger( "resize", event, filteredUi( ui ) ); - }, - stop: function( event, ui ) { - $( this ).removeClass( "ui-dialog-resizing" ); - options.height = $( this ).height(); - options.width = $( this ).width(); - that._trigger( "resizeStop", event, filteredUi( ui ) ); - $.ui.dialog.overlay.resize(); - } - }) - .css( "position", position ) - .find( ".ui-resizable-se" ) - .addClass( "ui-icon ui-icon-grip-diagonal-se" ); - }, - - _minHeight: function() { - var options = this.options; - - if ( options.height === "auto" ) { - return options.minHeight; - } else { - return Math.min( options.minHeight, options.height ); - } - }, - - _position: function( position ) { - var myAt = [], - offset = [ 0, 0 ], - isVisible; - - if ( position ) { - // deep extending converts arrays to objects in jQuery <= 1.3.2 :-( - // if (typeof position == 'string' || $.isArray(position)) { - // myAt = $.isArray(position) ? position : position.split(' '); - - if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) { - myAt = position.split ? position.split( " " ) : [ position[ 0 ], position[ 1 ] ]; - if ( myAt.length === 1 ) { - myAt[ 1 ] = myAt[ 0 ]; - } - - $.each( [ "left", "top" ], function( i, offsetPosition ) { - if ( +myAt[ i ] === myAt[ i ] ) { - offset[ i ] = myAt[ i ]; - myAt[ i ] = offsetPosition; - } - }); - - position = { - my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " + - myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]), - at: myAt.join( " " ) - }; - } - - position = $.extend( {}, $.ui.dialog.prototype.options.position, position ); - } else { - position = $.ui.dialog.prototype.options.position; - } - - // need to show the dialog to get the actual offset in the position plugin - isVisible = this.uiDialog.is( ":visible" ); - if ( !isVisible ) { - this.uiDialog.show(); - } - this.uiDialog.position( position ); - if ( !isVisible ) { - this.uiDialog.hide(); - } - }, - - _setOptions: function( options ) { - var that = this, - resizableOptions = {}, - resize = false; - - $.each( options, function( key, value ) { - that._setOption( key, value ); - - if ( key in sizeRelatedOptions ) { - resize = true; - } - if ( key in resizableRelatedOptions ) { - resizableOptions[ key ] = value; - } - }); - - if ( resize ) { - this._size(); - } - if ( this.uiDialog.is( ":data(resizable)" ) ) { - this.uiDialog.resizable( "option", resizableOptions ); - } - }, - - _setOption: function( key, value ) { - var isDraggable, isResizable, - uiDialog = this.uiDialog; - - switch ( key ) { - case "buttons": - this._createButtons( value ); - break; - case "closeText": - // ensure that we always pass a string - this.uiDialogTitlebarCloseText.text( "" + value ); - break; - case "dialogClass": - uiDialog - .removeClass( this.options.dialogClass ) - .addClass( uiDialogClasses + value ); - break; - case "disabled": - if ( value ) { - uiDialog.addClass( "ui-dialog-disabled" ); - } else { - uiDialog.removeClass( "ui-dialog-disabled" ); - } - break; - case "draggable": - isDraggable = uiDialog.is( ":data(draggable)" ); - if ( isDraggable && !value ) { - uiDialog.draggable( "destroy" ); - } - - if ( !isDraggable && value ) { - this._makeDraggable(); - } - break; - case "position": - this._position( value ); - break; - case "resizable": - // currently resizable, becoming non-resizable - isResizable = uiDialog.is( ":data(resizable)" ); - if ( isResizable && !value ) { - uiDialog.resizable( "destroy" ); - } - - // currently resizable, changing handles - if ( isResizable && typeof value === "string" ) { - uiDialog.resizable( "option", "handles", value ); - } - - // currently non-resizable, becoming resizable - if ( !isResizable && value !== false ) { - this._makeResizable( value ); - } - break; - case "title": - // convert whatever was passed in o a string, for html() to not throw up - $( ".ui-dialog-title", this.uiDialogTitlebar ) - .html( "" + ( value || " " ) ); - break; - } - - this._super( key, value ); - }, - - _size: function() { - /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content - * divs will both have width and height set, so we need to reset them - */ - var nonContentHeight, minContentHeight, autoHeight, - options = this.options, - isVisible = this.uiDialog.is( ":visible" ); - - // reset content sizing - this.element.show().css({ - width: "auto", - minHeight: 0, - height: 0 - }); - - if ( options.minWidth > options.width ) { - options.width = options.minWidth; - } - - // reset wrapper sizing - // determine the height of all the non-content elements - nonContentHeight = this.uiDialog.css({ - height: "auto", - width: options.width - }) - .outerHeight(); - minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); - - if ( options.height === "auto" ) { - // only needed for IE6 support - if ( $.support.minHeight ) { - this.element.css({ - minHeight: minContentHeight, - height: "auto" - }); - } else { - this.uiDialog.show(); - autoHeight = this.element.css( "height", "auto" ).height(); - if ( !isVisible ) { - this.uiDialog.hide(); - } - this.element.height( Math.max( autoHeight, minContentHeight ) ); - } - } else { - this.element.height( Math.max( options.height - nonContentHeight, 0 ) ); - } - - if (this.uiDialog.is( ":data(resizable)" ) ) { - this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); - } - } -}); - -$.extend($.ui.dialog, { - uuid: 0, - maxZ: 0, - - getTitleId: function($el) { - var id = $el.attr( "id" ); - if ( !id ) { - this.uuid += 1; - id = this.uuid; - } - return "ui-dialog-title-" + id; - }, - - overlay: function( dialog ) { - this.$el = $.ui.dialog.overlay.create( dialog ); - } -}); - -$.extend( $.ui.dialog.overlay, { - instances: [], - // reuse old instances due to IE memory leak with alpha transparency (see #5185) - oldInstances: [], - maxZ: 0, - events: $.map( - "focus,mousedown,mouseup,keydown,keypress,click".split( "," ), - function( event ) { - return event + ".dialog-overlay"; - } - ).join( " " ), - create: function( dialog ) { - if ( this.instances.length === 0 ) { - // prevent use of anchors and inputs - // we use a setTimeout in case the overlay is created from an - // event that we're going to be cancelling (see #2804) - setTimeout(function() { - // handle $(el).dialog().dialog('close') (see #4065) - if ( $.ui.dialog.overlay.instances.length ) { - $( document ).bind( $.ui.dialog.overlay.events, function( event ) { - // stop events if the z-index of the target is < the z-index of the overlay - // we cannot return true when we don't want to cancel the event (#3523) - if ( $( event.target ).zIndex() < $.ui.dialog.overlay.maxZ ) { - return false; - } - }); - } - }, 1 ); - - // handle window resize - $( window ).bind( "resize.dialog-overlay", $.ui.dialog.overlay.resize ); - } - - var $el = ( this.oldInstances.pop() || $( "<div>" ).addClass( "ui-widget-overlay" ) ); - - // allow closing by pressing the escape key - $( document ).bind( "keydown.dialog-overlay", function( event ) { - var instances = $.ui.dialog.overlay.instances; - // only react to the event if we're the top overlay - if ( instances.length !== 0 && instances[ instances.length - 1 ] === $el && - dialog.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && - event.keyCode === $.ui.keyCode.ESCAPE ) { - - dialog.close( event ); - event.preventDefault(); - } - }); - - $el.appendTo( document.body ).css({ - width: this.width(), - height: this.height() - }); - - if ( $.fn.bgiframe ) { - $el.bgiframe(); - } - - this.instances.push( $el ); - return $el; - }, - - destroy: function( $el ) { - var indexOf = $.inArray( $el, this.instances ), - maxZ = 0; - - if ( indexOf !== -1 ) { - this.oldInstances.push( this.instances.splice( indexOf, 1 )[ 0 ] ); - } - - if ( this.instances.length === 0 ) { - $( [ document, window ] ).unbind( ".dialog-overlay" ); - } - - $el.height( 0 ).width( 0 ).remove(); - - // adjust the maxZ to allow other modal dialogs to continue to work (see #4309) - $.each( this.instances, function() { - maxZ = Math.max( maxZ, this.css( "z-index" ) ); - }); - this.maxZ = maxZ; - }, - - height: function() { - var scrollHeight, - offsetHeight; - // handle IE - if ( $.ui.ie ) { - scrollHeight = Math.max( - document.documentElement.scrollHeight, - document.body.scrollHeight - ); - offsetHeight = Math.max( - document.documentElement.offsetHeight, - document.body.offsetHeight - ); - - if ( scrollHeight < offsetHeight ) { - return $( window ).height() + "px"; - } else { - return scrollHeight + "px"; - } - // handle "good" browsers - } else { - return $( document ).height() + "px"; - } - }, - - width: function() { - var scrollWidth, - offsetWidth; - // handle IE - if ( $.ui.ie ) { - scrollWidth = Math.max( - document.documentElement.scrollWidth, - document.body.scrollWidth - ); - offsetWidth = Math.max( - document.documentElement.offsetWidth, - document.body.offsetWidth - ); - - if ( scrollWidth < offsetWidth ) { - return $( window ).width() + "px"; - } else { - return scrollWidth + "px"; - } - // handle "good" browsers - } else { - return $( document ).width() + "px"; - } - }, - - resize: function() { - /* If the dialog is draggable and the user drags it past the - * right edge of the window, the document becomes wider so we - * need to stretch the overlay. If the user then drags the - * dialog back to the left, the document will become narrower, - * so we need to shrink the overlay to the appropriate size. - * This is handled by shrinking the overlay before setting it - * to the full document size. - */ - var $overlays = $( [] ); - $.each( $.ui.dialog.overlay.instances, function() { - $overlays = $overlays.add( this ); - }); - - $overlays.css({ - width: 0, - height: 0 - }).css({ - width: $.ui.dialog.overlay.width(), - height: $.ui.dialog.overlay.height() - }); - } -}); - -$.extend( $.ui.dialog.overlay.prototype, { - destroy: function() { - $.ui.dialog.overlay.destroy( this.$el ); - } -}); - -}( jQuery ) ); - -(function( $, undefined ) { - -var rvertical = /up|down|vertical/, - rpositivemotion = /up|left|vertical|horizontal/; - -$.effects.effect.blind = function( o, done ) { - // Create element - var el = $( this ), - props = [ "position", "top", "bottom", "left", "right", "height", "width" ], - mode = $.effects.setMode( el, o.mode || "hide" ), - direction = o.direction || "up", - vertical = rvertical.test( direction ), - ref = vertical ? "height" : "width", - ref2 = vertical ? "top" : "left", - motion = rpositivemotion.test( direction ), - animation = {}, - show = mode === "show", - wrapper, distance, margin; - - // if already wrapped, the wrapper's properties are my property. #6245 - if ( el.parent().is( ".ui-effects-wrapper" ) ) { - $.effects.save( el.parent(), props ); - } else { - $.effects.save( el, props ); - } - el.show(); - wrapper = $.effects.createWrapper( el ).css({ - overflow: "hidden" - }); - - distance = wrapper[ ref ](); - margin = parseFloat( wrapper.css( ref2 ) ) || 0; - - animation[ ref ] = show ? distance : 0; - if ( !motion ) { - el - .css( vertical ? "bottom" : "right", 0 ) - .css( vertical ? "top" : "left", "auto" ) - .css({ position: "absolute" }); - - animation[ ref2 ] = show ? margin : distance + margin; - } - - // start at 0 if we are showing - if ( show ) { - wrapper.css( ref, 0 ); - if ( ! motion ) { - wrapper.css( ref2, margin + distance ); - } - } - - // Animate - wrapper.animate( animation, { - duration: o.duration, - easing: o.easing, - queue: false, - complete: function() { - if ( mode === "hide" ) { - el.hide(); - } - $.effects.restore( el, props ); - $.effects.removeWrapper( el ); - done(); - } - }); - -}; - -})(jQuery); - -(function( $, undefined ) { - -$.effects.effect.bounce = function( o, done ) { - var el = $( this ), - props = [ "position", "top", "bottom", "left", "right", "height", "width" ], - - // defaults: - mode = $.effects.setMode( el, o.mode || "effect" ), - hide = mode === "hide", - show = mode === "show", - direction = o.direction || "up", - distance = o.distance, - times = o.times || 5, - - // number of internal animations - anims = times * 2 + ( show || hide ? 1 : 0 ), - speed = o.duration / anims, - easing = o.easing, - - // utility: - ref = ( direction === "up" || direction === "down" ) ? "top" : "left", - motion = ( direction === "up" || direction === "left" ), - i, - upAnim, - downAnim, - - // we will need to re-assemble the queue to stack our animations in place - queue = el.queue(), - queuelen = queue.length; - - // Avoid touching opacity to prevent clearType and PNG issues in IE - if ( show || hide ) { - props.push( "opacity" ); - } - - $.effects.save( el, props ); - el.show(); - $.effects.createWrapper( el ); // Create Wrapper - - // default distance for the BIGGEST bounce is the outer Distance / 3 - if ( !distance ) { - distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; - } - - if ( show ) { - downAnim = { opacity: 1 }; - downAnim[ ref ] = 0; - - // if we are showing, force opacity 0 and set the initial position - // then do the "first" animation - el.css( "opacity", 0 ) - .css( ref, motion ? -distance * 2 : distance * 2 ) - .animate( downAnim, speed, easing ); - } - - // start at the smallest distance if we are hiding - if ( hide ) { - distance = distance / Math.pow( 2, times - 1 ); - } - - downAnim = {}; - downAnim[ ref ] = 0; - // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here - for ( i = 0; i < times; i++ ) { - upAnim = {}; - upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; - - el.animate( upAnim, speed, easing ) - .animate( downAnim, speed, easing ); - - distance = hide ? distance * 2 : distance / 2; - } - - // Last Bounce when Hiding - if ( hide ) { - upAnim = { opacity: 0 }; - upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; - - el.animate( upAnim, speed, easing ); - } - - el.queue(function() { - if ( hide ) { - el.hide(); - } - $.effects.restore( el, props ); - $.effects.removeWrapper( el ); - done(); - }); - - // inject all the animations we just queued to be first in line (after "inprogress") - if ( queuelen > 1) { - queue.splice.apply( queue, - [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); - } - el.dequeue(); - -}; - -})(jQuery); - -(function( $, undefined ) { - -$.effects.effect.clip = function( o, done ) { - // Create element - var el = $( this ), - props = [ "position", "top", "bottom", "left", "right", "height", "width" ], - mode = $.effects.setMode( el, o.mode || "hide" ), - show = mode === "show", - direction = o.direction || "vertical", - vert = direction === "vertical", - size = vert ? "height" : "width", - position = vert ? "top" : "left", - animation = {}, - wrapper, animate, distance; - - // Save & Show - $.effects.save( el, props ); - el.show(); - - // Create Wrapper - wrapper = $.effects.createWrapper( el ).css({ - overflow: "hidden" - }); - animate = ( el[0].tagName === "IMG" ) ? wrapper : el; - distance = animate[ size ](); - - // Shift - if ( show ) { - animate.css( size, 0 ); - animate.css( position, distance / 2 ); - } - - // Create Animation Object: - animation[ size ] = show ? distance : 0; - animation[ position ] = show ? 0 : distance / 2; - - // Animate - animate.animate( animation, { - queue: false, - duration: o.duration, - easing: o.easing, - complete: function() { - if ( !show ) { - el.hide(); - } - $.effects.restore( el, props ); - $.effects.removeWrapper( el ); - done(); - } - }); - -}; - -})(jQuery); - -(function( $, undefined ) { - -$.effects.effect.drop = function( o, done ) { - - var el = $( this ), - props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ], - mode = $.effects.setMode( el, o.mode || "hide" ), - show = mode === "show", - direction = o.direction || "left", - ref = ( direction === "up" || direction === "down" ) ? "top" : "left", - motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg", - animation = { - opacity: show ? 1 : 0 - }, - distance; - - // Adjust - $.effects.save( el, props ); - el.show(); - $.effects.createWrapper( el ); - - distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2; - - if ( show ) { - el - .css( "opacity", 0 ) - .css( ref, motion === "pos" ? -distance : distance ); - } - - // Animation - animation[ ref ] = ( show ? - ( motion === "pos" ? "+=" : "-=" ) : - ( motion === "pos" ? "-=" : "+=" ) ) + - distance; - - // Animate - el.animate( animation, { - queue: false, - duration: o.duration, - easing: o.easing, - complete: function() { - if ( mode === "hide" ) { - el.hide(); - } - $.effects.restore( el, props ); - $.effects.removeWrapper( el ); - done(); - } - }); -}; - -})(jQuery); - -(function( $, undefined ) { - -$.effects.effect.explode = function( o, done ) { - - var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3, - cells = rows, - el = $( this ), - mode = $.effects.setMode( el, o.mode || "hide" ), - show = mode === "show", - - // show and then visibility:hidden the element before calculating offset - offset = el.show().css( "visibility", "hidden" ).offset(), - - // width and height of a piece - width = Math.ceil( el.outerWidth() / cells ), - height = Math.ceil( el.outerHeight() / rows ), - pieces = [], - - // loop - i, j, left, top, mx, my; - - // children animate complete: - function childComplete() { - pieces.push( this ); - if ( pieces.length === rows * cells ) { - animComplete(); - } - } - - // clone the element for each row and cell. - for( i = 0; i < rows ; i++ ) { // ===> - top = offset.top + i * height; - my = i - ( rows - 1 ) / 2 ; - - for( j = 0; j < cells ; j++ ) { // ||| - left = offset.left + j * width; - mx = j - ( cells - 1 ) / 2 ; - - // Create a clone of the now hidden main element that will be absolute positioned - // within a wrapper div off the -left and -top equal to size of our pieces - el - .clone() - .appendTo( "body" ) - .wrap( "<div></div>" ) - .css({ - position: "absolute", - visibility: "visible", - left: -j * width, - top: -i * height - }) - - // select the wrapper - make it overflow: hidden and absolute positioned based on - // where the original was located +left and +top equal to the size of pieces - .parent() - .addClass( "ui-effects-explode" ) - .css({ - position: "absolute", - overflow: "hidden", - width: width, - height: height, - left: left + ( show ? mx * width : 0 ), - top: top + ( show ? my * height : 0 ), - opacity: show ? 0 : 1 - }).animate({ - left: left + ( show ? 0 : mx * width ), - top: top + ( show ? 0 : my * height ), - opacity: show ? 1 : 0 - }, o.duration || 500, o.easing, childComplete ); - } - } - - function animComplete() { - el.css({ - visibility: "visible" - }); - $( pieces ).remove(); - if ( !show ) { - el.hide(); - } - done(); - } -}; - -})(jQuery); - -(function( $, undefined ) { - -$.effects.effect.fade = function( o, done ) { - var el = $( this ), - mode = $.effects.setMode( el, o.mode || "toggle" ); - - el.animate({ - opacity: mode - }, { - queue: false, - duration: o.duration, - easing: o.easing, - complete: done - }); -}; - -})( jQuery ); - -(function( $, undefined ) { - -$.effects.effect.fold = function( o, done ) { - - // Create element - var el = $( this ), - props = [ "position", "top", "bottom", "left", "right", "height", "width" ], - mode = $.effects.setMode( el, o.mode || "hide" ), - show = mode === "show", - hide = mode === "hide", - size = o.size || 15, - percent = /([0-9]+)%/.exec( size ), - horizFirst = !!o.horizFirst, - widthFirst = show !== horizFirst, - ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ], - duration = o.duration / 2, - wrapper, distance, - animation1 = {}, - animation2 = {}; - - $.effects.save( el, props ); - el.show(); - - // Create Wrapper - wrapper = $.effects.createWrapper( el ).css({ - overflow: "hidden" - }); - distance = widthFirst ? - [ wrapper.width(), wrapper.height() ] : - [ wrapper.height(), wrapper.width() ]; - - if ( percent ) { - size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; - } - if ( show ) { - wrapper.css( horizFirst ? { - height: 0, - width: size - } : { - height: size, - width: 0 - }); - } - - // Animation - animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size; - animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0; - - // Animate - wrapper - .animate( animation1, duration, o.easing ) - .animate( animation2, duration, o.easing, function() { - if ( hide ) { - el.hide(); - } - $.effects.restore( el, props ); - $.effects.removeWrapper( el ); - done(); - }); - -}; - -})(jQuery); - -(function( $, undefined ) { - -$.effects.effect.highlight = function( o, done ) { - var elem = $( this ), - props = [ "backgroundImage", "backgroundColor", "opacity" ], - mode = $.effects.setMode( elem, o.mode || "show" ), - animation = { - backgroundColor: elem.css( "backgroundColor" ) - }; - - if (mode === "hide") { - animation.opacity = 0; - } - - $.effects.save( elem, props ); - - elem - .show() - .css({ - backgroundImage: "none", - backgroundColor: o.color || "#ffff99" - }) - .animate( animation, { - queue: false, - duration: o.duration, - easing: o.easing, - complete: function() { - if ( mode === "hide" ) { - elem.hide(); - } - $.effects.restore( elem, props ); - done(); - } - }); -}; - -})(jQuery); - -(function( $, undefined ) { - -$.effects.effect.pulsate = function( o, done ) { - var elem = $( this ), - mode = $.effects.setMode( elem, o.mode || "show" ), - show = mode === "show", - hide = mode === "hide", - showhide = ( show || mode === "hide" ), - - // showing or hiding leaves of the "last" animation - anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), - duration = o.duration / anims, - animateTo = 0, - queue = elem.queue(), - queuelen = queue.length, - i; - - if ( show || !elem.is(":visible")) { - elem.css( "opacity", 0 ).show(); - animateTo = 1; - } - - // anims - 1 opacity "toggles" - for ( i = 1; i < anims; i++ ) { - elem.animate({ - opacity: animateTo - }, duration, o.easing ); - animateTo = 1 - animateTo; - } - - elem.animate({ - opacity: animateTo - }, duration, o.easing); - - elem.queue(function() { - if ( hide ) { - elem.hide(); - } - done(); - }); - - // We just queued up "anims" animations, we need to put them next in the queue - if ( queuelen > 1 ) { - queue.splice.apply( queue, - [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); - } - elem.dequeue(); -}; - -})(jQuery); - -(function( $, undefined ) { - -$.effects.effect.puff = function( o, done ) { - var elem = $( this ), - mode = $.effects.setMode( elem, o.mode || "hide" ), - hide = mode === "hide", - percent = parseInt( o.percent, 10 ) || 150, - factor = percent / 100, - original = { - height: elem.height(), - width: elem.width(), - outerHeight: elem.outerHeight(), - outerWidth: elem.outerWidth() - }; - - $.extend( o, { - effect: "scale", - queue: false, - fade: true, - mode: mode, - complete: done, - percent: hide ? percent : 100, - from: hide ? - original : - { - height: original.height * factor, - width: original.width * factor, - outerHeight: original.outerHeight * factor, - outerWidth: original.outerWidth * factor - } - }); - - elem.effect( o ); -}; - -$.effects.effect.scale = function( o, done ) { - - // Create element - var el = $( this ), - options = $.extend( true, {}, o ), - mode = $.effects.setMode( el, o.mode || "effect" ), - percent = parseInt( o.percent, 10 ) || - ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ), - direction = o.direction || "both", - origin = o.origin, - original = { - height: el.height(), - width: el.width(), - outerHeight: el.outerHeight(), - outerWidth: el.outerWidth() - }, - factor = { - y: direction !== "horizontal" ? (percent / 100) : 1, - x: direction !== "vertical" ? (percent / 100) : 1 - }; - - // We are going to pass this effect to the size effect: - options.effect = "size"; - options.queue = false; - options.complete = done; - - // Set default origin and restore for show/hide - if ( mode !== "effect" ) { - options.origin = origin || ["middle","center"]; - options.restore = true; - } - - options.from = o.from || ( mode === "show" ? { - height: 0, - width: 0, - outerHeight: 0, - outerWidth: 0 - } : original ); - options.to = { - height: original.height * factor.y, - width: original.width * factor.x, - outerHeight: original.outerHeight * factor.y, - outerWidth: original.outerWidth * factor.x - }; - - // Fade option to support puff - if ( options.fade ) { - if ( mode === "show" ) { - options.from.opacity = 0; - options.to.opacity = 1; - } - if ( mode === "hide" ) { - options.from.opacity = 1; - options.to.opacity = 0; - } - } - - // Animate - el.effect( options ); - -}; - -$.effects.effect.size = function( o, done ) { - - // Create element - var original, baseline, factor, - el = $( this ), - props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ], - - // Always restore - props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ], - - // Copy for children - props2 = [ "width", "height", "overflow" ], - cProps = [ "fontSize" ], - vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], - hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], - - // Set options - mode = $.effects.setMode( el, o.mode || "effect" ), - restore = o.restore || mode !== "effect", - scale = o.scale || "both", - origin = o.origin || [ "middle", "center" ], - position = el.css( "position" ), - props = restore ? props0 : props1, - zero = { - height: 0, - width: 0, - outerHeight: 0, - outerWidth: 0 - }; - - if ( mode === "show" ) { - el.show(); - } - original = { - height: el.height(), - width: el.width(), - outerHeight: el.outerHeight(), - outerWidth: el.outerWidth() - }; - - if ( o.mode === "toggle" && mode === "show" ) { - el.from = o.to || zero; - el.to = o.from || original; - } else { - el.from = o.from || ( mode === "show" ? zero : original ); - el.to = o.to || ( mode === "hide" ? zero : original ); - } - - // Set scaling factor - factor = { - from: { - y: el.from.height / original.height, - x: el.from.width / original.width - }, - to: { - y: el.to.height / original.height, - x: el.to.width / original.width - } - }; - - // Scale the css box - if ( scale === "box" || scale === "both" ) { - - // Vertical props scaling - if ( factor.from.y !== factor.to.y ) { - props = props.concat( vProps ); - el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from ); - el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to ); - } - - // Horizontal props scaling - if ( factor.from.x !== factor.to.x ) { - props = props.concat( hProps ); - el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from ); - el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to ); - } - } - - // Scale the content - if ( scale === "content" || scale === "both" ) { - - // Vertical props scaling - if ( factor.from.y !== factor.to.y ) { - props = props.concat( cProps ).concat( props2 ); - el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from ); - el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to ); - } - } - - $.effects.save( el, props ); - el.show(); - $.effects.createWrapper( el ); - el.css( "overflow", "hidden" ).css( el.from ); - - // Adjust - if (origin) { // Calculate baseline shifts - baseline = $.effects.getBaseline( origin, original ); - el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y; - el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x; - el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y; - el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x; - } - el.css( el.from ); // set top & left - - // Animate - if ( scale === "content" || scale === "both" ) { // Scale the children - - // Add margins/font-size - vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps); - hProps = hProps.concat([ "marginLeft", "marginRight" ]); - props2 = props0.concat(vProps).concat(hProps); - - el.find( "*[width]" ).each( function(){ - var child = $( this ), - c_original = { - height: child.height(), - width: child.width(), - outerHeight: child.outerHeight(), - outerWidth: child.outerWidth() - }; - if (restore) { - $.effects.save(child, props2); - } - - child.from = { - height: c_original.height * factor.from.y, - width: c_original.width * factor.from.x, - outerHeight: c_original.outerHeight * factor.from.y, - outerWidth: c_original.outerWidth * factor.from.x - }; - child.to = { - height: c_original.height * factor.to.y, - width: c_original.width * factor.to.x, - outerHeight: c_original.height * factor.to.y, - outerWidth: c_original.width * factor.to.x - }; - - // Vertical props scaling - if ( factor.from.y !== factor.to.y ) { - child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from ); - child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to ); - } - - // Horizontal props scaling - if ( factor.from.x !== factor.to.x ) { - child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from ); - child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to ); - } - - // Animate children - child.css( child.from ); - child.animate( child.to, o.duration, o.easing, function() { - - // Restore children - if ( restore ) { - $.effects.restore( child, props2 ); - } - }); - }); - } - - // Animate - el.animate( el.to, { - queue: false, - duration: o.duration, - easing: o.easing, - complete: function() { - if ( el.to.opacity === 0 ) { - el.css( "opacity", el.from.opacity ); - } - if( mode === "hide" ) { - el.hide(); - } - $.effects.restore( el, props ); - if ( !restore ) { - - // we need to calculate our new positioning based on the scaling - if ( position === "static" ) { - el.css({ - position: "relative", - top: el.to.top, - left: el.to.left - }); - } else { - $.each([ "top", "left" ], function( idx, pos ) { - el.css( pos, function( _, str ) { - var val = parseInt( str, 10 ), - toRef = idx ? el.to.left : el.to.top; - - // if original was "auto", recalculate the new value from wrapper - if ( str === "auto" ) { - return toRef + "px"; - } - - return val + toRef + "px"; - }); - }); - } - } - - $.effects.removeWrapper( el ); - done(); - } - }); - -}; - -})(jQuery); - -(function( $, undefined ) { - -$.effects.effect.shake = function( o, done ) { - - var el = $( this ), - props = [ "position", "top", "bottom", "left", "right", "height", "width" ], - mode = $.effects.setMode( el, o.mode || "effect" ), - direction = o.direction || "left", - distance = o.distance || 20, - times = o.times || 3, - anims = times * 2 + 1, - speed = Math.round(o.duration/anims), - ref = (direction === "up" || direction === "down") ? "top" : "left", - positiveMotion = (direction === "up" || direction === "left"), - animation = {}, - animation1 = {}, - animation2 = {}, - i, - - // we will need to re-assemble the queue to stack our animations in place - queue = el.queue(), - queuelen = queue.length; - - $.effects.save( el, props ); - el.show(); - $.effects.createWrapper( el ); - - // Animation - animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; - animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; - animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; - - // Animate - el.animate( animation, speed, o.easing ); - - // Shakes - for ( i = 1; i < times; i++ ) { - el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing ); - } - el - .animate( animation1, speed, o.easing ) - .animate( animation, speed / 2, o.easing ) - .queue(function() { - if ( mode === "hide" ) { - el.hide(); - } - $.effects.restore( el, props ); - $.effects.removeWrapper( el ); - done(); - }); - - // inject all the animations we just queued to be first in line (after "inprogress") - if ( queuelen > 1) { - queue.splice.apply( queue, - [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); - } - el.dequeue(); - -}; - -})(jQuery); - -(function( $, undefined ) { - -$.effects.effect.slide = function( o, done ) { - - // Create element - var el = $( this ), - props = [ "position", "top", "bottom", "left", "right", "width", "height" ], - mode = $.effects.setMode( el, o.mode || "show" ), - show = mode === "show", - direction = o.direction || "left", - ref = (direction === "up" || direction === "down") ? "top" : "left", - positiveMotion = (direction === "up" || direction === "left"), - distance, - animation = {}; - - // Adjust - $.effects.save( el, props ); - el.show(); - distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ); - - $.effects.createWrapper( el ).css({ - overflow: "hidden" - }); - - if ( show ) { - el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance ); - } - - // Animation - animation[ ref ] = ( show ? - ( positiveMotion ? "+=" : "-=") : - ( positiveMotion ? "-=" : "+=")) + - distance; - - // Animate - el.animate( animation, { - queue: false, - duration: o.duration, - easing: o.easing, - complete: function() { - if ( mode === "hide" ) { - el.hide(); - } - $.effects.restore( el, props ); - $.effects.removeWrapper( el ); - done(); - } - }); -}; - -})(jQuery); - -(function( $, undefined ) { - -$.effects.effect.transfer = function( o, done ) { - var elem = $( this ), - target = $( o.to ), - targetFixed = target.css( "position" ) === "fixed", - body = $("body"), - fixTop = targetFixed ? body.scrollTop() : 0, - fixLeft = targetFixed ? body.scrollLeft() : 0, - endPosition = target.offset(), - animation = { - top: endPosition.top - fixTop , - left: endPosition.left - fixLeft , - height: target.innerHeight(), - width: target.innerWidth() - }, - startPosition = elem.offset(), - transfer = $( '<div class="ui-effects-transfer"></div>' ) - .appendTo( document.body ) - .addClass( o.className ) - .css({ - top: startPosition.top - fixTop , - left: startPosition.left - fixLeft , - height: elem.innerHeight(), - width: elem.innerWidth(), - position: targetFixed ? "fixed" : "absolute" - }) - .animate( animation, o.duration, o.easing, function() { - transfer.remove(); - done(); - }); -}; - -})(jQuery); - -(function( $, undefined ) { - -var mouseHandled = false; - -$.widget( "ui.menu", { - version: "1.9.2", - defaultElement: "<ul>", - delay: 300, - options: { - icons: { - submenu: "ui-icon-carat-1-e" - }, - menus: "ul", - position: { - my: "left top", - at: "right top" - }, - role: "menu", - - // callbacks - blur: null, - focus: null, - select: null - }, - - _create: function() { - this.activeMenu = this.element; - this.element - .uniqueId() - .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) - .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ) - .attr({ - role: this.options.role, - tabIndex: 0 - }) - // need to catch all clicks on disabled menu - // not possible through _on - .bind( "click" + this.eventNamespace, $.proxy(function( event ) { - if ( this.options.disabled ) { - event.preventDefault(); - } - }, this )); - - if ( this.options.disabled ) { - this.element - .addClass( "ui-state-disabled" ) - .attr( "aria-disabled", "true" ); - } - - this._on({ - // Prevent focus from sticking to links inside menu after clicking - // them (focus should always stay on UL during navigation). - "mousedown .ui-menu-item > a": function( event ) { - event.preventDefault(); - }, - "click .ui-state-disabled > a": function( event ) { - event.preventDefault(); - }, - "click .ui-menu-item:has(a)": function( event ) { - var target = $( event.target ).closest( ".ui-menu-item" ); - if ( !mouseHandled && target.not( ".ui-state-disabled" ).length ) { - mouseHandled = true; - - this.select( event ); - // Open submenu on click - if ( target.has( ".ui-menu" ).length ) { - this.expand( event ); - } else if ( !this.element.is( ":focus" ) ) { - // Redirect focus to the menu - this.element.trigger( "focus", [ true ] ); - - // If the active item is on the top level, let it stay active. - // Otherwise, blur the active item since it is no longer visible. - if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { - clearTimeout( this.timer ); - } - } - } - }, - "mouseenter .ui-menu-item": function( event ) { - var target = $( event.currentTarget ); - // Remove ui-state-active class from siblings of the newly focused menu item - // to avoid a jump caused by adjacent elements both having a class with a border - target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" ); - this.focus( event, target ); - }, - mouseleave: "collapseAll", - "mouseleave .ui-menu": "collapseAll", - focus: function( event, keepActiveItem ) { - // If there's already an active item, keep it active - // If not, activate the first item - var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 ); - - if ( !keepActiveItem ) { - this.focus( event, item ); - } - }, - blur: function( event ) { - this._delay(function() { - if ( !$.contains( this.element[0], this.document[0].activeElement ) ) { - this.collapseAll( event ); - } - }); - }, - keydown: "_keydown" - }); - - this.refresh(); - - // Clicks outside of a menu collapse any open menus - this._on( this.document, { - click: function( event ) { - if ( !$( event.target ).closest( ".ui-menu" ).length ) { - this.collapseAll( event ); - } - - // Reset the mouseHandled flag - mouseHandled = false; - } - }); - }, - - _destroy: function() { - // Destroy (sub)menus - this.element - .removeAttr( "aria-activedescendant" ) - .find( ".ui-menu" ).andSelf() - .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" ) - .removeAttr( "role" ) - .removeAttr( "tabIndex" ) - .removeAttr( "aria-labelledby" ) - .removeAttr( "aria-expanded" ) - .removeAttr( "aria-hidden" ) - .removeAttr( "aria-disabled" ) - .removeUniqueId() - .show(); - - // Destroy menu items - this.element.find( ".ui-menu-item" ) - .removeClass( "ui-menu-item" ) - .removeAttr( "role" ) - .removeAttr( "aria-disabled" ) - .children( "a" ) - .removeUniqueId() - .removeClass( "ui-corner-all ui-state-hover" ) - .removeAttr( "tabIndex" ) - .removeAttr( "role" ) - .removeAttr( "aria-haspopup" ) - .children().each( function() { - var elem = $( this ); - if ( elem.data( "ui-menu-submenu-carat" ) ) { - elem.remove(); - } - }); - - // Destroy menu dividers - this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" ); - }, - - _keydown: function( event ) { - var match, prev, character, skip, regex, - preventDefault = true; - - function escape( value ) { - return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); - } - - switch ( event.keyCode ) { - case $.ui.keyCode.PAGE_UP: - this.previousPage( event ); - break; - case $.ui.keyCode.PAGE_DOWN: - this.nextPage( event ); - break; - case $.ui.keyCode.HOME: - this._move( "first", "first", event ); - break; - case $.ui.keyCode.END: - this._move( "last", "last", event ); - break; - case $.ui.keyCode.UP: - this.previous( event ); - break; - case $.ui.keyCode.DOWN: - this.next( event ); - break; - case $.ui.keyCode.LEFT: - this.collapse( event ); - break; - case $.ui.keyCode.RIGHT: - if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { - this.expand( event ); - } - break; - case $.ui.keyCode.ENTER: - case $.ui.keyCode.SPACE: - this._activate( event ); - break; - case $.ui.keyCode.ESCAPE: - this.collapse( event ); - break; - default: - preventDefault = false; - prev = this.previousFilter || ""; - character = String.fromCharCode( event.keyCode ); - skip = false; - - clearTimeout( this.filterTimer ); - - if ( character === prev ) { - skip = true; - } else { - character = prev + character; - } - - regex = new RegExp( "^" + escape( character ), "i" ); - match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { - return regex.test( $( this ).children( "a" ).text() ); - }); - match = skip && match.index( this.active.next() ) !== -1 ? - this.active.nextAll( ".ui-menu-item" ) : - match; - - // If no matches on the current filter, reset to the last character pressed - // to move down the menu to the first item that starts with that character - if ( !match.length ) { - character = String.fromCharCode( event.keyCode ); - regex = new RegExp( "^" + escape( character ), "i" ); - match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { - return regex.test( $( this ).children( "a" ).text() ); - }); - } - - if ( match.length ) { - this.focus( event, match ); - if ( match.length > 1 ) { - this.previousFilter = character; - this.filterTimer = this._delay(function() { - delete this.previousFilter; - }, 1000 ); - } else { - delete this.previousFilter; - } - } else { - delete this.previousFilter; - } - } - - if ( preventDefault ) { - event.preventDefault(); - } - }, - - _activate: function( event ) { - if ( !this.active.is( ".ui-state-disabled" ) ) { - if ( this.active.children( "a[aria-haspopup='true']" ).length ) { - this.expand( event ); - } else { - this.select( event ); - } - } - }, - - refresh: function() { - var menus, - icon = this.options.icons.submenu, - submenus = this.element.find( this.options.menus ); - - // Initialize nested menus - submenus.filter( ":not(.ui-menu)" ) - .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) - .hide() - .attr({ - role: this.options.role, - "aria-hidden": "true", - "aria-expanded": "false" - }) - .each(function() { - var menu = $( this ), - item = menu.prev( "a" ), - submenuCarat = $( "<span>" ) - .addClass( "ui-menu-icon ui-icon " + icon ) - .data( "ui-menu-submenu-carat", true ); - - item - .attr( "aria-haspopup", "true" ) - .prepend( submenuCarat ); - menu.attr( "aria-labelledby", item.attr( "id" ) ); - }); - - menus = submenus.add( this.element ); - - // Don't refresh list items that are already adapted - menus.children( ":not(.ui-menu-item):has(a)" ) - .addClass( "ui-menu-item" ) - .attr( "role", "presentation" ) - .children( "a" ) - .uniqueId() - .addClass( "ui-corner-all" ) - .attr({ - tabIndex: -1, - role: this._itemRole() - }); - - // Initialize unlinked menu-items containing spaces and/or dashes only as dividers - menus.children( ":not(.ui-menu-item)" ).each(function() { - var item = $( this ); - // hyphen, em dash, en dash - if ( !/[^\-—–\s]/.test( item.text() ) ) { - item.addClass( "ui-widget-content ui-menu-divider" ); - } - }); - - // Add aria-disabled attribute to any disabled menu item - menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); - - // If the active item has been removed, blur the menu - if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { - this.blur(); - } - }, - - _itemRole: function() { - return { - menu: "menuitem", - listbox: "option" - }[ this.options.role ]; - }, - - focus: function( event, item ) { - var nested, focused; - this.blur( event, event && event.type === "focus" ); - - this._scrollIntoView( item ); - - this.active = item.first(); - focused = this.active.children( "a" ).addClass( "ui-state-focus" ); - // Only update aria-activedescendant if there's a role - // otherwise we assume focus is managed elsewhere - if ( this.options.role ) { - this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); - } - - // Highlight active parent menu item, if any - this.active - .parent() - .closest( ".ui-menu-item" ) - .children( "a:first" ) - .addClass( "ui-state-active" ); - - if ( event && event.type === "keydown" ) { - this._close(); - } else { - this.timer = this._delay(function() { - this._close(); - }, this.delay ); - } - - nested = item.children( ".ui-menu" ); - if ( nested.length && ( /^mouse/.test( event.type ) ) ) { - this._startOpening(nested); - } - this.activeMenu = item.parent(); - - this._trigger( "focus", event, { item: item } ); - }, - - _scrollIntoView: function( item ) { - var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; - if ( this._hasScroll() ) { - borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0; - paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0; - offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; - scroll = this.activeMenu.scrollTop(); - elementHeight = this.activeMenu.height(); - itemHeight = item.height(); - - if ( offset < 0 ) { - this.activeMenu.scrollTop( scroll + offset ); - } else if ( offset + itemHeight > elementHeight ) { - this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); - } - } - }, - - blur: function( event, fromFocus ) { - if ( !fromFocus ) { - clearTimeout( this.timer ); - } - - if ( !this.active ) { - return; - } - - this.active.children( "a" ).removeClass( "ui-state-focus" ); - this.active = null; - - this._trigger( "blur", event, { item: this.active } ); - }, - - _startOpening: function( submenu ) { - clearTimeout( this.timer ); - - // Don't open if already open fixes a Firefox bug that caused a .5 pixel - // shift in the submenu position when mousing over the carat icon - if ( submenu.attr( "aria-hidden" ) !== "true" ) { - return; - } - - this.timer = this._delay(function() { - this._close(); - this._open( submenu ); - }, this.delay ); - }, - - _open: function( submenu ) { - var position = $.extend({ - of: this.active - }, this.options.position ); - - clearTimeout( this.timer ); - this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) - .hide() - .attr( "aria-hidden", "true" ); - - submenu - .show() - .removeAttr( "aria-hidden" ) - .attr( "aria-expanded", "true" ) - .position( position ); - }, - - collapseAll: function( event, all ) { - clearTimeout( this.timer ); - this.timer = this._delay(function() { - // If we were passed an event, look for the submenu that contains the event - var currentMenu = all ? this.element : - $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); - - // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway - if ( !currentMenu.length ) { - currentMenu = this.element; - } - - this._close( currentMenu ); - - this.blur( event ); - this.activeMenu = currentMenu; - }, this.delay ); - }, - - // With no arguments, closes the currently active menu - if nothing is active - // it closes all menus. If passed an argument, it will search for menus BELOW - _close: function( startMenu ) { - if ( !startMenu ) { - startMenu = this.active ? this.active.parent() : this.element; - } - - startMenu - .find( ".ui-menu" ) - .hide() - .attr( "aria-hidden", "true" ) - .attr( "aria-expanded", "false" ) - .end() - .find( "a.ui-state-active" ) - .removeClass( "ui-state-active" ); - }, - - collapse: function( event ) { - var newItem = this.active && - this.active.parent().closest( ".ui-menu-item", this.element ); - if ( newItem && newItem.length ) { - this._close(); - this.focus( event, newItem ); - } - }, - - expand: function( event ) { - var newItem = this.active && - this.active - .children( ".ui-menu " ) - .children( ".ui-menu-item" ) - .first(); - - if ( newItem && newItem.length ) { - this._open( newItem.parent() ); - - // Delay so Firefox will not hide activedescendant change in expanding submenu from AT - this._delay(function() { - this.focus( event, newItem ); - }); - } - }, - - next: function( event ) { - this._move( "next", "first", event ); - }, - - previous: function( event ) { - this._move( "prev", "last", event ); - }, - - isFirstItem: function() { - return this.active && !this.active.prevAll( ".ui-menu-item" ).length; - }, - - isLastItem: function() { - return this.active && !this.active.nextAll( ".ui-menu-item" ).length; - }, - - _move: function( direction, filter, event ) { - var next; - if ( this.active ) { - if ( direction === "first" || direction === "last" ) { - next = this.active - [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) - .eq( -1 ); - } else { - next = this.active - [ direction + "All" ]( ".ui-menu-item" ) - .eq( 0 ); - } - } - if ( !next || !next.length || !this.active ) { - next = this.activeMenu.children( ".ui-menu-item" )[ filter ](); - } - - this.focus( event, next ); - }, - - nextPage: function( event ) { - var item, base, height; - - if ( !this.active ) { - this.next( event ); - return; - } - if ( this.isLastItem() ) { - return; - } - if ( this._hasScroll() ) { - base = this.active.offset().top; - height = this.element.height(); - this.active.nextAll( ".ui-menu-item" ).each(function() { - item = $( this ); - return item.offset().top - base - height < 0; - }); - - this.focus( event, item ); - } else { - this.focus( event, this.activeMenu.children( ".ui-menu-item" ) - [ !this.active ? "first" : "last" ]() ); - } - }, - - previousPage: function( event ) { - var item, base, height; - if ( !this.active ) { - this.next( event ); - return; - } - if ( this.isFirstItem() ) { - return; - } - if ( this._hasScroll() ) { - base = this.active.offset().top; - height = this.element.height(); - this.active.prevAll( ".ui-menu-item" ).each(function() { - item = $( this ); - return item.offset().top - base + height > 0; - }); - - this.focus( event, item ); - } else { - this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() ); - } - }, - - _hasScroll: function() { - return this.element.outerHeight() < this.element.prop( "scrollHeight" ); - }, - - select: function( event ) { - // TODO: It should never be possible to not have an active item at this - // point, but the tests don't trigger mouseenter before click. - this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); - var ui = { item: this.active }; - if ( !this.active.has( ".ui-menu" ).length ) { - this.collapseAll( event, true ); - } - this._trigger( "select", event, ui ); - } -}); - -}( jQuery )); - -(function( $, undefined ) { - -$.ui = $.ui || {}; - -var cachedScrollbarWidth, - max = Math.max, - abs = Math.abs, - round = Math.round, - rhorizontal = /left|center|right/, - rvertical = /top|center|bottom/, - roffset = /[\+\-]\d+%?/, - rposition = /^\w+/, - rpercent = /%$/, - _position = $.fn.position; - -function getOffsets( offsets, width, height ) { - return [ - parseInt( offsets[ 0 ], 10 ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), - parseInt( offsets[ 1 ], 10 ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) - ]; -} -function parseCss( element, property ) { - return parseInt( $.css( element, property ), 10 ) || 0; -} - -$.position = { - scrollbarWidth: function() { - if ( cachedScrollbarWidth !== undefined ) { - return cachedScrollbarWidth; - } - var w1, w2, - div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ), - innerDiv = div.children()[0]; - - $( "body" ).append( div ); - w1 = innerDiv.offsetWidth; - div.css( "overflow", "scroll" ); - - w2 = innerDiv.offsetWidth; - - if ( w1 === w2 ) { - w2 = div[0].clientWidth; - } - - div.remove(); - - return (cachedScrollbarWidth = w1 - w2); - }, - getScrollInfo: function( within ) { - var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ), - overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ), - hasOverflowX = overflowX === "scroll" || - ( overflowX === "auto" && within.width < within.element[0].scrollWidth ), - hasOverflowY = overflowY === "scroll" || - ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); - return { - width: hasOverflowX ? $.position.scrollbarWidth() : 0, - height: hasOverflowY ? $.position.scrollbarWidth() : 0 - }; - }, - getWithinInfo: function( element ) { - var withinElement = $( element || window ), - isWindow = $.isWindow( withinElement[0] ); - return { - element: withinElement, - isWindow: isWindow, - offset: withinElement.offset() || { left: 0, top: 0 }, - scrollLeft: withinElement.scrollLeft(), - scrollTop: withinElement.scrollTop(), - width: isWindow ? withinElement.width() : withinElement.outerWidth(), - height: isWindow ? withinElement.height() : withinElement.outerHeight() - }; - } -}; - -$.fn.position = function( options ) { - if ( !options || !options.of ) { - return _position.apply( this, arguments ); - } - - // make a copy, we don't want to modify arguments - options = $.extend( {}, options ); - - var atOffset, targetWidth, targetHeight, targetOffset, basePosition, - target = $( options.of ), - within = $.position.getWithinInfo( options.within ), - scrollInfo = $.position.getScrollInfo( within ), - targetElem = target[0], - collision = ( options.collision || "flip" ).split( " " ), - offsets = {}; - - if ( targetElem.nodeType === 9 ) { - targetWidth = target.width(); - targetHeight = target.height(); - targetOffset = { top: 0, left: 0 }; - } else if ( $.isWindow( targetElem ) ) { - targetWidth = target.width(); - targetHeight = target.height(); - targetOffset = { top: target.scrollTop(), left: target.scrollLeft() }; - } else if ( targetElem.preventDefault ) { - // force left top to allow flipping - options.at = "left top"; - targetWidth = targetHeight = 0; - targetOffset = { top: targetElem.pageY, left: targetElem.pageX }; - } else { - targetWidth = target.outerWidth(); - targetHeight = target.outerHeight(); - targetOffset = target.offset(); - } - // clone to reuse original targetOffset later - basePosition = $.extend( {}, targetOffset ); - - // force my and at to have valid horizontal and vertical positions - // if a value is missing or invalid, it will be converted to center - $.each( [ "my", "at" ], function() { - var pos = ( options[ this ] || "" ).split( " " ), - horizontalOffset, - verticalOffset; - - if ( pos.length === 1) { - pos = rhorizontal.test( pos[ 0 ] ) ? - pos.concat( [ "center" ] ) : - rvertical.test( pos[ 0 ] ) ? - [ "center" ].concat( pos ) : - [ "center", "center" ]; - } - pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; - pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; - - // calculate offsets - horizontalOffset = roffset.exec( pos[ 0 ] ); - verticalOffset = roffset.exec( pos[ 1 ] ); - offsets[ this ] = [ - horizontalOffset ? horizontalOffset[ 0 ] : 0, - verticalOffset ? verticalOffset[ 0 ] : 0 - ]; - - // reduce to just the positions without the offsets - options[ this ] = [ - rposition.exec( pos[ 0 ] )[ 0 ], - rposition.exec( pos[ 1 ] )[ 0 ] - ]; - }); - - // normalize collision option - if ( collision.length === 1 ) { - collision[ 1 ] = collision[ 0 ]; - } - - if ( options.at[ 0 ] === "right" ) { - basePosition.left += targetWidth; - } else if ( options.at[ 0 ] === "center" ) { - basePosition.left += targetWidth / 2; - } - - if ( options.at[ 1 ] === "bottom" ) { - basePosition.top += targetHeight; - } else if ( options.at[ 1 ] === "center" ) { - basePosition.top += targetHeight / 2; - } - - atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); - basePosition.left += atOffset[ 0 ]; - basePosition.top += atOffset[ 1 ]; - - return this.each(function() { - var collisionPosition, using, - elem = $( this ), - elemWidth = elem.outerWidth(), - elemHeight = elem.outerHeight(), - marginLeft = parseCss( this, "marginLeft" ), - marginTop = parseCss( this, "marginTop" ), - collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width, - collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height, - position = $.extend( {}, basePosition ), - myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); - - if ( options.my[ 0 ] === "right" ) { - position.left -= elemWidth; - } else if ( options.my[ 0 ] === "center" ) { - position.left -= elemWidth / 2; - } - - if ( options.my[ 1 ] === "bottom" ) { - position.top -= elemHeight; - } else if ( options.my[ 1 ] === "center" ) { - position.top -= elemHeight / 2; - } - - position.left += myOffset[ 0 ]; - position.top += myOffset[ 1 ]; - - // if the browser doesn't support fractions, then round for consistent results - if ( !$.support.offsetFractions ) { - position.left = round( position.left ); - position.top = round( position.top ); - } - - collisionPosition = { - marginLeft: marginLeft, - marginTop: marginTop - }; - - $.each( [ "left", "top" ], function( i, dir ) { - if ( $.ui.position[ collision[ i ] ] ) { - $.ui.position[ collision[ i ] ][ dir ]( position, { - targetWidth: targetWidth, - targetHeight: targetHeight, - elemWidth: elemWidth, - elemHeight: elemHeight, - collisionPosition: collisionPosition, - collisionWidth: collisionWidth, - collisionHeight: collisionHeight, - offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], - my: options.my, - at: options.at, - within: within, - elem : elem - }); - } - }); - - if ( $.fn.bgiframe ) { - elem.bgiframe(); - } - - if ( options.using ) { - // adds feedback as second argument to using callback, if present - using = function( props ) { - var left = targetOffset.left - position.left, - right = left + targetWidth - elemWidth, - top = targetOffset.top - position.top, - bottom = top + targetHeight - elemHeight, - feedback = { - target: { - element: target, - left: targetOffset.left, - top: targetOffset.top, - width: targetWidth, - height: targetHeight - }, - element: { - element: elem, - left: position.left, - top: position.top, - width: elemWidth, - height: elemHeight - }, - horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", - vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" - }; - if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { - feedback.horizontal = "center"; - } - if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { - feedback.vertical = "middle"; - } - if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { - feedback.important = "horizontal"; - } else { - feedback.important = "vertical"; - } - options.using.call( this, props, feedback ); - }; - } - - elem.offset( $.extend( position, { using: using } ) ); - }); -}; - -$.ui.position = { - fit: { - left: function( position, data ) { - var within = data.within, - withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, - outerWidth = within.width, - collisionPosLeft = position.left - data.collisionPosition.marginLeft, - overLeft = withinOffset - collisionPosLeft, - overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, - newOverRight; - - // element is wider than within - if ( data.collisionWidth > outerWidth ) { - // element is initially over the left side of within - if ( overLeft > 0 && overRight <= 0 ) { - newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; - position.left += overLeft - newOverRight; - // element is initially over right side of within - } else if ( overRight > 0 && overLeft <= 0 ) { - position.left = withinOffset; - // element is initially over both left and right sides of within - } else { - if ( overLeft > overRight ) { - position.left = withinOffset + outerWidth - data.collisionWidth; - } else { - position.left = withinOffset; - } - } - // too far left -> align with left edge - } else if ( overLeft > 0 ) { - position.left += overLeft; - // too far right -> align with right edge - } else if ( overRight > 0 ) { - position.left -= overRight; - // adjust based on position and margin - } else { - position.left = max( position.left - collisionPosLeft, position.left ); - } - }, - top: function( position, data ) { - var within = data.within, - withinOffset = within.isWindow ? within.scrollTop : within.offset.top, - outerHeight = data.within.height, - collisionPosTop = position.top - data.collisionPosition.marginTop, - overTop = withinOffset - collisionPosTop, - overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, - newOverBottom; - - // element is taller than within - if ( data.collisionHeight > outerHeight ) { - // element is initially over the top of within - if ( overTop > 0 && overBottom <= 0 ) { - newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; - position.top += overTop - newOverBottom; - // element is initially over bottom of within - } else if ( overBottom > 0 && overTop <= 0 ) { - position.top = withinOffset; - // element is initially over both top and bottom of within - } else { - if ( overTop > overBottom ) { - position.top = withinOffset + outerHeight - data.collisionHeight; - } else { - position.top = withinOffset; - } - } - // too far up -> align with top - } else if ( overTop > 0 ) { - position.top += overTop; - // too far down -> align with bottom edge - } else if ( overBottom > 0 ) { - position.top -= overBottom; - // adjust based on position and margin - } else { - position.top = max( position.top - collisionPosTop, position.top ); - } - } - }, - flip: { - left: function( position, data ) { - var within = data.within, - withinOffset = within.offset.left + within.scrollLeft, - outerWidth = within.width, - offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, - collisionPosLeft = position.left - data.collisionPosition.marginLeft, - overLeft = collisionPosLeft - offsetLeft, - overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, - myOffset = data.my[ 0 ] === "left" ? - -data.elemWidth : - data.my[ 0 ] === "right" ? - data.elemWidth : - 0, - atOffset = data.at[ 0 ] === "left" ? - data.targetWidth : - data.at[ 0 ] === "right" ? - -data.targetWidth : - 0, - offset = -2 * data.offset[ 0 ], - newOverRight, - newOverLeft; - - if ( overLeft < 0 ) { - newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; - if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { - position.left += myOffset + atOffset + offset; - } - } - else if ( overRight > 0 ) { - newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; - if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { - position.left += myOffset + atOffset + offset; - } - } - }, - top: function( position, data ) { - var within = data.within, - withinOffset = within.offset.top + within.scrollTop, - outerHeight = within.height, - offsetTop = within.isWindow ? within.scrollTop : within.offset.top, - collisionPosTop = position.top - data.collisionPosition.marginTop, - overTop = collisionPosTop - offsetTop, - overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, - top = data.my[ 1 ] === "top", - myOffset = top ? - -data.elemHeight : - data.my[ 1 ] === "bottom" ? - data.elemHeight : - 0, - atOffset = data.at[ 1 ] === "top" ? - data.targetHeight : - data.at[ 1 ] === "bottom" ? - -data.targetHeight : - 0, - offset = -2 * data.offset[ 1 ], - newOverTop, - newOverBottom; - if ( overTop < 0 ) { - newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; - if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) { - position.top += myOffset + atOffset + offset; - } - } - else if ( overBottom > 0 ) { - newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; - if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) { - position.top += myOffset + atOffset + offset; - } - } - } - }, - flipfit: { - left: function() { - $.ui.position.flip.left.apply( this, arguments ); - $.ui.position.fit.left.apply( this, arguments ); - }, - top: function() { - $.ui.position.flip.top.apply( this, arguments ); - $.ui.position.fit.top.apply( this, arguments ); - } - } -}; - -// fraction support test -(function () { - var testElement, testElementParent, testElementStyle, offsetLeft, i, - body = document.getElementsByTagName( "body" )[ 0 ], - div = document.createElement( "div" ); - - //Create a "fake body" for testing based on method used in jQuery.support - testElement = document.createElement( body ? "div" : "body" ); - testElementStyle = { - visibility: "hidden", - width: 0, - height: 0, - border: 0, - margin: 0, - background: "none" - }; - if ( body ) { - $.extend( testElementStyle, { - position: "absolute", - left: "-1000px", - top: "-1000px" - }); - } - for ( i in testElementStyle ) { - testElement.style[ i ] = testElementStyle[ i ]; - } - testElement.appendChild( div ); - testElementParent = body || document.documentElement; - testElementParent.insertBefore( testElement, testElementParent.firstChild ); - - div.style.cssText = "position: absolute; left: 10.7432222px;"; - - offsetLeft = $( div ).offset().left; - $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11; - - testElement.innerHTML = ""; - testElementParent.removeChild( testElement ); -})(); - -// DEPRECATED -if ( $.uiBackCompat !== false ) { - // offset option - (function( $ ) { - var _position = $.fn.position; - $.fn.position = function( options ) { - if ( !options || !options.offset ) { - return _position.call( this, options ); - } - var offset = options.offset.split( " " ), - at = options.at.split( " " ); - if ( offset.length === 1 ) { - offset[ 1 ] = offset[ 0 ]; - } - if ( /^\d/.test( offset[ 0 ] ) ) { - offset[ 0 ] = "+" + offset[ 0 ]; - } - if ( /^\d/.test( offset[ 1 ] ) ) { - offset[ 1 ] = "+" + offset[ 1 ]; - } - if ( at.length === 1 ) { - if ( /left|center|right/.test( at[ 0 ] ) ) { - at[ 1 ] = "center"; - } else { - at[ 1 ] = at[ 0 ]; - at[ 0 ] = "center"; - } - } - return _position.call( this, $.extend( options, { - at: at[ 0 ] + offset[ 0 ] + " " + at[ 1 ] + offset[ 1 ], - offset: undefined - } ) ); - }; - }( jQuery ) ); -} - -}( jQuery ) ); - -(function( $, undefined ) { - -$.widget( "ui.progressbar", { - version: "1.9.2", - options: { - value: 0, - max: 100 - }, - - min: 0, - - _create: function() { - this.element - .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) - .attr({ - role: "progressbar", - "aria-valuemin": this.min, - "aria-valuemax": this.options.max, - "aria-valuenow": this._value() - }); - - this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" ) - .appendTo( this.element ); - - this.oldValue = this._value(); - this._refreshValue(); - }, - - _destroy: function() { - this.element - .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) - .removeAttr( "role" ) - .removeAttr( "aria-valuemin" ) - .removeAttr( "aria-valuemax" ) - .removeAttr( "aria-valuenow" ); - - this.valueDiv.remove(); - }, - - value: function( newValue ) { - if ( newValue === undefined ) { - return this._value(); - } - - this._setOption( "value", newValue ); - return this; - }, - - _setOption: function( key, value ) { - if ( key === "value" ) { - this.options.value = value; - this._refreshValue(); - if ( this._value() === this.options.max ) { - this._trigger( "complete" ); - } - } - - this._super( key, value ); - }, - - _value: function() { - var val = this.options.value; - // normalize invalid value - if ( typeof val !== "number" ) { - val = 0; - } - return Math.min( this.options.max, Math.max( this.min, val ) ); - }, - - _percentage: function() { - return 100 * this._value() / this.options.max; - }, - - _refreshValue: function() { - var value = this.value(), - percentage = this._percentage(); - - if ( this.oldValue !== value ) { - this.oldValue = value; - this._trigger( "change" ); - } - - this.valueDiv - .toggle( value > this.min ) - .toggleClass( "ui-corner-right", value === this.options.max ) - .width( percentage.toFixed(0) + "%" ); - this.element.attr( "aria-valuenow", value ); - } -}); - -})( jQuery ); - -(function( $, undefined ) { - -// number of pages in a slider -// (how many times can you page up/down to go through the whole range) -var numPages = 5; - -$.widget( "ui.slider", $.ui.mouse, { - version: "1.9.2", - widgetEventPrefix: "slide", - - options: { - animate: false, - distance: 0, - max: 100, - min: 0, - orientation: "horizontal", - range: false, - step: 1, - value: 0, - values: null - }, - - _create: function() { - var i, handleCount, - o = this.options, - existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ), - handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>", - handles = []; - - this._keySliding = false; - this._mouseSliding = false; - this._animateOff = true; - this._handleIndex = null; - this._detectOrientation(); - this._mouseInit(); - - this.element - .addClass( "ui-slider" + - " ui-slider-" + this.orientation + - " ui-widget" + - " ui-widget-content" + - " ui-corner-all" + - ( o.disabled ? " ui-slider-disabled ui-disabled" : "" ) ); - - this.range = $([]); - - if ( o.range ) { - if ( o.range === true ) { - if ( !o.values ) { - o.values = [ this._valueMin(), this._valueMin() ]; - } - if ( o.values.length && o.values.length !== 2 ) { - o.values = [ o.values[0], o.values[0] ]; - } - } - - this.range = $( "<div></div>" ) - .appendTo( this.element ) - .addClass( "ui-slider-range" + - // note: this isn't the most fittingly semantic framework class for this element, - // but worked best visually with a variety of themes - " ui-widget-header" + - ( ( o.range === "min" || o.range === "max" ) ? " ui-slider-range-" + o.range : "" ) ); - } - - handleCount = ( o.values && o.values.length ) || 1; - - for ( i = existingHandles.length; i < handleCount; i++ ) { - handles.push( handle ); - } - - this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); - - this.handle = this.handles.eq( 0 ); - - this.handles.add( this.range ).filter( "a" ) - .click(function( event ) { - event.preventDefault(); - }) - .mouseenter(function() { - if ( !o.disabled ) { - $( this ).addClass( "ui-state-hover" ); - } - }) - .mouseleave(function() { - $( this ).removeClass( "ui-state-hover" ); - }) - .focus(function() { - if ( !o.disabled ) { - $( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" ); - $( this ).addClass( "ui-state-focus" ); - } else { - $( this ).blur(); - } - }) - .blur(function() { - $( this ).removeClass( "ui-state-focus" ); - }); - - this.handles.each(function( i ) { - $( this ).data( "ui-slider-handle-index", i ); - }); - - this._on( this.handles, { - keydown: function( event ) { - var allowed, curVal, newVal, step, - index = $( event.target ).data( "ui-slider-handle-index" ); - - switch ( event.keyCode ) { - case $.ui.keyCode.HOME: - case $.ui.keyCode.END: - case $.ui.keyCode.PAGE_UP: - case $.ui.keyCode.PAGE_DOWN: - case $.ui.keyCode.UP: - case $.ui.keyCode.RIGHT: - case $.ui.keyCode.DOWN: - case $.ui.keyCode.LEFT: - event.preventDefault(); - if ( !this._keySliding ) { - this._keySliding = true; - $( event.target ).addClass( "ui-state-active" ); - allowed = this._start( event, index ); - if ( allowed === false ) { - return; - } - } - break; - } - - step = this.options.step; - if ( this.options.values && this.options.values.length ) { - curVal = newVal = this.values( index ); - } else { - curVal = newVal = this.value(); - } - - switch ( event.keyCode ) { - case $.ui.keyCode.HOME: - newVal = this._valueMin(); - break; - case $.ui.keyCode.END: - newVal = this._valueMax(); - break; - case $.ui.keyCode.PAGE_UP: - newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) ); - break; - case $.ui.keyCode.PAGE_DOWN: - newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) ); - break; - case $.ui.keyCode.UP: - case $.ui.keyCode.RIGHT: - if ( curVal === this._valueMax() ) { - return; - } - newVal = this._trimAlignValue( curVal + step ); - break; - case $.ui.keyCode.DOWN: - case $.ui.keyCode.LEFT: - if ( curVal === this._valueMin() ) { - return; - } - newVal = this._trimAlignValue( curVal - step ); - break; - } - - this._slide( event, index, newVal ); - }, - keyup: function( event ) { - var index = $( event.target ).data( "ui-slider-handle-index" ); - - if ( this._keySliding ) { - this._keySliding = false; - this._stop( event, index ); - this._change( event, index ); - $( event.target ).removeClass( "ui-state-active" ); - } - } - }); - - this._refreshValue(); - - this._animateOff = false; - }, - - _destroy: function() { - this.handles.remove(); - this.range.remove(); - - this.element - .removeClass( "ui-slider" + - " ui-slider-horizontal" + - " ui-slider-vertical" + - " ui-slider-disabled" + - " ui-widget" + - " ui-widget-content" + - " ui-corner-all" ); - - this._mouseDestroy(); - }, - - _mouseCapture: function( event ) { - var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, - that = this, - o = this.options; - - if ( o.disabled ) { - return false; - } - - this.elementSize = { - width: this.element.outerWidth(), - height: this.element.outerHeight() - }; - this.elementOffset = this.element.offset(); - - position = { x: event.pageX, y: event.pageY }; - normValue = this._normValueFromMouse( position ); - distance = this._valueMax() - this._valueMin() + 1; - this.handles.each(function( i ) { - var thisDistance = Math.abs( normValue - that.values(i) ); - if ( distance > thisDistance ) { - distance = thisDistance; - closestHandle = $( this ); - index = i; - } - }); - - // workaround for bug #3736 (if both handles of a range are at 0, - // the first is always used as the one with least distance, - // and moving it is obviously prevented by preventing negative ranges) - if( o.range === true && this.values(1) === o.min ) { - index += 1; - closestHandle = $( this.handles[index] ); - } - - allowed = this._start( event, index ); - if ( allowed === false ) { - return false; - } - this._mouseSliding = true; - - this._handleIndex = index; - - closestHandle - .addClass( "ui-state-active" ) - .focus(); - - offset = closestHandle.offset(); - mouseOverHandle = !$( event.target ).parents().andSelf().is( ".ui-slider-handle" ); - this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { - left: event.pageX - offset.left - ( closestHandle.width() / 2 ), - top: event.pageY - offset.top - - ( closestHandle.height() / 2 ) - - ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) - - ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) + - ( parseInt( closestHandle.css("marginTop"), 10 ) || 0) - }; - - if ( !this.handles.hasClass( "ui-state-hover" ) ) { - this._slide( event, index, normValue ); - } - this._animateOff = true; - return true; - }, - - _mouseStart: function() { - return true; - }, - - _mouseDrag: function( event ) { - var position = { x: event.pageX, y: event.pageY }, - normValue = this._normValueFromMouse( position ); - - this._slide( event, this._handleIndex, normValue ); - - return false; - }, - - _mouseStop: function( event ) { - this.handles.removeClass( "ui-state-active" ); - this._mouseSliding = false; - - this._stop( event, this._handleIndex ); - this._change( event, this._handleIndex ); - - this._handleIndex = null; - this._clickOffset = null; - this._animateOff = false; - - return false; - }, - - _detectOrientation: function() { - this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; - }, - - _normValueFromMouse: function( position ) { - var pixelTotal, - pixelMouse, - percentMouse, - valueTotal, - valueMouse; - - if ( this.orientation === "horizontal" ) { - pixelTotal = this.elementSize.width; - pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 ); - } else { - pixelTotal = this.elementSize.height; - pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 ); - } - - percentMouse = ( pixelMouse / pixelTotal ); - if ( percentMouse > 1 ) { - percentMouse = 1; - } - if ( percentMouse < 0 ) { - percentMouse = 0; - } - if ( this.orientation === "vertical" ) { - percentMouse = 1 - percentMouse; - } - - valueTotal = this._valueMax() - this._valueMin(); - valueMouse = this._valueMin() + percentMouse * valueTotal; - - return this._trimAlignValue( valueMouse ); - }, - - _start: function( event, index ) { - var uiHash = { - handle: this.handles[ index ], - value: this.value() - }; - if ( this.options.values && this.options.values.length ) { - uiHash.value = this.values( index ); - uiHash.values = this.values(); - } - return this._trigger( "start", event, uiHash ); - }, - - _slide: function( event, index, newVal ) { - var otherVal, - newValues, - allowed; - - if ( this.options.values && this.options.values.length ) { - otherVal = this.values( index ? 0 : 1 ); - - if ( ( this.options.values.length === 2 && this.options.range === true ) && - ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) ) - ) { - newVal = otherVal; - } - - if ( newVal !== this.values( index ) ) { - newValues = this.values(); - newValues[ index ] = newVal; - // A slide can be canceled by returning false from the slide callback - allowed = this._trigger( "slide", event, { - handle: this.handles[ index ], - value: newVal, - values: newValues - } ); - otherVal = this.values( index ? 0 : 1 ); - if ( allowed !== false ) { - this.values( index, newVal, true ); - } - } - } else { - if ( newVal !== this.value() ) { - // A slide can be canceled by returning false from the slide callback - allowed = this._trigger( "slide", event, { - handle: this.handles[ index ], - value: newVal - } ); - if ( allowed !== false ) { - this.value( newVal ); - } - } - } - }, - - _stop: function( event, index ) { - var uiHash = { - handle: this.handles[ index ], - value: this.value() - }; - if ( this.options.values && this.options.values.length ) { - uiHash.value = this.values( index ); - uiHash.values = this.values(); - } - - this._trigger( "stop", event, uiHash ); - }, - - _change: function( event, index ) { - if ( !this._keySliding && !this._mouseSliding ) { - var uiHash = { - handle: this.handles[ index ], - value: this.value() - }; - if ( this.options.values && this.options.values.length ) { - uiHash.value = this.values( index ); - uiHash.values = this.values(); - } - - this._trigger( "change", event, uiHash ); - } - }, - - value: function( newValue ) { - if ( arguments.length ) { - this.options.value = this._trimAlignValue( newValue ); - this._refreshValue(); - this._change( null, 0 ); - return; - } - - return this._value(); - }, - - values: function( index, newValue ) { - var vals, - newValues, - i; - - if ( arguments.length > 1 ) { - this.options.values[ index ] = this._trimAlignValue( newValue ); - this._refreshValue(); - this._change( null, index ); - return; - } - - if ( arguments.length ) { - if ( $.isArray( arguments[ 0 ] ) ) { - vals = this.options.values; - newValues = arguments[ 0 ]; - for ( i = 0; i < vals.length; i += 1 ) { - vals[ i ] = this._trimAlignValue( newValues[ i ] ); - this._change( null, i ); - } - this._refreshValue(); - } else { - if ( this.options.values && this.options.values.length ) { - return this._values( index ); - } else { - return this.value(); - } - } - } else { - return this._values(); - } - }, - - _setOption: function( key, value ) { - var i, - valsLength = 0; - - if ( $.isArray( this.options.values ) ) { - valsLength = this.options.values.length; - } - - $.Widget.prototype._setOption.apply( this, arguments ); - - switch ( key ) { - case "disabled": - if ( value ) { - this.handles.filter( ".ui-state-focus" ).blur(); - this.handles.removeClass( "ui-state-hover" ); - this.handles.prop( "disabled", true ); - this.element.addClass( "ui-disabled" ); - } else { - this.handles.prop( "disabled", false ); - this.element.removeClass( "ui-disabled" ); - } - break; - case "orientation": - this._detectOrientation(); - this.element - .removeClass( "ui-slider-horizontal ui-slider-vertical" ) - .addClass( "ui-slider-" + this.orientation ); - this._refreshValue(); - break; - case "value": - this._animateOff = true; - this._refreshValue(); - this._change( null, 0 ); - this._animateOff = false; - break; - case "values": - this._animateOff = true; - this._refreshValue(); - for ( i = 0; i < valsLength; i += 1 ) { - this._change( null, i ); - } - this._animateOff = false; - break; - case "min": - case "max": - this._animateOff = true; - this._refreshValue(); - this._animateOff = false; - break; - } - }, - - //internal value getter - // _value() returns value trimmed by min and max, aligned by step - _value: function() { - var val = this.options.value; - val = this._trimAlignValue( val ); - - return val; - }, - - //internal values getter - // _values() returns array of values trimmed by min and max, aligned by step - // _values( index ) returns single value trimmed by min and max, aligned by step - _values: function( index ) { - var val, - vals, - i; - - if ( arguments.length ) { - val = this.options.values[ index ]; - val = this._trimAlignValue( val ); - - return val; - } else { - // .slice() creates a copy of the array - // this copy gets trimmed by min and max and then returned - vals = this.options.values.slice(); - for ( i = 0; i < vals.length; i+= 1) { - vals[ i ] = this._trimAlignValue( vals[ i ] ); - } - - return vals; - } - }, - - // returns the step-aligned value that val is closest to, between (inclusive) min and max - _trimAlignValue: function( val ) { - if ( val <= this._valueMin() ) { - return this._valueMin(); - } - if ( val >= this._valueMax() ) { - return this._valueMax(); - } - var step = ( this.options.step > 0 ) ? this.options.step : 1, - valModStep = (val - this._valueMin()) % step, - alignValue = val - valModStep; - - if ( Math.abs(valModStep) * 2 >= step ) { - alignValue += ( valModStep > 0 ) ? step : ( -step ); - } - - // Since JavaScript has problems with large floats, round - // the final value to 5 digits after the decimal point (see #4124) - return parseFloat( alignValue.toFixed(5) ); - }, - - _valueMin: function() { - return this.options.min; - }, - - _valueMax: function() { - return this.options.max; - }, - - _refreshValue: function() { - var lastValPercent, valPercent, value, valueMin, valueMax, - oRange = this.options.range, - o = this.options, - that = this, - animate = ( !this._animateOff ) ? o.animate : false, - _set = {}; - - if ( this.options.values && this.options.values.length ) { - this.handles.each(function( i ) { - valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100; - _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; - $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); - if ( that.options.range === true ) { - if ( that.orientation === "horizontal" ) { - if ( i === 0 ) { - that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate ); - } - if ( i === 1 ) { - that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); - } - } else { - if ( i === 0 ) { - that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate ); - } - if ( i === 1 ) { - that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); - } - } - } - lastValPercent = valPercent; - }); - } else { - value = this.value(); - valueMin = this._valueMin(); - valueMax = this._valueMax(); - valPercent = ( valueMax !== valueMin ) ? - ( value - valueMin ) / ( valueMax - valueMin ) * 100 : - 0; - _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; - this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); - - if ( oRange === "min" && this.orientation === "horizontal" ) { - this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate ); - } - if ( oRange === "max" && this.orientation === "horizontal" ) { - this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); - } - if ( oRange === "min" && this.orientation === "vertical" ) { - this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate ); - } - if ( oRange === "max" && this.orientation === "vertical" ) { - this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); - } - } - } - -}); - -}(jQuery)); - -(function( $ ) { - -function modifier( fn ) { - return function() { - var previous = this.element.val(); - fn.apply( this, arguments ); - this._refresh(); - if ( previous !== this.element.val() ) { - this._trigger( "change" ); - } - }; -} - -$.widget( "ui.spinner", { - version: "1.9.2", - defaultElement: "<input>", - widgetEventPrefix: "spin", - options: { - culture: null, - icons: { - down: "ui-icon-triangle-1-s", - up: "ui-icon-triangle-1-n" - }, - incremental: true, - max: null, - min: null, - numberFormat: null, - page: 10, - step: 1, - - change: null, - spin: null, - start: null, - stop: null - }, - - _create: function() { - // handle string values that need to be parsed - this._setOption( "max", this.options.max ); - this._setOption( "min", this.options.min ); - this._setOption( "step", this.options.step ); - - // format the value, but don't constrain - this._value( this.element.val(), true ); - - this._draw(); - this._on( this._events ); - this._refresh(); - - // turning off autocomplete prevents the browser from remembering the - // value when navigating through history, so we re-enable autocomplete - // if the page is unloaded before the widget is destroyed. #7790 - this._on( this.window, { - beforeunload: function() { - this.element.removeAttr( "autocomplete" ); - } - }); - }, - - _getCreateOptions: function() { - var options = {}, - element = this.element; - - $.each( [ "min", "max", "step" ], function( i, option ) { - var value = element.attr( option ); - if ( value !== undefined && value.length ) { - options[ option ] = value; - } - }); - - return options; - }, - - _events: { - keydown: function( event ) { - if ( this._start( event ) && this._keydown( event ) ) { - event.preventDefault(); - } - }, - keyup: "_stop", - focus: function() { - this.previous = this.element.val(); - }, - blur: function( event ) { - if ( this.cancelBlur ) { - delete this.cancelBlur; - return; - } - - this._refresh(); - if ( this.previous !== this.element.val() ) { - this._trigger( "change", event ); - } - }, - mousewheel: function( event, delta ) { - if ( !delta ) { - return; - } - if ( !this.spinning && !this._start( event ) ) { - return false; - } - - this._spin( (delta > 0 ? 1 : -1) * this.options.step, event ); - clearTimeout( this.mousewheelTimer ); - this.mousewheelTimer = this._delay(function() { - if ( this.spinning ) { - this._stop( event ); - } - }, 100 ); - event.preventDefault(); - }, - "mousedown .ui-spinner-button": function( event ) { - var previous; - - // We never want the buttons to have focus; whenever the user is - // interacting with the spinner, the focus should be on the input. - // If the input is focused then this.previous is properly set from - // when the input first received focus. If the input is not focused - // then we need to set this.previous based on the value before spinning. - previous = this.element[0] === this.document[0].activeElement ? - this.previous : this.element.val(); - function checkFocus() { - var isActive = this.element[0] === this.document[0].activeElement; - if ( !isActive ) { - this.element.focus(); - this.previous = previous; - // support: IE - // IE sets focus asynchronously, so we need to check if focus - // moved off of the input because the user clicked on the button. - this._delay(function() { - this.previous = previous; - }); - } - } - - // ensure focus is on (or stays on) the text field - event.preventDefault(); - checkFocus.call( this ); - - // support: IE - // IE doesn't prevent moving focus even with event.preventDefault() - // so we set a flag to know when we should ignore the blur event - // and check (again) if focus moved off of the input. - this.cancelBlur = true; - this._delay(function() { - delete this.cancelBlur; - checkFocus.call( this ); - }); - - if ( this._start( event ) === false ) { - return; - } - - this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); - }, - "mouseup .ui-spinner-button": "_stop", - "mouseenter .ui-spinner-button": function( event ) { - // button will add ui-state-active if mouse was down while mouseleave and kept down - if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { - return; - } - - if ( this._start( event ) === false ) { - return false; - } - this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); - }, - // TODO: do we really want to consider this a stop? - // shouldn't we just stop the repeater and wait until mouseup before - // we trigger the stop event? - "mouseleave .ui-spinner-button": "_stop" - }, - - _draw: function() { - var uiSpinner = this.uiSpinner = this.element - .addClass( "ui-spinner-input" ) - .attr( "autocomplete", "off" ) - .wrap( this._uiSpinnerHtml() ) - .parent() - // add buttons - .append( this._buttonHtml() ); - - this.element.attr( "role", "spinbutton" ); - - // button bindings - this.buttons = uiSpinner.find( ".ui-spinner-button" ) - .attr( "tabIndex", -1 ) - .button() - .removeClass( "ui-corner-all" ); - - // IE 6 doesn't understand height: 50% for the buttons - // unless the wrapper has an explicit height - if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) && - uiSpinner.height() > 0 ) { - uiSpinner.height( uiSpinner.height() ); - } - - // disable spinner if element was already disabled - if ( this.options.disabled ) { - this.disable(); - } - }, - - _keydown: function( event ) { - var options = this.options, - keyCode = $.ui.keyCode; - - switch ( event.keyCode ) { - case keyCode.UP: - this._repeat( null, 1, event ); - return true; - case keyCode.DOWN: - this._repeat( null, -1, event ); - return true; - case keyCode.PAGE_UP: - this._repeat( null, options.page, event ); - return true; - case keyCode.PAGE_DOWN: - this._repeat( null, -options.page, event ); - return true; - } - - return false; - }, - - _uiSpinnerHtml: function() { - return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"; - }, - - _buttonHtml: function() { - return "" + - "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" + - "<span class='ui-icon " + this.options.icons.up + "'>▲</span>" + - "</a>" + - "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" + - "<span class='ui-icon " + this.options.icons.down + "'>▼</span>" + - "</a>"; - }, - - _start: function( event ) { - if ( !this.spinning && this._trigger( "start", event ) === false ) { - return false; - } - - if ( !this.counter ) { - this.counter = 1; - } - this.spinning = true; - return true; - }, - - _repeat: function( i, steps, event ) { - i = i || 500; - - clearTimeout( this.timer ); - this.timer = this._delay(function() { - this._repeat( 40, steps, event ); - }, i ); - - this._spin( steps * this.options.step, event ); - }, - - _spin: function( step, event ) { - var value = this.value() || 0; - - if ( !this.counter ) { - this.counter = 1; - } - - value = this._adjustValue( value + step * this._increment( this.counter ) ); - - if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) { - this._value( value ); - this.counter++; - } - }, - - _increment: function( i ) { - var incremental = this.options.incremental; - - if ( incremental ) { - return $.isFunction( incremental ) ? - incremental( i ) : - Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 ); - } - - return 1; - }, - - _precision: function() { - var precision = this._precisionOf( this.options.step ); - if ( this.options.min !== null ) { - precision = Math.max( precision, this._precisionOf( this.options.min ) ); - } - return precision; - }, - - _precisionOf: function( num ) { - var str = num.toString(), - decimal = str.indexOf( "." ); - return decimal === -1 ? 0 : str.length - decimal - 1; - }, - - _adjustValue: function( value ) { - var base, aboveMin, - options = this.options; - - // make sure we're at a valid step - // - find out where we are relative to the base (min or 0) - base = options.min !== null ? options.min : 0; - aboveMin = value - base; - // - round to the nearest step - aboveMin = Math.round(aboveMin / options.step) * options.step; - // - rounding is based on 0, so adjust back to our base - value = base + aboveMin; - - // fix precision from bad JS floating point math - value = parseFloat( value.toFixed( this._precision() ) ); - - // clamp the value - if ( options.max !== null && value > options.max) { - return options.max; - } - if ( options.min !== null && value < options.min ) { - return options.min; - } - - return value; - }, - - _stop: function( event ) { - if ( !this.spinning ) { - return; - } - - clearTimeout( this.timer ); - clearTimeout( this.mousewheelTimer ); - this.counter = 0; - this.spinning = false; - this._trigger( "stop", event ); - }, - - _setOption: function( key, value ) { - if ( key === "culture" || key === "numberFormat" ) { - var prevValue = this._parse( this.element.val() ); - this.options[ key ] = value; - this.element.val( this._format( prevValue ) ); - return; - } - - if ( key === "max" || key === "min" || key === "step" ) { - if ( typeof value === "string" ) { - value = this._parse( value ); - } - } - - this._super( key, value ); - - if ( key === "disabled" ) { - if ( value ) { - this.element.prop( "disabled", true ); - this.buttons.button( "disable" ); - } else { - this.element.prop( "disabled", false ); - this.buttons.button( "enable" ); - } - } - }, - - _setOptions: modifier(function( options ) { - this._super( options ); - this._value( this.element.val() ); - }), - - _parse: function( val ) { - if ( typeof val === "string" && val !== "" ) { - val = window.Globalize && this.options.numberFormat ? - Globalize.parseFloat( val, 10, this.options.culture ) : +val; - } - return val === "" || isNaN( val ) ? null : val; - }, - - _format: function( value ) { - if ( value === "" ) { - return ""; - } - return window.Globalize && this.options.numberFormat ? - Globalize.format( value, this.options.numberFormat, this.options.culture ) : - value; - }, - - _refresh: function() { - this.element.attr({ - "aria-valuemin": this.options.min, - "aria-valuemax": this.options.max, - // TODO: what should we do with values that can't be parsed? - "aria-valuenow": this._parse( this.element.val() ) - }); - }, - - // update the value without triggering change - _value: function( value, allowAny ) { - var parsed; - if ( value !== "" ) { - parsed = this._parse( value ); - if ( parsed !== null ) { - if ( !allowAny ) { - parsed = this._adjustValue( parsed ); - } - value = this._format( parsed ); - } - } - this.element.val( value ); - this._refresh(); - }, - - _destroy: function() { - this.element - .removeClass( "ui-spinner-input" ) - .prop( "disabled", false ) - .removeAttr( "autocomplete" ) - .removeAttr( "role" ) - .removeAttr( "aria-valuemin" ) - .removeAttr( "aria-valuemax" ) - .removeAttr( "aria-valuenow" ); - this.uiSpinner.replaceWith( this.element ); - }, - - stepUp: modifier(function( steps ) { - this._stepUp( steps ); - }), - _stepUp: function( steps ) { - this._spin( (steps || 1) * this.options.step ); - }, - - stepDown: modifier(function( steps ) { - this._stepDown( steps ); - }), - _stepDown: function( steps ) { - this._spin( (steps || 1) * -this.options.step ); - }, - - pageUp: modifier(function( pages ) { - this._stepUp( (pages || 1) * this.options.page ); - }), - - pageDown: modifier(function( pages ) { - this._stepDown( (pages || 1) * this.options.page ); - }), - - value: function( newVal ) { - if ( !arguments.length ) { - return this._parse( this.element.val() ); - } - modifier( this._value ).call( this, newVal ); - }, - - widget: function() { - return this.uiSpinner; - } -}); - -}( jQuery ) ); - -(function( $, undefined ) { - -var tabId = 0, - rhash = /#.*$/; - -function getNextTabId() { - return ++tabId; -} - -function isLocal( anchor ) { - return anchor.hash.length > 1 && - anchor.href.replace( rhash, "" ) === - location.href.replace( rhash, "" ) - // support: Safari 5.1 - // Safari 5.1 doesn't encode spaces in window.location - // but it does encode spaces from anchors (#8777) - .replace( /\s/g, "%20" ); -} - -$.widget( "ui.tabs", { - version: "1.9.2", - delay: 300, - options: { - active: null, - collapsible: false, - event: "click", - heightStyle: "content", - hide: null, - show: null, - - // callbacks - activate: null, - beforeActivate: null, - beforeLoad: null, - load: null - }, - - _create: function() { - var that = this, - options = this.options, - active = options.active, - locationHash = location.hash.substring( 1 ); - - this.running = false; - - this.element - .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ) - .toggleClass( "ui-tabs-collapsible", options.collapsible ) - // Prevent users from focusing disabled tabs via click - .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) { - if ( $( this ).is( ".ui-state-disabled" ) ) { - event.preventDefault(); - } - }) - // support: IE <9 - // Preventing the default action in mousedown doesn't prevent IE - // from focusing the element, so if the anchor gets focused, blur. - // We don't have to worry about focusing the previously focused - // element since clicking on a non-focusable element should focus - // the body anyway. - .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() { - if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { - this.blur(); - } - }); - - this._processTabs(); - - if ( active === null ) { - // check the fragment identifier in the URL - if ( locationHash ) { - this.tabs.each(function( i, tab ) { - if ( $( tab ).attr( "aria-controls" ) === locationHash ) { - active = i; - return false; - } - }); - } - - // check for a tab marked active via a class - if ( active === null ) { - active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); - } - - // no active tab, set to false - if ( active === null || active === -1 ) { - active = this.tabs.length ? 0 : false; - } - } - - // handle numbers: negative, out of range - if ( active !== false ) { - active = this.tabs.index( this.tabs.eq( active ) ); - if ( active === -1 ) { - active = options.collapsible ? false : 0; - } - } - options.active = active; - - // don't allow collapsible: false and active: false - if ( !options.collapsible && options.active === false && this.anchors.length ) { - options.active = 0; - } - - // Take disabling tabs via class attribute from HTML - // into account and update option properly. - if ( $.isArray( options.disabled ) ) { - options.disabled = $.unique( options.disabled.concat( - $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { - return that.tabs.index( li ); - }) - ) ).sort(); - } - - // check for length avoids error when initializing empty list - if ( this.options.active !== false && this.anchors.length ) { - this.active = this._findActive( this.options.active ); - } else { - this.active = $(); - } - - this._refresh(); - - if ( this.active.length ) { - this.load( options.active ); - } - }, - - _getCreateEventData: function() { - return { - tab: this.active, - panel: !this.active.length ? $() : this._getPanelForTab( this.active ) - }; - }, - - _tabKeydown: function( event ) { - var focusedTab = $( this.document[0].activeElement ).closest( "li" ), - selectedIndex = this.tabs.index( focusedTab ), - goingForward = true; - - if ( this._handlePageNav( event ) ) { - return; - } - - switch ( event.keyCode ) { - case $.ui.keyCode.RIGHT: - case $.ui.keyCode.DOWN: - selectedIndex++; - break; - case $.ui.keyCode.UP: - case $.ui.keyCode.LEFT: - goingForward = false; - selectedIndex--; - break; - case $.ui.keyCode.END: - selectedIndex = this.anchors.length - 1; - break; - case $.ui.keyCode.HOME: - selectedIndex = 0; - break; - case $.ui.keyCode.SPACE: - // Activate only, no collapsing - event.preventDefault(); - clearTimeout( this.activating ); - this._activate( selectedIndex ); - return; - case $.ui.keyCode.ENTER: - // Toggle (cancel delayed activation, allow collapsing) - event.preventDefault(); - clearTimeout( this.activating ); - // Determine if we should collapse or activate - this._activate( selectedIndex === this.options.active ? false : selectedIndex ); - return; - default: - return; - } - - // Focus the appropriate tab, based on which key was pressed - event.preventDefault(); - clearTimeout( this.activating ); - selectedIndex = this._focusNextTab( selectedIndex, goingForward ); - - // Navigating with control key will prevent automatic activation - if ( !event.ctrlKey ) { - // Update aria-selected immediately so that AT think the tab is already selected. - // Otherwise AT may confuse the user by stating that they need to activate the tab, - // but the tab will already be activated by the time the announcement finishes. - focusedTab.attr( "aria-selected", "false" ); - this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); - - this.activating = this._delay(function() { - this.option( "active", selectedIndex ); - }, this.delay ); - } - }, - - _panelKeydown: function( event ) { - if ( this._handlePageNav( event ) ) { - return; - } - - // Ctrl+up moves focus to the current tab - if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { - event.preventDefault(); - this.active.focus(); - } - }, - - // Alt+page up/down moves focus to the previous/next tab (and activates) - _handlePageNav: function( event ) { - if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { - this._activate( this._focusNextTab( this.options.active - 1, false ) ); - return true; - } - if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { - this._activate( this._focusNextTab( this.options.active + 1, true ) ); - return true; - } - }, - - _findNextTab: function( index, goingForward ) { - var lastTabIndex = this.tabs.length - 1; - - function constrain() { - if ( index > lastTabIndex ) { - index = 0; - } - if ( index < 0 ) { - index = lastTabIndex; - } - return index; - } - - while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { - index = goingForward ? index + 1 : index - 1; - } - - return index; - }, - - _focusNextTab: function( index, goingForward ) { - index = this._findNextTab( index, goingForward ); - this.tabs.eq( index ).focus(); - return index; - }, - - _setOption: function( key, value ) { - if ( key === "active" ) { - // _activate() will handle invalid values and update this.options - this._activate( value ); - return; - } - - if ( key === "disabled" ) { - // don't use the widget factory's disabled handling - this._setupDisabled( value ); - return; - } - - this._super( key, value); - - if ( key === "collapsible" ) { - this.element.toggleClass( "ui-tabs-collapsible", value ); - // Setting collapsible: false while collapsed; open first panel - if ( !value && this.options.active === false ) { - this._activate( 0 ); - } - } - - if ( key === "event" ) { - this._setupEvents( value ); - } - - if ( key === "heightStyle" ) { - this._setupHeightStyle( value ); - } - }, - - _tabId: function( tab ) { - return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId(); - }, - - _sanitizeSelector: function( hash ) { - return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; - }, - - refresh: function() { - var options = this.options, - lis = this.tablist.children( ":has(a[href])" ); - - // get disabled tabs from class attribute from HTML - // this will get converted to a boolean if needed in _refresh() - options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { - return lis.index( tab ); - }); - - this._processTabs(); - - // was collapsed or no tabs - if ( options.active === false || !this.anchors.length ) { - options.active = false; - this.active = $(); - // was active, but active tab is gone - } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { - // all remaining tabs are disabled - if ( this.tabs.length === options.disabled.length ) { - options.active = false; - this.active = $(); - // activate previous tab - } else { - this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); - } - // was active, active tab still exists - } else { - // make sure active index is correct - options.active = this.tabs.index( this.active ); - } - - this._refresh(); - }, - - _refresh: function() { - this._setupDisabled( this.options.disabled ); - this._setupEvents( this.options.event ); - this._setupHeightStyle( this.options.heightStyle ); - - this.tabs.not( this.active ).attr({ - "aria-selected": "false", - tabIndex: -1 - }); - this.panels.not( this._getPanelForTab( this.active ) ) - .hide() - .attr({ - "aria-expanded": "false", - "aria-hidden": "true" - }); - - // Make sure one tab is in the tab order - if ( !this.active.length ) { - this.tabs.eq( 0 ).attr( "tabIndex", 0 ); - } else { - this.active - .addClass( "ui-tabs-active ui-state-active" ) - .attr({ - "aria-selected": "true", - tabIndex: 0 - }); - this._getPanelForTab( this.active ) - .show() - .attr({ - "aria-expanded": "true", - "aria-hidden": "false" - }); - } - }, - - _processTabs: function() { - var that = this; - - this.tablist = this._getList() - .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) - .attr( "role", "tablist" ); - - this.tabs = this.tablist.find( "> li:has(a[href])" ) - .addClass( "ui-state-default ui-corner-top" ) - .attr({ - role: "tab", - tabIndex: -1 - }); - - this.anchors = this.tabs.map(function() { - return $( "a", this )[ 0 ]; - }) - .addClass( "ui-tabs-anchor" ) - .attr({ - role: "presentation", - tabIndex: -1 - }); - - this.panels = $(); - - this.anchors.each(function( i, anchor ) { - var selector, panel, panelId, - anchorId = $( anchor ).uniqueId().attr( "id" ), - tab = $( anchor ).closest( "li" ), - originalAriaControls = tab.attr( "aria-controls" ); - - // inline tab - if ( isLocal( anchor ) ) { - selector = anchor.hash; - panel = that.element.find( that._sanitizeSelector( selector ) ); - // remote tab - } else { - panelId = that._tabId( tab ); - selector = "#" + panelId; - panel = that.element.find( selector ); - if ( !panel.length ) { - panel = that._createPanel( panelId ); - panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); - } - panel.attr( "aria-live", "polite" ); - } - - if ( panel.length) { - that.panels = that.panels.add( panel ); - } - if ( originalAriaControls ) { - tab.data( "ui-tabs-aria-controls", originalAriaControls ); - } - tab.attr({ - "aria-controls": selector.substring( 1 ), - "aria-labelledby": anchorId - }); - panel.attr( "aria-labelledby", anchorId ); - }); - - this.panels - .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) - .attr( "role", "tabpanel" ); - }, - - // allow overriding how to find the list for rare usage scenarios (#7715) - _getList: function() { - return this.element.find( "ol,ul" ).eq( 0 ); - }, - - _createPanel: function( id ) { - return $( "<div>" ) - .attr( "id", id ) - .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) - .data( "ui-tabs-destroy", true ); - }, - - _setupDisabled: function( disabled ) { - if ( $.isArray( disabled ) ) { - if ( !disabled.length ) { - disabled = false; - } else if ( disabled.length === this.anchors.length ) { - disabled = true; - } - } - - // disable tabs - for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) { - if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { - $( li ) - .addClass( "ui-state-disabled" ) - .attr( "aria-disabled", "true" ); - } else { - $( li ) - .removeClass( "ui-state-disabled" ) - .removeAttr( "aria-disabled" ); - } - } - - this.options.disabled = disabled; - }, - - _setupEvents: function( event ) { - var events = { - click: function( event ) { - event.preventDefault(); - } - }; - if ( event ) { - $.each( event.split(" "), function( index, eventName ) { - events[ eventName ] = "_eventHandler"; - }); - } - - this._off( this.anchors.add( this.tabs ).add( this.panels ) ); - this._on( this.anchors, events ); - this._on( this.tabs, { keydown: "_tabKeydown" } ); - this._on( this.panels, { keydown: "_panelKeydown" } ); - - this._focusable( this.tabs ); - this._hoverable( this.tabs ); - }, - - _setupHeightStyle: function( heightStyle ) { - var maxHeight, overflow, - parent = this.element.parent(); - - if ( heightStyle === "fill" ) { - // IE 6 treats height like minHeight, so we need to turn off overflow - // in order to get a reliable height - // we use the minHeight support test because we assume that only - // browsers that don't support minHeight will treat height as minHeight - if ( !$.support.minHeight ) { - overflow = parent.css( "overflow" ); - parent.css( "overflow", "hidden"); - } - maxHeight = parent.height(); - this.element.siblings( ":visible" ).each(function() { - var elem = $( this ), - position = elem.css( "position" ); - - if ( position === "absolute" || position === "fixed" ) { - return; - } - maxHeight -= elem.outerHeight( true ); - }); - if ( overflow ) { - parent.css( "overflow", overflow ); - } - - this.element.children().not( this.panels ).each(function() { - maxHeight -= $( this ).outerHeight( true ); - }); - - this.panels.each(function() { - $( this ).height( Math.max( 0, maxHeight - - $( this ).innerHeight() + $( this ).height() ) ); - }) - .css( "overflow", "auto" ); - } else if ( heightStyle === "auto" ) { - maxHeight = 0; - this.panels.each(function() { - maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); - }).height( maxHeight ); - } - }, - - _eventHandler: function( event ) { - var options = this.options, - active = this.active, - anchor = $( event.currentTarget ), - tab = anchor.closest( "li" ), - clickedIsActive = tab[ 0 ] === active[ 0 ], - collapsing = clickedIsActive && options.collapsible, - toShow = collapsing ? $() : this._getPanelForTab( tab ), - toHide = !active.length ? $() : this._getPanelForTab( active ), - eventData = { - oldTab: active, - oldPanel: toHide, - newTab: collapsing ? $() : tab, - newPanel: toShow - }; - - event.preventDefault(); - - if ( tab.hasClass( "ui-state-disabled" ) || - // tab is already loading - tab.hasClass( "ui-tabs-loading" ) || - // can't switch durning an animation - this.running || - // click on active header, but not collapsible - ( clickedIsActive && !options.collapsible ) || - // allow canceling activation - ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { - return; - } - - options.active = collapsing ? false : this.tabs.index( tab ); - - this.active = clickedIsActive ? $() : tab; - if ( this.xhr ) { - this.xhr.abort(); - } - - if ( !toHide.length && !toShow.length ) { - $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); - } - - if ( toShow.length ) { - this.load( this.tabs.index( tab ), event ); - } - this._toggle( event, eventData ); - }, - - // handles show/hide for selecting tabs - _toggle: function( event, eventData ) { - var that = this, - toShow = eventData.newPanel, - toHide = eventData.oldPanel; - - this.running = true; - - function complete() { - that.running = false; - that._trigger( "activate", event, eventData ); - } - - function show() { - eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); - - if ( toShow.length && that.options.show ) { - that._show( toShow, that.options.show, complete ); - } else { - toShow.show(); - complete(); - } - } - - // start out by hiding, then showing, then completing - if ( toHide.length && this.options.hide ) { - this._hide( toHide, this.options.hide, function() { - eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); - show(); - }); - } else { - eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); - toHide.hide(); - show(); - } - - toHide.attr({ - "aria-expanded": "false", - "aria-hidden": "true" - }); - eventData.oldTab.attr( "aria-selected", "false" ); - // If we're switching tabs, remove the old tab from the tab order. - // If we're opening from collapsed state, remove the previous tab from the tab order. - // If we're collapsing, then keep the collapsing tab in the tab order. - if ( toShow.length && toHide.length ) { - eventData.oldTab.attr( "tabIndex", -1 ); - } else if ( toShow.length ) { - this.tabs.filter(function() { - return $( this ).attr( "tabIndex" ) === 0; - }) - .attr( "tabIndex", -1 ); - } - - toShow.attr({ - "aria-expanded": "true", - "aria-hidden": "false" - }); - eventData.newTab.attr({ - "aria-selected": "true", - tabIndex: 0 - }); - }, - - _activate: function( index ) { - var anchor, - active = this._findActive( index ); - - // trying to activate the already active panel - if ( active[ 0 ] === this.active[ 0 ] ) { - return; - } - - // trying to collapse, simulate a click on the current active header - if ( !active.length ) { - active = this.active; - } - - anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; - this._eventHandler({ - target: anchor, - currentTarget: anchor, - preventDefault: $.noop - }); - }, - - _findActive: function( index ) { - return index === false ? $() : this.tabs.eq( index ); - }, - - _getIndex: function( index ) { - // meta-function to give users option to provide a href string instead of a numerical index. - if ( typeof index === "string" ) { - index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) ); - } - - return index; - }, - - _destroy: function() { - if ( this.xhr ) { - this.xhr.abort(); - } - - this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" ); - - this.tablist - .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) - .removeAttr( "role" ); - - this.anchors - .removeClass( "ui-tabs-anchor" ) - .removeAttr( "role" ) - .removeAttr( "tabIndex" ) - .removeData( "href.tabs" ) - .removeData( "load.tabs" ) - .removeUniqueId(); - - this.tabs.add( this.panels ).each(function() { - if ( $.data( this, "ui-tabs-destroy" ) ) { - $( this ).remove(); - } else { - $( this ) - .removeClass( "ui-state-default ui-state-active ui-state-disabled " + - "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" ) - .removeAttr( "tabIndex" ) - .removeAttr( "aria-live" ) - .removeAttr( "aria-busy" ) - .removeAttr( "aria-selected" ) - .removeAttr( "aria-labelledby" ) - .removeAttr( "aria-hidden" ) - .removeAttr( "aria-expanded" ) - .removeAttr( "role" ); - } - }); - - this.tabs.each(function() { - var li = $( this ), - prev = li.data( "ui-tabs-aria-controls" ); - if ( prev ) { - li.attr( "aria-controls", prev ); - } else { - li.removeAttr( "aria-controls" ); - } - }); - - this.panels.show(); - - if ( this.options.heightStyle !== "content" ) { - this.panels.css( "height", "" ); - } - }, - - enable: function( index ) { - var disabled = this.options.disabled; - if ( disabled === false ) { - return; - } - - if ( index === undefined ) { - disabled = false; - } else { - index = this._getIndex( index ); - if ( $.isArray( disabled ) ) { - disabled = $.map( disabled, function( num ) { - return num !== index ? num : null; - }); - } else { - disabled = $.map( this.tabs, function( li, num ) { - return num !== index ? num : null; - }); - } - } - this._setupDisabled( disabled ); - }, - - disable: function( index ) { - var disabled = this.options.disabled; - if ( disabled === true ) { - return; - } - - if ( index === undefined ) { - disabled = true; - } else { - index = this._getIndex( index ); - if ( $.inArray( index, disabled ) !== -1 ) { - return; - } - if ( $.isArray( disabled ) ) { - disabled = $.merge( [ index ], disabled ).sort(); - } else { - disabled = [ index ]; - } - } - this._setupDisabled( disabled ); - }, - - load: function( index, event ) { - index = this._getIndex( index ); - var that = this, - tab = this.tabs.eq( index ), - anchor = tab.find( ".ui-tabs-anchor" ), - panel = this._getPanelForTab( tab ), - eventData = { - tab: tab, - panel: panel - }; - - // not remote - if ( isLocal( anchor[ 0 ] ) ) { - return; - } - - this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); - - // support: jQuery <1.8 - // jQuery <1.8 returns false if the request is canceled in beforeSend, - // but as of 1.8, $.ajax() always returns a jqXHR object. - if ( this.xhr && this.xhr.statusText !== "canceled" ) { - tab.addClass( "ui-tabs-loading" ); - panel.attr( "aria-busy", "true" ); - - this.xhr - .success(function( response ) { - // support: jQuery <1.8 - // http://bugs.jquery.com/ticket/11778 - setTimeout(function() { - panel.html( response ); - that._trigger( "load", event, eventData ); - }, 1 ); - }) - .complete(function( jqXHR, status ) { - // support: jQuery <1.8 - // http://bugs.jquery.com/ticket/11778 - setTimeout(function() { - if ( status === "abort" ) { - that.panels.stop( false, true ); - } - - tab.removeClass( "ui-tabs-loading" ); - panel.removeAttr( "aria-busy" ); - - if ( jqXHR === that.xhr ) { - delete that.xhr; - } - }, 1 ); - }); - } - }, - - // TODO: Remove this function in 1.10 when ajaxOptions is removed - _ajaxSettings: function( anchor, event, eventData ) { - var that = this; - return { - url: anchor.attr( "href" ), - beforeSend: function( jqXHR, settings ) { - return that._trigger( "beforeLoad", event, - $.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) ); - } - }; - }, - - _getPanelForTab: function( tab ) { - var id = $( tab ).attr( "aria-controls" ); - return this.element.find( this._sanitizeSelector( "#" + id ) ); - } -}); - -// DEPRECATED -if ( $.uiBackCompat !== false ) { - - // helper method for a lot of the back compat extensions - $.ui.tabs.prototype._ui = function( tab, panel ) { - return { - tab: tab, - panel: panel, - index: this.anchors.index( tab ) - }; - }; - - // url method - $.widget( "ui.tabs", $.ui.tabs, { - url: function( index, url ) { - this.anchors.eq( index ).attr( "href", url ); - } - }); - - // TODO: Remove _ajaxSettings() method when removing this extension - // ajaxOptions and cache options - $.widget( "ui.tabs", $.ui.tabs, { - options: { - ajaxOptions: null, - cache: false - }, - - _create: function() { - this._super(); - - var that = this; - - this._on({ tabsbeforeload: function( event, ui ) { - // tab is already cached - if ( $.data( ui.tab[ 0 ], "cache.tabs" ) ) { - event.preventDefault(); - return; - } - - ui.jqXHR.success(function() { - if ( that.options.cache ) { - $.data( ui.tab[ 0 ], "cache.tabs", true ); - } - }); - }}); - }, - - _ajaxSettings: function( anchor, event, ui ) { - var ajaxOptions = this.options.ajaxOptions; - return $.extend( {}, ajaxOptions, { - error: function( xhr, status ) { - try { - // Passing index avoid a race condition when this method is - // called after the user has selected another tab. - // Pass the anchor that initiated this request allows - // loadError to manipulate the tab content panel via $(a.hash) - ajaxOptions.error( - xhr, status, ui.tab.closest( "li" ).index(), ui.tab[ 0 ] ); - } - catch ( error ) {} - } - }, this._superApply( arguments ) ); - }, - - _setOption: function( key, value ) { - // reset cache if switching from cached to not cached - if ( key === "cache" && value === false ) { - this.anchors.removeData( "cache.tabs" ); - } - this._super( key, value ); - }, - - _destroy: function() { - this.anchors.removeData( "cache.tabs" ); - this._super(); - }, - - url: function( index ){ - this.anchors.eq( index ).removeData( "cache.tabs" ); - this._superApply( arguments ); - } - }); - - // abort method - $.widget( "ui.tabs", $.ui.tabs, { - abort: function() { - if ( this.xhr ) { - this.xhr.abort(); - } - } - }); - - // spinner - $.widget( "ui.tabs", $.ui.tabs, { - options: { - spinner: "<em>Loading…</em>" - }, - _create: function() { - this._super(); - this._on({ - tabsbeforeload: function( event, ui ) { - // Don't react to nested tabs or tabs that don't use a spinner - if ( event.target !== this.element[ 0 ] || - !this.options.spinner ) { - return; - } - - var span = ui.tab.find( "span" ), - html = span.html(); - span.html( this.options.spinner ); - ui.jqXHR.complete(function() { - span.html( html ); - }); - } - }); - } - }); - - // enable/disable events - $.widget( "ui.tabs", $.ui.tabs, { - options: { - enable: null, - disable: null - }, - - enable: function( index ) { - var options = this.options, - trigger; - - if ( index && options.disabled === true || - ( $.isArray( options.disabled ) && $.inArray( index, options.disabled ) !== -1 ) ) { - trigger = true; - } - - this._superApply( arguments ); - - if ( trigger ) { - this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) ); - } - }, - - disable: function( index ) { - var options = this.options, - trigger; - - if ( index && options.disabled === false || - ( $.isArray( options.disabled ) && $.inArray( index, options.disabled ) === -1 ) ) { - trigger = true; - } - - this._superApply( arguments ); - - if ( trigger ) { - this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) ); - } - } - }); - - // add/remove methods and events - $.widget( "ui.tabs", $.ui.tabs, { - options: { - add: null, - remove: null, - tabTemplate: "<li><a href='#{href}'><span>#{label}</span></a></li>" - }, - - add: function( url, label, index ) { - if ( index === undefined ) { - index = this.anchors.length; - } - - var doInsertAfter, panel, - options = this.options, - li = $( options.tabTemplate - .replace( /#\{href\}/g, url ) - .replace( /#\{label\}/g, label ) ), - id = !url.indexOf( "#" ) ? - url.replace( "#", "" ) : - this._tabId( li ); - - li.addClass( "ui-state-default ui-corner-top" ).data( "ui-tabs-destroy", true ); - li.attr( "aria-controls", id ); - - doInsertAfter = index >= this.tabs.length; - - // try to find an existing element before creating a new one - panel = this.element.find( "#" + id ); - if ( !panel.length ) { - panel = this._createPanel( id ); - if ( doInsertAfter ) { - if ( index > 0 ) { - panel.insertAfter( this.panels.eq( -1 ) ); - } else { - panel.appendTo( this.element ); - } - } else { - panel.insertBefore( this.panels[ index ] ); - } - } - panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ).hide(); - - if ( doInsertAfter ) { - li.appendTo( this.tablist ); - } else { - li.insertBefore( this.tabs[ index ] ); - } - - options.disabled = $.map( options.disabled, function( n ) { - return n >= index ? ++n : n; - }); - - this.refresh(); - if ( this.tabs.length === 1 && options.active === false ) { - this.option( "active", 0 ); - } - - this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) ); - return this; - }, - - remove: function( index ) { - index = this._getIndex( index ); - var options = this.options, - tab = this.tabs.eq( index ).remove(), - panel = this._getPanelForTab( tab ).remove(); - - // If selected tab was removed focus tab to the right or - // in case the last tab was removed the tab to the left. - // We check for more than 2 tabs, because if there are only 2, - // then when we remove this tab, there will only be one tab left - // so we don't need to detect which tab to activate. - if ( tab.hasClass( "ui-tabs-active" ) && this.anchors.length > 2 ) { - this._activate( index + ( index + 1 < this.anchors.length ? 1 : -1 ) ); - } - - options.disabled = $.map( - $.grep( options.disabled, function( n ) { - return n !== index; - }), - function( n ) { - return n >= index ? --n : n; - }); - - this.refresh(); - - this._trigger( "remove", null, this._ui( tab.find( "a" )[ 0 ], panel[ 0 ] ) ); - return this; - } - }); - - // length method - $.widget( "ui.tabs", $.ui.tabs, { - length: function() { - return this.anchors.length; - } - }); - - // panel ids (idPrefix option + title attribute) - $.widget( "ui.tabs", $.ui.tabs, { - options: { - idPrefix: "ui-tabs-" - }, - - _tabId: function( tab ) { - var a = tab.is( "li" ) ? tab.find( "a[href]" ) : tab; - a = a[0]; - return $( a ).closest( "li" ).attr( "aria-controls" ) || - a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF\-]/g, "" ) || - this.options.idPrefix + getNextTabId(); - } - }); - - // _createPanel method - $.widget( "ui.tabs", $.ui.tabs, { - options: { - panelTemplate: "<div></div>" - }, - - _createPanel: function( id ) { - return $( this.options.panelTemplate ) - .attr( "id", id ) - .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) - .data( "ui-tabs-destroy", true ); - } - }); - - // selected option - $.widget( "ui.tabs", $.ui.tabs, { - _create: function() { - var options = this.options; - if ( options.active === null && options.selected !== undefined ) { - options.active = options.selected === -1 ? false : options.selected; - } - this._super(); - options.selected = options.active; - if ( options.selected === false ) { - options.selected = -1; - } - }, - - _setOption: function( key, value ) { - if ( key !== "selected" ) { - return this._super( key, value ); - } - - var options = this.options; - this._super( "active", value === -1 ? false : value ); - options.selected = options.active; - if ( options.selected === false ) { - options.selected = -1; - } - }, - - _eventHandler: function() { - this._superApply( arguments ); - this.options.selected = this.options.active; - if ( this.options.selected === false ) { - this.options.selected = -1; - } - } - }); - - // show and select event - $.widget( "ui.tabs", $.ui.tabs, { - options: { - show: null, - select: null - }, - _create: function() { - this._super(); - if ( this.options.active !== false ) { - this._trigger( "show", null, this._ui( - this.active.find( ".ui-tabs-anchor" )[ 0 ], - this._getPanelForTab( this.active )[ 0 ] ) ); - } - }, - _trigger: function( type, event, data ) { - var tab, panel, - ret = this._superApply( arguments ); - - if ( !ret ) { - return false; - } - - if ( type === "beforeActivate" ) { - tab = data.newTab.length ? data.newTab : data.oldTab; - panel = data.newPanel.length ? data.newPanel : data.oldPanel; - ret = this._super( "select", event, { - tab: tab.find( ".ui-tabs-anchor" )[ 0], - panel: panel[ 0 ], - index: tab.closest( "li" ).index() - }); - } else if ( type === "activate" && data.newTab.length ) { - ret = this._super( "show", event, { - tab: data.newTab.find( ".ui-tabs-anchor" )[ 0 ], - panel: data.newPanel[ 0 ], - index: data.newTab.closest( "li" ).index() - }); - } - return ret; - } - }); - - // select method - $.widget( "ui.tabs", $.ui.tabs, { - select: function( index ) { - index = this._getIndex( index ); - if ( index === -1 ) { - if ( this.options.collapsible && this.options.selected !== -1 ) { - index = this.options.selected; - } else { - return; - } - } - this.anchors.eq( index ).trigger( this.options.event + this.eventNamespace ); - } - }); - - // cookie option - (function() { - - var listId = 0; - - $.widget( "ui.tabs", $.ui.tabs, { - options: { - cookie: null // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true } - }, - _create: function() { - var options = this.options, - active; - if ( options.active == null && options.cookie ) { - active = parseInt( this._cookie(), 10 ); - if ( active === -1 ) { - active = false; - } - options.active = active; - } - this._super(); - }, - _cookie: function( active ) { - var cookie = [ this.cookie || - ( this.cookie = this.options.cookie.name || "ui-tabs-" + (++listId) ) ]; - if ( arguments.length ) { - cookie.push( active === false ? -1 : active ); - cookie.push( this.options.cookie ); - } - return $.cookie.apply( null, cookie ); - }, - _refresh: function() { - this._super(); - if ( this.options.cookie ) { - this._cookie( this.options.active, this.options.cookie ); - } - }, - _eventHandler: function() { - this._superApply( arguments ); - if ( this.options.cookie ) { - this._cookie( this.options.active, this.options.cookie ); - } - }, - _destroy: function() { - this._super(); - if ( this.options.cookie ) { - this._cookie( null, this.options.cookie ); - } - } - }); - - })(); - - // load event - $.widget( "ui.tabs", $.ui.tabs, { - _trigger: function( type, event, data ) { - var _data = $.extend( {}, data ); - if ( type === "load" ) { - _data.panel = _data.panel[ 0 ]; - _data.tab = _data.tab.find( ".ui-tabs-anchor" )[ 0 ]; - } - return this._super( type, event, _data ); - } - }); - - // fx option - // The new animation options (show, hide) conflict with the old show callback. - // The old fx option wins over show/hide anyway (always favor back-compat). - // If a user wants to use the new animation API, they must give up the old API. - $.widget( "ui.tabs", $.ui.tabs, { - options: { - fx: null // e.g. { height: "toggle", opacity: "toggle", duration: 200 } - }, - - _getFx: function() { - var hide, show, - fx = this.options.fx; - - if ( fx ) { - if ( $.isArray( fx ) ) { - hide = fx[ 0 ]; - show = fx[ 1 ]; - } else { - hide = show = fx; - } - } - - return fx ? { show: show, hide: hide } : null; - }, - - _toggle: function( event, eventData ) { - var that = this, - toShow = eventData.newPanel, - toHide = eventData.oldPanel, - fx = this._getFx(); - - if ( !fx ) { - return this._super( event, eventData ); - } - - that.running = true; - - function complete() { - that.running = false; - that._trigger( "activate", event, eventData ); - } - - function show() { - eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); - - if ( toShow.length && fx.show ) { - toShow - .animate( fx.show, fx.show.duration, function() { - complete(); - }); - } else { - toShow.show(); - complete(); - } - } - - // start out by hiding, then showing, then completing - if ( toHide.length && fx.hide ) { - toHide.animate( fx.hide, fx.hide.duration, function() { - eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); - show(); - }); - } else { - eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); - toHide.hide(); - show(); - } - } - }); -} - -})( jQuery ); - -(function( $ ) { - -var increments = 0; - -function addDescribedBy( elem, id ) { - var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ); - describedby.push( id ); - elem - .data( "ui-tooltip-id", id ) - .attr( "aria-describedby", $.trim( describedby.join( " " ) ) ); -} - -function removeDescribedBy( elem ) { - var id = elem.data( "ui-tooltip-id" ), - describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ), - index = $.inArray( id, describedby ); - if ( index !== -1 ) { - describedby.splice( index, 1 ); - } - - elem.removeData( "ui-tooltip-id" ); - describedby = $.trim( describedby.join( " " ) ); - if ( describedby ) { - elem.attr( "aria-describedby", describedby ); - } else { - elem.removeAttr( "aria-describedby" ); - } -} - -$.widget( "ui.tooltip", { - version: "1.9.2", - options: { - content: function() { - return $( this ).attr( "title" ); - }, - hide: true, - // Disabled elements have inconsistent behavior across browsers (#8661) - items: "[title]:not([disabled])", - position: { - my: "left top+15", - at: "left bottom", - collision: "flipfit flip" - }, - show: true, - tooltipClass: null, - track: false, - - // callbacks - close: null, - open: null - }, - - _create: function() { - this._on({ - mouseover: "open", - focusin: "open" - }); - - // IDs of generated tooltips, needed for destroy - this.tooltips = {}; - // IDs of parent tooltips where we removed the title attribute - this.parents = {}; - - if ( this.options.disabled ) { - this._disable(); - } - }, - - _setOption: function( key, value ) { - var that = this; - - if ( key === "disabled" ) { - this[ value ? "_disable" : "_enable" ](); - this.options[ key ] = value; - // disable element style changes - return; - } - - this._super( key, value ); - - if ( key === "content" ) { - $.each( this.tooltips, function( id, element ) { - that._updateContent( element ); - }); - } - }, - - _disable: function() { - var that = this; - - // close open tooltips - $.each( this.tooltips, function( id, element ) { - var event = $.Event( "blur" ); - event.target = event.currentTarget = element[0]; - that.close( event, true ); - }); - - // remove title attributes to prevent native tooltips - this.element.find( this.options.items ).andSelf().each(function() { - var element = $( this ); - if ( element.is( "[title]" ) ) { - element - .data( "ui-tooltip-title", element.attr( "title" ) ) - .attr( "title", "" ); - } - }); - }, - - _enable: function() { - // restore title attributes - this.element.find( this.options.items ).andSelf().each(function() { - var element = $( this ); - if ( element.data( "ui-tooltip-title" ) ) { - element.attr( "title", element.data( "ui-tooltip-title" ) ); - } - }); - }, - - open: function( event ) { - var that = this, - target = $( event ? event.target : this.element ) - // we need closest here due to mouseover bubbling, - // but always pointing at the same event target - .closest( this.options.items ); - - // No element to show a tooltip for or the tooltip is already open - if ( !target.length || target.data( "ui-tooltip-id" ) ) { - return; - } - - if ( target.attr( "title" ) ) { - target.data( "ui-tooltip-title", target.attr( "title" ) ); - } - - target.data( "ui-tooltip-open", true ); - - // kill parent tooltips, custom or native, for hover - if ( event && event.type === "mouseover" ) { - target.parents().each(function() { - var parent = $( this ), - blurEvent; - if ( parent.data( "ui-tooltip-open" ) ) { - blurEvent = $.Event( "blur" ); - blurEvent.target = blurEvent.currentTarget = this; - that.close( blurEvent, true ); - } - if ( parent.attr( "title" ) ) { - parent.uniqueId(); - that.parents[ this.id ] = { - element: this, - title: parent.attr( "title" ) - }; - parent.attr( "title", "" ); - } - }); - } - - this._updateContent( target, event ); - }, - - _updateContent: function( target, event ) { - var content, - contentOption = this.options.content, - that = this, - eventType = event ? event.type : null; - - if ( typeof contentOption === "string" ) { - return this._open( event, target, contentOption ); - } - - content = contentOption.call( target[0], function( response ) { - // ignore async response if tooltip was closed already - if ( !target.data( "ui-tooltip-open" ) ) { - return; - } - // IE may instantly serve a cached response for ajax requests - // delay this call to _open so the other call to _open runs first - that._delay(function() { - // jQuery creates a special event for focusin when it doesn't - // exist natively. To improve performance, the native event - // object is reused and the type is changed. Therefore, we can't - // rely on the type being correct after the event finished - // bubbling, so we set it back to the previous value. (#8740) - if ( event ) { - event.type = eventType; - } - this._open( event, target, response ); - }); - }); - if ( content ) { - this._open( event, target, content ); - } - }, - - _open: function( event, target, content ) { - var tooltip, events, delayedShow, - positionOption = $.extend( {}, this.options.position ); - - if ( !content ) { - return; - } - - // Content can be updated multiple times. If the tooltip already - // exists, then just update the content and bail. - tooltip = this._find( target ); - if ( tooltip.length ) { - tooltip.find( ".ui-tooltip-content" ).html( content ); - return; - } - - // if we have a title, clear it to prevent the native tooltip - // we have to check first to avoid defining a title if none exists - // (we don't want to cause an element to start matching [title]) - // - // We use removeAttr only for key events, to allow IE to export the correct - // accessible attributes. For mouse events, set to empty string to avoid - // native tooltip showing up (happens only when removing inside mouseover). - if ( target.is( "[title]" ) ) { - if ( event && event.type === "mouseover" ) { - target.attr( "title", "" ); - } else { - target.removeAttr( "title" ); - } - } - - tooltip = this._tooltip( target ); - addDescribedBy( target, tooltip.attr( "id" ) ); - tooltip.find( ".ui-tooltip-content" ).html( content ); - - function position( event ) { - positionOption.of = event; - if ( tooltip.is( ":hidden" ) ) { - return; - } - tooltip.position( positionOption ); - } - if ( this.options.track && event && /^mouse/.test( event.type ) ) { - this._on( this.document, { - mousemove: position - }); - // trigger once to override element-relative positioning - position( event ); - } else { - tooltip.position( $.extend({ - of: target - }, this.options.position ) ); - } - - tooltip.hide(); - - this._show( tooltip, this.options.show ); - // Handle tracking tooltips that are shown with a delay (#8644). As soon - // as the tooltip is visible, position the tooltip using the most recent - // event. - if ( this.options.show && this.options.show.delay ) { - delayedShow = setInterval(function() { - if ( tooltip.is( ":visible" ) ) { - position( positionOption.of ); - clearInterval( delayedShow ); - } - }, $.fx.interval ); - } - - this._trigger( "open", event, { tooltip: tooltip } ); - - events = { - keyup: function( event ) { - if ( event.keyCode === $.ui.keyCode.ESCAPE ) { - var fakeEvent = $.Event(event); - fakeEvent.currentTarget = target[0]; - this.close( fakeEvent, true ); - } - }, - remove: function() { - this._removeTooltip( tooltip ); - } - }; - if ( !event || event.type === "mouseover" ) { - events.mouseleave = "close"; - } - if ( !event || event.type === "focusin" ) { - events.focusout = "close"; - } - this._on( true, target, events ); - }, - - close: function( event ) { - var that = this, - target = $( event ? event.currentTarget : this.element ), - tooltip = this._find( target ); - - // disabling closes the tooltip, so we need to track when we're closing - // to avoid an infinite loop in case the tooltip becomes disabled on close - if ( this.closing ) { - return; - } - - // only set title if we had one before (see comment in _open()) - if ( target.data( "ui-tooltip-title" ) ) { - target.attr( "title", target.data( "ui-tooltip-title" ) ); - } - - removeDescribedBy( target ); - - tooltip.stop( true ); - this._hide( tooltip, this.options.hide, function() { - that._removeTooltip( $( this ) ); - }); - - target.removeData( "ui-tooltip-open" ); - this._off( target, "mouseleave focusout keyup" ); - // Remove 'remove' binding only on delegated targets - if ( target[0] !== this.element[0] ) { - this._off( target, "remove" ); - } - this._off( this.document, "mousemove" ); - - if ( event && event.type === "mouseleave" ) { - $.each( this.parents, function( id, parent ) { - $( parent.element ).attr( "title", parent.title ); - delete that.parents[ id ]; - }); - } - - this.closing = true; - this._trigger( "close", event, { tooltip: tooltip } ); - this.closing = false; - }, - - _tooltip: function( element ) { - var id = "ui-tooltip-" + increments++, - tooltip = $( "<div>" ) - .attr({ - id: id, - role: "tooltip" - }) - .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " + - ( this.options.tooltipClass || "" ) ); - $( "<div>" ) - .addClass( "ui-tooltip-content" ) - .appendTo( tooltip ); - tooltip.appendTo( this.document[0].body ); - if ( $.fn.bgiframe ) { - tooltip.bgiframe(); - } - this.tooltips[ id ] = element; - return tooltip; - }, - - _find: function( target ) { - var id = target.data( "ui-tooltip-id" ); - return id ? $( "#" + id ) : $(); - }, - - _removeTooltip: function( tooltip ) { - tooltip.remove(); - delete this.tooltips[ tooltip.attr( "id" ) ]; - }, - - _destroy: function() { - var that = this; - - // close open tooltips - $.each( this.tooltips, function( id, element ) { - // Delegate to close method to handle common cleanup - var event = $.Event( "blur" ); - event.target = event.currentTarget = element[0]; - that.close( event, true ); - - // Remove immediately; destroying an open tooltip doesn't use the - // hide animation - $( "#" + id ).remove(); - - // Restore the title - if ( element.data( "ui-tooltip-title" ) ) { - element.attr( "title", element.data( "ui-tooltip-title" ) ); - element.removeData( "ui-tooltip-title" ); - } - }); - } -}); - -}( jQuery ) ); diff --git a/unittests/example_labfolder_data/static/js/labfolder-global.js b/unittests/example_labfolder_data/static/js/labfolder-global.js deleted file mode 100644 index 0e69b6a2b2e7fa3767f7082fd8bf571570601f43..0000000000000000000000000000000000000000 --- a/unittests/example_labfolder_data/static/js/labfolder-global.js +++ /dev/null @@ -1,81 +0,0 @@ -$(document).ready(function(){ - Global.init(); -}); - -var Global = { - - init: function(){ - var globalData = $("#global_data"); - - // firstLogin - this.firstLogin = (globalData.attr("data-firstlogin") == "true") ? true : false; - - // currentUser - this.userShowHiddenItems = (globalData.attr("data-user-show-hidden-items") == "true") ? true : false; - this.userId = globalData.attr("data-user-id"); - this.userProfilePictureHash = globalData.attr("data-user-profilePictureHash"); - this.userFirstName = globalData.attr("data-user-firstName"); - this.userLastName = globalData.attr("data-user-lastName"); - this.userProfileComplete = (globalData.attr("data-user-profileComplete") == "true") ? true : false; - this.orderASC = (globalData.attr("data-user-orderASC") == "true" ) ? true : false; - - // currentProject - this.projectId = globalData.attr("data-project-id"); - this.projectIsTemplate = (globalData.attr("data-project-is-template") == "true") ? true : false; - this.projectIsHidden = (globalData.attr("data-project-is-hidden") == "true") ? true : false; - - // currentGroup - this.groupId = globalData.attr("data-group-id"); - this.groupType = globalData.attr("data-group-type"); - this.groupSettingsPreventDeleteProject = (globalData.attr("data-group-settings-prevent-delete-project") == "true") ? true : false; - - // currentGroupMemberAdminLevels - this.groupMemberAdminLevels = []; - var groupMemberAdminLevelsStr = globalData.attr("data-group-member-admin-levels"); - if(groupMemberAdminLevelsStr) { - var arr = groupMemberAdminLevelsStr.split(","); - for(var i=0; i<arr.length; i++) { - var trimmed = $.trim(arr[i]); - if(trimmed != "") { - this.groupMemberAdminLevels.push(trimmed); - } - } - } - - this.installedApps = []; - var installedAppsStr = globalData.attr("data-installed-apps"); - if(installedAppsStr) { - var arr = installedAppsStr.split(","); - for(var i=0; i<arr.length; i++) { - var trimmed = $.trim(arr[i]); - if(trimmed != "") { - this.installedApps.push(trimmed); - } - } - } - - this.buildNumber = globalData.attr("data-build-number"); - - this.viewname = $("#data_element").attr("data-viewname"); - - }, - - isGroupAdmin: function(subgroupId) { - for (var i = 0; i < this.groupMemberAdminLevels.length; i++) { - if(this.groupMemberAdminLevels[i] == subgroupId) { - return true; - } - } - return false; - }, - - isAppInstalled: function(appKey) { - for (var i = 0; i < this.installedApps.length; i++) { - if(this.installedApps[i] == appKey) { - return true; - } - } - return false; - } - -} diff --git a/unittests/example_labfolder_data/static/js/tree.js b/unittests/example_labfolder_data/static/js/tree.js deleted file mode 100644 index 180c860065ac22a98f3ce61ff90ffe5141a81979..0000000000000000000000000000000000000000 --- a/unittests/example_labfolder_data/static/js/tree.js +++ /dev/null @@ -1,505 +0,0 @@ -function initTreelineButtonsElnProjects(treeId) { - initTreelineMoreOptionsDeleteFolder(treeId, "/eln/workspace/{id}/isEmpty", "/eln/workspace/{id}/delete"); -} - -function initTreelineButtonsTextTemplates(treeId) { - initTreelineMoreOptionsDeleteFolder(treeId, "/eln/workspace/{id}/isEmpty", "/eln/workspace/{id}/delete"); -} - -var TreeElement = { - - createNew: function(item, elType, group, callback) { - - var saveCallback = function(formData) { - var formObj = convertFormArrayToObject(formData); - TreeElement.saveNew(item, elType, formObj, callback); - }; - - var isTemplate = (elType == "TEMPLATE"); - var itemName = isTemplate ? "template" : "project"; - - var options = { - templateName: "jsTemplate_workspace_create_project_dialog", - treeId: "project_popup", - treeUrl: "/eln/workspace/treeInPopup", - template: isTemplate, - showTreeFoldersOnly: true, - treeFolderSelectable: true, - treeItemSelectable: false, - selectedTreelineCallback: function(formData){ - saveCallback(formData); - } - }; - - if(item == "item"){ - openSelectTreelineDialog("Create " + itemName, options); - - }else if(item == "folder"){ - options.templateName= "jsTemplate_workspace_create_folder_dialog"; - openSelectTreelineDialog("Create folder", options); - } - }, - - saveNew: function(item, elType, formObj, fCallback){ - - var formData = { - name: formObj.name, - groupId: formObj.selectedTreelineGroupId, - parentId: formObj.selectedTreelineObjectId, - csrfToken: getCSRFToken(), - type: elType - }; - - var callback; - - var postUrl; - - if(item == "item"){ - - postUrl = "/eln/workspace/createProject"; - - callback = function(data, textStatus, jqXHR){ - - if(data.status == 0) { - if (data.dataObj.groupId > 0 && data.dataObj.shareable) { - Group.projects.shareEdit(data.dataObj.id, data.dataObj.groupId); - - } else if(fCallback) { - fCallback(data); - - } else { - Dialog.close(); - location.reload(true); - } - - } else { - Dialog.showError(data.errorMessageList); - } - - } - } - else if(item == "folder"){ - - postUrl = "/eln/workspace/createFolder"; - - callback = function(data, textStatus, jqXHR){ - - if(data.status == 0) { - - Dialog.close(); - - var itemName = (elType == "TEMPLATE") ? "templates" : "projects"; - - var targetFolder = $("#treeline_eln_" + itemName +"_" + formObj.selectedTreelineGroupId + "_" + formObj.selectedTreelineObjectId).next(); - - var shareSettings = ""; - if(data.dataObj.shareable) { - shareSettings = "<div class='more_options_item buttonShareSettings'>" + - "<span aria-hidden='true' class='icon-conf'></span> Share settings" + - "</div>"; - } - - var newFolder = $("<a id='treeline_eln_" + itemName + "_" + formObj.selectedTreelineGroupId + "_" - + data.dataObj.id + "' data-groupid='" + formObj.selectedTreelineGroupId + "' " - + "data-objectid='" + data.dataObj.id + "' class='treeline is_folder is_open_folder'>") - .append("<span class='updateTS'>"+ data.dataObj.createTS + "</span>") - .append("<div class='tree_button more_options in_tree'>" - +"<button class='more_options_button_tree'><span aria-hidden='true' class='wheel-img'></span></button>" - +"<div class='more_options_panel in_tree' style='display: none;'>" - - +"<span class='menu_arrow-img'></span>" - +"<ul>" - +"<li class='more_options_item buttonRename'>Rename folder<span class='edit-img'></span></li>" - +"<li class='more_options_item treelineButtonDeleteFolder'>Delete folder<span class='trash_dark-img'></span></li>" - +"</ul>" - +"</div>" - +"</div>") - .append("<span class='folder_dn-img'></span>") - .append("<span class='name'> " + formObj.name + "</span>"); - - makeDroppable(newFolder); - makeDraggable(newFolder); - - var newChildren = $("<div class='treeline_children'><div class='treeline_children_empty'>empty folder</div></div>"); - newFolder.after(newChildren).hide(); - - targetFolder.append(newFolder).children(".treeline_children_empty").slideUp(300,function(){ - this.remove(); - }); - - newFolder.eq(0).css("background", "rgb(236, 240, 243)"); - - newFolder.show(300, function() { - $(newFolder.parents(".treeline_children").siblings(".is_folder")).each(function(){ - openTreelineFolder($(this)); - }); - newFolder.eq(0).css("overflow", "visible"); - setTimeout(function(){ - // TODO we should have exactly 1 main element in all pages - // in all projects page we have #eln_main_content - // in group projects page we have #eln_project_content - $("#eln_main_content, #eln_project_content").animate({ - scrollTop: $(newFolder).offset().top-200 - }, 500); - },500); - }); - - } else { - Dialog.showError(data.errorMessageList); - } - } - } - - $.post(postUrl, formData, function(data, textStatus, jqXHR){ - callback(data, textStatus, jqXHR); - }); - - } -} - - - -function initTreelineMoreOptionsDeleteFolder(treeId, isEmptyUrl, deleteUrl) { - $("body").on("click", ".treelineButtonDeleteFolder", function(){ - var treeline = $(this).closest("a.treeline"); - var objectId = treeline.attr("data-objectId"); - - var isEmptyUrlReplaced = isEmptyUrl.replace("{id}", objectId); - $.get(isEmptyUrlReplaced, {}, function(data, textStatus, jqXHR){ - if(data.status == 0) { - if(data.dataObj == true) { - - var templateData = { treeline_name: treeline.find("span.name").text() }; - var content = $.jsTemplate("jsTemplate_basic_delete_folder_dialog", templateData); - - var confirmButtonCallback = function() { - var deleteUrlReplaced = deleteUrl.replace("{id}", objectId); - $.post(deleteUrlReplaced, {csrfToken: getCSRFToken()}, function(data, textStatus, jqXHR){ - if(data.status == 0) { - var parentLine = treeline.parent(); - treeline.next().andSelf().slideUp(300, function(){ - this.remove(); - if(parentLine.children().length == 0){ - var emptyChildren = $("<div class='treeline_children_empty' style='display:none'>empty folder</div>"); - parentLine.append(emptyChildren); - emptyChildren.slideDown(300); - } - }); - Dialog.close(); - } else { - Dialog.showError(data.errorMessageList); - } - }); - }; - Dialog.confirm("Delete folder", content, {text: "Delete", callback: confirmButtonCallback}); - - } else { - Dialog.alert("Delete folder"); - Dialog.showError("This folder is not empty. Please delete all of its content first, then you can delete the folder itself"); - } - } else { - return ; - } - }); - - $(".more_options_panel").hide(); - return false; - }); -} - - -function selectTreeline(treeId, groupId, objectId) { - $("#tree_" + treeId + " input[name=selectedTreelineGroupId]").val(groupId); - $("#tree_" + treeId + " input[name=selectedTreelineObjectId]").val(objectId); - $("#tree_" + treeId + " .treeline").removeClass("selected"); - $("#treeline_" + treeId + "_" + groupId + "_" + objectId).addClass("selected"); -} - - - -function openSelectTreelineDialog(dialogTitle, options) { - - var content = $.jsTemplate(options.templateName, null); - - var confirmButtonCallback = function() { - var groupId = $("#tree_" + options.treeId + " input[name=selectedTreelineGroupId]").val(); - var objectId = $("#tree_" + options.treeId + " input[name=selectedTreelineObjectId]").val(); - - if(groupId == "" || objectId == "") { - if(dialogTitle == "Use template"){ - - Dialog.showError("Please select a template that you would like to use"); - - } else if(dialogTitle == "Save as new template"){ - - Dialog.showError("Please select a template folder"); - - }else if(dialogTitle == "Create a new entry"){ - - setTimeout(function(){Dialog.showError("Please select a project");}, 300); - } - - } else { - var formData = $("#my_popup_content form").serializeArray(); - options.selectedTreelineCallback(formData); - } - }; - - var loadedCallback = function() { - $.get(options.treeUrl, - { - treeId: options.treeId, - template: options.template, - showTreeFoldersOnly: options.showTreeFoldersOnly, - treeFolderSelectable: options.treeFolderSelectable, - treeItemSelectable: options.treeItemSelectable - }, - function(data, textStatus, jqXHR){ - var selectTree = $(data); - - $("#my_popup_content .spinner").fadeOut(300, function(){ - $("#my_popup_content .treeInPopupContainer").html(selectTree).slideDown(300, function(){ - var firstLine = $("#tree_project_popup a").first(); - selectTreeline(options.treeId, firstLine.attr("data-groupid"), firstLine.attr("data-objectid")); - Dialog.center(); - initTreelineFolders(options.treeId); - }); - }); - } - ); - - $("#my_popup_content input:first").focus(); - $("#my_popup_content form").submit(function(){ - confirmButtonCallback(); - return false; - }); - - }; - - Dialog.confirm(dialogTitle, content, {text: dialogTitle, callback: confirmButtonCallback}, {}, {}, loadedCallback); -} - -function moveProject(objectId, groupId, parentId){ - $.post("/eln/workspace/" + objectId + "/move", - { - "csrfToken": getCSRFToken(), - "parentId": parentId - }, - function(data){ - if(data.status != 0) { - Dialog.showError(data.errorMessageList); - } - } - ); -} - -function bindTreeUI(){ - //Hacky hack to fix jquery bug in 1.8.2 that adds overflow hidden when animating hide and show - $('body').on('mouseover', '.treeline, .treeline_children', function(){ - if($(this).css('overflow') == "hidden" ) $(this).css("overflow", "visible"); - }); - - var droppableScope = $("a.is_folder"); - makeDroppable(droppableScope); - - var draggableScope = $("a.is_folder, a.is_item").not($("[data-objectid='0']")); - makeDraggable(draggableScope); -} - -function makeDroppable(elements){ - - elements.droppable({ - accept: function(el){ - if(el.hasClass("is_item")){ - return (el.attr("data-groupid") == $(this).attr("data-groupid")); - } - else { - var notOwnChild = (el.next().find($(this)).length == 0); - if(el.hasClass("is_folder") && notOwnChild) return (el.attr("data-groupid") == $(this).attr("data-groupid")); - } - }, - activeClass: "droppable_folder", - drop: function(event, ui){ - - var el = this; - var siblings = $(el).next().children("a"); - var inserted = false; - var originSiblings = ui.draggable.siblings("a").length; - var parent = ui.draggable.parent(); - - for(var i = 0; i < siblings.length; i++){ - - if(ui.draggable.hasClass("is_item")){ - if(siblings.eq(i).hasClass("is_folder")){ - ui.draggable.hide(300,function(){ - siblings.eq(i).before(ui.draggable.show(300)); - }); - inserted = true; - break; - } else if(siblings.eq(i).hasClass("is_item")){ - if(ui.draggable.find("span.name").text().trim().toLowerCase() < siblings.eq(i).find("span.name").text().trim().toLowerCase()){ - ui.draggable.hide(300,function(){ - siblings.eq(i).before(ui.draggable.show(300)); - }); - inserted = true; - break; - } - } - } else if(ui.draggable.hasClass("is_folder")){ - if(siblings.eq(i).hasClass("is_folder")){ - if(ui.draggable.find("span.name").text().trim().toLowerCase() < siblings.eq(i).find("span.name").text().trim().toLowerCase()){ - ui.draggable.next().andSelf().hide(300,function(){ - siblings.eq(i).before(ui.draggable.next().andSelf()); - if (ui.draggable.hasClass("is_open_folder")){ - ui.draggable.next().andSelf().show(300); - } - else ui.draggable.show(300); - }); - inserted = true; - break; - } - } - } - } - - if(!inserted){ - if(ui.draggable.hasClass("is_folder")){ - ui.draggable.next().andSelf().hide(300,function(){ - $(el).next().append(ui.draggable.next().andSelf()); - if (ui.draggable.hasClass("is_open_folder")){ - ui.draggable.next().andSelf().show(300); - } - else ui.draggable.show(300); - }); - } - else if(ui.draggable.hasClass("is_item")){ - ui.draggable.hide(300,function(){ - $(el).next().append(ui.draggable.show(300)); - }); - } - } - - if(originSiblings == 0){ - parent.append("<div class='treeline_children_empty'>empty folder</div>"); - } - - $(el).next().children(".treeline_children_empty").hide("fast", function(){ - $(this).remove(); - }); - - var objectId = ui.draggable.attr("data-objectid"); - var groupId = ui.draggable.attr("data-groupid"); - var parentId = $(el).attr("data-objectid"); - - moveProject(objectId, groupId, parentId); - - }, - hoverClass: "hover_droppable_folder" - }); -} - -function makeDraggable(elements){ - - elements.draggable({ - appendTo: '.eln_scroll-y', - cursorAt: { bottom: 15, left: 45 }, - distance: 25, - revert: "invalid", - revertDuration: 200, - helper: function(){ - var helper = $(this).clone(); - helper.addClass("dragging_helper").css({ - "height": "auto", - "line-height": "0", - "color": "#69bfee" - }).find(".tree_button, span.updateTS").remove(); - return helper; - }, - drag: function(event, ui){ - $(this).css("z-index", 20); - }, - stop: function(event, ui){ - - $(this).next().andSelf().css({ - 'position': 'relative', - 'top': '', - 'left': '', - 'z-index': '' - }); - - $(this).next().css('position', ''); - - $(".hover_droppable_folder").removeClass("hover_droppable_folder"); - } - }); -} - -function getCookieNameForTree(el) { - var treeId = el.parents(".tree_top_level").attr("data-treeid"); - return "tree_" + treeId + "_open_folders"; -} - -function initTreelineFolders(treeId) { - var cookieName = "tree_" + treeId + "_open_folders"; - var curValue = getCookieValue(cookieName); - if(curValue) { - var arr = curValue.split(","); - for(var i=0; i<arr.length; i++) { - var treeNode = $("#treeline_" + treeId + "_" + arr[i] + ".is_closed_folder"); - var treeNodeChildren = treeNode.next(".treeline_children"); - treeNode.removeClass("is_closed_folder").addClass("is_open_folder"); - treeNodeChildren.css("display", "block"); - } - } - - $("a.is_closed_folder").children("span.folder_dn-img").removeClass("folder_dn-img").addClass("folder_up-img"); - $("a.is_open_folder").children("span.folder_up-img").removeClass("folder_up-img").addClass("folder_dn-img"); -} - -function openTreelineFolder(treeNode) { - var treelineId = treeNode.attr("data-groupId") + "_" + treeNode.attr("data-objectId"); - var treeNodeChildren = treeNode.next(); - - if(treeNode.hasClass("is_closed_folder")){ - treeNodeChildren.slideDown(); - treeNode.removeClass("is_closed_folder").addClass("is_open_folder"); - treeNode.find("span.icon-arrow_right").removeClass("icon-arrow_right").addClass("icon-arrow_down"); - } -} - -$(document).ready(function() { - - if(Global.viewname == "WORKSPACE_INDEX") { - var treeId = "eln_projects"; - initTreelineFolders(treeId); - initTreelineButtonsElnProjects(treeId); - bindTreeUI(); - } else if(Global.viewname == "TEMPLATE_INDEX") { - var treeId = "eln_templates"; - initTreelineFolders(treeId); - initTreelineButtonsTextTemplates(treeId); - bindTreeUI(); - } - - $("body").on("click", "a.is_folder", function(event){ - - if($(event.target).hasClass("icon-conf_drop") || $(event.target).hasClass("default_button")) { - return; - } - - var treeNode = $(this); - var treeNodeChildren = treeNode.next(); - - if(treeNode.hasClass("is_closed_folder")) { - treeNodeChildren.slideDown(); - treeNode.removeClass("is_closed_folder").addClass("is_open_folder"); - treeNode.find("span.folder_up-img").removeClass("folder_up-img").addClass("folder_dn-img"); - } else { - treeNodeChildren.slideUp(); - treeNode.removeClass("is_open_folder").addClass("is_closed_folder"); - treeNode.find("span.folder_dn-img").removeClass("folder_dn-img").addClass("folder_up-img"); - } - }); - -}); - diff --git a/unittests/example_labfolder_data/templates.html b/unittests/example_labfolder_data/templates.html deleted file mode 100644 index 34037cc3b36f3ca91e94b94d680d406a03693274..0000000000000000000000000000000000000000 --- a/unittests/example_labfolder_data/templates.html +++ /dev/null @@ -1,135 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> - <meta name="apple-mobile-web-app-capable" content="yes"> - <meta name="apple-mobile-web-app-status-bar-style" - content="black-translucent"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>Templates</title> - <link rel="shortcut icon" type="image/x-icon" - href="static/img/favicon2.ico" /> - - <script - src="static/js/jquery-1.8.2.min.js" - type="text/javascript"></script> - - <script src="static/js/tree.js" - type="text/javascript"></script> - - <!-- This must be the first labfolder JS file included --> - <script - src="static/js/labfolder-global.js?13fcc6eeb30608bb104f4b234c2fa3fd86699ffe" - type="text/javascript"></script> - - <link rel="stylesheet" type="text/css" - href="static/css/eln_layout.css" /> - - <link rel="stylesheet" type="text/css" - href="static/css/pixel_icon.css" /> - - <link rel="stylesheet" type="text/css" - href="static/css/tree.css" /> - - <link rel="stylesheet" type="text/css" - href="static/css/notebook.css" /> - -</head> -<body> -<div class="body_bg"></div> -<div class="eln_header eln_row"> - <div class="headerbar_top"> - <a href="/eln/"><span class="logo-img"></span></a> - <header> - <span aria-hidden="true" class="manage_s-img"></span> Templates - </header> - <nav> - <div class="nav_top"> - <ul> - <li><a href="projects.html"> - <button class="header_btn "> - <span class="desk-img"></span> - <p>Projects</p> - </button> - </a></li> - </ul> - </div> - </nav> - </div> - -</div> -<div class="action_bar clearfix"></div> -<div id="data_element" data-viewname="WORKSPACE_INDEX"></div> -<div id="eln_main_content" - class="eln_main_content eln_row eln_scroll-y"> - <div class="eln_main_content_box templates-list"> - <div class="headers"> - <div class="owner">Owner</div> - <div class="update">Last Modified</div> - <div class="created">Created</div> - </div> - <div class="tree_my_eln_projects tree_top_level" data-treeid="eln_projects"> - <a id="treeline_eln_projects_0_0" - data-groupid="0" - data-objectid="0" - data-ownerid="{{ownerId}}" - class="treeline is_folder ui-droppable is_closed_folder"> - <span class="updateTS"></span> - <span class="folder_up-img"></span> - <span class="name">My private templates</span> - <span class="details"> - <span class="box-owner"> - <label>Owner:</label> - - -</span> -<span class="box-last-update"> - <label>Last update:</label> - -</span> - - </span> - </a> - <div class="treeline_children"style="overflow: hidden; display: none;"><a id="treeline_eln_projects" data-id="118219" data-parentId="0" data-userId="30003" data-groupId="0" data-name="template2" data-folder="false" data-template="true" data-createTS="22.10.2019 15:54" data-hidden="false" data-shareable="false" data-owner-profilePictureHash="null" data-owner-tutorial="1" data-owner-zoneId="Europe/Berlin" data-owner-id="30003" data-owner-firstname="max" data-owner-lastname="muster" data-owner-email="max.muster@posteo.de" data-numberOfBlocks="1" data-lastEditedTS="22.10.2019 16:45" data-adminUserIds="[]" data-adminOrOwner="true" class="treeline is_item ui-draggable" href="./templates/My private templates_0/118219_template2/index.html"> - <span class="updateTS">22.10.2019 15:54</span> - <span class="project_s-img"></span> - <span class="name">template2</span> - <span class="details"> - <span class="box-owner"> - <label>Owner:</label> - max - muster -</span> -<span class="box-last-update"> - <label>Last update:</label> - 22.10.2019 16:45 -</span> - - </span> -</a> -<div class="treeline_children"style="overflow: hidden; display: none;"></div> -<a id="treeline_eln_projects" data-id="118218" data-parentId="0" data-userId="30003" data-groupId="0" data-name="test_template" data-folder="false" data-template="true" data-createTS="22.10.2019 15:54" data-hidden="false" data-shareable="false" data-owner-profilePictureHash="null" data-owner-tutorial="1" data-owner-zoneId="Europe/Berlin" data-owner-id="30003" data-owner-firstname="max" data-owner-lastname="muster" data-owner-email="max.muster@posteo.de" data-numberOfBlocks="1" data-lastEditedTS="22.10.2019 16:47" data-adminUserIds="[]" data-adminOrOwner="true" class="treeline is_item ui-draggable" href="./templates/My private templates_0/118218_test_template/index.html"> - <span class="updateTS">22.10.2019 15:54</span> - <span class="project_s-img"></span> - <span class="name">test_template</span> - <span class="details"> - <span class="box-owner"> - <label>Owner:</label> - max - muster -</span> -<span class="box-last-update"> - <label>Last update:</label> - 22.10.2019 16:47 -</span> - - </span> -</a> -<div class="treeline_children"style="overflow: hidden; display: none;"></div> -</div> -</div> - - </div> -</div> -</body> -</html> diff --git a/unittests/example_labfolder_data/templates/My private templates_0/118218_test_template/index.html b/unittests/example_labfolder_data/templates/My private templates_0/118218_test_template/index.html deleted file mode 100644 index 0fb347c67e5e94daf948ca203702d244c72f570f..0000000000000000000000000000000000000000 --- a/unittests/example_labfolder_data/templates/My private templates_0/118218_test_template/index.html +++ /dev/null @@ -1,437 +0,0 @@ -<html> -<head> - <style type="text/css"> - @charset "UTF-8"; - [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak, .ng-hide:not(.ng-hide-animate) { - display: none !important; - } - - ng\:form { - display: block; - } - </style> - - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> - <meta name="apple-mobile-web-app-capable" content="yes"> - <meta name="apple-mobile-web-app-status-bar-style" - content="black-translucent"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - - - <title>Notebook</title> - - - <link rel="shortcut icon" type="image/x-icon" - href="../../../static/img/favicon2.ico"> - - <script src="../../../static/js/jquery-1.8.2.min.js" - type="text/javascript"></script> - <style type="text/css"></style> - - - <!-- This must be the first labfolder JS file included --> - <script - src="../../../static/js/labfolder-global.js?no-build-number" - type="text/javascript"></script> - - <link rel="stylesheet" type="text/css" - href="../../../static/css/export-table-element.css"> - <link rel="stylesheet" type="text/css" - href="../../../static/css/jquery-ui.css"> - - <link rel="stylesheet" type="text/css" - href="../../../static/css/data-elements.css?no-build-number"> - <link rel="stylesheet" type="text/css" - href="../../../static/css/combined.css?no-build-number"> - <link rel="stylesheet" type="text/css" - href="../../../static/css/export-entry-footer.css"> - <link rel="stylesheet" type="text/css" - href="../../../static/css/redactor.css"/> - - <script type="text/javascript"> - function getTemplateText(className) { - return $("#jsTemplate_jsText").find(".jstext_" + className).text(); - } - - $(document).ready(function () { - // expand tags and custom dates container on hover - $(".entry_menu_less").hover( - function () { - if (!$(this).children(":first").hasClass("entry_name_menu")) { - $(this).addClass('entry_menu_more'); - $(this).children(":first").addClass('show_list_more'); - if ($(this).children(":first").hasClass("entry_tags")) { - $(".entry_tags").css("height", "auto"); - } - } - }, - function () { - if (!$(this).children(":first").hasClass("entry_name_menu")) { - $(this).removeClass('entry_menu_more'); - $(this).children(":first").removeClass('show_list_more'); - if ($(this).children(":first").hasClass("entry_tags")) { - $(".entry_tags").css("height", "100%"); - } - } - } - ); - - //selects the table sheet according to click - $(".sheet_tab").click(function () { - if ($(this).hasClass('selected') === false) { - var previous = $(this).siblings(".selected"); - var previousElementId = previous.data("elementid"); - var previousSheetIndex = previous.data("sheetidx"); - previous.removeClass("selected"); - - var targetElementId = $(this).data("elementid"); - var targetSheetIndex = $(this).data("sheetidx"); - $(this).addClass("selected"); - - $("#table_" + targetElementId + "_" + targetSheetIndex).css("display", "block"); - $("#table_" + previousElementId + "_" + previousSheetIndex).css("display", "none"); - } - }); - }); - </script> - - <script src="../../../static/js/jquery-ui.js" - type="text/javascript"></script> -</head> - -<body> -<div class="body_bg"></div> -<div id="global_data"></div> -<div class="eln_header eln_row"> - <div class="headerbar_top"> - <a href="/eln/"><span class="logo-img"></span></a> - <header> - <span class="notebook_s-img"></span> Notebook - </header> - <nav> - <div class="nav_top"> - <ul> - <li><a href="../../../projects.html"> - <button class="header_btn "> - <span class="desk-img"></span> - <p>Projects</p> - </button> - </a></li> - <li><a href="../../../templates.html"> - <button class="header_btn "> - <span class="desk-img"></span> - <p>Templates</p> - </button> - </a></li> - </ul> - </div> - </nav> - </div> - - -</div> -<div class="ng-scope"> - <div class="action_bar clearfix ng-scope"> - <div class="plus_btn_wrap"> - <div class="plus_btn_hover"> - <div class="add_dropdown more_options_menu" style="display: none;"> - <ul> - </ul> - </div> - </div> - </div> - <div class="action_menu_wrap"> - <div class="filter_wrap list_horizontal"></div> - </div> - </div> - <div id="eln_project_content" - class="eln_project_content eln_row eln_scroll-y ng-scope" data-id="118218" data-parentId="0" data-userId="30003" data-groupId="0" data-name="test_template" data-folder="false" data-template="true" data-createTS="22.10.2019 15:54" data-hidden="false" data-shareable="false" data-owner-profilePictureHash="null" data-owner-tutorial="1" data-owner-zoneId="Europe/Berlin" data-owner-id="30003" data-owner-firstname="max" data-owner-lastname="muster" data-owner-email="max.muster@posteo.de" data-numberOfBlocks="1" data-lastEditedTS="22.10.2019 16:47" data-adminUserIds="[]" data-adminOrOwner="true" > - <div id="epb_container"><div data-id="4625193"data-blockId="4624722"data-elnProjectId="118218"data-sourceId="0"data-userAction="2"data-groupId="0"data-hidden="false"data-readOnly="false"data-versionTS="22.10.2019 18:47"data-createTS="22.10.2019 17:54"data-signHash="null"data-signHashDescription=""data-signHashVersion="null"data-signTS="null"data-witnessTS="null"data-title="null"data-blockNumber="1"data-totalBlocksInProject="1"data-projectName="test_template"data-projectReferenceId="null"data-signBiometricsDocId="null"data-witnessBiometricsDocId="null"data-referenced="false"> - <div class="epb_header_container"> - <div class="epb_header clearfix" style="display: block;"> - - <div class="entry_container"> - <header class="entry_header"> - <div class="entry_author"> - <figure> - <span class="avatar-img"></span> - <img ng-src=""> - </figure> - - <div class="author_name"> - <div class="author_firstname ng-binding">max</div> - <div class="author_lastname ng-binding">muster</div> - </div> - </div> - <div class="entry_menu_less entry_title_wrap ng-scope"> - <div class="entry_name_menu has_tooltip"> - <ul> - <li> - <div style="display:none">Entry {{entryNumber}}/{{totalEntries}}:</div> - <div>Template:</div> - </li> - <li> - <div style="display:none" class="entry_title ng-binding">{{entryTitle}}</div> - <div>test_template</div> - </li> - </ul> - </div> - <div class="entry_menu_options"> - </div> - <div class="entry_dropdown entry_name"> - <div class="close_entry_menu"> - <span class="cancel_entry_title close_box-img"></span> - </div> - <ul> - <li><label>Entry name</label> <input - class="entry_name_input ng-pristine ng-untouched ng-valid" - type="text" data-title="" value=""></li> - <li><label>located in project</label> <select - class="ng-pristine ng-untouched ng-valid"> - <option - value="0">tableproject - </option> - <option value="1" selected="selected">a project</option> - </select></li> - <li> - <div class="save_entry_menu"> - <span class="cancel_dropdown cancel_entry_title grey_link" - ng-click="cancel()">cancel</span> - <button class="save_entry_title btn_on_grey" ng-click="save()">save</button> - </div> - </li> - </ul> - </div> - </div> - - <div class="entry_menus"> - <ul> - <li class="entry_menu_less ng-scope" - ng-controller="EntryDateController"> - <div class="entry_menu_list has_tooltip" - ng-class="{true: '', false: 'has_tooltip'}[entry.readOnly]"> - <ul> - <li><span>created:</span> <span class="ng-binding">22.10.2019 17:54</span> - </li> - <li><span>modified</span> <span class="ng-binding">22.10.2019 18:47</span> - </li> - <!-- ngRepeat: date in currentDates | orderBy:predicate --> - <li> - <span>todo</span> - <span class=\"ng-binding\">24.10.2019</span> -</li> - - </ul> - </div> - <div class="entry_menu_options"> - </div> - <div class="entry_dropdown" - ng-mouseenter="activateElement($event)"> - <div class="close_entry_menu"> - <span class="close_box-img" ng-click="cancel()"></span> - </div> - <ul class="entry_dates"> - <li><label>Dates</label></li> - <li> - <div class="date_key"> - <input type="text" value="created" disabled=""> - </div> - <div class="date_value"> - <input type="text" ng-value="parseDate(entry.createTS)" - disabled="" value="18.02.2015"> - </div> - </li> - <li> - <div class="date_key"> - <input type="text" value="modified" disabled=""> - </div> - <div class="date_value"> - <input type="text" ng-value="parseDate(entry.versionTS)" - disabled="" value="18.02.2015"> - </div> - </li> - <!-- ngRepeat: date in currentDates | orderBy:predicate --> - <li style="overflow: visible;"> - <div class="date_key"> - - <div class="selectize-control single ng-valid" - ng-keyup="updateInput($select.search)" - reset-search-input="false" ng-model="dateKeyInput.selected" - theme="selectize" style="min-width: 120px;"> - <div class="selectize-input" - ng-class="{'focus': $select.open, 'disabled': $select.disabled, 'selectize-focus' : $select.focus}" - ng-click="$select.activate()"> - <div - ng-hide="$select.searchEnabled && ($select.open || $select.isEmpty())" - class="ui-select-match ng-hide" ng-transclude="" - placeholder="Custom date" - ng-keydown="inputKeydown($event)"> - <span class="ng-binding ng-scope"></span> - </div> - <input type="text" autocomplete="off" tabindex="-1" - class="ui-select-search ui-select-toggle ng-pristine ng-untouched ng-valid" - ng-click="$select.toggle($event)" - placeholder="Custom date" ng-model="$select.search" - ng-hide="!$select.searchEnabled || ($select.selected && !$select.open)" - ng-disabled="$select.disabled"> - </div> - <div ng-show="$select.open" - class="ui-select-choices selectize-dropdown single ng-scope ng-hide" - repeat="date in availableDates | filter: $select.search"> - <div - class="ui-select-choices-content selectize-dropdown-content"> - <div class="ui-select-choices-group optgroup"> - <div ng-show="$select.isGrouped" - class="ui-select-choices-group-label optgroup-header ng-binding ng-hide"></div> - <!-- ngRepeat: date in $select.items --> - <div class="ui-select-choices-row ng-scope" - ng-class="{active: $select.isActive(this), disabled: $select.isDisabled(this)}" - ng-repeat="date in $select.items" - ng-mouseenter="$select.setActiveItem(date)" - ng-click="$select.select(date)"> - <div class="option ui-select-choices-row-inner" - data-selectable="" uis-transclude-append=""> - <span ng-bind-html="date | highlight: $select.search" - class="ng-binding ng-scope">due date</span> - </div> - </div> - <!-- end ngRepeat: date in $select.items --> - <div class="ui-select-choices-row ng-scope" - ng-class="{active: $select.isActive(this), disabled: $select.isDisabled(this)}" - ng-repeat="date in $select.items" - ng-mouseenter="$select.setActiveItem(date)" - ng-click="$select.select(date)"> - <div class="option ui-select-choices-row-inner" - data-selectable="" uis-transclude-append=""> - <span ng-bind-html="date | highlight: $select.search" - class="ng-binding ng-scope">my date</span> - </div> - </div> - <!-- end ngRepeat: date in $select.items --> - </div> - </div> - </div> - <input ng-disabled="$select.disabled" - class="ui-select-focusser ui-select-offscreen ng-scope" - type="text" aria-haspopup="true" role="button"> - </div> - </div> - - <div class="date_value"> - <input type="text" - class="entry_datepicker date_input ng-pristine ng-untouched ng-valid" - ng-model="dateValueInput" ng-keydown="inputKeydown($event)"> - </div> - </li> - </ul> - <div class="save_entry_menu"> - <span class="cancel_dropdown grey_link" ng-click="cancel()">cancel</span> - <button class="btn_on_grey" ng-click="save()">save</button> - </div> - </div> - </li> - <li class="entry_menu_less ng-scope" - ng-controller="EntryTagsController"> - <div class="entry_tags has_tooltip" - ng-class="{true: '', false: 'has_tooltip'}[entry.readOnly]"> - - </div> - <div class="entry_menu_options"> - </div> - <div class="entry_dropdown"> - <div class="close_entry_menu"> - <span class="close_box-img" ng-click="cancel()"></span> - </div> - <label>Create new tags by using commas</label> - <div class="token_input token_input_width"></div> - <div class="tags_input entry_tags_input" ng-click="focusInput()"> - - <!-- ngRepeat: tag in currentTokens --> - - <textarea class="token_input ng-pristine ng-untouched ng-valid" - ng-model="tagInput" ng-keydown="inputKeydown($event)"></textarea> - </div> - - <!-- <div class="save_entry_menu"> - <span class="cancel_dropdown grey_link" ng-click="cancel()">cancel</span> - <button class="btn_on_grey" ng-click='fromViewModel()'>fromViewModel</button> - </div> --> - <h3 class="all_tags">All tags</h3> - <div class="tag_data_wrap"> - <div class="tag_register"> - <ul> - <li> - <ul class="my_tags"> - <!-- ngRepeat: token in filteredValues = (availableTokens | filter:tagInput) --> - <li - ng-repeat="token in filteredValues = (availableTokens | filter:tagInput)" - class="ng-scope"><span - class="existing_tag ng-binding" - ng-class="{disabled: added(token), selected_tag: inputSelected(token)}" - ng-click="add(token)">demo</span></li> - <!-- end ngRepeat: token in filteredValues = (availableTokens | filter:tagInput) --> - <li - ng-repeat="token in filteredValues = (availableTokens | filter:tagInput)" - class="ng-scope"><span - class="existing_tag ng-binding" - ng-class="{disabled: added(token), selected_tag: inputSelected(token)}" - ng-click="add(token)">Entry</span></li> - <!-- end ngRepeat: token in filteredValues = (availableTokens | filter:tagInput) --> - <li - ng-repeat="token in filteredValues = (availableTokens | filter:tagInput)" - class="ng-scope"><span - class="existing_tag ng-binding" - ng-class="{disabled: added(token), selected_tag: inputSelected(token)}" - ng-click="add(token)">example</span></li> - <!-- end ngRepeat: token in filteredValues = (availableTokens | filter:tagInput) --> - </ul> - </li> - </ul> - </div> - </div> - </div> - </li> - <li> - <div class="entry_options"> - <ul> - </ul> - </div> - </li> - </ul> - </div> - </header> - <div class="entry_toolbar"></div> - </div> - <div class="clear"></div> - </div> -</div> - - <div class="epb_content_wrap"> - <div class="epb_content_container"> - <div class="hdrop ui-droppable"></div> - <div class="dd_entry_table"> - <div class="dd_entry_table"> - <div class="dd_entry_row"> - <div class="dd_entry_cell ui-draggable dd_text_entry"> - <div class="dd_entry_cell_wrapper" > - <div class="button_wrapper"></div> - <div class="dd_entry_cell_content redactor_editor"> - <p><p>Ein Text-Element.</p></p> -</div> - - </div> - </div> - </div> -</div> - - </div> - </div> -</div> - - -</div></div> - <div id="epb_newer_blocks_panel"></div> - </div> -</div> -</body> -</html> diff --git a/unittests/example_labfolder_data/templates/My private templates_0/118219_template2/index.html b/unittests/example_labfolder_data/templates/My private templates_0/118219_template2/index.html deleted file mode 100644 index c21b3c1ffa10c7f5c6c18589eea86864d36d9689..0000000000000000000000000000000000000000 --- a/unittests/example_labfolder_data/templates/My private templates_0/118219_template2/index.html +++ /dev/null @@ -1,653 +0,0 @@ -<html> -<head> - <style type="text/css"> - @charset "UTF-8"; - [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak, .ng-hide:not(.ng-hide-animate) { - display: none !important; - } - - ng\:form { - display: block; - } - </style> - - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> - <meta name="apple-mobile-web-app-capable" content="yes"> - <meta name="apple-mobile-web-app-status-bar-style" - content="black-translucent"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - - - <title>Notebook</title> - - - <link rel="shortcut icon" type="image/x-icon" - href="../../../static/img/favicon2.ico"> - - <script src="../../../static/js/jquery-1.8.2.min.js" - type="text/javascript"></script> - <style type="text/css"></style> - - - <!-- This must be the first labfolder JS file included --> - <script - src="../../../static/js/labfolder-global.js?no-build-number" - type="text/javascript"></script> - - <link rel="stylesheet" type="text/css" - href="../../../static/css/export-table-element.css"> - <link rel="stylesheet" type="text/css" - href="../../../static/css/jquery-ui.css"> - - <link rel="stylesheet" type="text/css" - href="../../../static/css/data-elements.css?no-build-number"> - <link rel="stylesheet" type="text/css" - href="../../../static/css/combined.css?no-build-number"> - <link rel="stylesheet" type="text/css" - href="../../../static/css/export-entry-footer.css"> - <link rel="stylesheet" type="text/css" - href="../../../static/css/redactor.css"/> - - <script type="text/javascript"> - function getTemplateText(className) { - return $("#jsTemplate_jsText").find(".jstext_" + className).text(); - } - - $(document).ready(function () { - // expand tags and custom dates container on hover - $(".entry_menu_less").hover( - function () { - if (!$(this).children(":first").hasClass("entry_name_menu")) { - $(this).addClass('entry_menu_more'); - $(this).children(":first").addClass('show_list_more'); - if ($(this).children(":first").hasClass("entry_tags")) { - $(".entry_tags").css("height", "auto"); - } - } - }, - function () { - if (!$(this).children(":first").hasClass("entry_name_menu")) { - $(this).removeClass('entry_menu_more'); - $(this).children(":first").removeClass('show_list_more'); - if ($(this).children(":first").hasClass("entry_tags")) { - $(".entry_tags").css("height", "100%"); - } - } - } - ); - - //selects the table sheet according to click - $(".sheet_tab").click(function () { - if ($(this).hasClass('selected') === false) { - var previous = $(this).siblings(".selected"); - var previousElementId = previous.data("elementid"); - var previousSheetIndex = previous.data("sheetidx"); - previous.removeClass("selected"); - - var targetElementId = $(this).data("elementid"); - var targetSheetIndex = $(this).data("sheetidx"); - $(this).addClass("selected"); - - $("#table_" + targetElementId + "_" + targetSheetIndex).css("display", "block"); - $("#table_" + previousElementId + "_" + previousSheetIndex).css("display", "none"); - } - }); - }); - </script> - - <script src="../../../static/js/jquery-ui.js" - type="text/javascript"></script> -</head> - -<body> -<div class="body_bg"></div> -<div id="global_data"></div> -<div class="eln_header eln_row"> - <div class="headerbar_top"> - <a href="/eln/"><span class="logo-img"></span></a> - <header> - <span class="notebook_s-img"></span> Notebook - </header> - <nav> - <div class="nav_top"> - <ul> - <li><a href="../../../projects.html"> - <button class="header_btn "> - <span class="desk-img"></span> - <p>Projects</p> - </button> - </a></li> - <li><a href="../../../templates.html"> - <button class="header_btn "> - <span class="desk-img"></span> - <p>Templates</p> - </button> - </a></li> - </ul> - </div> - </nav> - </div> - - -</div> -<div class="ng-scope"> - <div class="action_bar clearfix ng-scope"> - <div class="plus_btn_wrap"> - <div class="plus_btn_hover"> - <div class="add_dropdown more_options_menu" style="display: none;"> - <ul> - </ul> - </div> - </div> - </div> - <div class="action_menu_wrap"> - <div class="filter_wrap list_horizontal"></div> - </div> - </div> - <div id="eln_project_content" - class="eln_project_content eln_row eln_scroll-y ng-scope" data-id="118219" data-parentId="0" data-userId="30003" data-groupId="0" data-name="template2" data-folder="false" data-template="true" data-createTS="22.10.2019 15:54" data-hidden="false" data-shareable="false" data-owner-profilePictureHash="null" data-owner-tutorial="1" data-owner-zoneId="Europe/Berlin" data-owner-id="30003" data-owner-firstname="max" data-owner-lastname="muster" data-owner-email="max.muster@posteo.de" data-numberOfBlocks="1" data-lastEditedTS="22.10.2019 16:45" data-adminUserIds="[]" data-adminOrOwner="true" > - <div id="epb_container"><div data-id="4625184"data-blockId="4624724"data-elnProjectId="118219"data-sourceId="0"data-userAction="34"data-groupId="0"data-hidden="false"data-readOnly="false"data-versionTS="22.10.2019 18:45"data-createTS="22.10.2019 17:54"data-signHash="null"data-signHashDescription=""data-signHashVersion="null"data-signTS="null"data-witnessTS="null"data-title="null"data-blockNumber="1"data-totalBlocksInProject="1"data-projectName="template2"data-projectReferenceId="null"data-signBiometricsDocId="null"data-witnessBiometricsDocId="null"data-referenced="false"> - <div class="epb_header_container"> - <div class="epb_header clearfix" style="display: block;"> - - <div class="entry_container"> - <header class="entry_header"> - <div class="entry_author"> - <figure> - <span class="avatar-img"></span> - <img ng-src=""> - </figure> - - <div class="author_name"> - <div class="author_firstname ng-binding">max</div> - <div class="author_lastname ng-binding">muster</div> - </div> - </div> - <div class="entry_menu_less entry_title_wrap ng-scope"> - <div class="entry_name_menu has_tooltip"> - <ul> - <li> - <div style="display:none">Entry {{entryNumber}}/{{totalEntries}}:</div> - <div>Template:</div> - </li> - <li> - <div style="display:none" class="entry_title ng-binding">{{entryTitle}}</div> - <div>template2</div> - </li> - </ul> - </div> - <div class="entry_menu_options"> - </div> - <div class="entry_dropdown entry_name"> - <div class="close_entry_menu"> - <span class="cancel_entry_title close_box-img"></span> - </div> - <ul> - <li><label>Entry name</label> <input - class="entry_name_input ng-pristine ng-untouched ng-valid" - type="text" data-title="" value=""></li> - <li><label>located in project</label> <select - class="ng-pristine ng-untouched ng-valid"> - <option - value="0">tableproject - </option> - <option value="1" selected="selected">a project</option> - </select></li> - <li> - <div class="save_entry_menu"> - <span class="cancel_dropdown cancel_entry_title grey_link" - ng-click="cancel()">cancel</span> - <button class="save_entry_title btn_on_grey" ng-click="save()">save</button> - </div> - </li> - </ul> - </div> - </div> - - <div class="entry_menus"> - <ul> - <li class="entry_menu_less ng-scope" - ng-controller="EntryDateController"> - <div class="entry_menu_list has_tooltip" - ng-class="{true: '', false: 'has_tooltip'}[entry.readOnly]"> - <ul> - <li><span>created:</span> <span class="ng-binding">22.10.2019 17:54</span> - </li> - <li><span>modified</span> <span class="ng-binding">22.10.2019 18:45</span> - </li> - <!-- ngRepeat: date in currentDates | orderBy:predicate --> - - </ul> - </div> - <div class="entry_menu_options"> - </div> - <div class="entry_dropdown" - ng-mouseenter="activateElement($event)"> - <div class="close_entry_menu"> - <span class="close_box-img" ng-click="cancel()"></span> - </div> - <ul class="entry_dates"> - <li><label>Dates</label></li> - <li> - <div class="date_key"> - <input type="text" value="created" disabled=""> - </div> - <div class="date_value"> - <input type="text" ng-value="parseDate(entry.createTS)" - disabled="" value="18.02.2015"> - </div> - </li> - <li> - <div class="date_key"> - <input type="text" value="modified" disabled=""> - </div> - <div class="date_value"> - <input type="text" ng-value="parseDate(entry.versionTS)" - disabled="" value="18.02.2015"> - </div> - </li> - <!-- ngRepeat: date in currentDates | orderBy:predicate --> - <li style="overflow: visible;"> - <div class="date_key"> - - <div class="selectize-control single ng-valid" - ng-keyup="updateInput($select.search)" - reset-search-input="false" ng-model="dateKeyInput.selected" - theme="selectize" style="min-width: 120px;"> - <div class="selectize-input" - ng-class="{'focus': $select.open, 'disabled': $select.disabled, 'selectize-focus' : $select.focus}" - ng-click="$select.activate()"> - <div - ng-hide="$select.searchEnabled && ($select.open || $select.isEmpty())" - class="ui-select-match ng-hide" ng-transclude="" - placeholder="Custom date" - ng-keydown="inputKeydown($event)"> - <span class="ng-binding ng-scope"></span> - </div> - <input type="text" autocomplete="off" tabindex="-1" - class="ui-select-search ui-select-toggle ng-pristine ng-untouched ng-valid" - ng-click="$select.toggle($event)" - placeholder="Custom date" ng-model="$select.search" - ng-hide="!$select.searchEnabled || ($select.selected && !$select.open)" - ng-disabled="$select.disabled"> - </div> - <div ng-show="$select.open" - class="ui-select-choices selectize-dropdown single ng-scope ng-hide" - repeat="date in availableDates | filter: $select.search"> - <div - class="ui-select-choices-content selectize-dropdown-content"> - <div class="ui-select-choices-group optgroup"> - <div ng-show="$select.isGrouped" - class="ui-select-choices-group-label optgroup-header ng-binding ng-hide"></div> - <!-- ngRepeat: date in $select.items --> - <div class="ui-select-choices-row ng-scope" - ng-class="{active: $select.isActive(this), disabled: $select.isDisabled(this)}" - ng-repeat="date in $select.items" - ng-mouseenter="$select.setActiveItem(date)" - ng-click="$select.select(date)"> - <div class="option ui-select-choices-row-inner" - data-selectable="" uis-transclude-append=""> - <span ng-bind-html="date | highlight: $select.search" - class="ng-binding ng-scope">due date</span> - </div> - </div> - <!-- end ngRepeat: date in $select.items --> - <div class="ui-select-choices-row ng-scope" - ng-class="{active: $select.isActive(this), disabled: $select.isDisabled(this)}" - ng-repeat="date in $select.items" - ng-mouseenter="$select.setActiveItem(date)" - ng-click="$select.select(date)"> - <div class="option ui-select-choices-row-inner" - data-selectable="" uis-transclude-append=""> - <span ng-bind-html="date | highlight: $select.search" - class="ng-binding ng-scope">my date</span> - </div> - </div> - <!-- end ngRepeat: date in $select.items --> - </div> - </div> - </div> - <input ng-disabled="$select.disabled" - class="ui-select-focusser ui-select-offscreen ng-scope" - type="text" aria-haspopup="true" role="button"> - </div> - </div> - - <div class="date_value"> - <input type="text" - class="entry_datepicker date_input ng-pristine ng-untouched ng-valid" - ng-model="dateValueInput" ng-keydown="inputKeydown($event)"> - </div> - </li> - </ul> - <div class="save_entry_menu"> - <span class="cancel_dropdown grey_link" ng-click="cancel()">cancel</span> - <button class="btn_on_grey" ng-click="save()">save</button> - </div> - </div> - </li> - <li class="entry_menu_less ng-scope" - ng-controller="EntryTagsController"> - <div class="entry_tags has_tooltip" - ng-class="{true: '', false: 'has_tooltip'}[entry.readOnly]"> - <i>No tags associated</i> - </div> - <div class="entry_menu_options"> - </div> - <div class="entry_dropdown"> - <div class="close_entry_menu"> - <span class="close_box-img" ng-click="cancel()"></span> - </div> - <label>Create new tags by using commas</label> - <div class="token_input token_input_width"></div> - <div class="tags_input entry_tags_input" ng-click="focusInput()"> - - <!-- ngRepeat: tag in currentTokens --> - - <textarea class="token_input ng-pristine ng-untouched ng-valid" - ng-model="tagInput" ng-keydown="inputKeydown($event)"></textarea> - </div> - - <!-- <div class="save_entry_menu"> - <span class="cancel_dropdown grey_link" ng-click="cancel()">cancel</span> - <button class="btn_on_grey" ng-click='fromViewModel()'>fromViewModel</button> - </div> --> - <h3 class="all_tags">All tags</h3> - <div class="tag_data_wrap"> - <div class="tag_register"> - <ul> - <li> - <ul class="my_tags"> - <!-- ngRepeat: token in filteredValues = (availableTokens | filter:tagInput) --> - <li - ng-repeat="token in filteredValues = (availableTokens | filter:tagInput)" - class="ng-scope"><span - class="existing_tag ng-binding" - ng-class="{disabled: added(token), selected_tag: inputSelected(token)}" - ng-click="add(token)">demo</span></li> - <!-- end ngRepeat: token in filteredValues = (availableTokens | filter:tagInput) --> - <li - ng-repeat="token in filteredValues = (availableTokens | filter:tagInput)" - class="ng-scope"><span - class="existing_tag ng-binding" - ng-class="{disabled: added(token), selected_tag: inputSelected(token)}" - ng-click="add(token)">Entry</span></li> - <!-- end ngRepeat: token in filteredValues = (availableTokens | filter:tagInput) --> - <li - ng-repeat="token in filteredValues = (availableTokens | filter:tagInput)" - class="ng-scope"><span - class="existing_tag ng-binding" - ng-class="{disabled: added(token), selected_tag: inputSelected(token)}" - ng-click="add(token)">example</span></li> - <!-- end ngRepeat: token in filteredValues = (availableTokens | filter:tagInput) --> - </ul> - </li> - </ul> - </div> - </div> - </div> - </li> - <li> - <div class="entry_options"> - <ul> - </ul> - </div> - </li> - </ul> - </div> - </header> - <div class="entry_toolbar"></div> - </div> - <div class="clear"></div> - </div> -</div> - - <div class="epb_content_wrap"> - <div class="epb_content_container"> - <div class="hdrop ui-droppable"></div> - <div class="dd_entry_table"> - <div class="dd_entry_table"> - <div class="dd_entry_row"> - <div class="dd_entry_cell ui-draggable dd_text_entry"> - <div class="dd_entry_cell_wrapper" > - <div class="button_wrapper"></div> - <div class="dd_entry_cell_content redactor_editor"> - <p><p>Text ist hier</p></p> -</div> - - </div> - </div> - </div> -</div> -<div class="dd_entry_table"> - <div class="dd_entry_row"> - <div class="dd_entry_cell ui-draggable dd_text_entry"> - <div class="dd_entry_cell_wrapper" > - <div class="button_wrapper"></div> - <div class="notebook-element-content data-elements-container data-elements"> - <html><head></head><body><div class="data-element-wrap data-group-wrap"> - <svg class="data-element-icon data-group-icon" viewbox="0 0 67 64"> - <title>icon-vf-group-filled</title> - <path d="M32.119 39.613c0-0.238-0.119-0.476-0.357-0.595s-0.476-0.119-0.595 0l-12.372 7.138c-0.714 0.357-1.071 1.071-1.071 1.903v14.394c0 0.238 0.119 0.476 0.357 0.595s0.476 0.119 0.595 0l11.896-6.9c0.952-0.595 1.546-1.546 1.546-2.617v-13.918z"></path> - <path d="M0.952 39.019c-0.238-0.119-0.476-0.119-0.595 0-0.238 0.119-0.357 0.357-0.357 0.595v0 13.799c0 1.071 0.595 2.141 1.546 2.617l11.896 6.9c0.238 0.119 0.476 0.119 0.595 0 0.238-0.119 0.357-0.357 0.357-0.595v-14.275c0-0.714-0.357-1.428-1.071-1.903l-12.372-7.138z"></path> - <path d="M29.502 36.996c0.238-0.119 0.357-0.357 0.357-0.595s-0.119-0.476-0.357-0.595v0l-11.896-6.9c-0.952-0.595-2.141-0.595-3.093 0l-11.896 6.9c-0.238 0.119-0.357 0.357-0.357 0.595s0.119 0.476 0.357 0.595l12.372 7.138c0.714 0.357 1.428 0.357 2.141 0l12.372-7.138z"></path> - <path d="M49.487 11.063c0-0.238-0.119-0.476-0.357-0.595s-0.476-0.119-0.595 0l-12.372 7.138c-0.714 0.357-1.071 1.071-1.071 1.903v14.394c0 0.238 0.119 0.476 0.357 0.595s0.476 0.119 0.595 0l11.896-6.9c0.952-0.595 1.546-1.546 1.546-2.617v-13.918z"></path> - <path d="M19.39 10.587c-0.238-0.119-0.476-0.119-0.595 0-0.238 0.119-0.357 0.357-0.357 0.595v0 13.799c0 1.071 0.595 2.141 1.546 2.617l11.896 6.9c0.238 0.119 0.476 0.119 0.595 0 0.238-0.119 0.357-0.357 0.357-0.595v-14.394c0-0.714-0.357-1.427-1.071-1.903l-12.372-7.019z"></path> - <path d="M46.87 8.565c0.238-0.119 0.357-0.357 0.357-0.595s-0.119-0.476-0.357-0.595v0l-11.896-6.9c-0.952-0.595-2.141-0.595-3.093 0l-11.896 6.9c-0.238 0.119-0.357 0.357-0.357 0.595s0.119 0.476 0.357 0.595l12.372 7.138c0.714 0.357 1.428 0.357 2.141 0l12.372-7.138z"></path> - <path d="M66.498 40.327c0-0.238-0.119-0.476-0.357-0.595s-0.476-0.119-0.595 0l-12.372 7.138c-0.714 0.357-1.071 1.071-1.071 1.903v14.394c0 0.238 0.119 0.476 0.357 0.595s0.476 0.119 0.595 0l11.896-6.9c0.952-0.595 1.546-1.546 1.546-2.617v-13.918z"></path> - <path d="M35.331 39.851c-0.238-0.119-0.476-0.119-0.595 0-0.238 0.119-0.357 0.357-0.357 0.595v0 13.799c0 1.071 0.595 2.141 1.546 2.617l11.896 6.9c0 0 0 0 0 0 0.238 0.119 0.476 0.119 0.595 0 0.238-0.119 0.357-0.357 0.357-0.595v-14.394c0-0.714-0.357-1.428-1.071-1.903l-12.372-7.019z"></path> - <path d="M64 37.71c0.238-0.119 0.357-0.357 0.357-0.595s-0.119-0.476-0.357-0.595c0 0 0 0 0 0l-11.896-6.9c-0.952-0.595-2.141-0.595-3.093 0l-11.896 6.9c-0.238 0.119-0.357 0.357-0.357 0.595s0.119 0.476 0.357 0.595l12.372 7.138c0.714 0.357 1.428 0.357 2.141 0l12.372-7.138z"></path> - </svg> - - <div class="data-group-content display-mode"> - <div class="data-element-wrap data-group-header"> - <div class="data-element-display data-group-display"> - <span class="element-title">gruppe 1</span> - </div> - </div> - - <div class="data-group-children"> - <div class="data-element-wrap single-element-wrap"> - <svg class="data-element-icon single-element-icon" viewbox="0 0 67 64"> - <title>icon-vf-filled</title> - <path d="M59.413 20.587c0-0.427-0.213-0.853-0.64-1.067-0.32-0.213-0.853-0.213-1.173 0l-22.827 13.227c-1.173 0.747-1.92 2.027-1.92 3.413v26.453c0 0.427 0.213 0.853 0.64 1.067 0.32 0.213 0.853 0.213 1.173 0l21.867-12.8c1.707-1.067 2.88-2.88 2.88-4.907v-25.387z"></path> - <path d="M2.027 19.52c-0.32-0.213-0.853-0.213-1.173 0s-0.64 0.64-0.64 1.067v0 25.387c0 2.027 1.067 3.947 2.88 4.907l21.973 12.693c0 0 0 0 0 0 0.32 0.213 0.853 0.213 1.173 0s0.64-0.64 0.64-1.067v-26.347c0-1.387-0.747-2.667-1.92-3.413l-22.933-13.227z"></path> - <path d="M54.72 15.787c0.32-0.213 0.64-0.64 0.64-1.067s-0.213-0.853-0.64-1.067c0 0 0 0 0 0l-22.080-12.587c-1.707-1.067-3.947-1.067-5.653 0l-21.973 12.693c-0.32 0.213-0.64 0.64-0.64 1.067s0.213 0.853 0.64 1.067l22.827 13.227c1.173 0.747 2.667 0.747 3.947 0l22.933-13.333z"></path> - </svg> - - <div class="data-element-display single-element-display"> - <span class="element-title ">foo</span> - <span class="element-quantity">: Angular Momentum: </span> - <span class="element-value ">20€ </span> - <span class="element-unit">kg/m<sup>2</sup> s<sup>-1</sup></span> - </div> -</div> -<div class="data-element-wrap single-element-wrap"> - <svg class="data-element-icon single-element-icon" viewbox="0 0 67 64"> - <title>icon-vf-filled</title> - <path d="M59.413 20.587c0-0.427-0.213-0.853-0.64-1.067-0.32-0.213-0.853-0.213-1.173 0l-22.827 13.227c-1.173 0.747-1.92 2.027-1.92 3.413v26.453c0 0.427 0.213 0.853 0.64 1.067 0.32 0.213 0.853 0.213 1.173 0l21.867-12.8c1.707-1.067 2.88-2.88 2.88-4.907v-25.387z"></path> - <path d="M2.027 19.52c-0.32-0.213-0.853-0.213-1.173 0s-0.64 0.64-0.64 1.067v0 25.387c0 2.027 1.067 3.947 2.88 4.907l21.973 12.693c0 0 0 0 0 0 0.32 0.213 0.853 0.213 1.173 0s0.64-0.64 0.64-1.067v-26.347c0-1.387-0.747-2.667-1.92-3.413l-22.933-13.227z"></path> - <path d="M54.72 15.787c0.32-0.213 0.64-0.64 0.64-1.067s-0.213-0.853-0.64-1.067c0 0 0 0 0 0l-22.080-12.587c-1.707-1.067-3.947-1.067-5.653 0l-21.973 12.693c-0.32 0.213-0.64 0.64-0.64 1.067s0.213 0.853 0.64 1.067l22.827 13.227c1.173 0.747 2.667 0.747 3.947 0l22.933-13.333z"></path> - </svg> - - <div class="data-element-display single-element-display"> - <span class="element-title ">bar</span> - <span class="element-quantity">: Fugacity: </span> - <span class="element-value ">12 </span> - <span class="element-unit">Pa</span> - </div> -</div> - - </div> - </div> -</div> -</body></html><html><head></head><body><div class="data-element-wrap single-element-wrap"> - <svg class="data-element-icon single-element-icon" viewbox="0 0 67 64"> - <title>icon-vf-filled</title> - <path d="M59.413 20.587c0-0.427-0.213-0.853-0.64-1.067-0.32-0.213-0.853-0.213-1.173 0l-22.827 13.227c-1.173 0.747-1.92 2.027-1.92 3.413v26.453c0 0.427 0.213 0.853 0.64 1.067 0.32 0.213 0.853 0.213 1.173 0l21.867-12.8c1.707-1.067 2.88-2.88 2.88-4.907v-25.387z"></path> - <path d="M2.027 19.52c-0.32-0.213-0.853-0.213-1.173 0s-0.64 0.64-0.64 1.067v0 25.387c0 2.027 1.067 3.947 2.88 4.907l21.973 12.693c0 0 0 0 0 0 0.32 0.213 0.853 0.213 1.173 0s0.64-0.64 0.64-1.067v-26.347c0-1.387-0.747-2.667-1.92-3.413l-22.933-13.227z"></path> - <path d="M54.72 15.787c0.32-0.213 0.64-0.64 0.64-1.067s-0.213-0.853-0.64-1.067c0 0 0 0 0 0l-22.080-12.587c-1.707-1.067-3.947-1.067-5.653 0l-21.973 12.693c-0.32 0.213-0.64 0.64-0.64 1.067s0.213 0.853 0.64 1.067l22.827 13.227c1.173 0.747 2.667 0.747 3.947 0l22.933-13.333z"></path> - </svg> - - <div class="data-element-display single-element-display"> - <span class="element-title empty-value">⎵</span> - <span class="element-quantity">: Electric Displacement: </span> - <span class="element-value empty-value">⎵ </span> - <span class="element-unit">C/m<sup>2</sup></span> - </div> -</div> -</body></html><html><head></head><body><div class="data-element-wrap descriptive-element-wrap"> - <svg class="data-element-icon descriptive-element-icon" viewbox="0 0 64 64"> - <title>icon-dde</title> - <path d="M62.080 48.96h-60.16c-1.088 0-1.92 0.832-1.92 1.92v11.2c0 1.088 0.832 1.92 1.92 1.92h60.16c1.088 0 1.92-0.832 1.92-1.92v-11.2c0-1.024-0.832-1.92-1.92-1.92z"></path> - <path d="M62.080 24.192h-60.16c-1.088 0-1.92 0.832-1.92 1.92v11.2c0 1.088 0.832 1.92 1.92 1.92h60.16c1.088 0 1.92-0.832 1.92-1.92v-11.2c0-1.088-0.832-1.92-1.92-1.92z"></path> - <path d="M37.504 0h-35.584c-1.088 0-1.92 0.832-1.92 1.92v11.2c0 1.088 0.832 1.92 1.92 1.92h35.584c1.088 0 1.92-0.832 1.92-1.92v-11.2c0-1.088-0.832-1.92-1.92-1.92z"></path> - </svg> - - <div class="data-element-display descriptive-element-display"> - <span class="element-title">DE name: </span> - <span class="element-description ">fdgdfghgfdhgdfhh dfghdfghdfghfgh dfghdfgd</span> - </div> -</div> -</body></html><html><head></head><body><div class="data-element-wrap data-group-wrap"> - <svg class="data-element-icon data-group-icon" viewbox="0 0 67 64"> - <title>icon-vf-group-filled</title> - <path d="M32.119 39.613c0-0.238-0.119-0.476-0.357-0.595s-0.476-0.119-0.595 0l-12.372 7.138c-0.714 0.357-1.071 1.071-1.071 1.903v14.394c0 0.238 0.119 0.476 0.357 0.595s0.476 0.119 0.595 0l11.896-6.9c0.952-0.595 1.546-1.546 1.546-2.617v-13.918z"></path> - <path d="M0.952 39.019c-0.238-0.119-0.476-0.119-0.595 0-0.238 0.119-0.357 0.357-0.357 0.595v0 13.799c0 1.071 0.595 2.141 1.546 2.617l11.896 6.9c0.238 0.119 0.476 0.119 0.595 0 0.238-0.119 0.357-0.357 0.357-0.595v-14.275c0-0.714-0.357-1.428-1.071-1.903l-12.372-7.138z"></path> - <path d="M29.502 36.996c0.238-0.119 0.357-0.357 0.357-0.595s-0.119-0.476-0.357-0.595v0l-11.896-6.9c-0.952-0.595-2.141-0.595-3.093 0l-11.896 6.9c-0.238 0.119-0.357 0.357-0.357 0.595s0.119 0.476 0.357 0.595l12.372 7.138c0.714 0.357 1.428 0.357 2.141 0l12.372-7.138z"></path> - <path d="M49.487 11.063c0-0.238-0.119-0.476-0.357-0.595s-0.476-0.119-0.595 0l-12.372 7.138c-0.714 0.357-1.071 1.071-1.071 1.903v14.394c0 0.238 0.119 0.476 0.357 0.595s0.476 0.119 0.595 0l11.896-6.9c0.952-0.595 1.546-1.546 1.546-2.617v-13.918z"></path> - <path d="M19.39 10.587c-0.238-0.119-0.476-0.119-0.595 0-0.238 0.119-0.357 0.357-0.357 0.595v0 13.799c0 1.071 0.595 2.141 1.546 2.617l11.896 6.9c0.238 0.119 0.476 0.119 0.595 0 0.238-0.119 0.357-0.357 0.357-0.595v-14.394c0-0.714-0.357-1.427-1.071-1.903l-12.372-7.019z"></path> - <path d="M46.87 8.565c0.238-0.119 0.357-0.357 0.357-0.595s-0.119-0.476-0.357-0.595v0l-11.896-6.9c-0.952-0.595-2.141-0.595-3.093 0l-11.896 6.9c-0.238 0.119-0.357 0.357-0.357 0.595s0.119 0.476 0.357 0.595l12.372 7.138c0.714 0.357 1.428 0.357 2.141 0l12.372-7.138z"></path> - <path d="M66.498 40.327c0-0.238-0.119-0.476-0.357-0.595s-0.476-0.119-0.595 0l-12.372 7.138c-0.714 0.357-1.071 1.071-1.071 1.903v14.394c0 0.238 0.119 0.476 0.357 0.595s0.476 0.119 0.595 0l11.896-6.9c0.952-0.595 1.546-1.546 1.546-2.617v-13.918z"></path> - <path d="M35.331 39.851c-0.238-0.119-0.476-0.119-0.595 0-0.238 0.119-0.357 0.357-0.357 0.595v0 13.799c0 1.071 0.595 2.141 1.546 2.617l11.896 6.9c0 0 0 0 0 0 0.238 0.119 0.476 0.119 0.595 0 0.238-0.119 0.357-0.357 0.357-0.595v-14.394c0-0.714-0.357-1.428-1.071-1.903l-12.372-7.019z"></path> - <path d="M64 37.71c0.238-0.119 0.357-0.357 0.357-0.595s-0.119-0.476-0.357-0.595c0 0 0 0 0 0l-11.896-6.9c-0.952-0.595-2.141-0.595-3.093 0l-11.896 6.9c-0.238 0.119-0.357 0.357-0.357 0.595s0.119 0.476 0.357 0.595l12.372 7.138c0.714 0.357 1.428 0.357 2.141 0l12.372-7.138z"></path> - </svg> - - <div class="data-group-content display-mode"> - <div class="data-element-wrap data-group-header"> - <div class="data-element-display data-group-display"> - <span class="element-title">gruppe 2</span> - </div> - </div> - - <div class="data-group-children"> - <div class="data-element-wrap data-group-wrap"> - <svg class="data-element-icon data-group-icon" viewbox="0 0 67 64"> - <title>icon-vf-group-filled</title> - <path d="M32.119 39.613c0-0.238-0.119-0.476-0.357-0.595s-0.476-0.119-0.595 0l-12.372 7.138c-0.714 0.357-1.071 1.071-1.071 1.903v14.394c0 0.238 0.119 0.476 0.357 0.595s0.476 0.119 0.595 0l11.896-6.9c0.952-0.595 1.546-1.546 1.546-2.617v-13.918z"></path> - <path d="M0.952 39.019c-0.238-0.119-0.476-0.119-0.595 0-0.238 0.119-0.357 0.357-0.357 0.595v0 13.799c0 1.071 0.595 2.141 1.546 2.617l11.896 6.9c0.238 0.119 0.476 0.119 0.595 0 0.238-0.119 0.357-0.357 0.357-0.595v-14.275c0-0.714-0.357-1.428-1.071-1.903l-12.372-7.138z"></path> - <path d="M29.502 36.996c0.238-0.119 0.357-0.357 0.357-0.595s-0.119-0.476-0.357-0.595v0l-11.896-6.9c-0.952-0.595-2.141-0.595-3.093 0l-11.896 6.9c-0.238 0.119-0.357 0.357-0.357 0.595s0.119 0.476 0.357 0.595l12.372 7.138c0.714 0.357 1.428 0.357 2.141 0l12.372-7.138z"></path> - <path d="M49.487 11.063c0-0.238-0.119-0.476-0.357-0.595s-0.476-0.119-0.595 0l-12.372 7.138c-0.714 0.357-1.071 1.071-1.071 1.903v14.394c0 0.238 0.119 0.476 0.357 0.595s0.476 0.119 0.595 0l11.896-6.9c0.952-0.595 1.546-1.546 1.546-2.617v-13.918z"></path> - <path d="M19.39 10.587c-0.238-0.119-0.476-0.119-0.595 0-0.238 0.119-0.357 0.357-0.357 0.595v0 13.799c0 1.071 0.595 2.141 1.546 2.617l11.896 6.9c0.238 0.119 0.476 0.119 0.595 0 0.238-0.119 0.357-0.357 0.357-0.595v-14.394c0-0.714-0.357-1.427-1.071-1.903l-12.372-7.019z"></path> - <path d="M46.87 8.565c0.238-0.119 0.357-0.357 0.357-0.595s-0.119-0.476-0.357-0.595v0l-11.896-6.9c-0.952-0.595-2.141-0.595-3.093 0l-11.896 6.9c-0.238 0.119-0.357 0.357-0.357 0.595s0.119 0.476 0.357 0.595l12.372 7.138c0.714 0.357 1.428 0.357 2.141 0l12.372-7.138z"></path> - <path d="M66.498 40.327c0-0.238-0.119-0.476-0.357-0.595s-0.476-0.119-0.595 0l-12.372 7.138c-0.714 0.357-1.071 1.071-1.071 1.903v14.394c0 0.238 0.119 0.476 0.357 0.595s0.476 0.119 0.595 0l11.896-6.9c0.952-0.595 1.546-1.546 1.546-2.617v-13.918z"></path> - <path d="M35.331 39.851c-0.238-0.119-0.476-0.119-0.595 0-0.238 0.119-0.357 0.357-0.357 0.595v0 13.799c0 1.071 0.595 2.141 1.546 2.617l11.896 6.9c0 0 0 0 0 0 0.238 0.119 0.476 0.119 0.595 0 0.238-0.119 0.357-0.357 0.357-0.595v-14.394c0-0.714-0.357-1.428-1.071-1.903l-12.372-7.019z"></path> - <path d="M64 37.71c0.238-0.119 0.357-0.357 0.357-0.595s-0.119-0.476-0.357-0.595c0 0 0 0 0 0l-11.896-6.9c-0.952-0.595-2.141-0.595-3.093 0l-11.896 6.9c-0.238 0.119-0.357 0.357-0.357 0.595s0.119 0.476 0.357 0.595l12.372 7.138c0.714 0.357 1.428 0.357 2.141 0l12.372-7.138z"></path> - </svg> - - <div class="data-group-content display-mode"> - <div class="data-element-wrap data-group-header"> - <div class="data-element-display data-group-display"> - <span class="element-title">Untergruppe 2.1</span> - </div> - </div> - - <div class="data-group-children"> - <div class="data-element-wrap descriptive-element-wrap"> - <svg class="data-element-icon descriptive-element-icon" viewbox="0 0 64 64"> - <title>icon-dde</title> - <path d="M62.080 48.96h-60.16c-1.088 0-1.92 0.832-1.92 1.92v11.2c0 1.088 0.832 1.92 1.92 1.92h60.16c1.088 0 1.92-0.832 1.92-1.92v-11.2c0-1.024-0.832-1.92-1.92-1.92z"></path> - <path d="M62.080 24.192h-60.16c-1.088 0-1.92 0.832-1.92 1.92v11.2c0 1.088 0.832 1.92 1.92 1.92h60.16c1.088 0 1.92-0.832 1.92-1.92v-11.2c0-1.088-0.832-1.92-1.92-1.92z"></path> - <path d="M37.504 0h-35.584c-1.088 0-1.92 0.832-1.92 1.92v11.2c0 1.088 0.832 1.92 1.92 1.92h35.584c1.088 0 1.92-0.832 1.92-1.92v-11.2c0-1.088-0.832-1.92-1.92-1.92z"></path> - </svg> - - <div class="data-element-display descriptive-element-display"> - <span class="element-title">DE name 2 (desc): </span> - <span class="element-description empty-value">⎵</span> - </div> -</div> -<div class="data-element-wrap single-element-wrap"> - <svg class="data-element-icon single-element-icon" viewbox="0 0 67 64"> - <title>icon-vf-filled</title> - <path d="M59.413 20.587c0-0.427-0.213-0.853-0.64-1.067-0.32-0.213-0.853-0.213-1.173 0l-22.827 13.227c-1.173 0.747-1.92 2.027-1.92 3.413v26.453c0 0.427 0.213 0.853 0.64 1.067 0.32 0.213 0.853 0.213 1.173 0l21.867-12.8c1.707-1.067 2.88-2.88 2.88-4.907v-25.387z"></path> - <path d="M2.027 19.52c-0.32-0.213-0.853-0.213-1.173 0s-0.64 0.64-0.64 1.067v0 25.387c0 2.027 1.067 3.947 2.88 4.907l21.973 12.693c0 0 0 0 0 0 0.32 0.213 0.853 0.213 1.173 0s0.64-0.64 0.64-1.067v-26.347c0-1.387-0.747-2.667-1.92-3.413l-22.933-13.227z"></path> - <path d="M54.72 15.787c0.32-0.213 0.64-0.64 0.64-1.067s-0.213-0.853-0.64-1.067c0 0 0 0 0 0l-22.080-12.587c-1.707-1.067-3.947-1.067-5.653 0l-21.973 12.693c-0.32 0.213-0.64 0.64-0.64 1.067s0.213 0.853 0.64 1.067l22.827 13.227c1.173 0.747 2.667 0.747 3.947 0l22.933-13.333z"></path> - </svg> - - <div class="data-element-display single-element-display"> - <span class="element-title ">DE 2.1.1</span> - <span class="element-quantity">: Amount of substance: </span> - <span class="element-value ">20 </span> - <span class="element-unit">mol</span> - </div> -</div> - - </div> - </div> -</div> -<div class="data-element-wrap single-element-wrap"> - <svg class="data-element-icon single-element-icon" viewbox="0 0 67 64"> - <title>icon-vf-filled</title> - <path d="M59.413 20.587c0-0.427-0.213-0.853-0.64-1.067-0.32-0.213-0.853-0.213-1.173 0l-22.827 13.227c-1.173 0.747-1.92 2.027-1.92 3.413v26.453c0 0.427 0.213 0.853 0.64 1.067 0.32 0.213 0.853 0.213 1.173 0l21.867-12.8c1.707-1.067 2.88-2.88 2.88-4.907v-25.387z"></path> - <path d="M2.027 19.52c-0.32-0.213-0.853-0.213-1.173 0s-0.64 0.64-0.64 1.067v0 25.387c0 2.027 1.067 3.947 2.88 4.907l21.973 12.693c0 0 0 0 0 0 0.32 0.213 0.853 0.213 1.173 0s0.64-0.64 0.64-1.067v-26.347c0-1.387-0.747-2.667-1.92-3.413l-22.933-13.227z"></path> - <path d="M54.72 15.787c0.32-0.213 0.64-0.64 0.64-1.067s-0.213-0.853-0.64-1.067c0 0 0 0 0 0l-22.080-12.587c-1.707-1.067-3.947-1.067-5.653 0l-21.973 12.693c-0.32 0.213-0.64 0.64-0.64 1.067s0.213 0.853 0.64 1.067l22.827 13.227c1.173 0.747 2.667 0.747 3.947 0l22.933-13.333z"></path> - </svg> - - <div class="data-element-display single-element-display"> - <span class="element-title ">DE 2.2</span> - <span class="element-quantity">: Capacitance: </span> - <span class="element-value ">876x876x87 </span> - <span class="element-unit">µF</span> - </div> -</div> - - </div> - </div> -</div> -</body></html> -</div> - - </div> - </div> - </div> -</div> -<div class="dd_entry_table"> - <div class="dd_entry_row"> - <div class="dd_entry_cell ui-draggable dd_text_entry"> - <div class="dd_entry_cell_wrapper" {{elementMeta1}}> - <div class="button_wrapper"></div> - <div class="dd_entry_cell_content table-el-container"> - <div> - <div class="table-el-info"> - Your labfolder table is available for visualization as the following Excel file: - </div> - <div class="table-el-download"> - <a href="labfolder_table_4625184_3.xlsx"> - <svg class="table-el-icon" viewBox="0 0 475.1 402.5"> - <title>icon-table</title> - <path d="M461.7,14C452.7,5,442,0.5,429.4,0.5H45.7C33.1,0.5,22.4,5,13.4,14C4.5,22.9,0,33.7,0,46.2v310.6 c0,12.6,4.5,23.3,13.4,32.3c8.9,8.9,19.7,13.4,32.3,13.4h383.7c12.6,0,23.3-4.5,32.3-13.4c8.9-9,13.4-19.7,13.4-32.3V46.2 C475.1,33.7,470.6,22.9,461.7,14z M146.2,356.9c0,2.7-0.9,4.9-2.6,6.6c-1.7,1.7-3.9,2.6-6.6,2.6H45.7c-2.7,0-4.9-0.9-6.6-2.6 c-1.7-1.7-2.6-3.9-2.6-6.6V302c0-2.7,0.9-4.9,2.6-6.6c1.7-1.7,3.9-2.6,6.6-2.6H137c2.7,0,4.9,0.9,6.6,2.6c1.7,1.7,2.6,3.9,2.6,6.6 L146.2,356.9L146.2,356.9z M146.2,247.2c0,2.7-0.9,4.9-2.6,6.6c-1.7,1.7-3.9,2.6-6.6,2.6H45.7c-2.7,0-4.9-0.9-6.6-2.6 c-1.7-1.7-2.6-3.9-2.6-6.6v-54.8c0-2.7,0.9-4.9,2.6-6.6c1.7-1.7,3.9-2.6,6.6-2.6H137c2.7,0,4.9,0.9,6.6,2.6 c1.7,1.7,2.6,3.9,2.6,6.6L146.2,247.2L146.2,247.2z M146.2,137.6c0,2.7-0.9,4.9-2.6,6.6c-1.7,1.7-3.9,2.6-6.6,2.6H45.7 c-2.7,0-4.9-0.9-6.6-2.6c-1.7-1.7-2.6-3.9-2.6-6.6V82.8c0-2.7,0.9-4.9,2.6-6.6c1.7-1.7,3.9-2.6,6.6-2.6H137c2.7,0,4.9,0.9,6.6,2.6 c1.7,1.7,2.6,3.9,2.6,6.6L146.2,137.6L146.2,137.6z M292.4,356.9c0,2.7-0.9,4.9-2.6,6.6c-1.7,1.7-3.9,2.6-6.6,2.6h-91.4 c-2.7,0-4.9-0.9-6.6-2.6c-1.7-1.7-2.6-3.9-2.6-6.6V302c0-2.7,0.9-4.9,2.6-6.6c1.7-1.7,3.9-2.6,6.6-2.6h91.4c2.7,0,4.9,0.9,6.6,2.6 c1.7,1.7,2.6,3.9,2.6,6.6L292.4,356.9L292.4,356.9L292.4,356.9z M292.4,247.2c0,2.7-0.9,4.9-2.6,6.6c-1.7,1.7-3.9,2.6-6.6,2.6 h-91.4c-2.7,0-4.9-0.9-6.6-2.6c-1.7-1.7-2.6-3.9-2.6-6.6v-54.8c0-2.7,0.9-4.9,2.6-6.6c1.7-1.7,3.9-2.6,6.6-2.6h91.4 c2.7,0,4.9,0.9,6.6,2.6c1.7,1.7,2.6,3.9,2.6,6.6L292.4,247.2L292.4,247.2z M292.4,137.6c0,2.7-0.9,4.9-2.6,6.6 c-1.7,1.7-3.9,2.6-6.6,2.6h-91.4c-2.7,0-4.9-0.9-6.6-2.6c-1.7-1.7-2.6-3.9-2.6-6.6V82.8c0-2.7,0.9-4.9,2.6-6.6 c1.7-1.7,3.9-2.6,6.6-2.6h91.4c2.7,0,4.9,0.9,6.6,2.6c1.7,1.7,2.6,3.9,2.6,6.6L292.4,137.6L292.4,137.6z M438.5,356.9 c0,2.7-0.9,4.9-2.6,6.6c-1.7,1.7-3.9,2.6-6.6,2.6H338c-2.7,0-4.9-0.9-6.6-2.6c-1.7-1.7-2.6-3.9-2.6-6.6V302c0-2.7,0.8-4.9,2.6-6.6 c1.7-1.7,3.9-2.6,6.6-2.6h91.4c2.7,0,4.9,0.9,6.6,2.6c1.7,1.7,2.6,3.9,2.6,6.6V356.9z M438.5,247.2c0,2.7-0.9,4.9-2.6,6.6 c-1.7,1.7-3.9,2.6-6.6,2.6H338c-2.7,0-4.9-0.9-6.6-2.6c-1.7-1.7-2.6-3.9-2.6-6.6v-54.8c0-2.7,0.8-4.9,2.6-6.6 c1.7-1.7,3.9-2.6,6.6-2.6h91.4c2.7,0,4.9,0.9,6.6,2.6c1.7,1.7,2.6,3.9,2.6,6.6V247.2z M438.5,137.6c0,2.7-0.9,4.9-2.6,6.6 c-1.7,1.7-3.9,2.6-6.6,2.6H338c-2.7,0-4.9-0.9-6.6-2.6c-1.7-1.7-2.6-3.9-2.6-6.6V82.8c0-2.7,0.8-4.9,2.6-6.6 c1.7-1.7,3.9-2.6,6.6-2.6h91.4c2.7,0,4.9,0.9,6.6,2.6c1.7,1.7,2.6,3.9,2.6,6.6V137.6z"/> - </svg> - <div class="table-el-filename"> - labfolder_table_4625184_3.xlsx - </div> - </a> - </div> - </div> -</div> - - </div> - </div> - </div> -</div> - - </div> - </div> -</div> - - -</div></div> - <div id="epb_newer_blocks_panel"></div> - </div> -</div> -</body> -</html> diff --git a/unittests/example_labfolder_data/templates/My private templates_0/118219_template2/labfolder_table_4625184_3.xlsx b/unittests/example_labfolder_data/templates/My private templates_0/118219_template2/labfolder_table_4625184_3.xlsx deleted file mode 100644 index 83d3d8119085d311ceb5a54e56c5363351aa1c0d..0000000000000000000000000000000000000000 Binary files a/unittests/example_labfolder_data/templates/My private templates_0/118219_template2/labfolder_table_4625184_3.xlsx and /dev/null differ diff --git a/unittests/caosdbignore-example b/unittests/linkaheadignore-example similarity index 100% rename from unittests/caosdbignore-example rename to unittests/linkaheadignore-example diff --git a/unittests/table_json_conversion/data/simple_data_booleans.json b/unittests/table_json_conversion/data/simple_data_booleans.json new file mode 100644 index 0000000000000000000000000000000000000000..f7d452b39f51ea3e0903af8c50007fb483cb05e4 --- /dev/null +++ b/unittests/table_json_conversion/data/simple_data_booleans.json @@ -0,0 +1,47 @@ +{ + "Training": [ + { + "date": "2023-01-01", + "url": "www.indiscale.com", + "coach": [ + { + "family_name": "Sky", + "given_name": "Max", + "Organisation": "ECB" + }, + { + "family_name": "Sky", + "given_name": "Min", + "Organisation": "ECB" + } + ], + "supervisor": { + "family_name": "Steve", + "given_name": "Stevie", + "Organisation": "IMF" + }, + "duration": 1.0, + "participants": 1, + "subjects": ["Math", "Physics"], + "remote": false + }, + { + "date": "2023-01-02", + "url": "www.indiscale.com", + "supervisor": { + "family_name": "Steve", + "given_name": "Stevie", + "Organisation": "IMF" + }, + "duration": 1.0, + "participants": 1, + "subjects": ["Math", "Physics"], + "remote": true + } + ], + "Person": [{ + "family_name": "Steve", + "given_name": "Stevie", + "Organisation": "IMF" + }] +} diff --git a/unittests/table_json_conversion/data/simple_data_booleans.xlsx b/unittests/table_json_conversion/data/simple_data_booleans.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..6a67d7a8d6df76b7d88d0d575c6ed1c30b8f8363 Binary files /dev/null and b/unittests/table_json_conversion/data/simple_data_booleans.xlsx differ diff --git a/unittests/table_json_conversion/data/simple_data_broken.xlsx b/unittests/table_json_conversion/data/simple_data_broken.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..1e61cf108365d8e825c97742924c8ffc7b9643c1 Binary files /dev/null and b/unittests/table_json_conversion/data/simple_data_broken.xlsx differ diff --git a/unittests/table_json_conversion/data/simple_data_broken_paths.xlsx b/unittests/table_json_conversion/data/simple_data_broken_paths.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..0221570c942fc28f2b59a282f751781ff4a504fa Binary files /dev/null and b/unittests/table_json_conversion/data/simple_data_broken_paths.xlsx differ diff --git a/unittests/table_json_conversion/data/simple_data_broken_paths_2.xlsx b/unittests/table_json_conversion/data/simple_data_broken_paths_2.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..14bdbaaa5bcdf3e5541e8cfbddc68505e35f11f2 Binary files /dev/null and b/unittests/table_json_conversion/data/simple_data_broken_paths_2.xlsx differ diff --git a/unittests/table_json_conversion/test_read_xlsx.py b/unittests/table_json_conversion/test_read_xlsx.py index 0eec2e9caa1f800ad86ab43057b8c512dc09881f..ff32c6b1203112c6931e98e55de5e4c981167452 100644 --- a/unittests/table_json_conversion/test_read_xlsx.py +++ b/unittests/table_json_conversion/test_read_xlsx.py @@ -26,7 +26,9 @@ import os import re from types import SimpleNamespace +from typing import Optional +import jsonschema import pytest from caosadvancedtools.table_json_conversion import convert @@ -40,8 +42,8 @@ def rfp(*pathcomponents): def convert_and_compare(xlsx_file: str, schema_file: str, known_good_file: str, - known_good_data: dict = None, strict: bool = False, - validate: bool = True) -> dict: + known_good_data: Optional[dict] = None, strict: bool = False, + validate: bool = False) -> dict: """Convert an XLSX file and compare to a known result. Exactly one of ``known_good_file`` and ``known_good_data`` should be non-empty. @@ -51,6 +53,8 @@ Returns json: dict The result of the conversion. """ + # FIXME Set default "validate" back to True, after implementation of + # https://gitlab.indiscale.com/caosdb/src/caosdb-advanced-user-tools/-/issues/138 result = convert.to_dict(xlsx=xlsx_file, schema=schema_file, validate=validate) if known_good_file: with open(known_good_file, encoding="utf-8") as myfile: @@ -76,6 +80,9 @@ def test_conversions(): schema_file=rfp("data/multiple_choice_schema.json"), known_good_file=rfp("data/multiple_choice_data.json"), strict=True) + convert_and_compare(xlsx_file=rfp("data/simple_data_booleans.xlsx"), + schema_file=rfp("data/simple_schema.json"), + known_good_file=rfp("data/simple_data_booleans.json")) with open(rfp("data/simple_data.json"), encoding="utf-8") as myfile: expected_datetime = json.load(myfile) @@ -100,7 +107,8 @@ def test_missing_columns(): with pytest.warns(UserWarning) as caught: convert.to_dict(xlsx=rfp("data/simple_data_missing.xlsx"), schema=rfp("data/simple_schema.json")) - assert str(caught.pop().message) == "Missing column: Training.coach.given_name" + messages = {str(w.message) for w in caught} + assert "Missing column: Training.coach.given_name" in messages with pytest.warns(UserWarning) as caught: convert.to_dict(xlsx=rfp("data/multiple_choice_data_missing.xlsx"), schema=rfp("data/multiple_choice_schema.json")) @@ -112,6 +120,99 @@ def test_missing_columns(): assert expected in messages +def test_error_table(): + with pytest.raises(jsonschema.ValidationError) as caught: + convert.to_dict(xlsx=rfp("data/simple_data_broken.xlsx"), + schema=rfp("data/simple_schema.json")) + # Correct Errors + assert "'Not a num' is not of type 'number'" in str(caught.value) + assert "'Yes a number?' is not of type 'number'" in str(caught.value) + assert "1.5 is not of type 'integer'" in str(caught.value) + assert "1.2345 is not of type 'integer'" in str(caught.value) + assert "'Not an enum' is not one of [" in str(caught.value) + # Correct Locations + matches = set() + for line in str(caught.value).split('\n'): + if "'Not a num' is not of type 'number'" in line: + assert "J7" in line + matches.add("J7") + if "'Yes a number?' is not of type 'number'" in line: + assert "J8" in line + matches.add("J8") + if "1.5 is not of type 'integer'" in line: + assert "K7" in line + matches.add("K7") + if "1.2345 is not of type 'integer'" in line: + assert "K8" in line + matches.add("K8") + if "'Not an enum' is not one of [" in line: + assert "G8" in line + matches.add("K8") + # The next two tests could potentially be removed in the future, once we evaluate formulas. + if "'=NOT(FALSE())' is not of type 'boolean'" in line: + assert "L9" in line + matches.add("L9") + if "'=NOT(TRUE())' is not of type 'boolean'" in line: + assert "L10" in line + matches.add("L10") + assert matches == {"J7", "J8", "K7", "K8", "K8", "L9", "L10"} + + # No additional errors + assert str(caught.value).count("is not one of") == 1 + assert str(caught.value).count("is not of type") == 6 + + +def test_malformed_paths(): + with pytest.raises(jsonschema.ValidationError) as caught: + convert.to_dict(xlsx=rfp("data/simple_data_broken_paths_2.xlsx"), + schema=rfp("data/simple_schema.json")) + message_lines = str(caught.value).lower().split('\n') + expected_errors = { + 'person': {'c': "column type is missing", + 'd': "parsing of the path", + 'e': "path may be incomplete"}, + 'training': {'c': "path is missing", + 'd': "column type is missing", + 'e': "path may be incomplete", + 'f': "parsing of the path", + 'g': "path may be incomplete", + 'h': "parsing of the path", + 'i': "parsing of the path"}, + 'training.coach': {'f': "no column metadata set"}} + current_sheet = None + for line in message_lines: + if 'in sheet' in line: + current_sheet = line.replace('in sheet ', '').replace(':', '') + continue + if 'in column' in line: + for column, expected_error in expected_errors[current_sheet].items(): + if f'in column {column}' in line: + assert expected_error in line + expected_errors[current_sheet].pop(column) + break + for _, errors_left in expected_errors.items(): + assert len(errors_left) == 0 + + +def test_empty_columns(): + with pytest.warns(UserWarning) as caught: + try: + convert.to_dict(xlsx=rfp("data/simple_data_broken.xlsx"), + schema=rfp("data/simple_schema.json")) + except jsonschema.ValidationError: + pass # Errors are checked in test_error_table + messages = {str(w.message).lower() for w in caught} + expected_warnings = {"column h": "no column metadata"} + for message in messages: + for column, warning in list(expected_warnings.items()): + if column in message: + assert warning in message + expected_warnings.pop(column) + else: + assert warning not in message + assert len(expected_warnings) == 0 + + def test_faulty_foreign(): # Simple wrong foreign key converter = convert.XLSXConverter(xlsx=rfp("data/simple_data_wrong_foreign.xlsx"), diff --git a/unittests/table_json_conversion/utils.py b/unittests/table_json_conversion/utils.py index b95715f72b08384f75857e48bcba328488313ad5..ac76fbea4508017261385e4e8fd70bedc378da5a 100644 --- a/unittests/table_json_conversion/utils.py +++ b/unittests/table_json_conversion/utils.py @@ -58,7 +58,8 @@ Raise an assertion exception if they are not equal.""" "the other.") return assert isinstance(json1, list) and isinstance(json2, list), f"Is not a list, path: {path}" - assert len(json1) == len(json2), f"Lists must have equal length, path: {path}" + assert len(json1) == len(json2), (f"Lists must have equal length, path: {path}\n" + f"{json1}\n ---\n{json2}") for idx, (el1, el2) in enumerate(zip(json1, json2)): this_path = path + [idx] if isinstance(el1, dict): diff --git a/unittests/test_base_table_exporter.py b/unittests/test_base_table_exporter.py index 8a65b71aa489f8fca457c0e700452a6dc5956eed..c69a64a0d44639563656688f7ef993963aaa725c 100644 --- a/unittests/test_base_table_exporter.py +++ b/unittests/test_base_table_exporter.py @@ -2,7 +2,7 @@ # encoding: utf-8 # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2020 Indiscale GmbH <info@indiscale.com> # Copyright (C) 2020 Florian Sprecklelsen <f.spreckelsen@indiscale.com> @@ -28,7 +28,7 @@ tested without db connection. """ import json import os -import caosdb as db +import linkahead as db from pytest import raises from caosadvancedtools import table_export as te diff --git a/unittests/test_cache.py b/unittests/test_cache.py index de3430bf2f28a6b05ea36b1047ac11937809ff44..1a53f16d7e865e2299e427ed1c6692f4b0c35a60 100644 --- a/unittests/test_cache.py +++ b/unittests/test_cache.py @@ -2,7 +2,7 @@ # encoding: utf-8 # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2019 Henrik tom Wörden # @@ -26,7 +26,7 @@ from copy import deepcopy from tempfile import NamedTemporaryFile import sqlite3 -import caosdb as db +import linkahead as db from caosadvancedtools.cache import IdentifiableCache, cleanXML from lxml import etree diff --git a/unittests/test_caosdbignore.py b/unittests/test_caosdbignore.py index 9394bf0c8b177bc6df132ee0b43dcb2753d70f28..39839db4b8787a2a70a507d09d132ff66a6e2d97 100644 --- a/unittests/test_caosdbignore.py +++ b/unittests/test_caosdbignore.py @@ -2,7 +2,7 @@ # encoding: utf-8 # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2022 Indiscale GmbH <info@indiscale.com> # Copyright (C) 2022 Henrik tom Wörden <h.tomwoerden@indiscale.com> @@ -34,17 +34,17 @@ from caosadvancedtools.loadFiles import compile_file_list, create_re_for_file_li BASEDIR = os.path.dirname(os.path.realpath(__file__)) -class Caosdbignore(unittest.TestCase): +class Linkaheadignore(unittest.TestCase): def setUp(self): pass def test_compile(self): - files = compile_file_list(os.path.join(BASEDIR, "caosdbignore-example"), + files = compile_file_list(os.path.join(BASEDIR, "linkaheadignore-example"), os.path.join(BASEDIR, "data")) assert len(files) == 3 assert os.path.join(BASEDIR, "data", "datatypes.xlsx") in files assert os.path.join(BASEDIR, "data", "README.xlsx") in files - assert os.path.join(BASEDIR, "data", "Publications/Posters/2019-02-03_something/README.md") in files + assert os.path.join(BASEDIR, "data", "Publications", "Posters", "2019-02-03_something", "README.md") in files def test_regex(self): files = [r"/dies/ist/simple", r"/dies/eh(er)/nich?t"] diff --git a/unittests/test_cfood.py b/unittests/test_cfood.py index e2f15ffdc7929fbd67aee37bccdb0f44cacef104..77fd654ba7a69f47eb272dbeaae0c1c6827f22d9 100644 --- a/unittests/test_cfood.py +++ b/unittests/test_cfood.py @@ -2,7 +2,7 @@ # encoding: utf-8 # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2018 Research Group Biomedical Physics, # Max-Planck-Institute for Dynamics and Self-Organization Göttingen @@ -24,7 +24,7 @@ import re import unittest -import caosdb as db +import linkahead as db from caosadvancedtools.cfood import (AbstractCFood, AbstractFileCFood, CMeal, assure_has_parent, assure_has_property, assure_object_is_in_list, diff --git a/unittests/test_crawler.py b/unittests/test_crawler.py index 64bf291c1181d901ac39a4d2535dcd6eddf39f70..15e783a6d78667584576900841789cdf5cd1440e 100644 --- a/unittests/test_crawler.py +++ b/unittests/test_crawler.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # encoding: utf-8 # -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2020 Indiscale GmbH <info@indiscale.com> # Copyright (C) 2020 Henrik tom Wörden <h.tomwoerden@indiscale.com> @@ -23,7 +23,7 @@ import re import unittest -import caosdb as db +import linkahead as db from caosadvancedtools.crawler import Crawler diff --git a/unittests/test_data_model.py b/unittests/test_data_model.py index cafeb6ca6a43d7e0409aee3352b43f26d5208732..174f15fcfd4018f200ce98958a7a9f2760f97898 100644 --- a/unittests/test_data_model.py +++ b/unittests/test_data_model.py @@ -1,6 +1,6 @@ import unittest -import caosdb as db +import linkahead as db from caosadvancedtools.models.data_model import DataModel from caosadvancedtools.models.parser import parse_model_from_string @@ -44,7 +44,10 @@ RT1: """ model_recursive = parse_model_from_string(model_recursive_str) prop1 = model_recursive["RT1"].get_property("RT1") - assert prop1.datatype is None + + assert prop1.datatype is not None + assert prop1.datatype == "RT1" + # TODO The next line actually changes model_recursive in place, is this OK? RT1 = model_recursive.get_deep("RT1") assert model_recursive["RT1"] == RT1 diff --git a/unittests/test_generic_analysis.py b/unittests/test_generic_analysis.py index a1077b97ec58f80c8534c89d5fa5f57d8d815cb9..3e6f4dbc1a4fc86e0ed36eba096cd2a75ac2208e 100644 --- a/unittests/test_generic_analysis.py +++ b/unittests/test_generic_analysis.py @@ -2,7 +2,7 @@ # encoding: utf-8 # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2021 Indiscale GmbH <info@indiscale.com> # Copyright (C) 2021 Henrik tom Wörden <h.tomwoerden@indiscale.com> @@ -27,7 +27,7 @@ module description """ -import caosdb as db +import linkahead as db from caosadvancedtools.serverside.generic_analysis import \ check_referenced_script diff --git a/unittests/test_json_schema_exporter.py b/unittests/test_json_schema_exporter.py index 1cea2f58e42d28545b8354d0f821ab2c61e7a4f8..3b37f638fc0115fd47757e3bb0afb52c84b66b3e 100644 --- a/unittests/test_json_schema_exporter.py +++ b/unittests/test_json_schema_exporter.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # encoding: utf-8 # -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2023 Indiscale GmbH <info@indiscale.com> # Copyright (C) 2023 Florian Spreckelsen <f.spreckelsen@indiscale.com> @@ -23,18 +23,16 @@ """Tests the Json schema exporter.""" import json - -import linkahead as db -import caosadvancedtools.json_schema_exporter as jsex - from collections import OrderedDict - -from jsonschema import FormatChecker, validate, ValidationError -from pytest import raises from unittest.mock import Mock, patch -from caosadvancedtools.json_schema_exporter import recordtype_to_json_schema as rtjs +import caosadvancedtools.json_schema_exporter as jsex +import linkahead as db +from caosadvancedtools.json_schema_exporter import \ + recordtype_to_json_schema as rtjs from caosadvancedtools.models.parser import parse_model_from_string +from jsonschema import FormatChecker, ValidationError, validate +from pytest import raises GLOBAL_MODEL = parse_model_from_string(""" RT1: @@ -920,10 +918,12 @@ RT3: schema_noexist = rtjs(model.get_deep("RT3")) assert schema_noexist["properties"]["NoRecords"].get("type") == "object" - schema_noexist_noremote = rtjs(model.get_deep("RT3"), no_remote=True) - assert schema_noexist_noremote["properties"]["NoRecords"].get("type") == "object" - assert (schema_noexist_noremote["properties"]["NoRecords"].get("properties") - == OrderedDict([('some_text', {'type': 'string'})])) + with raises(NotImplementedError, + match="Behavior is not implemented when _no_remote == True and datatype is given as a string."): + schema_noexist_noremote = rtjs(model.get_deep("RT3"), no_remote=True) + assert schema_noexist_noremote["properties"]["NoRecords"].get("type") == "object" + assert (schema_noexist_noremote["properties"]["NoRecords"].get("properties") + == OrderedDict([('some_text', {'type': 'string'})])) uischema = {} schema_noexist_noretrieve = rtjs(model.get_deep("RT2"), do_not_retrieve=["RT1"], diff --git a/unittests/test_json_schema_model_parser.py b/unittests/test_json_schema_model_parser.py index a991076e6a1e1a3e92cafc7f1bb88b42b4b2ab3d..619714aa6e85d50222252da2b1f7999aceaaa26a 100644 --- a/unittests/test_json_schema_model_parser.py +++ b/unittests/test_json_schema_model_parser.py @@ -1,5 +1,5 @@ # -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2022 IndiScale GmbH <info@indiscale.com> # Copyright (C) 2022 Florian Spreckelsen <f.spreckelsen@indiscale.com> @@ -24,7 +24,7 @@ import os import pytest -import caosdb as db +import linkahead as db from caosadvancedtools.models.parser import (parse_model_from_json_schema, JsonSchemaDefinitionError) @@ -357,8 +357,8 @@ def test_name_property(): broken = parse_model_from_json_schema(os.path.join( FILEPATH, "datamodel_name_wrong_type.schema.json")) assert str(err.value).startswith( - "The 'name' property must be string-typed, otherwise it cannot be identified with CaosDB's " - "name property.") + "The 'name' property must be string-typed, otherwise it cannot be identified with " + "LinkAhead's name property.") def test_no_toplevel_entity(): diff --git a/unittests/test_read_md_header.py b/unittests/test_read_md_header.py index 994f8f16b6158914ff87134f3efd6f157dea6736..71873e05ceffbc1fa74d2a68764013d94e8de1ce 100644 --- a/unittests/test_read_md_header.py +++ b/unittests/test_read_md_header.py @@ -2,7 +2,7 @@ # encoding: utf-8 # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2019 Henrik tom Wörden # @@ -25,7 +25,7 @@ import unittest from copy import deepcopy from tempfile import NamedTemporaryFile -import caosdb as db +import linkahead as db from caosadvancedtools.read_md_header import get_header diff --git a/unittests/test_result_table_cfood.py b/unittests/test_result_table_cfood.py index 3341a2394cc9ef15ae172bb8992445d87c60d063..ad0d639707017dd03a28ea9c956b4c8396631fdd 100644 --- a/unittests/test_result_table_cfood.py +++ b/unittests/test_result_table_cfood.py @@ -2,7 +2,7 @@ # encoding: utf-8 # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2018 Research Group Biomedical Physics, # Max-Planck-Institute for Dynamics and Self-Organization Göttingen @@ -32,7 +32,7 @@ import os import re import unittest -import caosdb as db +import linkahead as db from caosadvancedtools.scifolder.result_table_cfood import ResultTableCFood diff --git a/unittests/test_sss_helper.py b/unittests/test_sss_helper.py index 71408fa6e34f17f18a803e00e944ef9105eae311..caaf49d46ecfd73cfcb787add80d003ed1b22001 100644 --- a/unittests/test_sss_helper.py +++ b/unittests/test_sss_helper.py @@ -2,14 +2,14 @@ import subprocess from email import message_from_file, policy from os import listdir, remove from os.path import abspath, dirname, exists, isfile, join - -import caosdb as db +import platform +import linkahead as db from caosadvancedtools.serverside.helper import (NameCollector, get_data, get_file_via_download, init_data_model, parse_arguments, send_mail) -from caosdb import RecordType, configure_connection, get_config -from caosdb.connection.mockup import MockUpResponse, MockUpServerConnection +from linkahead import RecordType, configure_connection, get_config +from linkahead.connection.mockup import MockUpResponse, MockUpServerConnection from pytest import mark, raises @@ -85,7 +85,10 @@ def test_send_mail(): assert msg["Subject"] == "the subject" assert msg.get_content() == "hello!\n" +# skip on windows (has no sendmail) + +@mark.skipif(platform.system() == "Windows", reason="no sendmail on Windows") def test_send_mail_error(): with raises(subprocess.CalledProcessError): send_mail("me@example.com", "you@example.com", "the subject", "hello!", @@ -110,8 +113,8 @@ def test_get_file_via_download(): # TODO test whether something ends up in the logger class NotThere(DummyFile): def download(*args, **kwargs): - raise db.CaosDBException() - with raises(db.CaosDBException): + raise db.LinkAheadException() + with raises(db.LinkAheadException): get_file_via_download(Inconsistent()) diff --git a/unittests/test_structure_mapping.py b/unittests/test_structure_mapping.py index 5cc4114fc7f92c580f53dd8855bda659082e2b46..a426cf78f35017a02414a091850501332737fec0 100644 --- a/unittests/test_structure_mapping.py +++ b/unittests/test_structure_mapping.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2021 IndiScale GmbH <www.indiscale.com> # Copyright (C) 2021 Henrik tom Wörden <h.tomwoerden@indiscale.com> @@ -22,10 +22,10 @@ import unittest from os import name -import caosdb as db +import linkahead as db from caosadvancedtools.structure_mapping import (EntityMapping, collect_existing_structure) -from caosdb.common import datatype +from linkahead.common import datatype class structureMappingTest(unittest.TestCase): diff --git a/unittests/test_suppressKnown.py b/unittests/test_suppressKnown.py index 07c2e18ead500f26556e2400611a0357f26f169f..80af892d2ad17f6420f8f3f2a83247f3431c9a3d 100644 --- a/unittests/test_suppressKnown.py +++ b/unittests/test_suppressKnown.py @@ -2,7 +2,7 @@ # encoding: utf-8 # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2020 IndiScale GmbH # Copyright (C) 2020 Henrik tom Wörden @@ -25,7 +25,7 @@ import logging import os import unittest -from tempfile import NamedTemporaryFile +from tempfile import NamedTemporaryFile, gettempdir from caosadvancedtools.suppressKnown import SuppressKnown @@ -40,7 +40,7 @@ class Record(object): class SupTestBasic(unittest.TestCase): def setUp(self): - self.db_file = "/tmp/test_suppress_msg_db_file.db" + self.db_file = os.path.join(gettempdir(), "test_suppress_msg_db_file_basic.db") self.basic = SuppressKnown(db_file=self.db_file) def test_msg(self): @@ -52,26 +52,31 @@ class SupTestBasic(unittest.TestCase): self.basic.filter(r) def tearDown(self): - os.remove(self.db_file) + pass class SupTestAdvanced(SupTestBasic): def setUp(self): - self.db_file = "/tmp/test_suppress_msg_db_file.db" + self.db_file = os.path.join(gettempdir(), "test_suppress_msg_db_file_advanced.db") self.basic = SuppressKnown(db_file=self.db_file) + @unittest.skipIf(os.name == "nt", reason="Known issue on Windows, see https://docs.python.org/3/library/tempfile.html#tempfile.NamedTemporaryFile") def test_logger(self): """ The logging output is directed to a file which is then checked whether the output is as expected. """ - logfile = NamedTemporaryFile() + # TODO: this test is problematic on Windows due to the file being locked + # by the logger. This is a known issue and should be fixed in the + # future. + # For now, the test is disabled on Windows. + # See https://docs.python.org/3/library/tempfile.html#tempfile.NamedTemporaryFile + logfile = NamedTemporaryFile(delete=False, mode="w") logger = logging.getLogger() logger.addHandler(logging.FileHandler(logfile.name)) logger.setLevel(logging.DEBUG) sup = SuppressKnown(db_file=self.db_file) logger.addFilter(sup) - logger.info("hi", extra={"identifier": "5", 'category': "test"}) with open(logfile.name) as lf: log = lf.read() diff --git a/unittests/test_table_converter.py b/unittests/test_table_converter.py index 9b1ac11b7c9ed5251f05c921fb08f7c42079c91a..b4f0c4d32d0c28044f7865b3b0dbd2f74210d74b 100644 --- a/unittests/test_table_converter.py +++ b/unittests/test_table_converter.py @@ -2,7 +2,7 @@ # encoding: utf-8 # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2019 Henrik tom Wörden # @@ -24,9 +24,9 @@ import os import unittest from tempfile import NamedTemporaryFile -import caosdb as db +import linkahead as db import pandas as pd -from caosdb.apiutils import compare_entities +from linkahead.apiutils import compare_entities from numpy import nan from caosadvancedtools.table_converter import (from_table, from_tsv, to_table, diff --git a/unittests/test_table_importer.py b/unittests/test_table_importer.py index 0abc28bba17dfbcf8f0ce59a15e51ace68db9167..c1336ee5a62e361564cb52ed79c380aab7bdb9a1 100644 --- a/unittests/test_table_importer.py +++ b/unittests/test_table_importer.py @@ -196,8 +196,8 @@ class TableImporterTest(unittest.TestCase): [5678, 1, 2.0, 3, 'yes']], columns=['a', 'b', 'c', 'float', 'd']) # wrong datatypes before - assert df["a"].dtype == int - assert df["float"].dtype == int + assert df["a"].dtype != pd.StringDtype + assert df["float"].dtype != float # strict = False by default, so this shouldn't raise an error importer.check_datatype(df) # The types should be correct now. diff --git a/unittests/test_update_cache.py b/unittests/test_update_cache.py index 8376da482b4828dd09de2ac6f3aca4fb9617c08d..318a35ae50dd280cdd4adf9a802b8e80029a3d7f 100644 --- a/unittests/test_update_cache.py +++ b/unittests/test_update_cache.py @@ -2,7 +2,7 @@ # encoding: utf-8 # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2020 Henrik tom Wörden # @@ -26,7 +26,7 @@ import unittest from copy import deepcopy from tempfile import NamedTemporaryFile -import caosdb as db +import linkahead as db from caosadvancedtools.cache import UpdateCache, get_pretty_xml diff --git a/unittests/test_utils.py b/unittests/test_utils.py index 468e9200de723c65c75e21912b5b3940d758821c..aeae08e4775c92f04959c67f06aa0dfb9b1ea9ca 100644 --- a/unittests/test_utils.py +++ b/unittests/test_utils.py @@ -2,7 +2,7 @@ # encoding: utf-8 # # ** header v3.0 -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2019 Henrik tom Wörden # @@ -23,13 +23,13 @@ import logging import unittest from tempfile import NamedTemporaryFile - -import caosdb as db +import os +import linkahead as db from caosadvancedtools.utils import (check_win_path, get_referenced_files, string_to_person, create_entity_link) -from caosdb import RecordType, configure_connection, get_config -from caosdb.connection.mockup import MockUpResponse, MockUpServerConnection -from caosdb.exceptions import TransactionError +from linkahead import RecordType, configure_connection, get_config +from linkahead.connection.mockup import MockUpResponse, MockUpServerConnection +from linkahead.exceptions import TransactionError class BaseMockUpTest(unittest.TestCase): @@ -47,7 +47,7 @@ class BaseMockUpTest(unittest.TestCase): connection._delegate_connection.resources.append( lambda **kwargs: MockUpResponse(200, {}, self.entities)) - self.logfile = NamedTemporaryFile() + self.logfile = NamedTemporaryFile(delete=False) logger = logging.getLogger() logger.addHandler(logging.FileHandler(self.logfile.name)) logger.setLevel(logging.DEBUG) diff --git a/unittests/test_yaml_model_parser.py b/unittests/test_yaml_model_parser.py index d6dbf718dfa539e97214c2329cccc5a6bbf172b6..8728e128f11503e607c856b0cb91ff7cb58fdaa7 100644 --- a/unittests/test_yaml_model_parser.py +++ b/unittests/test_yaml_model_parser.py @@ -1,4 +1,4 @@ -# This file is a part of the CaosDB Project. +# This file is a part of the LinkAhead project. # # Copyright (C) 2023 IndiScale GmbH <info@indiscale.com> # Copyright (C) 2023 Daniel Hornung <d.hornung@indiscale.com> @@ -19,13 +19,16 @@ import unittest from datetime import date from tempfile import NamedTemporaryFile -from pytest import raises, mark +from unittest.mock import Mock +import caosadvancedtools import linkahead as db from caosadvancedtools.models.parser import (TwiceDefinedException, YamlDefinitionError, parse_model_from_string, parse_model_from_yaml) +from linkahead.apiutils import compare_entities +from pytest import mark, raises def to_file(string): @@ -609,14 +612,13 @@ RT2: obligatory_properties: *RT1_oblig """ model = parse_model_from_string(model_string) - assert str(model) == """{'foo': <Property name="foo" datatype="INTEGER"/> -, 'RT1': <RecordType name="RT1"> - <Property name="foo" importance="OBLIGATORY" flag="inheritance:FIX"/> -</RecordType> -, 'RT2': <RecordType name="RT2"> - <Property name="foo" importance="OBLIGATORY" flag="inheritance:FIX"/> -</RecordType> -}""" + + assert len(model) == 3 + assert isinstance(model["foo"], db.Property) + assert model["foo"].datatype == db.INTEGER + for st in ("RT1", "RT2"): + assert isinstance(model[st], db.RecordType) + assert model[st].get_property("foo").datatype == db.INTEGER # Aliasing with override model_string = """ @@ -631,13 +633,183 @@ RT2: bar: """ model = parse_model_from_string(model_string) - assert str(model) == """{'foo': <Property name="foo" datatype="INTEGER"/> -, 'RT1': <RecordType name="RT1"> - <Property name="foo" importance="OBLIGATORY" flag="inheritance:FIX"/> -</RecordType> -, 'RT2': <RecordType name="RT2"> - <Property name="foo" importance="OBLIGATORY" flag="inheritance:FIX"/> - <Property name="bar" importance="OBLIGATORY" flag="inheritance:FIX"/> -</RecordType> -, 'bar': <RecordType name="bar"/> -}""" + + assert len(model) == 4 + assert isinstance(model["bar"], db.RecordType) + for st in ("RT1", "RT2"): + assert isinstance(model[st], db.RecordType) + assert model[st].get_property("foo").datatype == db.INTEGER + assert model["RT2"].get_property("bar").datatype == "bar" + + +def test_comparison_yaml_model(capfd): + """ + Test for this issue: + https://gitlab.indiscale.com/caosdb/src/caosdb-advanced-user-tools/-/issues/130 + """ + model_string = """ +foo: + datatype: INTEGER + description: bla bla + unit: m + +RT1: + obligatory_properties: + foo: + RT2: + datatype: LIST<RT2> + test_reference: + +RT2: + description: Describe RT2 + +test_reference: + datatype: RT2 + """ + model = parse_model_from_string(model_string) + + # Without the fix, foo will have no datatype, description and no unit **as part of RT1**, so the + # comparison with a version taken from a LinkAhead instance will have these attributes. + # Furthermore, RT2 will be set as the datatype **in object version** in the yaml definition, while + # it is an ID in case of the version from the LinkAhead instance. + + server_response = """ +<Entities> + <noscript> + </noscript> + <Property id="2272" name="foo" description="bla bla" datatype="INTEGER" unit="m"> + <Version id="7819eedaeba2aa7305e10c96e8cf7b9ac84aea4a" head="true"/> + </Property> + <RecordType id="2273" name="RT1"> + <Version id="0c1b9df6677ee40d1e1429b2123e078ee6c863e0" head="true"/> + <Property id="2272" name="foo" description="bla bla" datatype="INTEGER" unit="m" importance="OBLIGATORY" flag="inheritance:FIX"/> + <Property id="2274" name="RT2" description="Describe RT2" datatype="LIST<RT2>" importance="OBLIGATORY" flag="inheritance:FIX"/> + <Property id="2275" name="test_reference" datatype="RT2" importance="OBLIGATORY" flag="inheritance:FIX"/> + </RecordType> + <RecordType id="2274" name="RT2" description="Describe RT2"> + <Version id="185940642680a7eba7f71914dd8dd7758dd13faa" head="true"/> + </RecordType> + <Property id="2275" name="test_reference" datatype="RT2"> + <Version id="03cf86061c78a079b376394dfecdf32566b72fb7" head="true"/> + </Property> +</Entities>""" + + entities = db.Container.from_xml(server_response) + + c1 = compare_entities(model["foo"], entities[0]) + c2 = compare_entities(model["RT1"], entities[1]) + c3 = compare_entities(model["RT2"], entities[2]) + c4 = compare_entities(model["test_reference"], entities[3]) + + # Make sure the mock response matches the datamodel definiton + # exactly, i.e., they only differ in ids which are None for all + # entities from the datamodel and not None for the mocked + # response. + for cs in (c1, c2, c3, c4): + assert "id" in cs[0] + assert cs[0]["id"] is None + assert cs[0]["parents"] == [] + for name, val in cs[0]["properties"].items(): + # Also properties differ in ids: The one from the + # datamodel have None + assert len(val) == 1 + assert "id" in val + assert val["id"] is None + assert "id" in cs[1] + assert cs[1]["id"] is not None + assert cs[1]["parents"] == [] + for name, val in cs[1]["properties"].items(): + # Also properties differ in ids: The one from the + # mock response have not None + assert len(val) == 1 + assert "id" in val + assert val["id"] is not None + + # The server response would be the same as the xml above: + + def get_existing_entities(ent_cont): + return entities + + class MockQuery: + def __init__(self, q): + self.q = q + + def execute(self, unique=True): + id = int(self.q.split("=")[1]) + for existing_ent in entities: + if existing_ent.id == id: + return existing_ent + return None + + model.get_existing_entities = get_existing_entities + caosadvancedtools.models.parser.db.Query = MockQuery + caosadvancedtools.models.parser.db.Container.update = Mock() + caosadvancedtools.models.parser.db.Container.insert = Mock() + + model.sync_data_model(True, True) + assert not caosadvancedtools.models.parser.db.Container.update.called + assert not caosadvancedtools.models.parser.db.Container.insert.called + output, err = capfd.readouterr() + assert "No new entities." in output + assert "No differences found. No update" in output + + +def test_sync_output(capfd): + model = parse_model_from_string(""" +RT: + obligatory_properties: + identifier: + datatype: TEXT +""") + + existing_entities = [db.RecordType( + name="RT", id=25).add_property(name="identifier", + datatype="INTEGER", + importance="OBLIGATORY", + id=24), + db.Property(name="identifier", datatype="INTEGER", id=24)] + + def get_existing_entities(ent_cont): + return existing_entities + + class MockQuery: + def __init__(self, q): + self.q = q + + def execute(self, unique=True): + id = int(self.q.split("=")[1]) + for existing_ent in existing_entities: + if existing_ent.id == id: + return existing_ent + return None + + model.get_existing_entities = get_existing_entities + caosadvancedtools.models.parser.db.Query = MockQuery + caosadvancedtools.models.parser.db.Container.update = Mock() + caosadvancedtools.models.parser.db.Container.insert = Mock() + + model.sync_data_model(True, True) + assert caosadvancedtools.models.parser.db.Container.update.called + assert not caosadvancedtools.models.parser.db.Container.insert.called + output, err = capfd.readouterr() + print(output) + assert "version from the yaml file: TEXT" in output + assert "version from LinkAhead: INTEGER" in output + + +def test_setting_values(): + model = parse_model_from_string(""" + parameter: + datatype: INTEGER + + Simulation: + role: Record + obligatory_properties: + parameter: 26 + """) + + assert len(model) == 2 + assert str(model["parameter"])[:-1] == '<Property name="parameter" datatype="INTEGER"/>' + assert model["Simulation"].role == "Record" + assert model["Simulation"].name == "Simulation" + assert model["Simulation"].get_property("parameter").value == 26