├── .gitignore ├── .gitmodules ├── LICENSE ├── Makefile ├── README.md ├── manage.py ├── requirements.txt ├── tellina ├── __init__.py ├── settings.py ├── urls.py └── wsgi.py └── website ├── __init__.py ├── admin.py ├── annotator.py ├── apps.py ├── backend_interface.py ├── cmd2html.py ├── constants.py ├── context_processor.py ├── functions.py ├── manpage_expl.json ├── models.py ├── scripts ├── __init__.py └── db_changes.py ├── static ├── css │ ├── animate.css │ ├── annotator │ │ ├── login.css │ │ └── panel.css │ ├── comment.css │ ├── developers.css │ ├── font-awesome.min.css │ ├── index.css │ ├── introjs.min.css │ ├── main.css │ ├── perfect-scrollbar.css │ ├── perfect-scrollbar.min.css │ ├── responsive-mp.css │ └── translate.css ├── font │ ├── FontAwesome.otf │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.svg │ ├── fontawesome-webfont.ttf │ └── fontawesome-webfont.woff ├── html │ ├── annotator │ │ ├── base.html │ │ ├── collect_page.html │ │ ├── login.html │ │ ├── url_panel.html │ │ ├── user_panel.html │ │ ├── user_profile.html │ │ └── utility_panel.html │ └── translator │ │ ├── base.html │ │ ├── developers.html │ │ ├── index.html │ │ ├── macros.html │ │ ├── options.html │ │ ├── query_history.html │ │ └── translate.html ├── img │ ├── cli.png │ ├── clippy.svg │ ├── developers │ │ └── system_overview.png │ ├── gear.svg │ ├── gears.gif │ ├── globe.svg │ ├── glyphicons-halflings-white.png │ ├── glyphicons-halflings.png │ ├── tellina.svg │ └── tellina_avatar.svg ├── js │ ├── annotator │ │ └── main.js │ ├── clipboard.js │ ├── clipboard.min.js │ ├── comment.js │ ├── d3.v3.js │ ├── d3.v3.min.js │ ├── intro.min.js │ ├── jquery-3.1.1.js │ ├── perfect-scrollbar.jquery.js │ ├── perfect-scrollbar.jquery.min.js │ ├── perfect-scrollbar.js │ ├── perfect-scrollbar.min.js │ ├── tellina.js │ └── underscore.js └── lib │ ├── bootstrap │ ├── config.json │ ├── css │ │ ├── bootstrap-theme.css │ │ ├── bootstrap-theme.min.css │ │ ├── bootstrap.css │ │ └── bootstrap.min.css │ ├── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ ├── glyphicons-halflings-regular.woff │ │ └── glyphicons-halflings-regular.woff2 │ └── js │ │ ├── bootstrap-dialog.js │ │ ├── bootstrap-modal.js │ │ ├── bootstrap.js │ │ └── bootstrap.min.js │ ├── font-awesome-4.7.0 2 │ ├── css │ │ ├── font-awesome.css │ │ └── font-awesome.min.css │ ├── fonts │ │ ├── FontAwesome.otf │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.svg │ │ ├── fontawesome-webfont.ttf │ │ ├── fontawesome-webfont.woff │ │ └── fontawesome-webfont.woff2 │ ├── less │ │ ├── animated.less │ │ ├── bordered-pulled.less │ │ ├── core.less │ │ ├── fixed-width.less │ │ ├── font-awesome.less │ │ ├── icons.less │ │ ├── larger.less │ │ ├── list.less │ │ ├── mixins.less │ │ ├── path.less │ │ ├── rotated-flipped.less │ │ ├── screen-reader.less │ │ ├── stacked.less │ │ └── variables.less │ └── scss │ │ ├── _animated.scss │ │ ├── _bordered-pulled.scss │ │ ├── _core.scss │ │ ├── _fixed-width.scss │ │ ├── _icons.scss │ │ ├── _larger.scss │ │ ├── _list.scss │ │ ├── _mixins.scss │ │ ├── _path.scss │ │ ├── _rotated-flipped.scss │ │ ├── _screen-reader.scss │ │ ├── _stacked.scss │ │ ├── _variables.scss │ │ └── font-awesome.scss │ ├── google-plus.themes │ └── google-plus.css │ ├── hljs.themes │ ├── agate.css │ ├── bash.js │ ├── color-brewer.css │ ├── dracula.css │ ├── github-gist.css │ ├── hljs-9.8.0.min.js │ ├── solarized-light.css │ ├── tomorrow.css │ └── zenburn.css │ ├── jquery-ui-1.12.1.custom │ ├── AUTHORS.txt │ ├── LICENSE.txt │ ├── external │ │ └── jquery │ │ │ └── jquery.js │ ├── images │ │ ├── ui-icons_444444_256x240.png │ │ ├── ui-icons_555555_256x240.png │ │ ├── ui-icons_777620_256x240.png │ │ ├── ui-icons_777777_256x240.png │ │ ├── ui-icons_cc0000_256x240.png │ │ └── ui-icons_ffffff_256x240.png │ ├── index.html │ ├── jquery-ui.css │ ├── jquery-ui.js │ ├── jquery-ui.min.css │ ├── jquery-ui.min.js │ ├── jquery-ui.structure.css │ ├── jquery-ui.structure.min.css │ ├── jquery-ui.theme.css │ ├── jquery-ui.theme.min.css │ └── package.json │ └── jquery.upvote │ ├── images │ ├── sprites-meta-stackoverflow.png │ ├── sprites-programmers.png │ ├── sprites-serverfault.png │ ├── sprites-stackoverflow.png │ ├── sprites-superuser.png │ └── sprites-unix.png │ ├── jquery.upvote.css │ └── jquery.upvote.js ├── utils.py └── views.py /.gitignore: -------------------------------------------------------------------------------- 1 | website/migrations 2 | website/config.py 3 | 4 | # LaTeX junk 5 | *.aux 6 | *.log 7 | *.bbl 8 | *.blg 9 | *.fdb_latexmk 10 | *.fls 11 | *.pdf 12 | *.synctex.gz 13 | *.out 14 | *.dvi 15 | 16 | # uncompressed StackOverflow data 17 | *.sqlite 18 | 19 | # IDE junk 20 | *.sublime-* 21 | 22 | # Python 23 | *.pyc 24 | 25 | # Java 26 | *.class 27 | 28 | # moses files 29 | *.final 30 | *.vcb 31 | 32 | # auto-generated files 33 | parsetab.py 34 | /man-parser/out 35 | 36 | # Shell scripts 37 | *.sh 38 | 39 | # Database file 40 | *.db 41 | *.txt 42 | *.sqlite3 43 | 44 | # Misc 45 | MANIFEST 46 | .DS_Store 47 | *.csv 48 | *.key 49 | eval.* 50 | temp*.txt 51 | *dump*.txt 52 | spell.txt 53 | manual.eval.results* 54 | *beam_search.eval 55 | beam_search*eval* 56 | *.swp 57 | *.swo 58 | *.debug 59 | /paper 60 | website/data/ 61 | website/scripts/export_pairs.py 62 | tools/spellcheck/*.txt 63 | 64 | # IDE-specific stuff: 65 | __pycache__ 66 | .idea 67 | *.iml 68 | site_config.py 69 | 70 | # Intellij project 71 | parsers/out/production/* 72 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "tellina_learning_module"] 2 | path = tellina_learning_module 3 | url = https://github.com/TellinaTool/tellina_learning_module 4 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # This Makefile wraps commands used to set up the learning module and 2 | # start the Tellina server. 3 | 4 | LR_MODULE=tellina_learning_module 5 | 6 | submodule: 7 | # Update learning submodule 8 | git submodule update --remote 9 | # Set up data files used in the learning module 10 | tar xf $(LR_MODULE)/data/bash/vocab.tar.xz --directory $(LR_MODULE)/data/bash/ 11 | # tar xf $(LR_MODULE)/data/bash.final/vocab.tar.xz --directory $(LR_MODULE)/data/bash.final/ 12 | # Set up nlp tools 13 | tar xf $(LR_MODULE)/nlp_tools/spellcheck/most_common.tar.xz --directory $(LR_MODULE)/nlp_tools/spellcheck/ 14 | 15 | db: 16 | # Setup database tables 17 | python3 manage.py makemigrations website 18 | python3 manage.py migrate 19 | 20 | run: 21 | # Set CUDAPATH 22 | # source ~/.profile 23 | # Set PYTHONPATH 24 | export PYTHONPATH=`pwd` 25 | # Run server 26 | python3 manage.py runserver 0.0.0.0:8000 --insecure 27 | 28 | clean: 29 | # Destroy database and migrations 30 | find . -type d -name "__pycache__" | xargs rm -r 31 | rm -rf website/migrations 32 | # rm -rf db.sqlite3 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Tellina 2 | 3 | Tellina uses natural language processing (NLP) to translate an English sentence, such as "Find text file in the current folder", into a bash command, such as `find . -name "*.txt"`. 4 | 5 | You can try it now at http://tellina.rocks . 6 | Or, you can install it locally; this document tells you how. 7 | 8 | ## Installation 9 | 10 | ### Install Tensorflow 11 | Tellina uses Tensorflow 2.0. 12 | 13 | Follow the instructions on the [Tensorflow website](https://www.tensorflow.org/get_started/get_started). The simplest way is to install using [`pip3`](https://www.tensorflow.org/install/). 14 | 15 | ### Install other dependencies: 16 | 17 | ``` 18 | pip3 install -r requirements.txt 19 | ``` 20 | 21 | ### Set up tellina_learning_module submodule: 22 | 23 | ``` 24 | git submodule update --init --remote 25 | git submodule foreach git pull origin master 26 | make submodule 27 | ``` 28 | To update the tellina_learning_module in the future, run: 29 | ``` 30 | make submodule 31 | ``` 32 | 33 | ### Set up databases: 34 | 35 | ``` 36 | make db 37 | ``` 38 | 39 | ### Run webapp: 40 | 41 | ``` 42 | make run 43 | ``` 44 | 45 | To experiment with the translation model locally, make sure to set following control variables correctly. 46 | 47 | ### Control variables: 48 | 49 | ``` 50 | WEBSITE_DEVELOP (website/views.py) 51 | 52 | - True, start the web server without importing the Tensorflow translation module (no server start delay, suggested setting when testing peripheral website functions) 53 | - False (default), start the web server and translate new queries (5-10 secs server start delay due to Tensorflow graph building) 54 | 55 | CACHE_TRANSLATIONS (website/views.py) 56 | 57 | - True, cache translation results for natural language queries that were seen 58 | - False (default), run translation model on every query, regardless of whether it has been seen or not 59 | 60 | CPU_ONLY (website/backend_interface.py) 61 | 62 | - True (default), run Tellina on CPU 63 | - False, run Tellina on GPU if and only if the host machine has GPU installed 64 | ``` 65 | Visit http://127.0.0.1:8000 in your browser. 66 | 67 | ## Citation 68 | 69 | If you used Tellina in your work, please cite 70 | ``` 71 | @techreport{LinWPVZE2017:TR, 72 | author = {Xi Victoria Lin and Chenglong Wang and Deric Pang and Kevin Vu and Luke Zettlemoyer and Michael D. Ernst}, 73 | title = {Program synthesis from natural language using recurrent neural networks}, 74 | institution = {University of Washington Department of Computer Science and Engineering}, 75 | number = {UW-CSE-17-03-01}, 76 | address = {Seattle, WA, USA}, 77 | month = mar, 78 | year = {2017} 79 | } 80 | ``` 81 | -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tellina.settings") 7 | try: 8 | from django.core.management import execute_from_command_line 9 | except ImportError: 10 | # The above import may fail for some other reason. Ensure that the 11 | # issue is really that Django is missing to avoid masking other 12 | # exceptions on Python 2. 13 | try: 14 | import django 15 | except ImportError: 16 | raise ImportError( 17 | "Couldn't import Django. Are you sure it's installed and " 18 | "available on your PYTHONPATH environment variable? Did you " 19 | "forget to activate a virtual environment?" 20 | ) 21 | raise 22 | execute_from_command_line(sys.argv) 23 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Django>=1.10.8 2 | nltk==3.6.6 3 | matplotlib==1.5.3 4 | tqdm==4.9.0 5 | requests==2.31.0 6 | -------------------------------------------------------------------------------- /tellina/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TellinaTool/tellina/61f1398eb3c2adaad32660d9185d646ff3fcd857/tellina/__init__.py -------------------------------------------------------------------------------- /tellina/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for tellina project. 3 | 4 | Generated by 'django-admin startproject' using Django 1.10.2. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.10/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/1.10/ref/settings/ 11 | """ 12 | 13 | import os 14 | 15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 17 | 18 | 19 | # Quick-start development settings - unsuitable for production 20 | # See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/ 21 | 22 | # SECURITY WARNING: keep the secret key used in production secret! 23 | SECRET_KEY = '*zca^nlaejb32n)5@cevdlsb@g3ea4in=x_k1x9we788v&6k5r' 24 | 25 | # SECURITY WARNING: don't run with debug turned on in production! 26 | DEBUG = True 27 | 28 | ALLOWED_HOSTS = ['kirin.cs.washington.edu', '127.0.0.1', '205.175.118.26', 29 | '69.91.132.97'] 30 | 31 | 32 | # Application definition 33 | 34 | INSTALLED_APPS = [ 35 | 'website.apps.TranslatorConfig', 36 | 'django.contrib.admin', 37 | 'django.contrib.auth', 38 | 'django.contrib.contenttypes', 39 | 'django.contrib.sessions', 40 | 'django.contrib.messages', 41 | 'django.contrib.staticfiles', 42 | ] 43 | 44 | MIDDLEWARE = [ 45 | 'django.middleware.security.SecurityMiddleware', 46 | 'django.contrib.sessions.middleware.SessionMiddleware', 47 | 'django.middleware.common.CommonMiddleware', 48 | 'django.middleware.csrf.CsrfViewMiddleware', 49 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 50 | 'django.contrib.messages.middleware.MessageMiddleware', 51 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 52 | ] 53 | 54 | ROOT_URLCONF = 'tellina.urls' 55 | 56 | TEMPLATES = [ 57 | { 58 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 59 | 'DIRS': [os.path.join(BASE_DIR, 'website/static/html/')], 60 | 'APP_DIRS': True, 61 | 'OPTIONS': { 62 | 'context_processors': [ 63 | 'django.template.context_processors.debug', 64 | 'django.template.context_processors.request', 65 | 'django.contrib.auth.context_processors.auth', 66 | 'django.contrib.messages.context_processors.messages', 67 | ], 68 | }, 69 | }, 70 | ] 71 | 72 | 73 | WSGI_APPLICATION = 'tellina.wsgi.application' 74 | 75 | 76 | # Database 77 | # https://docs.djangoproject.com/en/1.10/ref/settings/#databases 78 | 79 | DATABASES = { 80 | 'default': { 81 | 'ENGINE': 'django.db.backends.sqlite3', 82 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 83 | } 84 | } 85 | 86 | 87 | # Password validation 88 | # https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators 89 | 90 | AUTH_PASSWORD_VALIDATORS = [ 91 | { 92 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 93 | }, 94 | { 95 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 96 | }, 97 | { 98 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 99 | }, 100 | { 101 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 102 | }, 103 | ] 104 | 105 | 106 | # Internationalization 107 | # https://docs.djangoproject.com/en/1.10/topics/i18n/ 108 | 109 | LANGUAGE_CODE = 'en-us' 110 | 111 | TIME_ZONE = 'UTC' 112 | 113 | USE_I18N = True 114 | 115 | USE_L10N = True 116 | 117 | USE_TZ = True 118 | 119 | 120 | # Static files (CSS, JavaScript, Images) 121 | # https://docs.djangoproject.com/en/1.10/howto/static-files/ 122 | 123 | STATIC_URL = '/static/' 124 | 125 | STATICFILES_DIRS = [ 126 | BASE_DIR + "/website/static/", 127 | ] 128 | -------------------------------------------------------------------------------- /tellina/urls.py: -------------------------------------------------------------------------------- 1 | """django_project URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/1.10/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.conf.urls import url, include 14 | 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) 15 | """ 16 | from django.conf.urls import url 17 | from django.contrib import admin 18 | from django.http import HttpResponse 19 | 20 | from website import annotator, cmd2html, views 21 | 22 | urlpatterns = [ 23 | url(r'^$', views.index), 24 | url(r'^index$', views.index), 25 | url(r'^translate$', views.translate), 26 | url(r'^load_example_requests_with_translations', views.example_requests_with_translations), 27 | url(r'^load_latest_requests_with_translations', views.latest_requests_with_translations), 28 | url(r'^developers$', views.developers), 29 | 30 | url(r'^remember_ip_address$', views.remember_ip_address), 31 | url(r'^vote$', views.vote), 32 | 33 | url(r'^explain_cmd$', cmd2html.explain_cmd), 34 | 35 | url(r'^login$', annotator.login), 36 | url(r'^register_user', annotator.register_user), 37 | url(r'^user_login$', annotator.user_login), 38 | url(r'^logout$', annotator.user_logout), 39 | 40 | url(r'^url_panel$', annotator.url_panel), 41 | url(r'^utility_panel$', annotator.utility_panel), 42 | 43 | url(r'^collect_page$', annotator.collect_page), 44 | url(r'^previous_url$', annotator.previous_url), 45 | url(r'^next_url$', annotator.next_url), 46 | url(r'^submit_annotation$', annotator.submit_annotation), 47 | url(r'^submit_edit$', annotator.submit_edit), 48 | url(r'^delete_annotation$', annotator.delete_annotation), 49 | url(r'^mark_duplicate$', annotator.mark_duplicate), 50 | url(r'^mark_wrong$', annotator.mark_wrong), 51 | url(r'^mark_i_dont_know', annotator.mark_i_dont_know), 52 | url(r'^update_progress$', annotator.update_progress), 53 | 54 | url(r'^accept_update', annotator.accept_update), 55 | url(r'^retract_update', annotator.retract_update), 56 | url(r'^submit_annotation_update', annotator.submit_annotation_update), 57 | url(r'^get_relevant_updates', annotator.get_relevant_updates), 58 | url(r'^get_update_status', annotator.get_update_status), 59 | url(r'^get_url_stats', annotator.get_url_stats), 60 | url(r'^get_utility_stats', annotator.get_utility_stats), 61 | url(r'^get_utility_num_notifications', annotator.get_utility_num_notifications), 62 | url(r'^get_url_num_notifications', annotator.get_url_num_notifications), 63 | url(r'^reject_update', annotator.reject_update), 64 | 65 | url(r'user_panel', annotator.user_panel), 66 | url(r'user_profile', annotator.user_profile), 67 | url(r'update_user_time_logged', annotator.update_user_time_logged), 68 | 69 | url(r'^robots.txt$', lambda r: HttpResponse("User-agent: *\nDisallow: /", mimetype="text/plain")), 70 | 71 | url(r'^admin', admin.site.urls) 72 | ] 73 | -------------------------------------------------------------------------------- /tellina/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for django_project project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.10/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tellina.settings") 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /website/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TellinaTool/tellina/61f1398eb3c2adaad32660d9185d646ff3fcd857/website/__init__.py -------------------------------------------------------------------------------- /website/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | from .models import Annotation, AnnotationUpdate, Command, CommandAdmin, NLRequest, \ 4 | Translation, URL, URLTag, User, UserAdmin 5 | 6 | admin.site.register(Command, CommandAdmin) 7 | 8 | admin.site.register(URL) 9 | admin.site.register(User, UserAdmin) 10 | admin.site.register(NLRequest) 11 | admin.site.register(Translation) 12 | admin.site.register(Annotation) 13 | admin.site.register(AnnotationUpdate) 14 | admin.site.register(URLTag) 15 | -------------------------------------------------------------------------------- /website/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | class TranslatorConfig(AppConfig): # Our app config class 4 | name = 'website' 5 | -------------------------------------------------------------------------------- /website/backend_interface.py: -------------------------------------------------------------------------------- 1 | """ 2 | Interface to the neural translation model. 3 | """ 4 | import tensorflow as tf 5 | tf.compat.v1.disable_eager_execution() 6 | 7 | import os 8 | import sys 9 | 10 | learning_module_dir = os.path.join(os.path.dirname(__file__), "..", 11 | "tellina_learning_module") 12 | sys.path.append(learning_module_dir) 13 | 14 | from website.utils import NUM_TRANSLATIONS 15 | from encoder_decoder import data_utils 16 | from encoder_decoder import decode_tools 17 | from encoder_decoder import parse_args 18 | from encoder_decoder import translate 19 | 20 | CPU_ONLY=True 21 | if CPU_ONLY: 22 | os.environ["CUDA_VISIBLE_DEVICES"] = "-1" 23 | else: 24 | os.environ["CUDA_VISIBLE_DEVICES"] = "2" 25 | 26 | # initialize FLAGS by parsing a dummy argument list 27 | tf.compat.v1.flags.FLAGS(sys.argv[:1]) 28 | FLAGS = tf.compat.v1.flags.FLAGS 29 | 30 | FLAGS.demo = True 31 | FLAGS.fill_argument_slots = False 32 | FLAGS.num_nn_slot_filling = 5 33 | 34 | FLAGS.encoder_topology = 'birnn' 35 | 36 | FLAGS.sc_token_dim = 200 37 | FLAGS.batch_size = 128 38 | FLAGS.num_layers = 1 39 | FLAGS.learning_rate = 0.0001 40 | FLAGS.sc_input_keep = 0.6 41 | FLAGS.sc_output_keep = 0.6 42 | FLAGS.tg_input_keep = 0.6 43 | FLAGS.tg_output_keep = 0.6 44 | 45 | FLAGS.tg_token_use_attention = True 46 | FLAGS.tg_token_attn_fun = 'non-linear' 47 | FLAGS.attention_input_keep = 0.6 48 | FLAGS.attention_output_keep = 0.6 49 | FLAGS.beta = 0.0 50 | 51 | FLAGS.token_decoding_algorithm = 'beam_search' 52 | FLAGS.beam_size = 100 53 | FLAGS.alpha = 1 54 | 55 | FLAGS.min_vocab_frequency = 4 56 | FLAGS.normalized = False 57 | FLAGS.channel = 'partial.token' 58 | FLAGS.use_copy = True 59 | FLAGS.copy_fun = 'copynet' 60 | 61 | FLAGS.dataset = 'bash' 62 | FLAGS.data_dir = os.path.join(learning_module_dir, "data", FLAGS.dataset) 63 | FLAGS.model_root_dir = os.path.join(learning_module_dir, "model", "seq2seq") 64 | 65 | # Data-dependent parameters 66 | FLAGS.max_sc_length = 42 67 | FLAGS.max_tg_length = 57 68 | FLAGS.sc_vocab_size = 1324 69 | FLAGS.tg_vocab_size = 1219 70 | FLAGS.max_sc_token_size = 100 71 | FLAGS.max_tg_token_size = 100 72 | buckets = [(13, 57), (18, 57), (42, 57)] 73 | 74 | # Create tensorflow session 75 | sess = tf.compat.v1.Session(config=tf.compat.v1.ConfigProto(allow_soft_placement=True, 76 | log_device_placement=FLAGS.log_device_placement)) 77 | 78 | # create model and load nerual model parameters. 79 | model = translate.define_model(sess, forward_only=True, buckets=buckets) 80 | print('loading models from {}'.format(FLAGS.model_dir)) 81 | 82 | vocabs = data_utils.load_vocabulary(FLAGS) 83 | 84 | if FLAGS.fill_argument_slots: 85 | # Create slot filling classifier 86 | model_param_dir = os.path.join(FLAGS.model_dir, 'train.mappings.X.Y.npz') 87 | train_X, train_Y = data_utils.load_slot_filling_data(model_param_dir) 88 | slot_filling_classifier = classifiers.KNearestNeighborModel( 89 | FLAGS.num_nn_slot_filling, train_X, train_Y) 90 | print('Slot filling classifier parameters loaded.') 91 | else: 92 | slot_filling_classifier = None 93 | 94 | def translate_fun(sentence, slot_filling_classifier=slot_filling_classifier): 95 | print('translating |{}|'.format(sentence)) 96 | list_of_translations = decode_tools.translate_fun( 97 | sentence, sess, model, vocabs, FLAGS, slot_filling_classifier) 98 | return list_of_translations 99 | -------------------------------------------------------------------------------- /website/cmd2html.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import json 4 | 5 | from django.http import HttpResponse 6 | sys.path.append(os.path.join(os.path.dirname(__file__),"..", "tellina_learning_module")) 7 | from bashlint import data_tools 8 | 9 | ## load the manpage expl file, note that the root should be before tellina 10 | with open(os.path.join('website', 'manpage_expl.json'), encoding='UTF-8') as data_file: 11 | manpage_json = json.loads(data_file.read()) 12 | 13 | def explain_cmd(request): 14 | """ This is the responser for flag explanation: 15 | it takes in a request consist of a tuple (cmd_head, flag_name, node_kind) and returns the explanation of the flag. 16 | Arguments: 17 | request { 18 | cmd_head: the command to query 19 | flag_name: the flag to query 20 | node_kind: the type of span that the query is issued from 21 | } 22 | Returns: 23 | returns the manpage explanation of the cmd_head/flag_name 24 | """ 25 | 26 | if request.method == 'POST': 27 | cmd_head = request.POST.get('cmd_head') 28 | flag_name = request.POST.get('flag_name') 29 | node_kind = request.POST.get('node_kind') 30 | else: 31 | cmd_head = request.GET.get('cmd_head') 32 | flag_name = request.GET.get('flag_name') 33 | node_kind = request.GET.get('node_kind') 34 | 35 | if cmd_head: 36 | # retrieve the explanation of the command 37 | for cmd_obj in manpage_json: 38 | if cmd_head in cmd_obj["aliases"]: 39 | #cmd_expl = "Aliases:" + " ".join(cmd_obj["aliases"]) + "\n\n" + cmd_obj["description"] 40 | 41 | # note that we use "None" due to the serialized field is of string type 42 | if flag_name != "None": 43 | # in this case, our goal is to explain a command 44 | flag_expl_list = [] 45 | for option_desc in cmd_obj["optionDesc"]: 46 | if flag_name == option_desc["name"].split()[0]: 47 | flag_expl_list.append(option_desc["description"]) 48 | if flag_expl_list: 49 | return HttpResponse("".join(flag_expl_list)) 50 | else: 51 | return HttpResponse("") 52 | 53 | # if the flag is not provided, or we cannot find the flag 54 | if node_kind == "argument": 55 | return HttpResponse(cmd_obj["rawSynopsis"]) 56 | elif node_kind == "utility": 57 | return HttpResponse(cmd_obj["description"]) 58 | 59 | # in this case, either the thead is not provided or the head cannot be retrieved 60 | return HttpResponse("") 61 | 62 | def cmd2html(cmd_str): 63 | """ A wrapper for the function ast2html (see below) that takes in a cmd string 64 | and translate into a html string with highlinghting. 65 | """ 66 | return " ".join(ast2html(data_tools.bash_parser(cmd_str))) 67 | 68 | def tokens2html(cmd_str): 69 | """ A wrapper for the function ast2html (see below) that takes in a cmd string 70 | and translate into a html string with highlinghting. 71 | """ 72 | return " ".join(ast2html(cmd_str)) 73 | 74 | def ast2html(node): 75 | 76 | """ Translate a bash AST from tellina_learning_module/bashlint/nast.py into html code, 77 | with proper syntax highlighting. 78 | Argument: 79 | node: an ast returned from tellina_learning_module.data_tools.bash_parser(cmd_str) 80 | Returns: 81 | a html string that can be embedded into your browser with appropriate syntax highlighting 82 | """ 83 | 84 | dominator = retrieve_dominators(node) 85 | 86 | # the documation of the span 87 | span_doc = "dominate_cmd=\"" + (str(dominator[0]) if dominator[0] else "None") \ 88 | + "\" dominate_flag=\"" + (str(dominator[1]) if dominator[1] else "None") \ 89 | + "\" node_kind=\"" + node.kind + "\""; 90 | 91 | html_spans = [] 92 | 93 | # switching among node kinds for the generation of different spans 94 | if node.kind == "root": 95 | for child in node.children: 96 | html_spans.extend(ast2html(child)) 97 | elif node.kind == "pipeline": 98 | is_first = True 99 | for child in node.children: 100 | if is_first: 101 | is_first = False 102 | else: 103 | html_spans.append("|") 104 | html_spans.extend(ast2html(child)) 105 | elif node.kind == "utility": 106 | span = "" + node.value + "" 107 | html_spans.append(span) 108 | for child in node.children: 109 | html_spans.extend(ast2html(child)) 110 | elif node.kind == "flag": 111 | # note there are two corner cases of flags: 112 | # -exec::; and -exec::+ since they have different endings 113 | if node.value == "-exec::;" or node.value == "-exec::+": 114 | head_span = "" + "-exec" + "" 115 | else: 116 | head_span = "" + node.value + "" 117 | html_spans.append(head_span) 118 | for child in node.children: 119 | html_spans.extend(ast2html(child)) 120 | if node.value == "-exec::;": 121 | html_spans.append("\\;") 122 | elif node.value == "-exec::+": 123 | html_spans.append("+"); 124 | elif node.kind == "argument" and node.arg_type != "ReservedWord": 125 | span = "" + node.value + "" 126 | html_spans.append(span) 127 | for child in node.children: 128 | html_spans.extend(ast2html(child)) 129 | elif node.kind == "bracket": 130 | html_spans.append("\\(") 131 | for child in node.children: 132 | html_spans.extend(ast2html(child)) 133 | html_spans.append("\\)") 134 | elif node.kind in ["binarylogicop", "unarylogicop", "redirect"]: 135 | span = "" + node.value + "" 136 | html_spans.append(span) 137 | elif node.kind in ["commandsubstitution", "processsubstitution"]: 138 | html_spans.append(node.value) 139 | html_spans.append("(") 140 | for child in node.children: 141 | html_spans.extend(ast2html(child)) 142 | html_spans.append(")") 143 | else: 144 | html_spans.append(node.value) 145 | 146 | return html_spans 147 | 148 | def retrieve_dominators(node): 149 | """ Given a node, retrieve its dominator, 150 | i.e., its utility and/or its dominate flag 151 | """ 152 | dominate_headcmd = None 153 | dominate_flag = None 154 | 155 | current_node = node 156 | 157 | while True: 158 | if current_node and current_node.kind == "flag": 159 | if not dominate_flag: 160 | dominate_flag = current_node.value 161 | # this is resulted from a corner case by Victoria, 162 | # for -exec::; -exec::+ and potentially others 163 | if "::" in dominate_flag: 164 | dominate_flag = dominate_flag[0: dominate_flag.index("::")] 165 | elif current_node and current_node.kind == "utility": 166 | dominate_headcmd = current_node.value 167 | return (dominate_headcmd, dominate_flag) 168 | 169 | # we have already find dominate_headcmd or we have reached root 170 | if current_node and (not current_node.parent): 171 | return (dominate_headcmd, dominate_flag) 172 | elif current_node: 173 | current_node = current_node.parent 174 | 175 | if dominate_headcmd is None: 176 | return ('', '') 177 | return (dominate_headcmd, dominate_flag) 178 | 179 | def test(): 180 | cmd_str_list = [ 181 | "find Path -iname Regex -exec grep -i -l Regex {} \;", 182 | "find Path -type f -iname Regex | xargs -I {} grep -i -l Regex {}", 183 | "find Path \( -name Regex-01 -or -name Regex-02 \) -print", 184 | "find Path -not -name Regex", 185 | "find . \( -mtime 10d -or -atime Timespan -or -atime Timespan -or -atime Timespan -or -atime Timespan \) -print", 186 | "find Documents \( -name \"*.py\" -o -name \"*.html\" \)" 187 | ]; 188 | for cmd_str in cmd_str_list: 189 | print(cmd2html(cmd_str)) 190 | 191 | if __name__ == '__main__': 192 | test() 193 | -------------------------------------------------------------------------------- /website/constants.py: -------------------------------------------------------------------------------- 1 | INVALID_ANNOTATION_TAGS = { 2 | 'NA', 3 | 'ERROR', 4 | 'DUPLICATE', 5 | 'WRONG', 6 | 'I DON\'T KNOW' 7 | } 8 | 9 | WHITE_LIST = { 10 | 'find', 11 | 'xargs' 12 | } 13 | -------------------------------------------------------------------------------- /website/context_processor.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | 3 | def debug(context): 4 | return {'DEBUG': settings.DEBUG} 5 | -------------------------------------------------------------------------------- /website/functions.py: -------------------------------------------------------------------------------- 1 | """ 2 | Standard python package file with syntax comaptible with python3.5 and above. 3 | """ 4 | 5 | import collections 6 | import inspect 7 | 8 | from functools import partial, wraps 9 | 10 | 11 | def first(coll): # rewrite to use frozen dict 12 | """Return the first item in a dictionary, list, or tuple.""" 13 | if not coll: 14 | return None 15 | try: 16 | return dict((coll.items()[0],)) 17 | except AttributeError: 18 | return coll[0] 19 | 20 | 21 | def last(coll): # rewrite to use frozen dict 22 | """Return the last item in a dictionary, list, or tuple.""" 23 | try: 24 | return dict((coll.items()[-1],)) 25 | except AttributeError: 26 | return coll[-1] 27 | 28 | 29 | def rest(coll): # rewrite to use frozen dict 30 | """Return the remaining items in a dictionary, list, or tuple.""" 31 | try: 32 | return dict(coll.items()[1:]) 33 | except AttributeError: 34 | return coll[1:] 35 | 36 | 37 | def none(*args, **kwargs): 38 | return None 39 | 40 | 41 | identity = lambda x: x 42 | 43 | 44 | def is_seq(x): 45 | """Return True if x is iterable.""" 46 | return (not hasattr(x, "strip") and 47 | hasattr(x, "__getitem__") or 48 | hasattr(x, "__iter__")) 49 | 50 | 51 | def fmap(f, coll): 52 | """Apply a function to each item in a dictionary, list, or tuple.""" 53 | try: 54 | return {k: f(v) for k, v in coll.iteritems()} 55 | except AttributeError: 56 | return tuple(f(v) for v in coll) 57 | 58 | 59 | def walk(inner, outer, data): 60 | """Traverse an arbitrary data structure and apply a function to each node.""" 61 | def process_node(inner, k, v): 62 | if not isinstance(v, collections.Iterable) or isinstance(v, basestring): 63 | return inner(k, v) 64 | if isinstance(v, collections.Sequence): 65 | rows = tuple(walk(inner, identity, row) for row in v) 66 | rv = tuple(filter(lambda row: row, rows)) 67 | else: 68 | rv = walk(inner, identity, v) 69 | return (k, rv) if rv else None 70 | if isinstance(data, collections.Sequence): 71 | return outer(tuple(map(lambda x: walk(inner, identity, x), data))) 72 | nodes = tuple(map(lambda kv: process_node(inner, kv[0], kv[1]), 73 | data.iteritems())) 74 | return outer(dict(filter(lambda node: node is not None, nodes))) 75 | 76 | 77 | def cons(x, seq): 78 | """Return a tuple where x is the first element and seq is the rest.""" 79 | return (x,) + tuple(seq) 80 | 81 | 82 | def thread(x, form): 83 | if isinstance(form, tuple): 84 | f, args = first(form), rest(form) 85 | return f(x, *args) 86 | return form(x) 87 | 88 | 89 | def threadfirst(x, form, *more): 90 | """Thread the expression through the forms.""" 91 | if not more: 92 | return thread(x, form) 93 | return thread_first(*cons(thread(x, form), more)) 94 | 95 | 96 | def compose(*funcs): 97 | def compose2(f, g): 98 | if not callable(f): 99 | foo = partial(*f) 100 | else: 101 | foo = f 102 | if not callable(g): 103 | bar = partial(*g) 104 | else: 105 | bar = g 106 | return lambda x: foo(bar(x)) 107 | return reduce(compose2, reversed(funcs)) 108 | 109 | 110 | def threadlast(x, *funcs): 111 | return compose(*funcs)(x) 112 | 113 | 114 | def thread_first(x, form, *more): 115 | return threadfirst(x, form, *more) 116 | 117 | 118 | def thread_last(x, *funcs): 119 | return threadlast(x, *funcs) 120 | 121 | 122 | def memoize(f): 123 | """Return a memoized version of a function.""" 124 | cache = {} 125 | 126 | @wraps(f) 127 | def wrapper(*args): 128 | if args in cache: 129 | return cache[args] 130 | rv = f(*args) 131 | cache[args] = rv 132 | return rv 133 | return wrapper 134 | 135 | 136 | def frozendict(*keyvals): 137 | """Return an immutable dictionary""" 138 | return frozenset(keyvals) 139 | 140 | 141 | def zipdict(keys, vals): 142 | """Return an immutable dictionary with keys mapped to corresponding 143 | values""" 144 | return frozendict(*zip(keys, vals)) 145 | 146 | 147 | def get(fdict, key, default=None): 148 | """Return the value mapped to a key, default or None if key not present""" 149 | if fdict is None: 150 | return default 151 | try: 152 | return dict(fdict)[key] 153 | except KeyError: 154 | return default 155 | 156 | 157 | def contains(fdict, key): 158 | return key in dict(fdict) 159 | 160 | 161 | def find(fdict, key): 162 | try: 163 | return (key, dict(fdict)[key]) 164 | except KeyError: 165 | return None 166 | 167 | 168 | def keys(fdict): 169 | return tuple(dict(fdict).keys()) 170 | 171 | 172 | def vals(fdict): 173 | return tuple(dict(fdict).values()) 174 | 175 | 176 | def merge(*fdicts): 177 | """Merge two or more frozen dictionaries.""" 178 | def items(fdict): 179 | return tuple(dict(fdict).items()) 180 | if len(fdicts) == 2: 181 | return dict(items(first(fdicts)) + items(last(fdicts))) 182 | return merge(first(fdicts), apply(merge, rest(fdicts))) 183 | 184 | 185 | def walk_replace(smap, data): 186 | def replace_at(k, v): 187 | if k in smap: 188 | return (smap[k], v) 189 | return (k, v) 190 | 191 | def process_node(k, v): 192 | if not isinstance(v, collections.Iterable) or isinstance(v, basestring): 193 | return replace_at(k, v) 194 | if isinstance(v, collections.Sequence): 195 | rows = () 196 | for row in v: 197 | if isinstance(row, basestring): 198 | rows += (row,) 199 | else: 200 | rows += (walk_replace(smap, row),) 201 | rv = tuple(filter(lambda row: row, rows)) 202 | else: 203 | rv = walk_replace(smap, v) 204 | return replace_at(k, rv) if rv else None 205 | 206 | if isinstance(data, collections.Sequence): 207 | return tuple(map(lambda x: walk_replace(smap, x), data)) 208 | try: 209 | nodes = tuple(map(lambda kv: process_node(kv[0], kv[1]), data.iteritems())) 210 | return dict(filter(lambda node: node is not None, nodes)) 211 | except AttributeError: 212 | return data 213 | 214 | 215 | def union(*sets): 216 | return first(sets).union(*rest(sets)) 217 | 218 | 219 | def intersection(x, y): 220 | return tuple(set(x).intersection(y)) 221 | 222 | 223 | def dict_invert(dict): 224 | return {v: k for (k, v) in dict.iteritems()} 225 | 226 | 227 | def flatten(dict): 228 | return reduce(merge, [{k: last(item) for k in first(item)} 229 | for item in dict.items()]) 230 | 231 | 232 | # not tested with frozen dicts, just regular ones 233 | def assoc(fdict, key, val, *kvs): 234 | keyvals = (key, val) + kvs 235 | return merge(fdict, dict(zip(keyvals[0::2], keyvals[1::2]))) 236 | 237 | 238 | # not tested with frozen dicts, just regular ones 239 | def dissoc(fdict, key, *ks): 240 | keys = (key,) + ks 241 | return {k: v for k, v in fdict.iteritems() if k not in keys} 242 | 243 | 244 | def hash_map(*keyvals): 245 | i = iter(keyvals) 246 | return dict(zip(i, i)) 247 | 248 | 249 | def format(fmt, *args, **kwargs): 250 | if kwargs: 251 | return fmt.format(**kwargs) 252 | else: 253 | return fmt.format(*args) 254 | 255 | 256 | def select_keys(fdict, keys): 257 | return {k: fdict[k] for k in keys if k in fdict} 258 | 259 | 260 | def destructure(f): 261 | @wraps(f) 262 | def wrapper(*args, **kwargs): 263 | params = select_keys(first(args), inspect.getargspec(f).args) 264 | return f(**(merge(kwargs, params))) 265 | return wrapper 266 | -------------------------------------------------------------------------------- /website/models.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.db import models 3 | from django.utils import timezone 4 | 5 | import datetime 6 | 7 | class NL(models.Model): 8 | """ 9 | Natural language command. 10 | """ 11 | str = models.TextField(primary_key=True) 12 | 13 | class Command(models.Model): 14 | """ 15 | Command line. 16 | """ 17 | str = models.TextField(primary_key=True) 18 | template = models.TextField(default='') 19 | language = models.TextField(default='bash') 20 | tags = models.ManyToManyField('Tag') 21 | 22 | class CommandAdmin(admin.ModelAdmin): 23 | fields = ['str', 'language'] 24 | list_display = ['get_str'] 25 | 26 | def get_str(self, obj): 27 | return '\n'.join(obj.str) 28 | 29 | class Tag(models.Model): 30 | """ 31 | Tag. 32 | """ 33 | str = models.TextField(primary_key=True) 34 | commands = models.ManyToManyField('Command') 35 | annotations = models.ManyToManyField('Annotation') 36 | 37 | class URL(models.Model): 38 | """ 39 | URL. 40 | 41 | :member str: url address. 42 | :member html_content: snapshot of the URL content at the time of annotation. 43 | :member commands: commands in the URL (automatically extracted) 44 | :member tags: tags of the URL (assigned based on user annotations) 45 | """ 46 | str = models.TextField(primary_key=True) 47 | html_content = models.TextField(default='') 48 | commands = models.ManyToManyField('Command') 49 | tags = models.ManyToManyField('Tag') 50 | 51 | class URLTag(models.Model): 52 | """ 53 | Each record stores a (url, tag) pair. 54 | """ 55 | url = models.ForeignKey(URL, on_delete=models.CASCADE) 56 | tag = models.TextField() 57 | 58 | class User(models.Model): 59 | """ 60 | Each record stores the information of a user. 61 | 62 | :member is_annotator: the annotator is responsible for collecting new data 63 | pairs 64 | :member is_judger: the judger is responsible for judging if a command pair 65 | is correct and add modifications and comments. 66 | """ 67 | access_code = models.TextField(default='') 68 | ip_address = models.TextField(default='') 69 | first_name = models.TextField(default='anonymous') 70 | last_name = models.TextField(default='anonymous') 71 | organization = models.TextField(default='--') 72 | city = models.TextField(default='--') 73 | region = models.TextField(default='--') 74 | country = models.TextField(default='--') 75 | is_annotator = models.BooleanField(default=False) 76 | is_judger = models.BooleanField(default=False) 77 | time_logged = models.FloatField(null=True, blank=True) 78 | 79 | class UserAdmin(admin.ModelAdmin): 80 | fields = ['first_name', 'last_name', 'is_annotator', 'is_judger'] 81 | list_display = ['get_full_name'] 82 | 83 | def get_full_name(self, obj): 84 | return '\n'.join(obj.first_name + obj.last_name) 85 | 86 | 87 | class Annotation(models.Model): 88 | """ 89 | Each record is a natural language <-> code translation annotated by a 90 | programmer. 91 | """ 92 | url = models.ForeignKey(URL, on_delete=models.CASCADE) 93 | nl = models.ForeignKey(NL, on_delete=models.CASCADE) 94 | cmd = models.ForeignKey(Command, on_delete=models.CASCADE) 95 | annotator = models.ForeignKey(User, on_delete=models.CASCADE) 96 | submission_time = models.DateTimeField(default=timezone.now) 97 | 98 | 99 | class AnnotationProgress(models.Model): 100 | """ 101 | Each record stores a user's annotation progress on a particular URL. 102 | """ 103 | url = models.ForeignKey(URL, on_delete=models.CASCADE) 104 | tag = models.ForeignKey(Tag, null=True, on_delete=models.CASCADE) 105 | annotator = models.ForeignKey(User, on_delete=models.CASCADE) 106 | status = models.TextField() 107 | 108 | 109 | class Comment(models.Model): 110 | """ 111 | Each record is a commend submitted by a user (either an annotator or a 112 | judger) to an annotation. 113 | """ 114 | user = models.ForeignKey(User, on_delete=models.CASCADE) 115 | reply = models.ForeignKey('self', null=True, on_delete=models.CASCADE) 116 | str = models.TextField() 117 | submission_time = models.DateTimeField(default=timezone.now) 118 | 119 | 120 | class AnnotationUpdate(models.Model): 121 | """ 122 | Each record is an update of an annotation submitted by a judger. 123 | """ 124 | annotation = models.ForeignKey(Annotation, on_delete=models.CASCADE) 125 | judger = models.ForeignKey(User, on_delete=models.CASCADE) 126 | update_str = models.TextField() 127 | update_type = models.TextField(default='nl') 128 | comment = models.ForeignKey(Comment, on_delete=models.CASCADE) 129 | submission_time = models.DateTimeField(default=timezone.now) 130 | status = models.TextField(default='open') 131 | 132 | 133 | class Notification(models.Model): 134 | """ 135 | Each record is a certain type of message issued from one annotator to 136 | another. 137 | """ 138 | sender = models.ForeignKey(User, related_name='notification_sender', 139 | on_delete=models.CASCADE) 140 | receiver = models.ForeignKey(User, related_name='notification_receiver', 141 | on_delete=models.CASCADE) 142 | type = models.TextField(default='comment') 143 | annotation_update = models.ForeignKey('AnnotationUpdate', null=True, 144 | on_delete=models.CASCADE) 145 | comment = models.ForeignKey('Comment', null=True, on_delete=models.CASCADE) 146 | url = models.ForeignKey('URL', on_delete=models.CASCADE) 147 | creation_time = models.DateTimeField(default=timezone.now) 148 | status = models.TextField(default='issued') 149 | 150 | 151 | class Translation(models.Model): 152 | """ 153 | Each record is a natural language -> code translation generated by the 154 | learning module in the backend. 155 | 156 | :member request: the natural language request issued by the user 157 | :member pred_cmd: the predicted command generated by the learning module 158 | :member score: the translation score of the predicted command 159 | :member num_upvotes: number of upvotes this translation has received 160 | :member num_downvotes: number of downvotes this translation has received 161 | :member num_stars: number of stars this translation has received 162 | """ 163 | nl = models.ForeignKey(NL, on_delete=models.CASCADE) 164 | pred_cmd = models.ForeignKey(Command, on_delete=models.CASCADE) 165 | score = models.FloatField() 166 | num_upvotes = models.PositiveIntegerField(default=0) 167 | num_downvotes = models.PositiveIntegerField(default=0) 168 | num_stars = models.PositiveIntegerField(default=0) 169 | 170 | def __str__(self): 171 | return "{}\n{}".format(self.request, self.pred_cmd) 172 | 173 | def inc_num_upvotes(self): 174 | self.num_upvotes += 1 175 | 176 | def dec_num_upvotes(self): 177 | self.num_upvotes -= 1 178 | 179 | def inc_num_downvotes(self): 180 | self.num_downvotes += 1 181 | 182 | def dec_num_downvotes(self): 183 | self.num_downvotes -= 1 184 | 185 | def inc_num_stars(self): 186 | self.num_stars += 1 187 | 188 | def dec_num_stars(self): 189 | self.num_stars -= 1 190 | 191 | @property 192 | def num_votes(self): 193 | return self.num_upvotes - self.num_downvotes 194 | 195 | 196 | class NLRequest(models.Model): 197 | """ 198 | Each record stores the IP address associated with a natural language 199 | request. 200 | :member request: a natural language request 201 | :member user: the user who submitted the request 202 | :member submission_time: the time when the request is submitted 203 | """ 204 | nl = models.ForeignKey(NL, on_delete=models.CASCADE) 205 | submission_time = models.DateTimeField(default=timezone.now) 206 | user = models.ForeignKey(User, null=True, on_delete=models.CASCADE) 207 | 208 | 209 | class Vote(models.Model): 210 | """ 211 | Each record stores the voting actions to a translation results issued by a 212 | specific IP address. 213 | """ 214 | translation = models.ForeignKey(Translation, on_delete=models.CASCADE) 215 | ip_address = models.TextField(default='') 216 | upvoted = models.BooleanField(default=False) 217 | downvoted = models.BooleanField(default=False) 218 | starred = models.BooleanField(default=False) 219 | # user = models.ForeignKey(User, null=True, on_delete=models.CASCADE) 220 | -------------------------------------------------------------------------------- /website/scripts/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TellinaTool/tellina/61f1398eb3c2adaad32660d9185d646ff3fcd857/website/scripts/__init__.py -------------------------------------------------------------------------------- /website/scripts/db_changes.py: -------------------------------------------------------------------------------- 1 | import html 2 | import os, sys 3 | import pickle 4 | import re 5 | import sqlite3 6 | 7 | from website.models import Annotation, AnnotationUpdate, Command, \ 8 | Notification, URL, URLTag 9 | from website.utils import get_tag, get_command, get_url 10 | 11 | learning_module_dir = os.path.join(os.path.dirname(__file__), '..', '..', 12 | "tellina_learning_module") 13 | sys.path.append(learning_module_dir) 14 | 15 | from bashlint import data_tools 16 | 17 | CODE_REGEX = re.compile(r"
([^<]+\n[^<]*)<\/code><\/pre>")
18 |
19 |
20 | def extract_code(text):
21 | for match in CODE_REGEX.findall(text):
22 | if match.strip():
23 | yield html.unescape(match.replace("
", "\n"))
24 |
25 | def extract_oneliners_from_code(code_block):
26 | for cmd in code_block.splitlines():
27 | if cmd.startswith('$ '):
28 | cmd = cmd[2:]
29 | if cmd.startswith('# '):
30 | cmd = cmd[2:]
31 | comment = re.search(r'\s+#\s+', cmd)
32 | if comment:
33 | old_cmd = cmd
34 | cmd = cmd[:comment.start()]
35 | print('Remove comment: {} -> {}'.format(old_cmd, cmd))
36 | cmd = cmd.strip()
37 |
38 | # discard code block opening line
39 | if cmd and not cmd[-1] in ['{', '[', '(']:
40 | yield cmd
41 |
42 | def load_urls(input_file_path):
43 | with open(input_file_path, 'rb') as f:
44 | urls_by_utility = pickle.load(f)
45 |
46 | for utility in urls_by_utility:
47 | for url in urls_by_utility[utility]:
48 | if not URLTag.objects.filter(url__str=url, tag=utility):
49 | URLTag.objects.create(url=get_url(url), tag=utility)
50 | print("Add {}, {}".format(url, utility))
51 |
52 | def load_commands_in_url(stackoverflow_dump_path):
53 | url_prefix = 'https://stackoverflow.com/questions/'
54 | with sqlite3.connect(stackoverflow_dump_path,
55 | detect_types=sqlite3.PARSE_DECLTYPES) as db:
56 | for url in URL.objects.all():
57 | # url = URL.objects.get(str='https://stackoverflow.com/questions/127669')
58 | url.commands.clear()
59 | print(url.str)
60 | for answer_body, in db.cursor().execute("""
61 | SELECT answers.Body FROM answers
62 | WHERE answers.ParentId = ?""", (url.str[len(url_prefix):],)):
63 | url.html_content = answer_body
64 | for code_block in extract_code(url.html_content):
65 | for cmd in extract_oneliners_from_code(code_block):
66 | ast = data_tools.bash_parser(cmd)
67 | if ast:
68 | command = get_command(cmd)
69 | print('extracted: {}'.format(cmd))
70 | url.commands.add(command)
71 | url.save()
72 |
73 | def populate_command_tags():
74 | for cmd in Command.objects.all():
75 | if len(cmd.str) > 600:
76 | cmd.delete()
77 | else:
78 | cmd.tags.clear()
79 | print(cmd.str)
80 | ast = data_tools.bash_parser(cmd.str)
81 | for utility in data_tools.get_utilities(ast):
82 | print(utility)
83 | cmd.tags.add(get_tag(utility))
84 | cmd.save()
85 |
86 | def populate_command_template():
87 | for cmd in Command.objects.all():
88 | if len(cmd.str) > 600:
89 | cmd.delete()
90 | else:
91 | ast = data_tools.bash_parser(cmd.str)
92 | template = data_tools.ast2template(ast, loose_constraints=True)
93 | cmd.template = template
94 | cmd.save()
95 |
96 | def populate_tag_commands():
97 | for tag in Tag.objects.all():
98 | tag.commands.clear()
99 | for url_tag in URLTag.objects.all():
100 | print(url_tag.url.str)
101 | tag = get_tag(url_tag.tag)
102 | for cmd in url_tag.url.commands.all():
103 | if tag in cmd.tags.all():
104 | tag.commands.add(cmd)
105 | tag.save()
106 |
107 | def populate_url_tags():
108 | for url in URL.objects.all():
109 | for annotation in Annotation.objects.filter(url=url):
110 | for tag in annotation.cmd.tags.all():
111 | url.tags.add(tag)
112 |
113 | def populate_tag_annotations():
114 | for annotation in Annotation.objects.all():
115 | for tag in annotation.cmd.tags.all():
116 | tag.annotations.add(annotation)
117 |
118 | def create_notifications():
119 | for annotation_update in AnnotationUpdate.objects.all():
120 | annotation = annotation_update.annotation
121 | Notification.objects.create(sender=annotation_update.judger,
122 | receiver=annotation.annotator, type='annotation_update',
123 | annotation_update=annotation_update, url=annotation.url)
124 |
125 | if __name__ == '__main__':
126 | load_urls()
127 |
--------------------------------------------------------------------------------
/website/static/css/annotator/login.css:
--------------------------------------------------------------------------------
1 | .body-panel {
2 | padding-top: 90px;
3 | }
4 | .panel-login {
5 | border-color: #ccc;
6 | -webkit-box-shadow: 0px 2px 3px 0px rgba(0,0,0,0.2);
7 | -moz-box-shadow: 0px 2px 3px 0px rgba(0,0,0,0.2);
8 | box-shadow: 0px 2px 3px 0px rgba(0,0,0,0.2);
9 | }
10 | .panel-login>.panel-heading {
11 | color: #00415d;
12 | background-color: #fff;
13 | border-color: #fff;
14 | text-align:center;
15 | }
16 | .panel-login>.panel-heading a{
17 | text-decoration: none;
18 | color: #666;
19 | font-weight: bold;
20 | font-size: 15px;
21 | -webkit-transition: all 0.1s linear;
22 | -moz-transition: all 0.1s linear;
23 | transition: all 0.1s linear;
24 | }
25 | .panel-login>.panel-heading a.active{
26 | color: #029f5b;
27 | font-size: 18px;
28 | }
29 | .panel-login>.panel-heading hr{
30 | margin-top: 10px;
31 | margin-bottom: 0px;
32 | clear: both;
33 | border: 0;
34 | height: 1px;
35 | background-image: -webkit-linear-gradient(left,rgba(0, 0, 0, 0),rgba(0, 0, 0, 0.15),rgba(0, 0, 0, 0));
36 | background-image: -moz-linear-gradient(left,rgba(0,0,0,0),rgba(0,0,0,0.15),rgba(0,0,0,0));
37 | background-image: -ms-linear-gradient(left,rgba(0,0,0,0),rgba(0,0,0,0.15),rgba(0,0,0,0));
38 | background-image: -o-linear-gradient(left,rgba(0,0,0,0),rgba(0,0,0,0.15),rgba(0,0,0,0));
39 | }
40 | .panel-login input[type="text"],.panel-login input[type="email"],.panel-login input[type="password"] {
41 | height: 45px;
42 | border: 1px solid #ddd;
43 | font-size: 16px;
44 | -webkit-transition: all 0.1s linear;
45 | -moz-transition: all 0.1s linear;
46 | transition: all 0.1s linear;
47 | }
48 | .panel-login input:hover,
49 | .panel-login input:focus {
50 | outline:none;
51 | -webkit-box-shadow: none;
52 | -moz-box-shadow: none;
53 | box-shadow: none;
54 | border-color: #ccc;
55 | }
56 | .btn-login {
57 | background-color: #59B2E0;
58 | outline: none;
59 | color: #fff;
60 | font-size: 14px;
61 | height: auto;
62 | font-weight: normal;
63 | padding: 14px 0;
64 | text-transform: uppercase;
65 | border-color: #59B2E6;
66 | }
67 | .btn-login:hover,
68 | .btn-login:focus {
69 | color: #fff;
70 | background-color: #53A3CD;
71 | border-color: #53A3CD;
72 | }
73 | .forgot-password {
74 | text-decoration: underline;
75 | color: #888;
76 | }
77 | .forgot-password:hover,
78 | .forgot-password:focus {
79 | text-decoration: underline;
80 | color: #666;
81 | }
82 |
83 | .btn-register {
84 | background-color: #1CB94E;
85 | outline: none;
86 | color: #fff;
87 | font-size: 14px;
88 | height: auto;
89 | font-weight: normal;
90 | padding: 14px 0;
91 | text-transform: uppercase;
92 | border-color: #1CB94A;
93 | }
94 | .btn-register:hover,
95 | .btn-register:focus {
96 | color: #fff;
97 | background-color: #1CA347;
98 | border-color: #1CA347;
99 | }
100 |
--------------------------------------------------------------------------------
/website/static/css/annotator/panel.css:
--------------------------------------------------------------------------------
1 | .body-panel {
2 | padding-top: 90px;
3 | }
4 |
5 | .url-content-panel {
6 | overflow: hidden;
7 | }
8 |
9 | .url-content-data {
10 | width: 100%;
11 | }
12 |
13 | .url-panel > h1 {
14 | text-align: left;
15 | font-size: 16px;
16 | font-weight: 300;
17 | }
18 |
19 | .collect-panel {
20 | overflow: show;
21 | }
22 |
23 | .collect-panel > h1 {
24 | text-align: left;
25 | font-size: 16px;
26 | font-weight: 300;
27 | overflow: hidden;
28 | }
29 |
30 | .collect-box {
31 | padding-top: 20px;
32 | }
33 |
34 | .annotation-box {
35 | padding-top: 20px;
36 | }
37 |
38 | .command-submission {
39 | background: #F0F0F0;
40 | }
41 |
42 | .annotate-utility-self-completed {
43 | background-color: #73C6B6;
44 | border: 1px;
45 | /* border-style: dotted;
46 | box-shadow: 6px 6px 3px #888888; */
47 | }
48 |
49 | .annotate-utility-completed {
50 | background-color: #73C6B6;
51 | }
52 |
53 | .annotate-utility-self-in-progress {
54 | background-color: #D0ECE7;
55 | border: 1px;
56 | /* border-style: dotted;
57 | box-shadow: 6px 6px 3px #888888; */
58 | }
59 |
60 | .annotate-utility-in-progress {
61 | background-color: #D0ECE7;
62 | }
63 |
64 | .url-num-notifications {
65 | color: #4B0082;
66 | background-color: #E6E6FA;
67 | }
68 |
69 | /* --- Facebook style notification badge --- */
70 |
71 | /* Make the badge float in the top right corner of the button */
72 | .missing_command_badge {
73 | background-color: #FFA500;
74 | border-radius: 2px;
75 | color: white;
76 |
77 | padding: 1px 3px;
78 | font-size: 10px;
79 |
80 | position: absolute; /* Position the badge within the relatively positioned button */
81 | top: 0px;
82 | left: 0px;
83 | }
84 |
85 | .notification_badge {
86 | background-color: #fa3e3e;
87 | border-radius: 2px;
88 | color: white;
89 |
90 | padding: 1px 3px;
91 | font-size: 10px;
92 |
93 | position: absolute; /* Position the badge within the relatively positioned button */
94 | top: 0;
95 | right: 0px;
96 | }
97 |
--------------------------------------------------------------------------------
/website/static/css/comment.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Oscuro: #283035
3 | * Azul: #03658c
4 | * Detalle: #c7cacb
5 | * Fondo: #dee1e3
6 | ----------------------------------*/
7 |
8 | /* body {
9 | font-family: 'Roboto', Arial, Helvetica, Sans-serif, Verdana;
10 | background: #dee1e3;
11 | } */
12 |
13 | /** ====================
14 | * Lista de Comentarios
15 | =======================*/
16 |
17 | ul {
18 | list-style:none;
19 | }
20 |
21 | .comments-container h1 {
22 | font-size: 36px;
23 | color: #283035;
24 | font-weight: 400;
25 | }
26 |
27 | .comments-container h1 a {
28 | font-size: 18px;
29 | font-weight: 700;
30 | }
31 |
32 | .comments-list {
33 | position: relative;
34 | }
35 |
36 | /**
37 | * Lineas / Detalles
38 | -----------------------*/
39 | /* .comments-list:before {
40 | content: '';
41 | width: 2px;
42 | height: 100%;
43 | background: #c7cacb;
44 | position: absolute;
45 | left: 32px;
46 | top: 0;
47 | } */
48 |
49 | /* .comments-list:after {
50 | content: '';
51 | position: absolute;
52 | background: #c7cacb;
53 | bottom: 0;
54 | left: 27px;
55 | width: 7px;
56 | height: 7px;
57 | border: 3px solid #dee1e3;
58 | -webkit-border-radius: 50%;
59 | -moz-border-radius: 50%;
60 | border-radius: 50%;
61 | } */
62 |
63 | /* .reply-list:before, .reply-list:after {display: none;}
64 | .reply-list li:before {
65 | content: '';
66 | width: 60px;
67 | height: 2px;
68 | background: #c7cacb;
69 | position: absolute;
70 | top: 25px;
71 | left: -55px;
72 | } */
73 |
74 |
75 | .comments-list li {
76 | margin-bottom: 15px;
77 | display: block;
78 | position: relative;
79 | }
80 |
81 | .comments-list li:after {
82 | content: '';
83 | display: block;
84 | clear: both;
85 | height: 0;
86 | width: 0;
87 | }
88 |
89 | .reply-list {
90 | clear: both;
91 | }
92 | /**
93 | * Avatar
94 | ---------------------------*/
95 | .comments-list .comment-avatar {
96 | width: 65px;
97 | height: 65px;
98 | position: relative;
99 | z-index: 99;
100 | float: left;
101 | border: 3px solid #FFF;
102 | -webkit-border-radius: 4px;
103 | -moz-border-radius: 4px;
104 | border-radius: 4px;
105 | -webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.2);
106 | -moz-box-shadow: 0 1px 2px rgba(0,0,0,0.2);
107 | box-shadow: 0 1px 2px rgba(0,0,0,0.2);
108 | overflow: hidden;
109 | }
110 |
111 | .comments-list .comment-avatar img {
112 | width: 100%;
113 | height: 100%;
114 | }
115 |
116 | .reply-list .comment-avatar {
117 | width: 50px;
118 | height: 50px;
119 | }
120 |
121 | .comment-main-level:after {
122 | content: '';
123 | width: 0;
124 | height: 0;
125 | display: block;
126 | clear: both;
127 | }
128 |
129 | /**
130 | * Caja del Comentario
131 | ---------------------------*/
132 | .comments-list .comment-box {
133 | width: 100%;
134 | float: left;
135 | position: relative;
136 | }
137 |
138 | /* .comments-list .comment-box:before, .comments-list .comment-box:after {
139 | content: '';
140 | height: 0;
141 | width: 0;
142 | position: absolute;
143 | display: block;
144 | border-width: 10px 12px 10px 0;
145 | border-style: solid;
146 | border-color: transparent #FCFCFC;
147 | top: 8px;
148 | left: 0px;
149 | } */
150 |
151 | /* .comments-list .comment-box:before {
152 | border-width: 11px 13px 11px 0;
153 | border-color: transparent rgba(0,0,0,0.05);
154 | left: -12px;
155 | } */
156 |
157 | .comment-box .comment-head {
158 | background: #FCFCFC;
159 | padding: 20px 12px 0px 12px;
160 | overflow: hidden;
161 | -webkit-border-radius: 4px 4px 0 0;
162 | -moz-border-radius: 4px 4px 0 0;
163 | border-radius: 4px 4px 0 0;
164 | }
165 |
166 | .comment-box .comment-head i {
167 | float: right;
168 | position: relative;
169 | color: #A6A6A6;
170 | cursor: pointer;
171 | -webkit-transition: color 0.3s ease;
172 | -o-transition: color 0.3s ease;
173 | transition: color 0.3s ease;
174 | }
175 |
176 | .comment-box .comment-head i:hover {
177 | color: #03658c;
178 | }
179 |
180 | .comment-box .submission-time {
181 | color: rgb(153, 153, 153);
182 | font-size: 12px;
183 | font-weight: 400;
184 | }
185 |
186 | .comment-box .comment-name {
187 | color: #283035;
188 | font-size: 14px;
189 | font-weight: 700;
190 | float: left;
191 | margin-right: 10px;
192 | }
193 |
194 | .comment-box .comment-name a {
195 | color: #283035;
196 | }
197 |
198 | .comment-box .comment-head span {
199 | float: left;
200 | color: #999;
201 | font-size: 13px;
202 | position: relative;
203 | top: 1px;
204 | }
205 |
206 | .comment-box .update-content {
207 | background: #D6EAF8;
208 | color: #2E86C1;
209 | margin: 12px 12px 0px 12px;
210 | }
211 |
212 | .comment-box .comment-content {
213 | background: #FFF;
214 | padding: 12px 12px 0px 12px;
215 | font-size: 15px;
216 | color: #595959;
217 | -webkit-border-radius: 0 0 4px 4px;
218 | -moz-border-radius: 0 0 4px 4px;
219 | border-radius: 0 0 4px 4px;
220 | }
221 |
222 | .comment-box .comment-name.by-author, .comment-box .comment-name.by-author a {color: #03658c;}
223 | .comment-box .comment-name.by-author:after {
224 | content: 'author';
225 | background: #03658c;
226 | color: #FFF;
227 | font-size: 12px;
228 | padding: 3px 5px;
229 | font-weight: 700;
230 | margin-left: 10px;
231 | -webkit-border-radius: 3px;
232 | -moz-border-radius: 3px;
233 | border-radius: 3px;
234 | }
235 |
236 | // .comment-box .comment-name.by-judger, .comment-box .comment-name.by-judger a {color: #28B463}
237 | .comment-box .comment-name.by-judger:after {
238 | content: 'modification-request';
239 | background: #28B463;
240 | color: #FFF;
241 | font-size: 12px;
242 | padding: 3px 5px;
243 | font-weight: 700;
244 | margin-left: 10px;
245 | -webkit-border-radius: 3px;
246 | -moz-border-radius: 3px;
247 | border-radius: 3px;
248 | }
249 |
250 | /** =====================
251 | * Responsive
252 | ========================*/
253 | @media only screen and (max-width: 766px) {
254 | .comments-container {
255 | width: 480px;
256 | }
257 |
258 | .comments-list .comment-box {
259 | width: 390px;
260 | }
261 |
262 | .reply-list .comment-box {
263 | width: 320px;
264 | }
265 | }
--------------------------------------------------------------------------------
/website/static/css/developers.css:
--------------------------------------------------------------------------------
1 | .project-description {
2 | font:18px/1.5 Lato, "Helvetica Neue", Helvetica, Arial, sans-serif;
3 | font-weight:300;
4 | color:#333;
5 | font-size: 18px;
6 | padding-top: 64px
7 | }
8 |
9 | .project-description h3 {
10 | margin-top: 30px;
11 | }
12 |
13 | .project-description h4 {
14 | margin-top: 20px;
15 | margin-bottom: 20px;
16 | font-style: bold;
17 | font-weight: 600;
18 | color:#777;
19 | }
20 |
21 | @media (max-width: 980px) {
22 | .project-description {
23 | padding-top: 100px;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/website/static/css/index.css:
--------------------------------------------------------------------------------
1 | html, body {
2 | width: 100%;
3 | height: 100%;
4 | min-height: 100%;
5 | }
6 |
7 | .body-panel {
8 | padding-top: 72px;
9 | padding-left: 40px;
10 | padding-right: 40px;
11 | }
12 |
13 | .instruction-panel {
14 | /* background-color: #e2edff; */
15 | background-color: #f9fbff;
16 | color: rgb(72, 72, 72);
17 | font-size: 16px;
18 | font-weight: 300;
19 | }
20 |
21 | .instruction-panel > h1 {
22 | text-align: left;
23 | font-size: 20px;
24 | font-weight: 400;
25 | margin: 12px 0 0 0;
26 | }
27 |
28 | .instruction-panel > h2 {
29 | text-align: left;
30 | line-height: 1.4;
31 | font-size: 16px;
32 | font-weight: 300;
33 | /* color: #43a047; */
34 | color: #163f8e;
35 | }
36 |
37 | .instruction-panel > ul > li{
38 | list-style-type:none;
39 | margin: 12px 0;
40 | }
41 |
42 | .instruction-panel > ul > li > ul > li{
43 | margin-left: -20px;
44 | }
45 |
46 | .instruction-panel > ul > li:before{
47 | content: "\e013";
48 | font-family: 'Glyphicons Halflings';
49 | font-size: 12px;
50 | float: left;
51 | margin-top: 4px;
52 | margin-left: -30px;
53 | color: rgb(72, 72, 72);
54 | }
55 |
56 | .panel-command {
57 | text-align: left;
58 | font-size: 20px;
59 | }
60 |
61 | .footer{
62 | text-align: left;
63 | line-height: 16px;
64 | color: rgb(108, 108, 108);
65 | }
66 |
67 | .fadeInUp {
68 | -webkit-animation-duration: 1s;
69 | }
70 |
71 | .btn-tag {
72 | border-radius:1px;
73 | background-color: #e2edff;
74 | color: #5a6b87;
75 | }
76 |
77 | .btn-top-k {
78 | border-radius:1px;
79 | background-color: #e5e3e1;
80 | color: #76716e;
81 | margin-right: 20px;
82 | float: right;
83 | }
84 |
85 | @media (max-width: 980px) {
86 | .body-panel {
87 | padding-top: 160px;
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/website/static/css/introjs.min.css:
--------------------------------------------------------------------------------
1 | .introjs-overlay{position:absolute;box-sizing:content-box;z-index:999999;background-color:#000;opacity:0;background:-moz-radial-gradient(center,ellipse cover,rgba(0,0,0,0.4) 0,rgba(0,0,0,0.9) 100%);background:-webkit-gradient(radial,center center,0px,center center,100%,color-stop(0%,rgba(0,0,0,0.4)),color-stop(100%,rgba(0,0,0,0.9)));background:-webkit-radial-gradient(center,ellipse cover,rgba(0,0,0,0.4) 0,rgba(0,0,0,0.9) 100%);background:-o-radial-gradient(center,ellipse cover,rgba(0,0,0,0.4) 0,rgba(0,0,0,0.9) 100%);background:-ms-radial-gradient(center,ellipse cover,rgba(0,0,0,0.4) 0,rgba(0,0,0,0.9) 100%);background:radial-gradient(center,ellipse cover,rgba(0,0,0,0.4) 0,rgba(0,0,0,0.9) 100%);filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr='#66000000',endColorstr='#e6000000',GradientType=1)";-ms-filter:"alpha(opacity=50)";filter:alpha(opacity=50);-webkit-transition:all .3s ease-out;-moz-transition:all .3s ease-out;-ms-transition:all .3s ease-out;-o-transition:all .3s ease-out;transition:all .3s ease-out}.introjs-fixParent{z-index:auto!important;opacity:1.0!important;-webkit-transform:none!important;-moz-transform:none!important;-ms-transform:none!important;-o-transform:none!important;transform:none!important}.introjs-showElement,tr.introjs-showElement>td,tr.introjs-showElement>th{z-index:9999999!important}.introjs-disableInteraction{z-index:99999999!important;position:absolute;background-color:white;opacity:0;filter:alpha(opacity=0)}.introjs-relativePosition,tr.introjs-showElement>td,tr.introjs-showElement>th{position:relative}.introjs-helperLayer{box-sizing:content-box;position:absolute;z-index:9999998;background-color:#FFF;background-color:rgba(255,255,255,.9);border:1px solid #777;border:1px solid rgba(0,0,0,.5);border-radius:4px;box-shadow:0 2px 15px rgba(0,0,0,.4);-webkit-transition:all .3s ease-out;-moz-transition:all .3s ease-out;-ms-transition:all .3s ease-out;-o-transition:all .3s ease-out;transition:all .3s ease-out}.introjs-tooltipReferenceLayer{box-sizing:content-box;position:absolute;visibility:hidden;z-index:10000000;background-color:transparent;-webkit-transition:all .3s ease-out;-moz-transition:all .3s ease-out;-ms-transition:all .3s ease-out;-o-transition:all .3s ease-out;transition:all .3s ease-out}.introjs-helperLayer *,.introjs-helperLayer *:before,.introjs-helperLayer *:after{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;-ms-box-sizing:content-box;-o-box-sizing:content-box;box-sizing:content-box}.introjs-helperNumberLayer{box-sizing:content-box;position:absolute;visibility:visible;top:-16px;left:-16px;z-index:9999999999!important;padding:2px;font-family:Arial,verdana,tahoma;font-size:13px;font-weight:bold;color:white;text-align:center;text-shadow:1px 1px 1px rgba(0,0,0,.3);background:#ff3019;background:-webkit-linear-gradient(top,#ff3019 0,#cf0404 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#ff3019),color-stop(100%,#cf0404));background:-moz-linear-gradient(top,#ff3019 0,#cf0404 100%);background:-ms-linear-gradient(top,#ff3019 0,#cf0404 100%);background:-o-linear-gradient(top,#ff3019 0,#cf0404 100%);background:linear-gradient(to bottom,#ff3019 0,#cf0404 100%);width:20px;height:20px;line-height:20px;border:3px solid white;border-radius:50%;filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3019', endColorstr='#cf0404', GradientType=0)";filter:"progid:DXImageTransform.Microsoft.Shadow(direction=135, strength=2, color=ff0000)";box-shadow:0 2px 5px rgba(0,0,0,.4)}.introjs-arrow{border:5px solid white;content:'';position:absolute}.introjs-arrow.top{top:-10px;border-top-color:transparent;border-right-color:transparent;border-bottom-color:white;border-left-color:transparent}.introjs-arrow.top-right{top:-10px;right:10px;border-top-color:transparent;border-right-color:transparent;border-bottom-color:white;border-left-color:transparent}.introjs-arrow.top-middle{top:-10px;left:50%;margin-left:-5px;border-top-color:transparent;border-right-color:transparent;border-bottom-color:white;border-left-color:transparent}.introjs-arrow.right{right:-10px;top:10px;border-top-color:transparent;border-right-color:transparent;border-bottom-color:transparent;border-left-color:white}.introjs-arrow.right-bottom{bottom:10px;right:-10px;border-top-color:transparent;border-right-color:transparent;border-bottom-color:transparent;border-left-color:white}.introjs-arrow.bottom{bottom:-10px;border-top-color:white;border-right-color:transparent;border-bottom-color:transparent;border-left-color:transparent}.introjs-arrow.left{left:-10px;top:10px;border-top-color:transparent;border-right-color:white;border-bottom-color:transparent;border-left-color:transparent}.introjs-arrow.left-bottom{left:-10px;bottom:10px;border-top-color:transparent;border-right-color:white;border-bottom-color:transparent;border-left-color:transparent}.introjs-tooltip{box-sizing:content-box;position:absolute;visibility:visible;padding:10px;background-color:white;min-width:200px;max-width:300px;border-radius:3px;box-shadow:0 1px 10px rgba(0,0,0,.4);-webkit-transition:opacity .1s ease-out;-moz-transition:opacity .1s ease-out;-ms-transition:opacity .1s ease-out;-o-transition:opacity .1s ease-out;transition:opacity .1s ease-out}.introjs-tooltipbuttons{text-align:right;white-space:nowrap}.introjs-button{box-sizing:content-box;position:relative;overflow:visible;display:inline-block;padding:.3em .8em;border:1px solid #d4d4d4;margin:0;text-decoration:none;text-shadow:1px 1px 0 #fff;font:11px/normal sans-serif;color:#333;white-space:nowrap;cursor:pointer;outline:0;background-color:#ececec;background-image:-webkit-gradient(linear,0 0,0 100%,from(#f4f4f4),to(#ececec));background-image:-moz-linear-gradient(#f4f4f4,#ececec);background-image:-o-linear-gradient(#f4f4f4,#ececec);background-image:linear-gradient(#f4f4f4,#ececec);-webkit-background-clip:padding;-moz-background-clip:padding;-o-background-clip:padding-box;-webkit-border-radius:.2em;-moz-border-radius:.2em;border-radius:.2em;zoom:1;*display:inline;margin-top:10px}.introjs-button:hover{border-color:#bcbcbc;text-decoration:none;box-shadow:0 1px 1px #e3e3e3}.introjs-button:focus,.introjs-button:active{background-image:-webkit-gradient(linear,0 0,0 100%,from(#ececec),to(#f4f4f4));background-image:-moz-linear-gradient(#ececec,#f4f4f4);background-image:-o-linear-gradient(#ececec,#f4f4f4);background-image:linear-gradient(#ececec,#f4f4f4)}.introjs-button::-moz-focus-inner{padding:0;border:0}.introjs-skipbutton{box-sizing:content-box;margin-right:5px;color:#7a7a7a}.introjs-prevbutton{-webkit-border-radius:.2em 0 0 .2em;-moz-border-radius:.2em 0 0 .2em;border-radius:.2em 0 0 .2em;border-right:0}.introjs-prevbutton.introjs-fullbutton{border:1px solid #d4d4d4;-webkit-border-radius:.2em;-moz-border-radius:.2em;border-radius:.2em}.introjs-nextbutton{-webkit-border-radius:0 .2em .2em 0;-moz-border-radius:0 .2em .2em 0;border-radius:0 .2em .2em 0}.introjs-nextbutton.introjs-fullbutton{-webkit-border-radius:.2em;-moz-border-radius:.2em;border-radius:.2em}.introjs-disabled,.introjs-disabled:hover,.introjs-disabled:focus{color:#9a9a9a;border-color:#d4d4d4;box-shadow:none;cursor:default;background-color:#f4f4f4;background-image:none;text-decoration:none}.introjs-hidden{display:none}.introjs-bullets{text-align:center}.introjs-bullets ul{box-sizing:content-box;clear:both;margin:15px auto 0;padding:0;display:inline-block}.introjs-bullets ul li{box-sizing:content-box;list-style:none;float:left;margin:0 2px}.introjs-bullets ul li a{box-sizing:content-box;display:block;width:6px;height:6px;background:#ccc;border-radius:10px;-moz-border-radius:10px;-webkit-border-radius:10px;text-decoration:none;cursor:pointer}.introjs-bullets ul li a:hover{background:#999}.introjs-bullets ul li a.active{background:#999}.introjs-progress{box-sizing:content-box;overflow:hidden;height:10px;margin:10px 0 5px 0;border-radius:4px;background-color:#ecf0f1}.introjs-progressbar{box-sizing:content-box;float:left;width:0;height:100%;font-size:10px;line-height:10px;text-align:center;background-color:#08c}.introjsFloatingElement{position:absolute;height:0;width:0;left:50%;top:50%}.introjs-fixedTooltip{position:fixed}.introjs-hint{box-sizing:content-box;position:absolute;background:transparent;width:20px;height:15px;cursor:pointer}.introjs-hint:focus{border:0;outline:0}.introjs-hidehint{display:none}.introjs-fixedhint{position:fixed}.introjs-hint:hover>.introjs-hint-pulse{border:5px solid rgba(60,60,60,0.57)}.introjs-hint-pulse{box-sizing:content-box;width:10px;height:10px;border:5px solid rgba(60,60,60,0.27);-webkit-border-radius:30px;-moz-border-radius:30px;border-radius:30px;background-color:rgba(136,136,136,0.24);z-index:10;position:absolute;-webkit-transition:all .2s ease-out;-moz-transition:all .2s ease-out;-ms-transition:all .2s ease-out;-o-transition:all .2s ease-out;transition:all .2s ease-out}.introjs-hint-no-anim .introjs-hint-dot{-webkit-animation:none;-moz-animation:none;animation:none}.introjs-hint-dot{box-sizing:content-box;border:10px solid rgba(146,146,146,0.36);background:transparent;-webkit-border-radius:60px;-moz-border-radius:60px;border-radius:60px;height:50px;width:50px;-webkit-animation:introjspulse 3s ease-out;-moz-animation:introjspulse 3s ease-out;animation:introjspulse 3s ease-out;-webkit-animation-iteration-count:infinite;-moz-animation-iteration-count:infinite;animation-iteration-count:infinite;position:absolute;top:-25px;left:-25px;z-index:1;opacity:0}@-moz-keyframes introjspulse{0%{-moz-transform:scale(0);opacity:.0}25%{-moz-transform:scale(0);opacity:.1}50%{-moz-transform:scale(0.1);opacity:.3}75%{-moz-transform:scale(0.5);opacity:.5}100%{-moz-transform:scale(1);opacity:.0}}@-webkit-keyframes introjspulse{0%{-webkit-transform:scale(0);opacity:.0}25%{-webkit-transform:scale(0);opacity:.1}50%{-webkit-transform:scale(0.1);opacity:.3}75%{-webkit-transform:scale(0.5);opacity:.5}100%{-webkit-transform:scale(1);opacity:.0}}
--------------------------------------------------------------------------------
/website/static/css/main.css:
--------------------------------------------------------------------------------
1 | html {
2 | overflow-y: scroll;
3 | }
4 |
5 | body {
6 | font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
7 | text-align: center;
8 | padding-bottom: 20px;
9 | }
10 |
11 | p {
12 | text-align:left;
13 | }
14 |
15 | li {
16 | text-align: left;
17 | }
18 |
19 | /* Start by setting display:none to make this hidden.
20 | Then we position it in relation to the viewport window
21 | with position:fixed. Width, height, top and left speak
22 | for themselves. Background we set to 80% white with
23 | our animation centered, and no-repeating */
24 | .modal {
25 | display: none;
26 | position: fixed;
27 | z-index: 1000;
28 | top: 0;
29 | left: 0;
30 | height: 100%;
31 | width: 100%;
32 | background: rgba( 255, 255, 255, .8 )
33 | url('/static/img/gears.gif')
34 | 50% 50%
35 | no-repeat;
36 | }
37 |
38 | /* When the body has the loading class, we turn
39 | the scrollbar off with overflow:hidden */
40 | body.loading {
41 | overflow: hidden;
42 | }
43 |
44 | /* Anytime the body has the loading class, our
45 | modal element will be visible */
46 | body.loading .modal {
47 | display: block;
48 | }
49 |
50 | /* Change the height of the nav bar */
51 | .navbar-nav > li > a {
52 | padding-top:10px !important; padding-bottom:10px !important;
53 | }
54 |
55 | .navbar {min-height:32px !important}
56 |
57 | /*.command {
58 | font-family: Monaco, Menlo, Consolas, monospace;
59 | font-size: 18px;
60 | text-align: center;
61 | }*/
62 |
63 | .program-text {
64 | font-weight: bold;
65 | }
66 |
67 | #command-wrapper {
68 | z-index: 3;
69 | }
70 |
71 | #command-wrapper.affix {
72 | position: fixed;
73 | top: 0;
74 | left: 0;
75 | width: 100%;
76 | height: 20px;
77 | background-color: white;
78 | padding-top: 10px;
79 | padding-bottom: 70px;
80 | box-shadow: 0 0 15px 5px #ffffff;
81 | }
82 |
83 | #about {
84 | text-align: justify;
85 | width: 700px;
86 | margin: 0 auto;
87 | }
88 |
89 | #canvas {
90 | position: absolute;
91 | z-index: 1;
92 | width: 100%;
93 | left: 0;
94 | pointer-events: none;
95 | }
96 |
97 | #help {
98 | z-index: 2;
99 | }
100 |
101 | .tiny-push {
102 | height: 10px;
103 | }
104 |
105 | .small-push {
106 | height: 20px;
107 | }
108 |
109 | .push {
110 | height: 40px;
111 | }
112 |
113 | .taggernooption {
114 | background-color: #f8c7c7;
115 | }
116 |
117 | .taggeroption {
118 | background-color: #caf8c7;
119 | }
120 |
121 | .taggercurrent {
122 | border-color: red;
123 | border-width: 2px;
124 | }
125 |
126 | .dropdown-menu {
127 | font-size: 14px;
128 | }
129 |
130 | .oneliner-index h4 {
131 | font-family: "Noto Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
132 | margin-left: 20px;
133 | }
134 |
135 | .explanation {
136 | margin-left: 20px;
137 | }
138 |
139 | .explanation h4 {
140 | font-family: "Noto Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
141 | }
142 |
143 | /* .oneliner .line {
144 | background: #eee;
145 | font-size: 16px;
146 | font-family: Consolas,monaco,monospace
147 | }
148 |
149 | .oneliner .line .add-on {
150 | color: #253;
151 | padding-right: .5em;
152 | font-weight: bold;
153 | } */
154 |
155 | .index {
156 | font-size: 20px;
157 | }
158 |
159 | .center-block {
160 | display: block;
161 | margin-right: auto;
162 | margin-left: auto;
163 | }
164 |
165 | .well {
166 | background: white;
167 | height:auto;
168 | }
169 |
170 | .translate-menu {
171 | left: 120px;
172 | }
173 |
174 | .top-search-container {
175 | padding-top: 6px;
176 | }
177 |
178 | .input-group .nl-request {
179 | width: 100%;
180 | border-radius: 6px;
181 | }
182 |
183 | #top-search {
184 | -webkit-transition: all .5s ease;
185 | -moz-transition: all .5s ease;
186 | transition: all .5s ease;
187 | position: relative;
188 | left: 0;
189 | }
190 |
191 | /* #top-search:focus {
192 | border-color: #7DCEA0;
193 | -moz-box-shadow: 0 0 8px rgba(125, 125, 206, 0.6);
194 | box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075) inset, 0 0 8px rgba(125, 125, 206, 0.6);
195 | outline: 0 none;
196 | } */
197 |
198 | #prevnext {
199 | text-align: center;
200 | padding-top: 10px;
201 | }
202 |
203 | #prevnext li:not(:first-child), #prevnext span:not(:first-child) {
204 | cursor: pointer;
205 | }
206 |
207 | .help-box {
208 | background-color: white;
209 | }
210 |
211 | .help-synopsis {
212 | background-color: #f5f5f5;
213 | }
214 |
215 | .popover-content {
216 | font-size: 12px;
217 | text-align: justify;
218 | }
219 |
220 | .popover {
221 | font-weight: normal;
222 | max-width: 450px;
223 | }
224 |
225 | .btn-search{
226 | background: white;
227 | box-shadow: none;
228 | outline: 0;
229 | }
230 |
231 | .btn-search:hover{
232 | background: rgba(250, 215, 160, 1);
233 | #box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075) inset, 0 0 6px rgba(250, 215, 160, 0.75);
234 | }
235 |
236 | /* -- navigation bar -- */
237 |
238 | .navbar-default {
239 | background: none;
240 | border-color: transparent;
241 | margin-bottom: 0;
242 | text-align: center;
243 | }
244 |
245 | .navbar-default .navbar-nav > li > a {
246 | font-size: 15px;
247 | font-family: 'Source Sans Pro', sans-serif;
248 | font-weight: 200;
249 | color: #666;
250 | padding: 5px 15px;
251 | }
252 |
253 | .navbar-default .navbar-nav > li > a:hover {
254 | color: #f48e5c;
255 | }
256 |
257 | .navbar-nav {
258 | float: right;
259 | display: inline-block;
260 | }
261 |
262 | .logo > a {
263 | font-size: 24px;
264 | font-family: 'Source Sans Pro', sans-serif;
265 | font-weight: 200;
266 | color: #666;
267 | padding: 5px 15px;
268 | }
269 |
270 | .logo > a:hover {
271 | color: #f48e5c;
272 | text-decoration: none;
273 | }
274 |
275 | .main-website-header {
276 | position: fixed;
277 | width: 100%;
278 | -webkit-box-shadow: 0 0 4px rgba(0, 0, 0, 0.2);
279 | -moz-box-shadow: 0 0 4px rgba(0, 0, 0, 0.2);
280 | -ms-box-shadow: 0 0 4px rgba(0, 0, 0, 0.2);
281 | -o-box-shadow: 0 0 4px rgba(0, 0, 0, 0.2);
282 | box-shadow: 0 0 4px rgba(0, 0, 0, 0.2);
283 | background: rgba(255, 255, 255, 0.96);
284 | z-index: 999;
285 | padding: 12px 0 8px 0
286 | }
287 |
288 | .fixed-in-scroll {
289 | position:fixed;
290 | top:0;
291 | left:0;
292 | }
293 |
--------------------------------------------------------------------------------
/website/static/css/perfect-scrollbar.css:
--------------------------------------------------------------------------------
1 | /* perfect-scrollbar v0.6.14 */
2 | .ps-container {
3 | -ms-touch-action: auto;
4 | touch-action: auto;
5 | overflow: hidden !important;
6 | -ms-overflow-style: none; }
7 | @supports (-ms-overflow-style: none) {
8 | .ps-container {
9 | overflow: auto !important; } }
10 | @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
11 | .ps-container {
12 | overflow: auto !important; } }
13 | .ps-container.ps-active-x > .ps-scrollbar-x-rail,
14 | .ps-container.ps-active-y > .ps-scrollbar-y-rail {
15 | display: block;
16 | background-color: transparent; }
17 | .ps-container.ps-in-scrolling.ps-x > .ps-scrollbar-x-rail {
18 | background-color: #eee;
19 | opacity: 0.9; }
20 | .ps-container.ps-in-scrolling.ps-x > .ps-scrollbar-x-rail > .ps-scrollbar-x {
21 | background-color: #999;
22 | height: 11px; }
23 | .ps-container.ps-in-scrolling.ps-y > .ps-scrollbar-y-rail {
24 | background-color: #eee;
25 | opacity: 0.9; }
26 | .ps-container.ps-in-scrolling.ps-y > .ps-scrollbar-y-rail > .ps-scrollbar-y {
27 | background-color: #999;
28 | width: 11px; }
29 | .ps-container > .ps-scrollbar-x-rail {
30 | display: none;
31 | position: absolute;
32 | /* please don't change 'position' */
33 | opacity: 0;
34 | -webkit-transition: background-color .2s linear, opacity .2s linear;
35 | -o-transition: background-color .2s linear, opacity .2s linear;
36 | -moz-transition: background-color .2s linear, opacity .2s linear;
37 | transition: background-color .2s linear, opacity .2s linear;
38 | bottom: 0px;
39 | /* there must be 'bottom' for ps-scrollbar-x-rail */
40 | height: 15px; }
41 | .ps-container > .ps-scrollbar-x-rail > .ps-scrollbar-x {
42 | position: absolute;
43 | /* please don't change 'position' */
44 | background-color: #aaa;
45 | -webkit-border-radius: 6px;
46 | -moz-border-radius: 6px;
47 | border-radius: 6px;
48 | -webkit-transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;
49 | transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;
50 | -o-transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;
51 | -moz-transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;
52 | transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;
53 | transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -webkit-border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;
54 | bottom: 2px;
55 | /* there must be 'bottom' for ps-scrollbar-x */
56 | height: 6px; }
57 | .ps-container > .ps-scrollbar-x-rail:hover > .ps-scrollbar-x, .ps-container > .ps-scrollbar-x-rail:active > .ps-scrollbar-x {
58 | height: 11px; }
59 | .ps-container > .ps-scrollbar-y-rail {
60 | display: none;
61 | position: absolute;
62 | /* please don't change 'position' */
63 | opacity: 0;
64 | -webkit-transition: background-color .2s linear, opacity .2s linear;
65 | -o-transition: background-color .2s linear, opacity .2s linear;
66 | -moz-transition: background-color .2s linear, opacity .2s linear;
67 | transition: background-color .2s linear, opacity .2s linear;
68 | right: 0;
69 | /* there must be 'right' for ps-scrollbar-y-rail */
70 | width: 15px; }
71 | .ps-container > .ps-scrollbar-y-rail > .ps-scrollbar-y {
72 | position: absolute;
73 | /* please don't change 'position' */
74 | background-color: #aaa;
75 | -webkit-border-radius: 6px;
76 | -moz-border-radius: 6px;
77 | border-radius: 6px;
78 | -webkit-transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;
79 | transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;
80 | -o-transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;
81 | -moz-transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;
82 | transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;
83 | transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -webkit-border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;
84 | right: 2px;
85 | /* there must be 'right' for ps-scrollbar-y */
86 | width: 6px; }
87 | .ps-container > .ps-scrollbar-y-rail:hover > .ps-scrollbar-y, .ps-container > .ps-scrollbar-y-rail:active > .ps-scrollbar-y {
88 | width: 11px; }
89 | .ps-container:hover.ps-in-scrolling.ps-x > .ps-scrollbar-x-rail {
90 | background-color: #eee;
91 | opacity: 0.9; }
92 | .ps-container:hover.ps-in-scrolling.ps-x > .ps-scrollbar-x-rail > .ps-scrollbar-x {
93 | background-color: #999;
94 | height: 11px; }
95 | .ps-container:hover.ps-in-scrolling.ps-y > .ps-scrollbar-y-rail {
96 | background-color: #eee;
97 | opacity: 0.9; }
98 | .ps-container:hover.ps-in-scrolling.ps-y > .ps-scrollbar-y-rail > .ps-scrollbar-y {
99 | background-color: #999;
100 | width: 11px; }
101 | .ps-container:hover > .ps-scrollbar-x-rail,
102 | .ps-container:hover > .ps-scrollbar-y-rail {
103 | opacity: 0.6; }
104 | .ps-container:hover > .ps-scrollbar-x-rail:hover {
105 | background-color: #eee;
106 | opacity: 0.9; }
107 | .ps-container:hover > .ps-scrollbar-x-rail:hover > .ps-scrollbar-x {
108 | background-color: #999; }
109 | .ps-container:hover > .ps-scrollbar-y-rail:hover {
110 | background-color: #eee;
111 | opacity: 0.9; }
112 | .ps-container:hover > .ps-scrollbar-y-rail:hover > .ps-scrollbar-y {
113 | background-color: #999; }
114 |
--------------------------------------------------------------------------------
/website/static/css/perfect-scrollbar.min.css:
--------------------------------------------------------------------------------
1 | /* perfect-scrollbar v0.6.14 */
2 | .ps-container{-ms-touch-action:auto;touch-action:auto;overflow:hidden !important;-ms-overflow-style:none}@supports (-ms-overflow-style: none){.ps-container{overflow:auto !important}}@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none){.ps-container{overflow:auto !important}}.ps-container.ps-active-x>.ps-scrollbar-x-rail,.ps-container.ps-active-y>.ps-scrollbar-y-rail{display:block;background-color:transparent}.ps-container.ps-in-scrolling.ps-x>.ps-scrollbar-x-rail{background-color:#eee;opacity:.9}.ps-container.ps-in-scrolling.ps-x>.ps-scrollbar-x-rail>.ps-scrollbar-x{background-color:#999;height:11px}.ps-container.ps-in-scrolling.ps-y>.ps-scrollbar-y-rail{background-color:#eee;opacity:.9}.ps-container.ps-in-scrolling.ps-y>.ps-scrollbar-y-rail>.ps-scrollbar-y{background-color:#999;width:11px}.ps-container>.ps-scrollbar-x-rail{display:none;position:absolute;opacity:0;-webkit-transition:background-color .2s linear, opacity .2s linear;-o-transition:background-color .2s linear, opacity .2s linear;-moz-transition:background-color .2s linear, opacity .2s linear;transition:background-color .2s linear, opacity .2s linear;bottom:0px;height:15px}.ps-container>.ps-scrollbar-x-rail>.ps-scrollbar-x{position:absolute;background-color:#aaa;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;-o-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;-moz-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -webkit-border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;bottom:2px;height:6px}.ps-container>.ps-scrollbar-x-rail:hover>.ps-scrollbar-x,.ps-container>.ps-scrollbar-x-rail:active>.ps-scrollbar-x{height:11px}.ps-container>.ps-scrollbar-y-rail{display:none;position:absolute;opacity:0;-webkit-transition:background-color .2s linear, opacity .2s linear;-o-transition:background-color .2s linear, opacity .2s linear;-moz-transition:background-color .2s linear, opacity .2s linear;transition:background-color .2s linear, opacity .2s linear;right:0;width:15px}.ps-container>.ps-scrollbar-y-rail>.ps-scrollbar-y{position:absolute;background-color:#aaa;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;-o-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;-moz-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -webkit-border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;right:2px;width:6px}.ps-container>.ps-scrollbar-y-rail:hover>.ps-scrollbar-y,.ps-container>.ps-scrollbar-y-rail:active>.ps-scrollbar-y{width:11px}.ps-container:hover.ps-in-scrolling.ps-x>.ps-scrollbar-x-rail{background-color:#eee;opacity:.9}.ps-container:hover.ps-in-scrolling.ps-x>.ps-scrollbar-x-rail>.ps-scrollbar-x{background-color:#999;height:11px}.ps-container:hover.ps-in-scrolling.ps-y>.ps-scrollbar-y-rail{background-color:#eee;opacity:.9}.ps-container:hover.ps-in-scrolling.ps-y>.ps-scrollbar-y-rail>.ps-scrollbar-y{background-color:#999;width:11px}.ps-container:hover>.ps-scrollbar-x-rail,.ps-container:hover>.ps-scrollbar-y-rail{opacity:.6}.ps-container:hover>.ps-scrollbar-x-rail:hover{background-color:#eee;opacity:.9}.ps-container:hover>.ps-scrollbar-x-rail:hover>.ps-scrollbar-x{background-color:#999}.ps-container:hover>.ps-scrollbar-y-rail:hover{background-color:#eee;opacity:.9}.ps-container:hover>.ps-scrollbar-y-rail:hover>.ps-scrollbar-y{background-color:#999}
3 |
--------------------------------------------------------------------------------
/website/static/css/translate.css:
--------------------------------------------------------------------------------
1 | .translate-panel {
2 | text-align: left;
3 | padding: 72px 12px 0 12px;
4 | }
5 |
6 | .btn-copy{
7 | border:0px solid transparent;
8 | }
9 |
10 | .btn-expl{
11 | border:0px solid transparent;
12 | }
13 |
14 | .btn-copy:hover,
15 | .btn-copy:focus,
16 | .btn-copy:active {
17 | background-color: rgb(255, 255, 255);
18 | color: #f48e5c
19 | }
20 |
21 | .btn-expl:hover,
22 | .btn-expl:focus,
23 | .btn-expl:active {
24 | background-color: rgb(255, 255, 255);
25 | color: #f48e5c
26 | }
27 |
28 | .cmd-result {
29 | table-layout:fixed;
30 | width: 100%;
31 | }
32 |
33 | .tooltip-inner {
34 | max-width: 100%;
35 | }
36 |
37 | .tooltip-inner > .cmd-expl {
38 | font-family: "Lucida Console", Monaco, monospace;
39 | text-align: left;
40 | white-space: pre
41 | }
42 |
43 | .code {
44 | font-family: "Lucida Console", Monaco, monospace;
45 | }
46 |
47 | @media (max-width: 980px) {
48 | .translate-panel {
49 | padding-top: 140px;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/website/static/font/FontAwesome.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TellinaTool/tellina/61f1398eb3c2adaad32660d9185d646ff3fcd857/website/static/font/FontAwesome.otf
--------------------------------------------------------------------------------
/website/static/font/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TellinaTool/tellina/61f1398eb3c2adaad32660d9185d646ff3fcd857/website/static/font/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/website/static/font/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TellinaTool/tellina/61f1398eb3c2adaad32660d9185d646ff3fcd857/website/static/font/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/website/static/font/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TellinaTool/tellina/61f1398eb3c2adaad32660d9185d646ff3fcd857/website/static/font/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/website/static/html/annotator/base.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Collecting Command - NL Pairs
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | {% block head %}{% endblock %}
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | Command2NL
27 |
28 | {% block navbar %}{% endblock %}
29 |
30 |
31 |
32 |
33 | {% block body %}{% endblock %}
34 |
35 |
36 |
37 |
38 |
39 |
40 | {% block other-js %}{% endblock %}
41 |
42 |
43 |
--------------------------------------------------------------------------------
/website/static/html/annotator/login.html:
--------------------------------------------------------------------------------
1 | {% extends "annotator/base.html" %}
2 | {% block head %}
3 |
4 | {% endblock %}
5 |
6 | {% block body %}
7 |
8 |
9 |
10 |
11 |
22 |
23 |
24 |
25 |
26 | {% csrf_token %}
27 |
28 |
29 |
30 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | Forgot Access Code?
46 |
47 |
48 |
49 |
50 |
51 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 | {% endblock %}
74 |
75 | {% block other-js %}
76 |
77 |
78 |
79 |
161 | {% endblock %}
--------------------------------------------------------------------------------
/website/static/html/annotator/url_panel.html:
--------------------------------------------------------------------------------
1 | {% extends "annotator/base.html" %}
2 | {% block head %}
3 |
4 | {% endblock %}
5 |
6 | {% block body %}
7 | {% block navbar %}
8 |
29 | {% endblock %}
30 |
31 |
32 |
33 | URLs that contain the utility {{utility}}
34 |
35 | Collect the data from the following URLs, including the ones tagged with
36 |
37 | {% if url_list %}
38 |
39 | {% for url, status in url_list %}
40 | -
41 | {{url.str}}
42 | {% if status == 'completed' %}
43 |
44 | {% else %}
45 | {% if status == 'in-progress' %}
46 |
47 | {% elif status == 'others-in-progress' %}
48 |
49 | {% endif %}
50 | {% endif %}
51 |
52 | {% endfor %}
53 |
54 | {% endif %}
55 |
56 |
57 | {% endblock %}
58 |
59 | {% block other-js %}
60 |
61 |
62 |
109 | {% endblock %}
110 |
--------------------------------------------------------------------------------
/website/static/html/annotator/user_panel.html:
--------------------------------------------------------------------------------
1 | {% extends "annotator/base.html" %}
2 | {% block head %}
3 |
4 | {% endblock %}
5 |
6 | {% block body %}
7 | {% block navbar %}
8 |
27 | {% endblock %}
28 |
29 |
30 |
45 |
46 |
47 | {% endblock %}
48 |
49 | {% block other-js %}
50 |
51 |
52 |
100 | {% endblock %}
101 |
--------------------------------------------------------------------------------
/website/static/html/annotator/user_profile.html:
--------------------------------------------------------------------------------
1 | {% extends "annotator/base.html" %}
2 | {% block head %}
3 |
4 | {% endblock %}
5 |
6 | {% block body %}
7 | {% block navbar %}
8 |
27 | {% endblock %}
28 |
29 |
30 |
32 |
33 |
34 | {% endblock %}
35 |
36 | {% block other-js %}
37 |
38 |
39 |
43 | {% endblock %}
44 |
--------------------------------------------------------------------------------
/website/static/html/annotator/utility_panel.html:
--------------------------------------------------------------------------------
1 | {% extends "annotator/base.html" %}
2 | {% block head %}
3 |
4 | {% endblock %}
5 |
6 | {% block body %}
7 | {% block navbar %}
8 |
27 | {% endblock %}
28 |
29 |
30 |
73 |
74 |
75 | # urls annotated:
76 | # pairs annotated:
77 |
78 |
79 |
80 | {% endblock %}
81 |
82 | {% block other-js %}
83 |
84 |
140 | {% endblock %}
141 |
--------------------------------------------------------------------------------
/website/static/html/translator/base.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Tellina - a natural language to command translation tool
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | {% block head %}{% endblock %}
19 |
20 |
21 |
22 |
29 |
30 |
31 |
32 |
33 |
34 |
57 |
58 |
59 |
60 | {% block body %}{% endblock %}
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
107 | {% block other-js %}{% endblock %}
108 |
109 |
110 |
--------------------------------------------------------------------------------
/website/static/html/translator/developers.html:
--------------------------------------------------------------------------------
1 | {% extends "translator/base.html" %}
2 | {% block head %}
3 |
4 |
5 | {% endblock %}
6 |
7 | {% block body %}
8 |
9 |
10 |
11 |
12 | About Tellina
13 |
19 | Tellina automatically translates the natural language commands of end-user programmers into a programming language. Currently Tellina supports Bash as its target language.
20 | Source Code & Data
21 | The source code for this website and the machine learning model & data is available on Github.
22 |
23 | Publications
24 | The following papers describe the research work and technical details of Tellina.
25 | If you use Tellina in your work, please cite the relevant paper(s) accordingly.
26 |
27 |
28 | Program Synthesis from Natural Language
29 | Using Recurrent Neural Networks. UW-CSE-TR. 2017
30 |
31 | Keywords: stage-wise translation, user study
32 | @techreport{LinWPVZE2017:TR,
33 | author = {Xi Victoria Lin and Chenglong Wang and Deric Pang and Kevin Vu and Luke Zettlemoyer and Michael D. Ernst},
34 | title = {Program synthesis from natural language using recurrent neural networks},
35 | institution = {University of Washington Department of Computer Science and Engineering},
36 | number = {UW-CSE-17-03-01},
37 | address = {Seattle, WA, USA},
38 | month = mar,
39 | year = {2017}
40 | }
41 |
42 |
43 |
44 | NL2Bash: A Corpus and Semantic Parser for Natural Language Interface to the Linux Operating System. LREC 2018.
45 |
46 | Keywords: end-to-end translation, CopyNet, sub-token, 100 Bash utilities, dataset
47 | @inproceedings{LinWZE2018:NL2Bash,
48 | author = {Xi Victoria Lin and Chenglong Wang and Luke Zettlemoyer and Michael D. Ernst},
49 | title = {NL2Bash: A Corpus and Semantic Parser for Natural Language Interface to the Linux Operating System},
50 | booktitle = {Proceedings of the Eleventh International Conference on Language Resources
51 | and Evaluation {LREC} 2018, Miyazaki (Japan), 7-12 May, 2018.},
52 | year = {2018}
53 | }
54 |
55 |
56 |
57 | Team
58 | Tellina is written by Victoria Lin, with help from Chenglong Wang and Deric Pang.
Research advisors: Michael D. Ernst and Luke Zettlemoyer.
59 |
60 | * We thank the Bash programmers who worked with us on data collection. You brought Tellina to life!
61 |
62 |
63 |
64 |
65 | {% endblock %}
66 |
67 | {% block other-js %}{% endblock %}
68 |
--------------------------------------------------------------------------------
/website/static/html/translator/macros.html:
--------------------------------------------------------------------------------
1 | {% macro outputcommand(mp, suggestions) -%}
2 | {% if suggestions|length == 0 %}
3 | {{ mp.program|e }}
4 | {% else %}
5 |
6 |
7 | {{ mp.program|e }}
8 |
15 |
16 | {% endif %}
17 | {% if mp.synopsis %}- {{ mp.synopsis|e }}{% endif %}
18 | {%- endmacro %}
19 |
20 | {%- macro outputcommandexplain(d) -%}
21 | {% if d.suggestions|length == 0 -%}
22 | {{ d.match|safe }}
23 | {%- else -%}
24 |
25 |
26 |
27 | {{ d.match|safe }}
28 |
35 |
36 |
37 | {%- endif %}
38 | {%- endmacro %}
39 |
40 | {%- macro spanclasses(d) -%}
41 | class="{{ d.commandclass }}"{% if d.helpclass %} helpref="{{ d.helpclass }}"{% endif %}
42 | {%- endmacro %}
43 |
44 | {%- macro examplebullet(cmd) -%}
45 | {{ cmd|e }}
46 | {%- endmacro %}
47 |
--------------------------------------------------------------------------------
/website/static/html/translator/options.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% set t = mp.program|e %}
3 | {% if mp.synopsis %}
4 | {% set t = mp.program|e + ' - ' + mp.synopsis|e %}
5 | {% endif %}
6 | {% block title %} - {{ t }}{% endblock %}
7 | {% block content %}
8 |
9 |
10 |
11 | {% import 'macros.html' as macros %}
12 | {{ macros.outputcommand(mp, suggestions) }}
13 |
14 |
15 |
16 |
17 |
18 | {% for desc in mp.options -%}
19 |
20 |
21 | {{ desc|safe }}
22 |
23 |
24 | {%- endfor %}
25 |
26 |
27 |
28 | {% endblock %}
29 |
--------------------------------------------------------------------------------
/website/static/html/translator/query_history.html:
--------------------------------------------------------------------------------
1 | {% extends "translator/base.html" %}
2 | {% block head %}
3 |
6 |
7 | {% endblock %}
8 | {% block body %}
9 | {% if latest_request_list %}
10 |
11 | Recently Asked
12 |
13 | {% for request, org, city, region, country in latest_request_list %}
14 | -
15 | {{request.request_str}} by anonymous from {{org}}, {{city}}, {{region}}, {{country}}
16 |
17 | {% endfor %}
18 |
19 |
20 | {% endif %}
21 | {% endblock %}
--------------------------------------------------------------------------------
/website/static/img/cli.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TellinaTool/tellina/61f1398eb3c2adaad32660d9185d646ff3fcd857/website/static/img/cli.png
--------------------------------------------------------------------------------
/website/static/img/clippy.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/website/static/img/developers/system_overview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TellinaTool/tellina/61f1398eb3c2adaad32660d9185d646ff3fcd857/website/static/img/developers/system_overview.png
--------------------------------------------------------------------------------
/website/static/img/gear.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/website/static/img/gears.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TellinaTool/tellina/61f1398eb3c2adaad32660d9185d646ff3fcd857/website/static/img/gears.gif
--------------------------------------------------------------------------------
/website/static/img/globe.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/website/static/img/glyphicons-halflings-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TellinaTool/tellina/61f1398eb3c2adaad32660d9185d646ff3fcd857/website/static/img/glyphicons-halflings-white.png
--------------------------------------------------------------------------------
/website/static/img/glyphicons-halflings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TellinaTool/tellina/61f1398eb3c2adaad32660d9185d646ff3fcd857/website/static/img/glyphicons-halflings.png
--------------------------------------------------------------------------------
/website/static/img/tellina.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/website/static/img/tellina_avatar.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/website/static/js/annotator/main.js:
--------------------------------------------------------------------------------
1 | $(document).ready(function () {
2 | $('.logout').click(function() {
3 | $.get(`logout`, function(data) {
4 | if (data.status == 'LOGOUT_SUCCESS') {
5 | window.location.replace(`login`);
6 | }
7 | });
8 | })
9 | })
--------------------------------------------------------------------------------
/website/static/js/clipboard.min.js:
--------------------------------------------------------------------------------
1 | /* clipboard.js v1.5.15
2 | * https://zenorocha.github.io/clipboard.js
3 | *
4 | * Licensed MIT © Zeno Rocha
5 | */
6 | !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.Clipboard=e()}}(function(){var e,t,n;return function e(t,n,i){function o(a,c){if(!n[a]){if(!t[a]){var l="function"==typeof require&&require;if(!c&&l)return l(a,!0);if(r)return r(a,!0);var s=new Error("Cannot find module '"+a+"'");throw s.code="MODULE_NOT_FOUND",s}var u=n[a]={exports:{}};t[a][0].call(u.exports,function(e){var n=t[a][1][e];return o(n?n:e)},u,u.exports,e,t,n,i)}return n[a].exports}for(var r="function"==typeof require&&require,a=0;a0&&void 0!==arguments[0]?arguments[0]:{};this.action=t.action,this.emitter=t.emitter,this.target=t.target,this.text=t.text,this.trigger=t.trigger,this.selectedText=""}},{key:"initSelection",value:function e(){this.text?this.selectFake():this.target&&this.selectTarget()}},{key:"selectFake",value:function e(){var t=this,n="rtl"==document.documentElement.getAttribute("dir");this.removeFake(),this.fakeHandlerCallback=function(){return t.removeFake()},this.fakeHandler=document.body.addEventListener("click",this.fakeHandlerCallback)||!0,this.fakeElem=document.createElement("textarea"),this.fakeElem.style.fontSize="12pt",this.fakeElem.style.border="0",this.fakeElem.style.padding="0",this.fakeElem.style.margin="0",this.fakeElem.style.position="absolute",this.fakeElem.style[n?"right":"left"]="-9999px";var i=window.pageYOffset||document.documentElement.scrollTop;this.fakeElem.addEventListener("focus",window.scrollTo(0,i)),this.fakeElem.style.top=i+"px",this.fakeElem.setAttribute("readonly",""),this.fakeElem.value=this.text,document.body.appendChild(this.fakeElem),this.selectedText=(0,o.default)(this.fakeElem),this.copyText()}},{key:"removeFake",value:function e(){this.fakeHandler&&(document.body.removeEventListener("click",this.fakeHandlerCallback),this.fakeHandler=null,this.fakeHandlerCallback=null),this.fakeElem&&(document.body.removeChild(this.fakeElem),this.fakeElem=null)}},{key:"selectTarget",value:function e(){this.selectedText=(0,o.default)(this.target),this.copyText()}},{key:"copyText",value:function e(){var t=void 0;try{t=document.execCommand(this.action)}catch(e){t=!1}this.handleResult(t)}},{key:"handleResult",value:function e(t){this.emitter.emit(t?"success":"error",{action:this.action,text:this.selectedText,trigger:this.trigger,clearSelection:this.clearSelection.bind(this)})}},{key:"clearSelection",value:function e(){this.target&&this.target.blur(),window.getSelection().removeAllRanges()}},{key:"destroy",value:function e(){this.removeFake()}},{key:"action",set:function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"copy";if(this._action=t,"copy"!==this._action&&"cut"!==this._action)throw new Error('Invalid "action" value, use either "copy" or "cut"')},get:function e(){return this._action}},{key:"target",set:function e(t){if(void 0!==t){if(!t||"object"!==("undefined"==typeof t?"undefined":r(t))||1!==t.nodeType)throw new Error('Invalid "target" value, use a valid Element');if("copy"===this.action&&t.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if("cut"===this.action&&(t.hasAttribute("readonly")||t.hasAttribute("disabled")))throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');this._target=t}},get:function e(){return this._target}}]),e}();e.exports=c})},{select:5}],8:[function(t,n,i){!function(o,r){if("function"==typeof e&&e.amd)e(["module","./clipboard-action","tiny-emitter","good-listener"],r);else if("undefined"!=typeof i)r(n,t("./clipboard-action"),t("tiny-emitter"),t("good-listener"));else{var a={exports:{}};r(a,o.clipboardAction,o.tinyEmitter,o.goodListener),o.clipboard=a.exports}}(this,function(e,t,n,i){"use strict";function o(e){return e&&e.__esModule?e:{default:e}}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function c(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}function l(e,t){var n="data-clipboard-"+e;if(t.hasAttribute(n))return t.getAttribute(n)}var s=o(t),u=o(n),f=o(i),d=function(){function e(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:{};this.action="function"==typeof t.action?t.action:this.defaultAction,this.target="function"==typeof t.target?t.target:this.defaultTarget,this.text="function"==typeof t.text?t.text:this.defaultText}},{key:"listenClick",value:function e(t){var n=this;this.listener=(0,f.default)(t,"click",function(e){return n.onClick(e)})}},{key:"onClick",value:function e(t){var n=t.delegateTarget||t.currentTarget;this.clipboardAction&&(this.clipboardAction=null),this.clipboardAction=new s.default({action:this.action(n),target:this.target(n),text:this.text(n),trigger:n,emitter:this})}},{key:"defaultAction",value:function e(t){return l("action",t)}},{key:"defaultTarget",value:function e(t){var n=l("target",t);if(n)return document.querySelector(n)}},{key:"defaultText",value:function e(t){return l("text",t)}},{key:"destroy",value:function e(){this.listener.destroy(),this.clipboardAction&&(this.clipboardAction.destroy(),this.clipboardAction=null)}}]),t}(u.default);e.exports=h})},{"./clipboard-action":7,"good-listener":4,"tiny-emitter":6}]},{},[8])(8)});
7 |
--------------------------------------------------------------------------------
/website/static/lib/bootstrap/fonts/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TellinaTool/tellina/61f1398eb3c2adaad32660d9185d646ff3fcd857/website/static/lib/bootstrap/fonts/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/website/static/lib/bootstrap/fonts/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TellinaTool/tellina/61f1398eb3c2adaad32660d9185d646ff3fcd857/website/static/lib/bootstrap/fonts/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/website/static/lib/bootstrap/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TellinaTool/tellina/61f1398eb3c2adaad32660d9185d646ff3fcd857/website/static/lib/bootstrap/fonts/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/website/static/lib/bootstrap/fonts/glyphicons-halflings-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TellinaTool/tellina/61f1398eb3c2adaad32660d9185d646ff3fcd857/website/static/lib/bootstrap/fonts/glyphicons-halflings-regular.woff2
--------------------------------------------------------------------------------
/website/static/lib/font-awesome-4.7.0 2/fonts/FontAwesome.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TellinaTool/tellina/61f1398eb3c2adaad32660d9185d646ff3fcd857/website/static/lib/font-awesome-4.7.0 2/fonts/FontAwesome.otf
--------------------------------------------------------------------------------
/website/static/lib/font-awesome-4.7.0 2/fonts/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TellinaTool/tellina/61f1398eb3c2adaad32660d9185d646ff3fcd857/website/static/lib/font-awesome-4.7.0 2/fonts/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/website/static/lib/font-awesome-4.7.0 2/fonts/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TellinaTool/tellina/61f1398eb3c2adaad32660d9185d646ff3fcd857/website/static/lib/font-awesome-4.7.0 2/fonts/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/website/static/lib/font-awesome-4.7.0 2/fonts/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TellinaTool/tellina/61f1398eb3c2adaad32660d9185d646ff3fcd857/website/static/lib/font-awesome-4.7.0 2/fonts/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/website/static/lib/font-awesome-4.7.0 2/fonts/fontawesome-webfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TellinaTool/tellina/61f1398eb3c2adaad32660d9185d646ff3fcd857/website/static/lib/font-awesome-4.7.0 2/fonts/fontawesome-webfont.woff2
--------------------------------------------------------------------------------
/website/static/lib/font-awesome-4.7.0 2/less/animated.less:
--------------------------------------------------------------------------------
1 | // Animated Icons
2 | // --------------------------
3 |
4 | .@{fa-css-prefix}-spin {
5 | -webkit-animation: fa-spin 2s infinite linear;
6 | animation: fa-spin 2s infinite linear;
7 | }
8 |
9 | .@{fa-css-prefix}-pulse {
10 | -webkit-animation: fa-spin 1s infinite steps(8);
11 | animation: fa-spin 1s infinite steps(8);
12 | }
13 |
14 | @-webkit-keyframes fa-spin {
15 | 0% {
16 | -webkit-transform: rotate(0deg);
17 | transform: rotate(0deg);
18 | }
19 | 100% {
20 | -webkit-transform: rotate(359deg);
21 | transform: rotate(359deg);
22 | }
23 | }
24 |
25 | @keyframes fa-spin {
26 | 0% {
27 | -webkit-transform: rotate(0deg);
28 | transform: rotate(0deg);
29 | }
30 | 100% {
31 | -webkit-transform: rotate(359deg);
32 | transform: rotate(359deg);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/website/static/lib/font-awesome-4.7.0 2/less/bordered-pulled.less:
--------------------------------------------------------------------------------
1 | // Bordered & Pulled
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-border {
5 | padding: .2em .25em .15em;
6 | border: solid .08em @fa-border-color;
7 | border-radius: .1em;
8 | }
9 |
10 | .@{fa-css-prefix}-pull-left { float: left; }
11 | .@{fa-css-prefix}-pull-right { float: right; }
12 |
13 | .@{fa-css-prefix} {
14 | &.@{fa-css-prefix}-pull-left { margin-right: .3em; }
15 | &.@{fa-css-prefix}-pull-right { margin-left: .3em; }
16 | }
17 |
18 | /* Deprecated as of 4.4.0 */
19 | .pull-right { float: right; }
20 | .pull-left { float: left; }
21 |
22 | .@{fa-css-prefix} {
23 | &.pull-left { margin-right: .3em; }
24 | &.pull-right { margin-left: .3em; }
25 | }
26 |
--------------------------------------------------------------------------------
/website/static/lib/font-awesome-4.7.0 2/less/core.less:
--------------------------------------------------------------------------------
1 | // Base Class Definition
2 | // -------------------------
3 |
4 | .@{fa-css-prefix} {
5 | display: inline-block;
6 | font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration
7 | font-size: inherit; // can't have font-size inherit on line above, so need to override
8 | text-rendering: auto; // optimizelegibility throws things off #1094
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/website/static/lib/font-awesome-4.7.0 2/less/fixed-width.less:
--------------------------------------------------------------------------------
1 | // Fixed Width Icons
2 | // -------------------------
3 | .@{fa-css-prefix}-fw {
4 | width: (18em / 14);
5 | text-align: center;
6 | }
7 |
--------------------------------------------------------------------------------
/website/static/lib/font-awesome-4.7.0 2/less/font-awesome.less:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
4 | */
5 |
6 | @import "variables.less";
7 | @import "mixins.less";
8 | @import "path.less";
9 | @import "core.less";
10 | @import "larger.less";
11 | @import "fixed-width.less";
12 | @import "list.less";
13 | @import "bordered-pulled.less";
14 | @import "animated.less";
15 | @import "rotated-flipped.less";
16 | @import "stacked.less";
17 | @import "icons.less";
18 | @import "screen-reader.less";
19 |
--------------------------------------------------------------------------------
/website/static/lib/font-awesome-4.7.0 2/less/larger.less:
--------------------------------------------------------------------------------
1 | // Icon Sizes
2 | // -------------------------
3 |
4 | /* makes the font 33% larger relative to the icon container */
5 | .@{fa-css-prefix}-lg {
6 | font-size: (4em / 3);
7 | line-height: (3em / 4);
8 | vertical-align: -15%;
9 | }
10 | .@{fa-css-prefix}-2x { font-size: 2em; }
11 | .@{fa-css-prefix}-3x { font-size: 3em; }
12 | .@{fa-css-prefix}-4x { font-size: 4em; }
13 | .@{fa-css-prefix}-5x { font-size: 5em; }
14 |
--------------------------------------------------------------------------------
/website/static/lib/font-awesome-4.7.0 2/less/list.less:
--------------------------------------------------------------------------------
1 | // List Icons
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-ul {
5 | padding-left: 0;
6 | margin-left: @fa-li-width;
7 | list-style-type: none;
8 | > li { position: relative; }
9 | }
10 | .@{fa-css-prefix}-li {
11 | position: absolute;
12 | left: -@fa-li-width;
13 | width: @fa-li-width;
14 | top: (2em / 14);
15 | text-align: center;
16 | &.@{fa-css-prefix}-lg {
17 | left: (-@fa-li-width + (4em / 14));
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/website/static/lib/font-awesome-4.7.0 2/less/mixins.less:
--------------------------------------------------------------------------------
1 | // Mixins
2 | // --------------------------
3 |
4 | .fa-icon() {
5 | display: inline-block;
6 | font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration
7 | font-size: inherit; // can't have font-size inherit on line above, so need to override
8 | text-rendering: auto; // optimizelegibility throws things off #1094
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 |
12 | }
13 |
14 | .fa-icon-rotate(@degrees, @rotation) {
15 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation})";
16 | -webkit-transform: rotate(@degrees);
17 | -ms-transform: rotate(@degrees);
18 | transform: rotate(@degrees);
19 | }
20 |
21 | .fa-icon-flip(@horiz, @vert, @rotation) {
22 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation}, mirror=1)";
23 | -webkit-transform: scale(@horiz, @vert);
24 | -ms-transform: scale(@horiz, @vert);
25 | transform: scale(@horiz, @vert);
26 | }
27 |
28 |
29 | // Only display content to screen readers. A la Bootstrap 4.
30 | //
31 | // See: http://a11yproject.com/posts/how-to-hide-content/
32 |
33 | .sr-only() {
34 | position: absolute;
35 | width: 1px;
36 | height: 1px;
37 | padding: 0;
38 | margin: -1px;
39 | overflow: hidden;
40 | clip: rect(0,0,0,0);
41 | border: 0;
42 | }
43 |
44 | // Use in conjunction with .sr-only to only display content when it's focused.
45 | //
46 | // Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1
47 | //
48 | // Credit: HTML5 Boilerplate
49 |
50 | .sr-only-focusable() {
51 | &:active,
52 | &:focus {
53 | position: static;
54 | width: auto;
55 | height: auto;
56 | margin: 0;
57 | overflow: visible;
58 | clip: auto;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/website/static/lib/font-awesome-4.7.0 2/less/path.less:
--------------------------------------------------------------------------------
1 | /* FONT PATH
2 | * -------------------------- */
3 |
4 | @font-face {
5 | font-family: 'FontAwesome';
6 | src: url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}');
7 | src: url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype'),
8 | url('@{fa-font-path}/fontawesome-webfont.woff2?v=@{fa-version}') format('woff2'),
9 | url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff'),
10 | url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype'),
11 | url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg');
12 | // src: url('@{fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
13 | font-weight: normal;
14 | font-style: normal;
15 | }
16 |
--------------------------------------------------------------------------------
/website/static/lib/font-awesome-4.7.0 2/less/rotated-flipped.less:
--------------------------------------------------------------------------------
1 | // Rotated & Flipped Icons
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-rotate-90 { .fa-icon-rotate(90deg, 1); }
5 | .@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); }
6 | .@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); }
7 |
8 | .@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); }
9 | .@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); }
10 |
11 | // Hook for IE8-9
12 | // -------------------------
13 |
14 | :root .@{fa-css-prefix}-rotate-90,
15 | :root .@{fa-css-prefix}-rotate-180,
16 | :root .@{fa-css-prefix}-rotate-270,
17 | :root .@{fa-css-prefix}-flip-horizontal,
18 | :root .@{fa-css-prefix}-flip-vertical {
19 | filter: none;
20 | }
21 |
--------------------------------------------------------------------------------
/website/static/lib/font-awesome-4.7.0 2/less/screen-reader.less:
--------------------------------------------------------------------------------
1 | // Screen Readers
2 | // -------------------------
3 |
4 | .sr-only { .sr-only(); }
5 | .sr-only-focusable { .sr-only-focusable(); }
6 |
--------------------------------------------------------------------------------
/website/static/lib/font-awesome-4.7.0 2/less/stacked.less:
--------------------------------------------------------------------------------
1 | // Stacked Icons
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-stack {
5 | position: relative;
6 | display: inline-block;
7 | width: 2em;
8 | height: 2em;
9 | line-height: 2em;
10 | vertical-align: middle;
11 | }
12 | .@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x {
13 | position: absolute;
14 | left: 0;
15 | width: 100%;
16 | text-align: center;
17 | }
18 | .@{fa-css-prefix}-stack-1x { line-height: inherit; }
19 | .@{fa-css-prefix}-stack-2x { font-size: 2em; }
20 | .@{fa-css-prefix}-inverse { color: @fa-inverse; }
21 |
--------------------------------------------------------------------------------
/website/static/lib/font-awesome-4.7.0 2/scss/_animated.scss:
--------------------------------------------------------------------------------
1 | // Spinning Icons
2 | // --------------------------
3 |
4 | .#{$fa-css-prefix}-spin {
5 | -webkit-animation: fa-spin 2s infinite linear;
6 | animation: fa-spin 2s infinite linear;
7 | }
8 |
9 | .#{$fa-css-prefix}-pulse {
10 | -webkit-animation: fa-spin 1s infinite steps(8);
11 | animation: fa-spin 1s infinite steps(8);
12 | }
13 |
14 | @-webkit-keyframes fa-spin {
15 | 0% {
16 | -webkit-transform: rotate(0deg);
17 | transform: rotate(0deg);
18 | }
19 | 100% {
20 | -webkit-transform: rotate(359deg);
21 | transform: rotate(359deg);
22 | }
23 | }
24 |
25 | @keyframes fa-spin {
26 | 0% {
27 | -webkit-transform: rotate(0deg);
28 | transform: rotate(0deg);
29 | }
30 | 100% {
31 | -webkit-transform: rotate(359deg);
32 | transform: rotate(359deg);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/website/static/lib/font-awesome-4.7.0 2/scss/_bordered-pulled.scss:
--------------------------------------------------------------------------------
1 | // Bordered & Pulled
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-border {
5 | padding: .2em .25em .15em;
6 | border: solid .08em $fa-border-color;
7 | border-radius: .1em;
8 | }
9 |
10 | .#{$fa-css-prefix}-pull-left { float: left; }
11 | .#{$fa-css-prefix}-pull-right { float: right; }
12 |
13 | .#{$fa-css-prefix} {
14 | &.#{$fa-css-prefix}-pull-left { margin-right: .3em; }
15 | &.#{$fa-css-prefix}-pull-right { margin-left: .3em; }
16 | }
17 |
18 | /* Deprecated as of 4.4.0 */
19 | .pull-right { float: right; }
20 | .pull-left { float: left; }
21 |
22 | .#{$fa-css-prefix} {
23 | &.pull-left { margin-right: .3em; }
24 | &.pull-right { margin-left: .3em; }
25 | }
26 |
--------------------------------------------------------------------------------
/website/static/lib/font-awesome-4.7.0 2/scss/_core.scss:
--------------------------------------------------------------------------------
1 | // Base Class Definition
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix} {
5 | display: inline-block;
6 | font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration
7 | font-size: inherit; // can't have font-size inherit on line above, so need to override
8 | text-rendering: auto; // optimizelegibility throws things off #1094
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/website/static/lib/font-awesome-4.7.0 2/scss/_fixed-width.scss:
--------------------------------------------------------------------------------
1 | // Fixed Width Icons
2 | // -------------------------
3 | .#{$fa-css-prefix}-fw {
4 | width: (18em / 14);
5 | text-align: center;
6 | }
7 |
--------------------------------------------------------------------------------
/website/static/lib/font-awesome-4.7.0 2/scss/_larger.scss:
--------------------------------------------------------------------------------
1 | // Icon Sizes
2 | // -------------------------
3 |
4 | /* makes the font 33% larger relative to the icon container */
5 | .#{$fa-css-prefix}-lg {
6 | font-size: (4em / 3);
7 | line-height: (3em / 4);
8 | vertical-align: -15%;
9 | }
10 | .#{$fa-css-prefix}-2x { font-size: 2em; }
11 | .#{$fa-css-prefix}-3x { font-size: 3em; }
12 | .#{$fa-css-prefix}-4x { font-size: 4em; }
13 | .#{$fa-css-prefix}-5x { font-size: 5em; }
14 |
--------------------------------------------------------------------------------
/website/static/lib/font-awesome-4.7.0 2/scss/_list.scss:
--------------------------------------------------------------------------------
1 | // List Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-ul {
5 | padding-left: 0;
6 | margin-left: $fa-li-width;
7 | list-style-type: none;
8 | > li { position: relative; }
9 | }
10 | .#{$fa-css-prefix}-li {
11 | position: absolute;
12 | left: -$fa-li-width;
13 | width: $fa-li-width;
14 | top: (2em / 14);
15 | text-align: center;
16 | &.#{$fa-css-prefix}-lg {
17 | left: -$fa-li-width + (4em / 14);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/website/static/lib/font-awesome-4.7.0 2/scss/_mixins.scss:
--------------------------------------------------------------------------------
1 | // Mixins
2 | // --------------------------
3 |
4 | @mixin fa-icon() {
5 | display: inline-block;
6 | font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration
7 | font-size: inherit; // can't have font-size inherit on line above, so need to override
8 | text-rendering: auto; // optimizelegibility throws things off #1094
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 |
12 | }
13 |
14 | @mixin fa-icon-rotate($degrees, $rotation) {
15 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation})";
16 | -webkit-transform: rotate($degrees);
17 | -ms-transform: rotate($degrees);
18 | transform: rotate($degrees);
19 | }
20 |
21 | @mixin fa-icon-flip($horiz, $vert, $rotation) {
22 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}, mirror=1)";
23 | -webkit-transform: scale($horiz, $vert);
24 | -ms-transform: scale($horiz, $vert);
25 | transform: scale($horiz, $vert);
26 | }
27 |
28 |
29 | // Only display content to screen readers. A la Bootstrap 4.
30 | //
31 | // See: http://a11yproject.com/posts/how-to-hide-content/
32 |
33 | @mixin sr-only {
34 | position: absolute;
35 | width: 1px;
36 | height: 1px;
37 | padding: 0;
38 | margin: -1px;
39 | overflow: hidden;
40 | clip: rect(0,0,0,0);
41 | border: 0;
42 | }
43 |
44 | // Use in conjunction with .sr-only to only display content when it's focused.
45 | //
46 | // Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1
47 | //
48 | // Credit: HTML5 Boilerplate
49 |
50 | @mixin sr-only-focusable {
51 | &:active,
52 | &:focus {
53 | position: static;
54 | width: auto;
55 | height: auto;
56 | margin: 0;
57 | overflow: visible;
58 | clip: auto;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/website/static/lib/font-awesome-4.7.0 2/scss/_path.scss:
--------------------------------------------------------------------------------
1 | /* FONT PATH
2 | * -------------------------- */
3 |
4 | @font-face {
5 | font-family: 'FontAwesome';
6 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}');
7 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'),
8 | url('#{$fa-font-path}/fontawesome-webfont.woff2?v=#{$fa-version}') format('woff2'),
9 | url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'),
10 | url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'),
11 | url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg');
12 | // src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
13 | font-weight: normal;
14 | font-style: normal;
15 | }
16 |
--------------------------------------------------------------------------------
/website/static/lib/font-awesome-4.7.0 2/scss/_rotated-flipped.scss:
--------------------------------------------------------------------------------
1 | // Rotated & Flipped Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); }
5 | .#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); }
6 | .#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); }
7 |
8 | .#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); }
9 | .#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); }
10 |
11 | // Hook for IE8-9
12 | // -------------------------
13 |
14 | :root .#{$fa-css-prefix}-rotate-90,
15 | :root .#{$fa-css-prefix}-rotate-180,
16 | :root .#{$fa-css-prefix}-rotate-270,
17 | :root .#{$fa-css-prefix}-flip-horizontal,
18 | :root .#{$fa-css-prefix}-flip-vertical {
19 | filter: none;
20 | }
21 |
--------------------------------------------------------------------------------
/website/static/lib/font-awesome-4.7.0 2/scss/_screen-reader.scss:
--------------------------------------------------------------------------------
1 | // Screen Readers
2 | // -------------------------
3 |
4 | .sr-only { @include sr-only(); }
5 | .sr-only-focusable { @include sr-only-focusable(); }
6 |
--------------------------------------------------------------------------------
/website/static/lib/font-awesome-4.7.0 2/scss/_stacked.scss:
--------------------------------------------------------------------------------
1 | // Stacked Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-stack {
5 | position: relative;
6 | display: inline-block;
7 | width: 2em;
8 | height: 2em;
9 | line-height: 2em;
10 | vertical-align: middle;
11 | }
12 | .#{$fa-css-prefix}-stack-1x, .#{$fa-css-prefix}-stack-2x {
13 | position: absolute;
14 | left: 0;
15 | width: 100%;
16 | text-align: center;
17 | }
18 | .#{$fa-css-prefix}-stack-1x { line-height: inherit; }
19 | .#{$fa-css-prefix}-stack-2x { font-size: 2em; }
20 | .#{$fa-css-prefix}-inverse { color: $fa-inverse; }
21 |
--------------------------------------------------------------------------------
/website/static/lib/font-awesome-4.7.0 2/scss/font-awesome.scss:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
4 | */
5 |
6 | @import "variables";
7 | @import "mixins";
8 | @import "path";
9 | @import "core";
10 | @import "larger";
11 | @import "fixed-width";
12 | @import "list";
13 | @import "bordered-pulled";
14 | @import "animated";
15 | @import "rotated-flipped";
16 | @import "stacked";
17 | @import "icons";
18 | @import "screen-reader";
19 |
--------------------------------------------------------------------------------
/website/static/lib/google-plus.themes/google-plus.css:
--------------------------------------------------------------------------------
1 | .panel-google-plus {
2 | position: relative;
3 | font-family: 'Source Sans Pro', sans-serif;
4 | border-radius: 5px;
5 | border: 1px solid rgb(216, 216, 216);
6 | box-shadow: 0 1px 6px rgba(0, 0, 0, 0.175);
7 | }
8 | .panel-google-plus > .dropdown {
9 | position: absolute;
10 | top: 5px;
11 | right: 15px;
12 | }
13 | .panel-google-plus > .dropdown > span > span {
14 | font-size: 10px;
15 | }
16 | .panel-google-plus > .dropdown > .dropdown-menu {
17 | left: initial;
18 | right: 0px;
19 | border-radius: 2px;
20 | }
21 | .panel-google-plus > .panel-google-plus-tags {
22 | position: absolute;
23 | top: 35px;
24 | right: -3px;
25 | }
26 | .panel-google-plus > .panel-google-plus-tags > ul {
27 | list-style: none;
28 | padding: 0px;
29 | margin: 0px;
30 | }
31 | .panel-google-plus > .panel-google-plus-tags > ul:hover {
32 | box-shadow: 0px 0px 3px rgb(0, 0, 0);
33 | box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.25);
34 | }
35 | .panel-google-plus > .panel-google-plus-tags > ul > li {
36 | display: block;
37 | right: 0px;
38 | width: 0px;
39 | padding: 5px 0px 5px 0px;
40 | background-color: rgb(245, 245, 245);
41 | font-size: 12px;
42 | overflow: hidden;
43 | }
44 | .panel-google-plus > .panel-google-plus-tags > ul > li::after {
45 | content:"";
46 | position: absolute;
47 | top: 0px;
48 | right: 0px;
49 | height: 100%;
50 | border-right: 3px solid rgb(66, 127, 237);
51 | }
52 | .panel-google-plus > .panel-google-plus-tags > ul:hover > li,
53 | .panel-google-plus > .panel-google-plus-tags > ul > li:first-child {
54 | padding: 5px 15px 5px 10px;
55 | width: auto;
56 | cursor: pointer;
57 | margin-left: auto;
58 | }
59 | .panel-google-plus > .panel-google-plus-tags > ul:hover > li {
60 | background-color: rgb(255, 255, 255);
61 | }
62 | .panel-google-plus > .panel-google-plus-tags > ul > li:hover {
63 | background-color: rgb(66, 127, 237);
64 | color: rgb(255, 255, 255);
65 | }
66 | .panel-google-plus > .panel-request,
67 | .panel-google-plus > .panel-footer {
68 | background-color: rgb(255, 255, 255);
69 | border-width: 0px;
70 | }
71 | .panel-google-plus > .panel-request {
72 | text-align: left;
73 | margin-left: 20px;
74 | margin-top: 20px;
75 | padding-bottom: 5px;
76 | }
77 | .panel-google-plus > .panel-request > img {
78 | margin-right: 15px;
79 | }
80 | .panel-google-plus > .panel-request > .nl-request {
81 | color: rgb(96, 96, 96);
82 | margin: 0px;
83 | font-size: 16px;
84 | font-weight: 400;
85 | }
86 | .panel-google-plus > .panel-request > .post-time,
87 | .panel-google-plus > .panel-request > .post-location {
88 | color: rgb(153, 153, 153);
89 | font-size: 12px;
90 | font-weight: 400;
91 | }
92 | .panel-google-plus > .panel-body {
93 | padding-top: 5px;
94 | font-size: 13px;
95 | }
96 | .panel-google-plus > .panel-body > .panel-google-plus-image {
97 | display: block;
98 | text-align: center;
99 | background-color: rgb(245, 245, 245);
100 | border: 1px solid rgb(217, 217, 217);
101 | }
102 | .panel-google-plus > .panel-body > .panel-google-plus-image > img {
103 | max-width: 100%;
104 | }
105 |
106 | .panel-google-plus > .panel-footer {
107 | padding-top: 0px;
108 | font-size: 14px;
109 | font-weight: 700;
110 | min-height: 40px;
111 | }
112 | .panel-google-plus > .panel-footer > .btn {
113 | float: right;
114 | margin-right: 8px;
115 | }
116 | .panel-google-plus > .panel-footer > .input-placeholder {
117 | display: block;
118 | margin-left: 98px;
119 | color: rgb(153, 153, 153);
120 | font-size: 12px;
121 | font-weight: 400;
122 | padding: 8px 6px 7px;
123 | border: 1px solid rgb(217, 217, 217);
124 | border-radius: 2px;
125 | box-shadow: rgba(0, 0, 0, 0.0470588) 0px 1px 0px 0px;
126 | }
127 | .panel-google-plus.panel-google-plus-show-comment > .panel-footer > .input-placeholder {
128 | display: none;
129 | }
130 | .panel-google-plus > .panel-google-plus-comment {
131 | display: none;
132 | padding: 10px 20px 15px;
133 | border-top: 1px solid rgb(229, 229, 229);
134 | background-color: rgb(245, 245, 245);
135 | }
136 | .panel-google-plus.panel-google-plus-show-comment > .panel-google-plus-comment {
137 | display: block;
138 | }
139 | /*.panel-google-plus > .panel-google-plus-comment > img {
140 | float: left;
141 | }*/
142 | .panel-google-plus > .panel-google-plus-comment > .panel-google-plus-textarea {
143 | float: right;
144 | width: calc(100% - 56px);
145 | }
146 | .panel-google-plus > .panel-google-plus-comment > .panel-google-plus-textarea > textarea {
147 | display: block;
148 | /*margin-left: 60px;
149 | width: calc(100% - 56px);*/
150 | width: 100%;
151 | background-color: rgb(255, 255, 255);
152 | border: 1px solid rgb(217, 217, 217);
153 | box-shadow: rgba(0, 0, 0, 0.0470588) 0px 1px 0px 0px;
154 | resize: vertical;
155 | }
156 | .panel-google-plus > .panel-google-plus-comment > .panel-google-plus-textarea > .btn {
157 | margin-top: 10px;
158 | margin-right: 8px;
159 | width: 100%;
160 | }
161 | @media (min-width: 992px) {
162 | .panel-google-plus > .panel-google-plus-comment > .panel-google-plus-textarea > .btn {
163 | width: auto;
164 | }
165 | }
166 |
167 | .panel-google-plus .btn-default {
168 | border: 0px solid rgb(217, 217, 217);
169 | }
170 | .panel-google-plus .btn-default:hover,
171 | .panel-google-plus .btn-default:focus,
172 | .panel-google-plus .btn-default:active {
173 | background-color: rgb(255, 255, 255);
174 | /* border-color: rgb(0, 0, 0); */
175 | color: #f48e5c
176 | }
177 |
178 |
--------------------------------------------------------------------------------
/website/static/lib/hljs.themes/agate.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Agate by Taufik Nurrohman
3 | * ----------------------------------------------------
4 | *
5 | * #ade5fc
6 | * #a2fca2
7 | * #c6b4f0
8 | * #d36363
9 | * #fcc28c
10 | * #fc9b9b
11 | * #ffa
12 | * #fff
13 | * #333
14 | * #62c8f3
15 | * #888
16 | *
17 | */.hljs{display:block;overflow-x:auto;padding:0.5em;background:#333;color:white}.hljs-name,.hljs-strong{font-weight:bold}.hljs-code,.hljs-emphasis{font-style:italic}.hljs-tag{color:#62c8f3}.hljs-variable,.hljs-template-variable,.hljs-selector-id,.hljs-selector-class{color:#ade5fc}.hljs-string,.hljs-bullet{color:#a2fca2}.hljs-type,.hljs-title,.hljs-section,.hljs-attribute,.hljs-quote,.hljs-built_in,.hljs-builtin-name{color:#ffa}.hljs-number,.hljs-symbol,.hljs-bullet{color:#d36363}.hljs-keyword,.hljs-selector-tag,.hljs-literal{color:#fcc28c}.hljs-comment,.hljs-deletion,.hljs-code{color:#888}.hljs-regexp,.hljs-link{color:#c6b4f0}.hljs-meta{color:#fc9b9b}.hljs-deletion{background-color:#fc9b9b;color:#333}.hljs-addition{background-color:#a2fca2;color:#333}.hljs a{color:inherit}.hljs a:focus,.hljs a:hover{color:inherit;text-decoration:underline}
--------------------------------------------------------------------------------
/website/static/lib/hljs.themes/bash.js:
--------------------------------------------------------------------------------
1 | hljs.registerLanguage("bash", function(e) {
2 | var t = {
3 | cN: "variable",
4 | v: [{
5 | b: /\$[\w\d#@][\w\d_]*/
6 | }, {
7 | b: /\$\{(.*?)}/
8 | }]
9 | },
10 | s = {
11 | cN: "string",
12 | b: /"/,
13 | e: /"/,
14 | c: [e.BE, t, {
15 | cN: "variable",
16 | b: /\$\(/,
17 | e: /\)/,
18 | c: [e.BE]
19 | }]
20 | },
21 | a = {
22 | cN: "string",
23 | b: /'/,
24 | e: /'/
25 | };
26 | return {
27 | aliases: ["sh", "zsh"],
28 | l: /-?[a-zA-Z0-9\.\(\)\!\\;\{\}_+-]+/,
29 | k: {
30 | keyword: "if then else elif fi for while in do done case esac function"
31 | + " -true"
32 | + " -false"
33 | + " -Bmin"
34 | + " -Bnewer"
35 | + " -Btime"
36 | + " -atime"
37 | + " -acl"
38 | + " -amin"
39 | + " -anewer"
40 | + " -cmin"
41 | + " -cnewer"
42 | + " -ctime"
43 | + " -d"
44 | + " -depth"
45 | + " -depth"
46 | + " -empty"
47 | + " -executable"
48 | + " -fstype"
49 | + " -gid"
50 | + " -group"
51 | + " -ignore_readdir_race"
52 | + " -ilname"
53 | + " -ilname"
54 | + " -iname"
55 | + " -inum"
56 | + " -ipath"
57 | + " -iregex"
58 | + " -iwholename"
59 | + " -links"
60 | + " -lname"
61 | + " -ls"
62 | + " -maxdepth"
63 | + " -mindepth"
64 | + " -mmin"
65 | + " -mnewer"
66 | + " -mount"
67 | + " -mtime"
68 | + " -name"
69 | + " -newer"
70 | + " -newerXY"
71 | + " -nogroup"
72 | + " -noignore_readdir_race"
73 | + " -noleaf"
74 | + " -nouser"
75 | + " -path"
76 | + " -perm"
77 | + " -print"
78 | + " -regex"
79 | + " -samefile"
80 | + " -size"
81 | + " -type"
82 | + " -uid"
83 | + " -user"
84 | + " -wholename"
85 | + " -xattr"
86 | + " -xattrname"
87 | + " -xi"
88 | + " -daystart"
89 | + " -xtype"
90 | + " -a"
91 | + " -b"
92 | + " -c"
93 | + " -d"
94 | + " -e"
95 | + " -f"
96 | + " -g"
97 | + " -h"
98 | + " -i"
99 | + " -j"
100 | + " -k"
101 | + " -l"
102 | + " -m"
103 | + " -n"
104 | + " -o"
105 | + " -p"
106 | + " -q"
107 | + " -r"
108 | + " -s"
109 | + " -t"
110 | + " -u"
111 | + " -v"
112 | + " -w"
113 | + " -x"
114 | + " -y"
115 | + " -z"
116 | + " -A"
117 | + " -B"
118 | + " -C"
119 | + " -D"
120 | + " -E"
121 | + " -F"
122 | + " -G"
123 | + " -H"
124 | + " -I"
125 | + " -J"
126 | + " -K"
127 | + " -L"
128 | + " -M"
129 | + " -N"
130 | + " -O"
131 | + " -P"
132 | + " -Q"
133 | + " -R"
134 | + " -S"
135 | + " -T"
136 | + " -U"
137 | + " -V"
138 | + " -W"
139 | + " -X"
140 | + " -Y"
141 | + " -Z"
142 | + " -1"
143 | + " -2"
144 | + " -3"
145 | + " -4"
146 | + " -5"
147 | + " -6"
148 | + " -7"
149 | + " -8"
150 | + " -9"
151 | + " -0",
152 | literal: "true false",
153 | built_in: "break cd continue eval exec exit export find getopts grep hash pwd readonly"
154 | + " return shift test times trap umask unset alias bind builtin caller command"
155 | + " declare echo enable help let local logout mapfile printf read readarray"
156 | + " source type typeset ulimit unalias set shopt autoload bg bindkey bye cap"
157 | + " chdir clone comparguments compcall compctl compdescribe compfiles compgroups"
158 | + " compquote comptags comptry compvalues dirs disable disown echotc echoti"
159 | + " emulate fc fg float functions getcap getln history integer jobs kill limit"
160 | + " log noglob popd print pushd pushln rehash sched setcap setopt stat suspend"
161 | + " ttyctl unfunction unhash unlimit unsetopt vared wait whence where which"
162 | + " zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket"
163 | + " zstyle ztcp rm sort head tail tar cp smv ls chmod chown chgrp wc xargs",
164 | operators: "\! \\\! -not -and -or",
165 | actions: "-detele -exec -execdir -fls -fprint -fprint0 -fprintf -ls -ok -okdir -print"
166 | + " -print0 -printf -prune -quit",
167 | special_symbols: "\\\( \\\) \\; \+",
168 | semantic_types: "File-01 File-02 File-03 File-04 File-05 File-06"
169 | + " Directory-01 Directory-02 Directory-03 Directory-04 Directory-05 Directory-06"
170 | + " Path-01 Path-02 Path-03 Path-04 Path-05 Path-06"
171 | + " Number-01 Number-02 Number-03 Number-04 Number-05 Number-06"
172 | + " Size-01 Size-02 Size-03 Size-04 Size-05 Size-06"
173 | + " Timespan-01 Timespan-02 Timespan-03 Timespan-04 Timespan-05 Timespan-06"
174 | + " Regex-01 Regex-02 Regex-03 Regex-04 Regex-05 Regex-06"
175 | + " DateTime-01 DateTime-02 DateTime-03 DateTime-04 DateTime-05 DateTime-06"
176 | + " Permission-01 Permission-02 Permission-03 Permission-04 Permission-05 Permission-06"
177 | + " Username-01 Username-02 Username-03 Username-04 Username-05 Username-06"
178 | + " Groupname-01 Groupname-02 Groupname-03 Groupname-04 Groupname-05 Groupname-06"
179 | + " File Directory Path Number Size Timespan Regex DateTime Type Option"
180 | + " Permission Username Groupname Prog"
181 | },
182 | c: [{
183 | cN: "meta",
184 | b: /^#![^\n]+sh\s*$/,
185 | r: 10
186 | }, {
187 | cN: "function",
188 | b: /\w[\w\d_]*\s*\(\s*\)\s*\{/,
189 | rB: !0,
190 | c: [e.inherit(e.TM, {
191 | b: /\w[\w\d_]*/
192 | })],
193 | r: 0
194 | }, e.HCM, s, a, t]
195 | }
196 | });
197 |
--------------------------------------------------------------------------------
/website/static/lib/hljs.themes/color-brewer.css:
--------------------------------------------------------------------------------
1 | .hljs{display:block;overflow-x:auto;padding:0.5em;background:#fff}.hljs,.hljs-subst{color:#000}.hljs-string,.hljs-meta,.hljs-symbol,.hljs-template-tag,.hljs-template-variable,.hljs-addition{color:#756bb1}.hljs-comment,.hljs-quote{color:#636363}.hljs-number,.hljs-regexp,.hljs-literal,.hljs-bullet,.hljs-link{color:#31a354}.hljs-deletion,.hljs-variable{color:#88f}.hljs-keyword,.hljs-selector-tag,.hljs-title,.hljs-section,.hljs-built_in,.hljs-doctag,.hljs-type,.hljs-tag,.hljs-name,.hljs-selector-id,.hljs-selector-class,.hljs-strong{color:#3182bd}.hljs-emphasis{font-style:italic}.hljs-attribute{color:#e6550d}
--------------------------------------------------------------------------------
/website/static/lib/hljs.themes/dracula.css:
--------------------------------------------------------------------------------
1 | .hljs{display:block;overflow-x:auto;padding:0.5em;background:#282a36}.hljs-keyword,.hljs-selector-tag,.hljs-literal,.hljs-section,.hljs-link{color:#8be9fd}.hljs-function .hljs-keyword{color:#ff79c6}.hljs,.hljs-subst{color:#f8f8f2}.hljs-string,.hljs-title,.hljs-name,.hljs-type,.hljs-attribute,.hljs-symbol,.hljs-bullet,.hljs-addition,.hljs-variable,.hljs-template-tag,.hljs-template-variable{color:#f1fa8c}.hljs-comment,.hljs-quote,.hljs-deletion,.hljs-meta{color:#6272a4}.hljs-keyword,.hljs-selector-tag,.hljs-literal,.hljs-title,.hljs-section,.hljs-doctag,.hljs-type,.hljs-name,.hljs-strong{font-weight:bold}.hljs-emphasis{font-style:italic}
--------------------------------------------------------------------------------
/website/static/lib/hljs.themes/github-gist.css:
--------------------------------------------------------------------------------
1 | .hljs{display:block;background:white;padding:0.5em;color:#333333;overflow-x:auto}.hljs-comment,.hljs-meta{color:#969896}.hljs-string,.hljs-variable,.hljs-template-variable,.hljs-strong,.hljs-emphasis,.hljs-quote{color:#df5000}.hljs-keyword,.hljs-selector-tag,.hljs-type{color:#a71d5d}.hljs-literal,.hljs-symbol,.hljs-bullet,.hljs-attribute{color:#0086b3}.hljs-section,.hljs-name{color:#63a35c}.hljs-tag{color:#333333}.hljs-title,.hljs-attr,.hljs-selector-id,.hljs-selector-class,.hljs-selector-attr,.hljs-selector-pseudo{color:#795da3}.hljs-addition{color:#55a532;background-color:#eaffea}.hljs-deletion{color:#bd2c00;background-color:#ffecec}.hljs-link{text-decoration:underline}
--------------------------------------------------------------------------------
/website/static/lib/hljs.themes/solarized-light.css:
--------------------------------------------------------------------------------
1 | .hljs{display:block;overflow-x:auto;padding:0.5em;background:#fdf6e3;color:#657b83}.hljs-comment,.hljs-quote{color:#93a1a1}.hljs-keyword,.hljs-selector-tag,.hljs-addition{color:#859900}.hljs-number,.hljs-string,.hljs-meta .hljs-meta-string,.hljs-literal,.hljs-doctag,.hljs-regexp{color:#2aa198}.hljs-title,.hljs-section,.hljs-name,.hljs-selector-id,.hljs-selector-class{color:#268bd2}.hljs-attribute,.hljs-attr,.hljs-variable,.hljs-template-variable,.hljs-class .hljs-title,.hljs-type{color:#b58900}.hljs-symbol,.hljs-bullet,.hljs-subst,.hljs-meta,.hljs-meta .hljs-keyword,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-link{color:#cb4b16}.hljs-built_in,.hljs-deletion{color:#dc322f}.hljs-formula{background:#eee8d5}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:bold}
--------------------------------------------------------------------------------
/website/static/lib/hljs.themes/tomorrow.css:
--------------------------------------------------------------------------------
1 | .hljs-comment,
2 | .hljs-quote {
3 | color: #8e908c
4 | }
5 |
6 | .hljs-variable,
7 | .hljs-template-variable,
8 | .hljs-tag,
9 | .hljs-name,
10 | .hljs-selector-id,
11 | .hljs-selector-class,
12 | .hljs-regexp,
13 | .hljs-deletion {
14 | color: #c82829
15 | }
16 |
17 | /* bash utilities */
18 | .hljs-number,
19 | .hljs-built_in,
20 | .hljs-builtin-name,
21 | .hljs-literal,
22 | .hljs-type,
23 | .hljs-params,
24 | .hljs-meta,
25 | .hljs-link{
26 | color: #f5871f
27 | }
28 | .hljs-special_symbols{
29 | color: #66cccc
30 | }
31 |
32 | /* bash operators */
33 | .hljs-operators {
34 | color: #ff4c4c
35 | }
36 |
37 | .hljs-string,
38 | .hljs-attribute {
39 | color: #718c00
40 | }
41 |
42 | /* bash actions */
43 | .hljs-actions,
44 | .hljs-symbol,
45 | .hljs-bullet,
46 | .hljs-addition {
47 | color: #4271ae
48 | }
49 |
50 | .hljs-title,
51 | .hljs-section {
52 | color: #eab700
53 | }
54 |
55 | /* bash tests */
56 | .hljs-keyword,
57 | .hljs-selector-tag {
58 | color: #8959a8
59 | }
60 |
61 | /* holes */
62 | .hljs-semantic_types {
63 | text-decoration: underline;
64 | }
65 |
66 | .hljs {
67 | display: block;
68 | overflow-x: auto;
69 | background: #f8f8f8;
70 | color: #4d4d4c;
71 | padding: 0.5em;
72 | font-size: 12px;
73 | }
74 |
75 | .hljs-emphasis {
76 | font-style: italic
77 | }
78 |
79 | .hljs-strong {
80 | font-weight: bold
81 | }
82 |
--------------------------------------------------------------------------------
/website/static/lib/hljs.themes/zenburn.css:
--------------------------------------------------------------------------------
1 | .hljs {
2 | display: block;
3 | overflow-x: auto;
4 | padding: 0.5em;
5 | background: #3f3f3f;
6 | color: #dcdcdc;
7 | font-size: 14px
8 | }
9 | .hljs-keyword,
10 | .hljs-selector-tag,
11 | .hljs-tag {
12 | color: #e3ceab
13 | }
14 | .hljs-template-tag {
15 | color: #dcdcdc
16 | }
17 | .hljs-number {
18 | color: #8cd0d3
19 | }
20 | .hljs-variable,
21 | .hljs-template-variable,
22 | .hljs-attribute {
23 | color: #efdcbc
24 | }
25 | .hljs-literal {
26 | color: #efefaf
27 | }
28 | .hljs-subst {
29 | color: #8f8f8f
30 | }
31 | .hljs-title,
32 | .hljs-name,
33 | .hljs-selector-id,
34 | .hljs-selector-class,
35 | .hljs-section,
36 | .hljs-type {
37 | color: #efef8f
38 | }
39 | .hljs-symbol,
40 | .hljs-bullet,
41 | .hljs-link {
42 | color: #dca3a3
43 | }
44 | .hljs-deletion,
45 | .hljs-string,
46 | .hljs-built_in,
47 | .hljs-builtin-name {
48 | color: #cc9393
49 | }
50 | .hljs-addition,
51 | .hljs-comment,
52 | .hljs-quote,
53 | .hljs-meta {
54 | color: #7f9f7f
55 | }
56 | .hljs-emphasis {
57 | font-style: italic
58 | }
59 | .hljs-strong {
60 | font-weight: bold
61 | }
--------------------------------------------------------------------------------
/website/static/lib/jquery-ui-1.12.1.custom/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright jQuery Foundation and other contributors, https://jquery.org/
2 |
3 | This software consists of voluntary contributions made by many
4 | individuals. For exact contribution history, see the revision history
5 | available at https://github.com/jquery/jquery-ui
6 |
7 | The following license applies to all parts of this software except as
8 | documented below:
9 |
10 | ====
11 |
12 | Permission is hereby granted, free of charge, to any person obtaining
13 | a copy of this software and associated documentation files (the
14 | "Software"), to deal in the Software without restriction, including
15 | without limitation the rights to use, copy, modify, merge, publish,
16 | distribute, sublicense, and/or sell copies of the Software, and to
17 | permit persons to whom the Software is furnished to do so, subject to
18 | the following conditions:
19 |
20 | The above copyright notice and this permission notice shall be
21 | included in all copies or substantial portions of the Software.
22 |
23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 |
31 | ====
32 |
33 | Copyright and related rights for sample code are waived via CC0. Sample
34 | code is defined as all source code contained within the demos directory.
35 |
36 | CC0: http://creativecommons.org/publicdomain/zero/1.0/
37 |
38 | ====
39 |
40 | All files located in the node_modules and external directories are
41 | externally maintained libraries used by this software which have their
42 | own licenses; we recommend you read them, as their terms may differ from
43 | the terms above.
44 |
--------------------------------------------------------------------------------
/website/static/lib/jquery-ui-1.12.1.custom/images/ui-icons_444444_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TellinaTool/tellina/61f1398eb3c2adaad32660d9185d646ff3fcd857/website/static/lib/jquery-ui-1.12.1.custom/images/ui-icons_444444_256x240.png
--------------------------------------------------------------------------------
/website/static/lib/jquery-ui-1.12.1.custom/images/ui-icons_555555_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TellinaTool/tellina/61f1398eb3c2adaad32660d9185d646ff3fcd857/website/static/lib/jquery-ui-1.12.1.custom/images/ui-icons_555555_256x240.png
--------------------------------------------------------------------------------
/website/static/lib/jquery-ui-1.12.1.custom/images/ui-icons_777620_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TellinaTool/tellina/61f1398eb3c2adaad32660d9185d646ff3fcd857/website/static/lib/jquery-ui-1.12.1.custom/images/ui-icons_777620_256x240.png
--------------------------------------------------------------------------------
/website/static/lib/jquery-ui-1.12.1.custom/images/ui-icons_777777_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TellinaTool/tellina/61f1398eb3c2adaad32660d9185d646ff3fcd857/website/static/lib/jquery-ui-1.12.1.custom/images/ui-icons_777777_256x240.png
--------------------------------------------------------------------------------
/website/static/lib/jquery-ui-1.12.1.custom/images/ui-icons_cc0000_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TellinaTool/tellina/61f1398eb3c2adaad32660d9185d646ff3fcd857/website/static/lib/jquery-ui-1.12.1.custom/images/ui-icons_cc0000_256x240.png
--------------------------------------------------------------------------------
/website/static/lib/jquery-ui-1.12.1.custom/images/ui-icons_ffffff_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TellinaTool/tellina/61f1398eb3c2adaad32660d9185d646ff3fcd857/website/static/lib/jquery-ui-1.12.1.custom/images/ui-icons_ffffff_256x240.png
--------------------------------------------------------------------------------
/website/static/lib/jquery-ui-1.12.1.custom/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jquery-ui",
3 | "title": "jQuery UI",
4 | "description": "A curated set of user interface interactions, effects, widgets, and themes built on top of the jQuery JavaScript Library.",
5 | "version": "1.12.1",
6 | "homepage": "http://jqueryui.com",
7 | "author": {
8 | "name": "jQuery Foundation and other contributors",
9 | "url": "https://github.com/jquery/jquery-ui/blob/1.12.1/AUTHORS.txt"
10 | },
11 | "main": "ui/widget.js",
12 | "maintainers": [
13 | {
14 | "name": "Scott González",
15 | "email": "scott.gonzalez@gmail.com",
16 | "url": "http://scottgonzalez.com"
17 | },
18 | {
19 | "name": "Jörn Zaefferer",
20 | "email": "joern.zaefferer@gmail.com",
21 | "url": "http://bassistance.de"
22 | },
23 | {
24 | "name": "Mike Sherov",
25 | "email": "mike.sherov@gmail.com",
26 | "url": "http://mike.sherov.com"
27 | },
28 | {
29 | "name": "TJ VanToll",
30 | "email": "tj.vantoll@gmail.com",
31 | "url": "http://tjvantoll.com"
32 | },
33 | {
34 | "name": "Felix Nagel",
35 | "email": "info@felixnagel.com",
36 | "url": "http://www.felixnagel.com"
37 | },
38 | {
39 | "name": "Alex Schmitz",
40 | "email": "arschmitz@gmail.com",
41 | "url": "https://github.com/arschmitz"
42 | }
43 | ],
44 | "repository": {
45 | "type": "git",
46 | "url": "git://github.com/jquery/jquery-ui.git"
47 | },
48 | "bugs": "https://bugs.jqueryui.com/",
49 | "license": "MIT",
50 | "scripts": {
51 | "test": "grunt"
52 | },
53 | "dependencies": {},
54 | "devDependencies": {
55 | "commitplease": "2.3.0",
56 | "grunt": "0.4.5",
57 | "grunt-bowercopy": "1.2.4",
58 | "grunt-cli": "0.1.13",
59 | "grunt-compare-size": "0.4.0",
60 | "grunt-contrib-concat": "0.5.1",
61 | "grunt-contrib-csslint": "0.5.0",
62 | "grunt-contrib-jshint": "0.12.0",
63 | "grunt-contrib-qunit": "1.0.1",
64 | "grunt-contrib-requirejs": "0.4.4",
65 | "grunt-contrib-uglify": "0.11.1",
66 | "grunt-git-authors": "3.1.0",
67 | "grunt-html": "6.0.0",
68 | "grunt-jscs": "2.1.0",
69 | "load-grunt-tasks": "3.4.0",
70 | "rimraf": "2.5.1",
71 | "testswarm": "1.1.0"
72 | },
73 | "keywords": []
74 | }
75 |
--------------------------------------------------------------------------------
/website/static/lib/jquery.upvote/images/sprites-meta-stackoverflow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TellinaTool/tellina/61f1398eb3c2adaad32660d9185d646ff3fcd857/website/static/lib/jquery.upvote/images/sprites-meta-stackoverflow.png
--------------------------------------------------------------------------------
/website/static/lib/jquery.upvote/images/sprites-programmers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TellinaTool/tellina/61f1398eb3c2adaad32660d9185d646ff3fcd857/website/static/lib/jquery.upvote/images/sprites-programmers.png
--------------------------------------------------------------------------------
/website/static/lib/jquery.upvote/images/sprites-serverfault.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TellinaTool/tellina/61f1398eb3c2adaad32660d9185d646ff3fcd857/website/static/lib/jquery.upvote/images/sprites-serverfault.png
--------------------------------------------------------------------------------
/website/static/lib/jquery.upvote/images/sprites-stackoverflow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TellinaTool/tellina/61f1398eb3c2adaad32660d9185d646ff3fcd857/website/static/lib/jquery.upvote/images/sprites-stackoverflow.png
--------------------------------------------------------------------------------
/website/static/lib/jquery.upvote/images/sprites-superuser.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TellinaTool/tellina/61f1398eb3c2adaad32660d9185d646ff3fcd857/website/static/lib/jquery.upvote/images/sprites-superuser.png
--------------------------------------------------------------------------------
/website/static/lib/jquery.upvote/images/sprites-unix.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TellinaTool/tellina/61f1398eb3c2adaad32660d9185d646ff3fcd857/website/static/lib/jquery.upvote/images/sprites-unix.png
--------------------------------------------------------------------------------
/website/static/lib/jquery.upvote/jquery.upvote.css:
--------------------------------------------------------------------------------
1 | div.upvote {
2 | text-align: center;
3 | }
4 |
5 | div.upvote a.upvote-enabled {
6 | cursor: pointer;
7 | }
8 |
9 | div.upvote a {
10 | color: transparent;
11 | background-image: url('images/sprites-stackoverflow.png?v=1');
12 | background-repeat: no-repeat;
13 | overflow: hidden;
14 | display: block;
15 | margin: 0 auto;
16 | width: 41px;
17 | height: 25px;
18 | }
19 |
20 | div.upvote span.count {
21 | display: block;
22 | font-size: 24px;
23 | font-family: Arial, Liberation, Sans, DejaVu Sans, sans-serif;
24 | color: #555;
25 | text-align: center;
26 | line-height: 1;
27 | }
28 |
29 | div.upvote a.upvote {
30 | background-position: 0px -265px;
31 | }
32 |
33 | div.upvote a.upvote.upvote-on {
34 | background-position: 0px -230px;
35 | }
36 |
37 | div.upvote a.downvote {
38 | background-position: 0px -300px;
39 | }
40 |
41 | div.upvote a.downvote.downvote-on {
42 | background-position: 0px -330px;
43 | }
44 |
45 | div.upvote a.star {
46 | width: 33px;
47 | height: 31px;
48 | background-position: 0px -150px;
49 | }
50 |
51 | div.upvote a.star.star-on {
52 | background-position: 0px -190px;
53 | }
54 |
55 | div.upvote-serverfault a {
56 | background-image: url('images/sprites-serverfault.png?v=1');
57 | }
58 |
59 | div.upvote-meta-stackoverflow a {
60 | background-image: url('images/sprites-meta-stackoverflow.png?v=1');
61 | }
62 |
63 | div.upvote-superuser a {
64 | background-image: url('images/sprites-superuser.png?v=1');
65 | }
66 |
67 | div.upvote-unix a {
68 | background-image: url('images/sprites-unix.png?v=1');
69 | width: 42px;
70 | height: 27px;
71 | }
72 |
73 | div.upvote-unix a.upvote {
74 | background-position: 0px -237px;
75 | }
76 |
77 | div.upvote-unix a.upvote.upvote-on {
78 | background-position: 0px -198px;
79 | }
80 |
81 | div.upvote-unix a.downvote {
82 | background-position: 0px -281px;
83 | }
84 |
85 | div.upvote-unix a.downvote.downvote-on {
86 | background-position: 0px -319px;
87 | }
88 |
89 | div.upvote-unix a.star {
90 | width: 42px;
91 | height: 30px;
92 | background-position: 0px -126px;
93 | }
94 |
95 | div.upvote-unix a.star.star-on {
96 | background-position: 0px -164px;
97 | }
98 |
99 | div.upvote-unix span.count {
100 | color: #333;
101 | line-height: 15px;
102 | padding: 9px 0;
103 | font-family: "DejaVu Sans Mono","Bitstream Vera Sans Mono","Courier New",Courier,Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter",monospace;
104 | text-shadow: 1px 1px 0 #ffffff;
105 | font-weight: bold;
106 | margin: 0;
107 | border: 0;
108 | vertical-align: baseline;
109 | }
110 |
111 | div.upvote-programmers a {
112 | background-image: url('images/sprites-programmers.png?v=1');
113 | width: 42px;
114 | height: 20px;
115 | }
116 |
117 | div.upvote-programmers a.upvote {
118 | background-position: 5px -248px;
119 | }
120 |
121 | div.upvote-programmers a.upvote.upvote-on {
122 | background-position: 5px -211px;
123 | }
124 |
125 | div.upvote-programmers a.downvote {
126 | background-position: 5px -282px;
127 | }
128 |
129 | div.upvote-programmers a.downvote.downvote-on {
130 | background-position: 5px -320px;
131 | }
132 |
133 | div.upvote-programmers a.star {
134 | width: 42px;
135 | height: 30px;
136 | background-position: 6px -128px;
137 | }
138 |
139 | div.upvote-programmers a.star.star-on {
140 | background-position: 6px -166px;
141 | }
142 |
143 | div.upvote-programmers span.count {
144 | color: #333;
145 | line-height: 15px;
146 | padding: 5px 0 7px;
147 | font-size: 20px;
148 | font-weight: bold;
149 | font-family: Tahoma,Geneva,Arial,sans-serif;
150 | }
--------------------------------------------------------------------------------
/website/static/lib/jquery.upvote/jquery.upvote.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * jQuery Upvote - a voting plugin
3 | * ------------------------------------------------------------------
4 | *
5 | * jQuery Upvote is a plugin that generates a voting widget like
6 | * the one used on Stack Exchange sites.
7 | *
8 | * Licensed under Creative Commons Attribution 3.0 Unported
9 | * http://creativecommons.org/licenses/by/3.0/
10 | *
11 | * @version 1.0.2
12 | * @since 2013.06.19
13 | * @author Janos Gyerik
14 | * @homepage https://janosgyerik.github.io/jquery-upvote
15 | * @twitter twitter.com/janosgyerik
16 | *
17 | * ------------------------------------------------------------------
18 | *
19 | *
25 | *
26 | * $('#topic').upvote();
27 | * $('#topic').upvote({count: 5, upvoted: true});
28 | *
29 | */
30 |
31 | ;(function($) {
32 | "use strict";
33 | var namespace = 'upvote';
34 | var dot_namespace = '.' + namespace;
35 | var upvote_css = 'upvote';
36 | var dot_upvote_css = '.' + upvote_css;
37 | var upvoted_css = 'upvote-on';
38 | var dot_upvoted_css = '.' + upvoted_css;
39 | var downvote_css = 'downvote';
40 | var dot_downvote_css = '.' + downvote_css;
41 | var downvoted_css = 'downvote-on';
42 | var dot_downvoted_css = '.' + downvoted_css;
43 | var star_css = 'star';
44 | var dot_star_css = '.' + star_css;
45 | var starred_css = 'star-on';
46 | var dot_starred_css = '.' + starred_css;
47 | var count_css = 'count';
48 | var dot_count_css = '.' + count_css;
49 | var enabled_css = 'upvote-enabled';
50 |
51 | function init(dom, options) {
52 | return dom.each(function() {
53 | var jqdom = $(this);
54 | methods.destroy(jqdom);
55 |
56 | var count = parseInt(jqdom.find(dot_count_css).text(), 10);
57 | count = isNaN(count) ? 0 : count;
58 | var initial = {
59 | id: jqdom.attr('data-id'),
60 | count: count,
61 | upvoted: jqdom.find(dot_upvoted_css).length,
62 | downvoted: jqdom.find(dot_downvoted_css).length,
63 | starred: jqdom.find(dot_starred_css).length,
64 | callback: function() {}
65 | };
66 |
67 | var data = $.extend(initial, options);
68 | if (data.upvoted && data.downvoted) {
69 | data.downvoted = false;
70 | }
71 |
72 | jqdom.data(namespace, data);
73 | render(jqdom);
74 | setupUI(jqdom);
75 | });
76 | }
77 |
78 | function setupUI(jqdom) {
79 | jqdom.find(dot_upvote_css).addClass(enabled_css);
80 | jqdom.find(dot_downvote_css).addClass(enabled_css);
81 | jqdom.find(dot_star_css).addClass(enabled_css);
82 | jqdom.find(dot_upvote_css).on('click.' + namespace, function() {
83 | jqdom.upvote('upvote');
84 | });
85 | jqdom.find('.downvote').on('click.' + namespace, function() {
86 | jqdom.upvote('downvote');
87 | });
88 | jqdom.find('.star').on('click.' + namespace, function() {
89 | jqdom.upvote('star');
90 | });
91 | }
92 |
93 | function _click_upvote(jqdom) {
94 | jqdom.find(dot_upvote_css).click();
95 | }
96 |
97 | function _click_downvote(jqdom) {
98 | jqdom.find(dot_downvote_css).click();
99 | }
100 |
101 | function _click_star(jqdom) {
102 | jqdom.find(dot_star_css).click();
103 | }
104 |
105 | function render(jqdom) {
106 | var data = jqdom.data(namespace);
107 | jqdom.find(dot_count_css).text(data.count);
108 | if (data.upvoted) {
109 | jqdom.find(dot_upvote_css).addClass(upvoted_css);
110 | jqdom.find(dot_downvote_css).removeClass(downvoted_css);
111 | } else if (data.downvoted) {
112 | jqdom.find(dot_upvote_css).removeClass(upvoted_css);
113 | jqdom.find(dot_downvote_css).addClass(downvoted_css);
114 | } else {
115 | jqdom.find(dot_upvote_css).removeClass(upvoted_css);
116 | jqdom.find(dot_downvote_css).removeClass(downvoted_css);
117 | }
118 | if (data.starred) {
119 | jqdom.find(dot_star_css).addClass(starred_css);
120 | } else {
121 | jqdom.find(dot_star_css).removeClass(starred_css);
122 | }
123 | }
124 |
125 | function callback(jqdom) {
126 | var data = jqdom.data(namespace);
127 | data.callback(data);
128 | }
129 |
130 | function upvote(jqdom) {
131 | var data = jqdom.data(namespace);
132 | if (data.upvoted) {
133 | data.upvoted = false;
134 | --data.count;
135 | } else {
136 | data.upvoted = true;
137 | ++data.count;
138 | if (data.downvoted) {
139 | data.downvoted = false;
140 | ++data.count;
141 | }
142 | }
143 | render(jqdom);
144 | callback(jqdom);
145 | return jqdom;
146 | }
147 |
148 | function downvote(jqdom) {
149 | var data = jqdom.data(namespace);
150 | if (data.downvoted) {
151 | data.downvoted = false;
152 | ++data.count;
153 | } else {
154 | data.downvoted = true;
155 | --data.count;
156 | if (data.upvoted) {
157 | data.upvoted = false;
158 | --data.count;
159 | }
160 | }
161 | render(jqdom);
162 | callback(jqdom);
163 | return jqdom;
164 | }
165 |
166 | function star(jqdom) {
167 | var data = jqdom.data(namespace);
168 | data.starred = ! data.starred;
169 | render(jqdom);
170 | callback(jqdom);
171 | return jqdom;
172 | }
173 |
174 | function count(jqdom) {
175 | return jqdom.data(namespace).count;
176 | }
177 |
178 | function upvoted(jqdom) {
179 | return jqdom.data(namespace).upvoted;
180 | }
181 |
182 | function downvoted(jqdom) {
183 | return jqdom.data(namespace).downvoted;
184 | }
185 |
186 | function starred(jqdom) {
187 | return jqdom.data(namespace).starred;
188 | }
189 |
190 | var methods = {
191 | init: init,
192 | count: count,
193 | upvote: upvote,
194 | upvoted: upvoted,
195 | downvote: downvote,
196 | downvoted: downvoted,
197 | starred: starred,
198 | star: star,
199 | _click_upvote: _click_upvote,
200 | _click_downvote: _click_downvote,
201 | _click_star: _click_star,
202 | destroy: destroy
203 | };
204 |
205 | function destroy(jqdom) {
206 | return jqdom.each(function() {
207 | $(window).unbind(dot_namespace);
208 | $(this).removeClass(enabled_css);
209 | $(this).removeData(namespace);
210 | });
211 | }
212 |
213 | $.fn.upvote = function(method) {
214 | var args;
215 | if (methods[method]) {
216 | args = Array.prototype.slice.call(arguments, 1);
217 | args.unshift(this);
218 | return methods[method].apply(this, args);
219 | }
220 | if (typeof method === 'object' || ! method) {
221 | args = Array.prototype.slice.call(arguments);
222 | args.unshift(this);
223 | return methods.init.apply(this, args);
224 | }
225 | $.error('Method ' + method + ' does not exist on jQuery.upvote');
226 | };
227 | })(jQuery);
228 |
--------------------------------------------------------------------------------
/website/utils.py:
--------------------------------------------------------------------------------
1 | import os, sys
2 | import socket
3 | import ssl
4 | import time
5 | import urllib
6 |
7 | from django.core.exceptions import ObjectDoesNotExist
8 | from django.http import JsonResponse
9 | from website.models import NL, Command, Tag, URL
10 |
11 | sys.path.append(os.path.join(
12 | os.path.dirname(__file__), "..", "tellina_learning_module"))
13 |
14 | from bashlint import data_tools
15 |
16 |
17 | # Number of translations to show
18 | NUM_TRANSLATIONS = 20
19 |
20 |
21 | def extract_html(url):
22 | hypothes_prefix = "https://via.hypothes.is/"
23 | try:
24 | time.sleep(0.1)
25 | html = urllib.request.urlopen(hypothes_prefix + url, timeout=2)
26 | except urllib.error.URLError:
27 | print("Error: extract_text_from_url() urllib2.URLError")
28 | # return "", randomstr(180)
29 | return None, None
30 | except socket.timeout:
31 | print("Error: extract_text_from_url() socket.timeout")
32 | # return "", randomstr(180)
33 | return None, None
34 | except ssl.SSLError:
35 | print("Error: extract_text_from_url() ssl.SSLError")
36 | # return "", randomstr(180)
37 | return None, None
38 | return html.read()
39 |
40 | def get_nl(nl_str):
41 | nl, _ = NL.objects.get_or_create(str=nl_str.strip())
42 | return nl
43 |
44 | def get_command(command_str):
45 | command_str=command_str.strip()
46 | if Command.objects.filter(str=command_str).exists():
47 | cmd = Command.objects.get(str=command_str)
48 | else:
49 | cmd = Command.objects.create(str=command_str)
50 | ast = data_tools.bash_parser(command_str)
51 | for utility in data_tools.get_utilities(ast):
52 | cmd.tags.add(get_tag(utility))
53 | template = data_tools.ast2template(
54 | ast, loose_constraints=True)
55 | cmd.template = template
56 | cmd.save()
57 | return cmd
58 |
59 | def get_tag(tag_str):
60 | tag, _ = Tag.objects.get_or_create(str=tag_str.strip())
61 | return tag
62 |
63 | def get_url(url_str):
64 | url_str = url_str.strip()
65 | try:
66 | url = URL.objects.get(str=url_str)
67 | except ObjectDoesNotExist:
68 | html = extract_html(url_str)
69 | if html is None:
70 | url = URL.objects.create(str=url_str)
71 | else:
72 | url = URL.objects.create(str=url_str, html_content=html)
73 | return url
74 |
75 | def json_response(d={}, status='SUCCESS'):
76 | d.update({'status': status})
77 | resp = JsonResponse(d)
78 | return resp
79 |
--------------------------------------------------------------------------------