├── .github
└── workflows
│ └── django.yml
├── .gitignore
├── CloudPanel
├── __init__.py
├── asgi.py
├── celery.py
├── settings.py
├── urls.py
└── wsgi.py
├── README.md
├── apps
├── azure
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── forms.py
│ ├── management
│ │ └── commands
│ │ │ ├── az_update.py
│ │ │ └── init_az_images.py
│ ├── models.py
│ ├── tasks.py
│ ├── urls.py
│ └── views.py
└── users
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── forms.py
│ ├── management
│ └── commands
│ │ └── init_db.py
│ ├── models.py
│ ├── urls.py
│ └── views.py
├── config
└── nginx.conf
├── entrypoint.sh
├── libs
├── azure.py
└── utils.py
├── manage.py
├── requirements.txt
├── scripts
├── celery-beat.conf
├── celery-worker.conf
└── django.conf
└── web
├── favicon.ico
├── index.html
└── static
├── admin
├── css
│ ├── autocomplete.css
│ ├── base.css
│ ├── changelists.css
│ ├── dashboard.css
│ ├── fonts.css
│ ├── forms.css
│ ├── login.css
│ ├── nav_sidebar.css
│ ├── responsive.css
│ ├── responsive_rtl.css
│ ├── rtl.css
│ ├── vendor
│ │ └── select2
│ │ │ ├── LICENSE-SELECT2.md
│ │ │ ├── select2.css
│ │ │ └── select2.min.css
│ └── widgets.css
├── fonts
│ ├── LICENSE.txt
│ ├── README.txt
│ ├── Roboto-Bold-webfont.woff
│ ├── Roboto-Light-webfont.woff
│ └── Roboto-Regular-webfont.woff
├── img
│ ├── LICENSE
│ ├── README.txt
│ ├── calendar-icons.svg
│ ├── gis
│ │ ├── move_vertex_off.svg
│ │ └── move_vertex_on.svg
│ ├── icon-addlink.svg
│ ├── icon-alert.svg
│ ├── icon-calendar.svg
│ ├── icon-changelink.svg
│ ├── icon-clock.svg
│ ├── icon-deletelink.svg
│ ├── icon-no.svg
│ ├── icon-unknown-alt.svg
│ ├── icon-unknown.svg
│ ├── icon-viewlink.svg
│ ├── icon-yes.svg
│ ├── inline-delete.svg
│ ├── search.svg
│ ├── selector-icons.svg
│ ├── sorting-icons.svg
│ ├── tooltag-add.svg
│ └── tooltag-arrowright.svg
└── js
│ ├── SelectBox.js
│ ├── SelectFilter2.js
│ ├── actions.js
│ ├── admin
│ ├── DateTimeShortcuts.js
│ └── RelatedObjectLookups.js
│ ├── autocomplete.js
│ ├── calendar.js
│ ├── cancel.js
│ ├── change_form.js
│ ├── collapse.js
│ ├── core.js
│ ├── inlines.js
│ ├── jquery.init.js
│ ├── nav_sidebar.js
│ ├── popup_response.js
│ ├── prepopulate.js
│ ├── prepopulate_init.js
│ ├── urlify.js
│ └── vendor
│ ├── jquery
│ ├── LICENSE.txt
│ ├── jquery.js
│ └── jquery.min.js
│ ├── select2
│ ├── LICENSE.md
│ ├── i18n
│ │ ├── af.js
│ │ ├── ar.js
│ │ ├── az.js
│ │ ├── bg.js
│ │ ├── bn.js
│ │ ├── bs.js
│ │ ├── ca.js
│ │ ├── cs.js
│ │ ├── da.js
│ │ ├── de.js
│ │ ├── dsb.js
│ │ ├── el.js
│ │ ├── en.js
│ │ ├── es.js
│ │ ├── et.js
│ │ ├── eu.js
│ │ ├── fa.js
│ │ ├── fi.js
│ │ ├── fr.js
│ │ ├── gl.js
│ │ ├── he.js
│ │ ├── hi.js
│ │ ├── hr.js
│ │ ├── hsb.js
│ │ ├── hu.js
│ │ ├── hy.js
│ │ ├── id.js
│ │ ├── is.js
│ │ ├── it.js
│ │ ├── ja.js
│ │ ├── ka.js
│ │ ├── km.js
│ │ ├── ko.js
│ │ ├── lt.js
│ │ ├── lv.js
│ │ ├── mk.js
│ │ ├── ms.js
│ │ ├── nb.js
│ │ ├── ne.js
│ │ ├── nl.js
│ │ ├── pl.js
│ │ ├── ps.js
│ │ ├── pt-BR.js
│ │ ├── pt.js
│ │ ├── ro.js
│ │ ├── ru.js
│ │ ├── sk.js
│ │ ├── sl.js
│ │ ├── sq.js
│ │ ├── sr-Cyrl.js
│ │ ├── sr.js
│ │ ├── sv.js
│ │ ├── th.js
│ │ ├── tk.js
│ │ ├── tr.js
│ │ ├── uk.js
│ │ ├── vi.js
│ │ ├── zh-CN.js
│ │ └── zh-TW.js
│ ├── select2.full.js
│ └── select2.full.min.js
│ └── xregexp
│ ├── LICENSE.txt
│ ├── xregexp.js
│ └── xregexp.min.js
├── css
├── app.d5578ff9.css
├── chunk-0475a8a9.c54cc8a5.css
├── chunk-1f940af7.6bb20c54.css
├── chunk-50499323.e2ce212c.css
├── chunk-5786617a.310d8994.css
├── chunk-6146664d.d855fcd7.css
├── chunk-714ebfa6.0f43044d.css
└── chunk-libs.3dfb7769.css
├── fonts
├── element-icons.535877f5.woff
└── element-icons.732389de.ttf
├── img
├── 401.089007e7.gif
├── 404.a57b6f31.png
└── 404_cloud.0f4bc32b.png
└── js
├── app.9e7b9244.js
├── chunk-0475a8a9.779a60da.js
├── chunk-1f940af7.6ecba6b3.js
├── chunk-2d2105d3.8eb9d2f2.js
├── chunk-2d230fe7.fcb684d8.js
├── chunk-50499323.0282e3c3.js
├── chunk-5786617a.f4a2e354.js
├── chunk-6146664d.515324ec.js
├── chunk-714ebfa6.57d9f2c9.js
├── chunk-elementUI.c3fe5fec.js
└── chunk-libs.d7c6d8a3.js
/.github/workflows/django.yml:
--------------------------------------------------------------------------------
1 | name: Django CI
2 |
3 | on:
4 | push:
5 | branches: [ "main" ]
6 | pull_request:
7 | branches: [ "main" ]
8 |
9 | jobs:
10 | build:
11 |
12 | runs-on: ubuntu-latest
13 | strategy:
14 | max-parallel: 4
15 | matrix:
16 | python-version: [3.8]
17 |
18 | steps:
19 | - uses: actions/checkout@v3
20 | - name: Set up Python ${{ matrix.python-version }}
21 | uses: actions/setup-python@v3
22 | with:
23 | python-version: ${{ matrix.python-version }}
24 | - name: Install Dependencies
25 | run: |
26 | python -m pip install --upgrade pip
27 | pip install -r requirements.txt
28 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | db.sqlite3
2 | migrations
3 | celerybeat*
4 | .idea
5 | __pycache__
6 | tests.py
7 | Dockerfile
--------------------------------------------------------------------------------
/CloudPanel/__init__.py:
--------------------------------------------------------------------------------
1 | from .celery import app as celery_app
2 |
3 | __all__ = ('celery_app',)
--------------------------------------------------------------------------------
/CloudPanel/asgi.py:
--------------------------------------------------------------------------------
1 | """
2 | ASGI config for CloudPanel project.
3 |
4 | It exposes the ASGI callable as a module-level variable named ``application``.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/3.2/howto/deployment/asgi/
8 | """
9 |
10 | import os
11 |
12 | from django.core.asgi import get_asgi_application
13 |
14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'CloudPanel.settings')
15 |
16 | application = get_asgi_application()
17 |
--------------------------------------------------------------------------------
/CloudPanel/celery.py:
--------------------------------------------------------------------------------
1 | from __future__ import absolute_import
2 | from __future__ import unicode_literals
3 | import os
4 | from celery import Celery
5 | from django.utils import timezone
6 | from kombu import Exchange
7 | from kombu import Queue
8 | import datetime
9 | from celery.schedules import crontab
10 |
11 | # set the default Django settings module for the 'celery' program.
12 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'CloudPanel.settings')
13 | os.environ.setdefault('FORKED_BY_MULTIPROCESSING', '1')
14 | app = Celery("app", backend='redis', broker='redis://127.0.0.1:6379/2')
15 |
16 | # app.now=datetime.datetime.utcnow
17 | # print app.now(), 'celery---------------->>>>>>'
18 |
19 | # Using a string here means the worker doesn't have to serialize
20 | # the configuration object to child processes.
21 | # - namespace='CELERY' means all celery-related configuration keys
22 | # should have a `CELERY_` prefix.
23 | # 在django配置文件中进行配置,以大写CELERY开头
24 | app.config_from_object('django.conf:settings', namespace='celery')
25 | # 解决时区问题,定时任务启动就循环输出
26 | app.now = datetime.datetime.now
27 |
28 | # Load task modules from all registered Django app configs.
29 | # celery自动发现所有django-app下面的任务tasks.py
30 | app.autodiscover_tasks()
31 |
32 | # 通过设置x-max-priority参数来配置队列以支持优先级
33 | # app.conf.task_queues = [
34 | # Queue('tasks', Exchange('tasks'), routing_key='tasks',
35 | # queue_arguments={'x-max-priority': 10}),
36 | # ]
37 |
38 | # 设置所有队列的默认值
39 | app.conf.task_queue_max_priority = 10
40 | CELERYD_MAX_TASKS_PER_CHILD = 5
41 | # 设置了三个Queue绑定到一个direct类型的exchange上,然后consumer监听所有的队列,消息来了后就轮询调用consumer进行处理.
42 | task_exchange = Exchange('tasks', type='direct')
43 | # 异步任务优先级
44 | task_queues = [Queue('hipri', task_exchange, routing_key='hipri'),
45 | Queue('midpri', task_exchange, routing_key='midpri'),
46 | Queue('lopri', task_exchange, routing_key='lopri')]
47 |
48 |
49 | app.conf.beat_schedule = {
50 | # AZURE 每小时 5 分, 自动更新一次订阅
51 | 'updateAzureAccount': {
52 | 'task': 'apps.azure.tasks.beat_update_azure_account',
53 | 'schedule': crontab(minute='05', hour='*'),
54 | 'args': ''
55 | },
56 |
57 | # AZURE 每 5 分, 自动更新一次异常VM
58 | 'updateAzureVM': {
59 | 'task': 'apps.azure.tasks.beat_update_azure_vm',
60 | 'schedule': crontab(minute='*'),
61 | 'args': ''
62 | },
63 | }
--------------------------------------------------------------------------------
/CloudPanel/settings.py:
--------------------------------------------------------------------------------
1 | """
2 | Django settings for CloudPanel project.
3 |
4 | Generated by 'django-admin startproject' using Django 3.2.5.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/3.2/topics/settings/
8 |
9 | For the full list of settings and their values, see
10 | https://docs.djangoproject.com/en/3.2/ref/settings/
11 | """
12 |
13 | from pathlib import Path
14 | import os
15 |
16 | # Build paths inside the project like this: BASE_DIR / 'subdir'.
17 | BASE_DIR = Path(__file__).resolve().parent.parent
18 |
19 |
20 | # Quick-start development settings - unsuitable for production
21 | # See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
22 |
23 | # SECURITY WARNING: keep the secret key used in production secret!
24 | SECRET_KEY = 'django-insecure-s5(icgo^*dlk91xt6_k-y@-)5^9vgjm)jcstt6)^ald^yuwy)w'
25 |
26 | # SECURITY WARNING: don't run with debug turned on in production!
27 | DEBUG = True
28 |
29 | ALLOWED_HOSTS = ['*']
30 |
31 |
32 | # Application definition
33 |
34 | INSTALLED_APPS = [
35 | 'django.contrib.admin',
36 | 'django.contrib.auth',
37 | 'django.contrib.contenttypes',
38 | 'django.contrib.sessions',
39 | 'django.contrib.messages',
40 | 'django.contrib.staticfiles',
41 | 'corsheaders',
42 | 'apps.users',
43 | 'apps.azure'
44 | ]
45 |
46 | MIDDLEWARE = [
47 | 'django.middleware.security.SecurityMiddleware',
48 | 'django.contrib.sessions.middleware.SessionMiddleware',
49 | 'corsheaders.middleware.CorsMiddleware',
50 | 'django.middleware.common.CommonMiddleware',
51 | # 'django.middleware.csrf.CsrfViewMiddleware',
52 | 'django.contrib.auth.middleware.AuthenticationMiddleware',
53 | 'django.contrib.messages.middleware.MessageMiddleware',
54 | 'django.middleware.clickjacking.XFrameOptionsMiddleware',
55 | ]
56 |
57 | # 跨域参数 start
58 | CORS_ALLOW_CREDENTIALS = True
59 | CORS_ORIGIN_ALLOW_ALL = True
60 | CORS_ORIGIN_WHITELIST = ()
61 | CORS_ALLOW_METHODS = (
62 | 'DELETE',
63 | 'GET',
64 | 'OPTIONS',
65 | 'PATCH',
66 | 'POST',
67 | 'PUT',
68 | 'VIEW',
69 | )
70 |
71 | CORS_ALLOW_HEADERS = (
72 | 'XMLHttpRequest',
73 | 'X_FILENAME',
74 | 'accept-encoding',
75 | 'authorization',
76 | 'content-type',
77 | 'dnt',
78 | 'origin',
79 | 'user-agent',
80 | 'x-token',
81 | 'x-csrftoken',
82 | 'x-requested-with',
83 | 'Pragma',
84 | )
85 | # 跨域参数 end
86 |
87 | ROOT_URLCONF = 'CloudPanel.urls'
88 |
89 | TEMPLATES = [
90 | {
91 | 'BACKEND': 'django.template.backends.django.DjangoTemplates',
92 | 'DIRS': [BASE_DIR / 'templates']
93 | ,
94 | 'APP_DIRS': True,
95 | 'OPTIONS': {
96 | 'context_processors': [
97 | 'django.template.context_processors.debug',
98 | 'django.template.context_processors.request',
99 | 'django.contrib.auth.context_processors.auth',
100 | 'django.contrib.messages.context_processors.messages',
101 | ],
102 | },
103 | },
104 | ]
105 |
106 | WSGI_APPLICATION = 'CloudPanel.wsgi.application'
107 |
108 |
109 | # Database
110 | # https://docs.djangoproject.com/en/3.2/ref/settings/#databases
111 |
112 | DATABASES = {
113 | 'default': {
114 | 'ENGINE': 'django.db.backends.sqlite3',
115 | 'NAME': BASE_DIR / 'db.sqlite3',
116 | }
117 | }
118 |
119 | CACHES = {
120 | "default": {
121 | "BACKEND": "django_redis.cache.RedisCache",
122 | "LOCATION": "redis://127.0.0.1:6379/1",
123 | "OPTIONS": {
124 | "CLIENT_CLASS": "django_redis.client.DefaultClient",
125 | }
126 | }
127 | }
128 | SESSION_COOKIE_AGE = 60 * 60 * 24 * 2 # 设置session过期时间为 2 天
129 | SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
130 |
131 | # Password validation
132 | # https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators
133 |
134 | AUTH_PASSWORD_VALIDATORS = [
135 | {
136 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
137 | },
138 | {
139 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
140 | },
141 | {
142 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
143 | },
144 | {
145 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
146 | },
147 | ]
148 |
149 |
150 | # Internationalization
151 | # https://docs.djangoproject.com/en/3.2/topics/i18n/
152 |
153 | LANGUAGE_CODE = 'zh-Hans'
154 |
155 | TIME_ZONE = 'Asia/Shanghai'
156 |
157 | USE_I18N = True
158 |
159 | USE_L10N = True
160 |
161 | USE_TZ = False
162 |
163 |
164 | # Static files (CSS, JavaScript, Images)
165 | # https://docs.djangoproject.com/en/3.2/howto/static-files/
166 |
167 | STATIC_URL = '/static/'
168 | STATIC_ROOT = os.path.join(BASE_DIR, 'static')
169 |
170 | # Default primary key field type
171 | # https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
172 |
173 | DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
174 |
175 |
176 | # CELERY
177 | CELERY_TASK_TRACK_STARTED = True
178 | CELERY_TASK_TIME_LIMIT = 30 * 60
179 | CELERY_TIMEZONE = 'Asia/Shanghai'
180 |
--------------------------------------------------------------------------------
/CloudPanel/urls.py:
--------------------------------------------------------------------------------
1 | """CloudPanel URL Configuration
2 |
3 | The `urlpatterns` list routes URLs to views. For more information please see:
4 | https://docs.djangoproject.com/en/3.2/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: path('', 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: path('', Home.as_view(), name='home')
12 | Including another URLconf
13 | 1. Import the include() function: from django.urls import include, path
14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
15 | """
16 | from django.contrib import admin
17 | from django.urls import path, include
18 |
19 | urlpatterns = [
20 | path('api/admin/', admin.site.urls),
21 | path('api/passport/', include('apps.users.urls')),
22 | path('api/azure/', include('apps.azure.urls')),
23 | ]
24 |
--------------------------------------------------------------------------------
/CloudPanel/wsgi.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for CloudPanel 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/3.2/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', 'CloudPanel.settings')
15 |
16 | application = get_wsgi_application()
17 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # cloudpanel
--------------------------------------------------------------------------------
/apps/azure/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdntip/cloudpanel/a093fd3d4b3c5ed9fbca72a8ca4080d412691976/apps/azure/__init__.py
--------------------------------------------------------------------------------
/apps/azure/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 |
3 | # Register your models here.
4 | # Register your models here.
5 | from apps.azure.models import Account, Vm, Images
6 |
7 | @admin.register(Account)
8 | class AccountAdmin(admin.ModelAdmin):
9 | search_fields = ['tenant_id', 'password', 'client_id', 'subscription_id']
10 |
11 | list_filter = ('status',)
12 | list_display = ('id', 'display_name', 'email', 'status', 'subscription_id', 'note', 'create_time', 'update_time')
13 |
14 | @admin.register(Vm)
15 | class VmAdmin(admin.ModelAdmin):
16 |
17 | search_fields = ('name', 'vm_id', 'ip', 'vm_size', 'image', 'os_disk', )
18 | list_filter = ('status',)
19 | list_display = ('id', 'name', 'vm_id', 'ip', 'status', 'vm_size', 'image', 'os_disk', 'create_time', 'update_time')
20 |
21 | @admin.register(Images)
22 | class ImagesAdmin(admin.ModelAdmin):
23 | search_fields = ('name', 'value', )
24 | list_filter = ('status', )
25 |
26 | list_display = ('id', 'name', 'value', 'status', 'create_time', 'update_time')
--------------------------------------------------------------------------------
/apps/azure/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class AzureConfig(AppConfig):
5 | name = 'apps.azure'
6 |
--------------------------------------------------------------------------------
/apps/azure/forms.py:
--------------------------------------------------------------------------------
1 | from django import forms
2 |
3 | from apps.azure import models
4 |
5 |
6 | class AccountForm(forms.Form):
7 | id = forms.IntegerField(required=False)
8 | email = forms.CharField(max_length=255)
9 | app_id = forms.CharField(max_length=255)
10 | password = forms.CharField(max_length=255)
11 | login_password = forms.CharField(max_length=255, required=False)
12 | tenant_id = forms.CharField(max_length=255)
13 | note = forms.CharField(max_length=255, required=False)
14 |
15 | def clean_id(self):
16 | try:
17 | id = self.cleaned_data.get('id', False)
18 | if not id: return False
19 | nodeInfo = models.Account.objects.filter(id=id).first()
20 | if not nodeInfo:
21 | raise forms.ValidationError(message='账号不存在')
22 | return nodeInfo
23 | except:
24 | return False
25 |
26 |
27 |
--------------------------------------------------------------------------------
/apps/azure/management/commands/az_update.py:
--------------------------------------------------------------------------------
1 | from django.core.management.base import BaseCommand
2 | from django.core.management import execute_from_command_line
3 | from django.conf import settings
4 |
5 | from apps.azure.models import Account, Vm
6 | import time
7 |
8 | class Command(BaseCommand):
9 | help = '更新全部azure账号信息'
10 |
11 | def handle(self, *args, **options):
12 | for _account in Account.objects.filter(status__in=['Enabled', 'Warned']):
13 | _account.update_subscriptions()
14 | _account.update_vm_list()
15 |
16 | for _vm in Vm.objects.filter():
17 | _vm.update_public_ip()
18 | _vm.update_vm_info()
--------------------------------------------------------------------------------
/apps/azure/management/commands/init_az_images.py:
--------------------------------------------------------------------------------
1 | from django.core.management.base import BaseCommand
2 | from django.core.management import execute_from_command_line
3 | from django.conf import settings
4 |
5 | from apps.azure.models import Images
6 |
7 | class Command(BaseCommand):
8 | help = '更新全部azure镜像地址'
9 |
10 | def handle(self, *args, **options):
11 | images = {
12 | 'OpenLogic:CentOS:7.5:latest': 'CentOS 7.5',
13 | 'OpenLogic:CentOS:7_9:latest': 'CentOS 7.9',
14 | 'Canonical:UbuntuServer:18.04-LTS:latest': 'Ubuntu 18.04',
15 | 'canonical:0001-com-ubuntu-server-focal:20_04-lts-gen2:latest': 'Ubuntu 20.04',
16 | 'Debian:debian-10:10:latest': 'Debian 10',
17 | 'MicrosoftWindowsServer:WindowsServer:2012-Datacenter-zhcn:latest': 'Windows 2012 DC CN',
18 | 'MicrosoftWindowsServer:WindowsServer:2016-Datacenter-zhcn:latest': 'Windows 2016 DC CN',
19 | 'MicrosoftWindowsServer:WindowsServer:2019-Datacenter-smalldisk:latest': 'Windows 2019 DC',
20 | 'MicrosoftWindowsDesktop:Windows-10:21h1-pro:latest ': 'Windows 10 PRO',
21 | }
22 | for k, v in images.items():
23 | # print(k, v)
24 | if Images.objects.filter(value=k).first(): continue
25 |
26 | Images.objects.create(name=v, value=k)
27 | continue
--------------------------------------------------------------------------------
/apps/azure/tasks.py:
--------------------------------------------------------------------------------
1 | from django.db.models import Q
2 |
3 | from celery import shared_task
4 |
5 | from apps.azure import models
6 |
7 | # 更新账号
8 | @shared_task()
9 | def task_update_az(account_id):
10 | account_info = models.Account.objects.filter(id=account_id).first()
11 |
12 | if not account_info:
13 | return '账号不存在', False
14 |
15 | account_info.update_subscriptions()
16 | account_info.update_vm_list()
17 |
18 | for _vm in models.Vm.objects.filter(account_id=account_info.id):
19 | _vm.update_public_ip()
20 | _vm.update_vm_info()
21 | return '更新完成', True
22 |
23 | # 更新虚拟机
24 | @shared_task()
25 | def update_azure_vm(vm_id):
26 | try:
27 | vm_info = models.Vm.objects.filter(id=vm_id).first()
28 | if not vm_info:
29 | return 'VM 实例不存在', False
30 | vm_info.update_public_ip()
31 | vm_info.update_vm_info()
32 | return '更新完成', True
33 | except:
34 | return '更新失败', False
35 |
36 | # 更新全部账号的订阅
37 | @shared_task()
38 | def beat_update_azure_account():
39 | account_list = models.Account.objects.filter(status__in=['Enabled', 'Warned'])
40 | print(f'需要更新的账号数量为 {account_list.count()}')
41 | for foo in account_list:
42 | task_update_az.delay(foo.id)
43 | return True
44 |
45 | # 更新全部需要更新的VM
46 | @shared_task()
47 | def beat_update_azure_vm():
48 | q = Q(ip='')
49 | q.add(~Q(status='running'), Q.OR)
50 | data_list = models.Vm.objects.filter(q)
51 | print(f'需要更新的VM数量为 {data_list.count()}')
52 | for foo in data_list:
53 | update_azure_vm.delay(foo.id)
54 | return True
--------------------------------------------------------------------------------
/apps/azure/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 | from apps.azure import views
3 | from apps.users.views import is_token
4 |
5 | urlpatterns = [
6 | # aws 账号
7 | path('account', is_token(views.AzureAccountView.as_view()), name="AzureAccountView"),
8 | path('account/delete', is_token(views.AzureAccountDeleteView.as_view()), name="AzureAccountDeleteView"),
9 | path('vm', is_token(views.AzureVmListView.as_view()), name="AzureVmListView"),
10 | path('vm/action', is_token(views.AzureVmActionView.as_view()), name="AzureVmActionView"),
11 | path('vm/create', is_token(views.AzureVmCreateView.as_view()), name="AzureVmCreateView"),
12 | ]
13 |
--------------------------------------------------------------------------------
/apps/users/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdntip/cloudpanel/a093fd3d4b3c5ed9fbca72a8ca4080d412691976/apps/users/__init__.py
--------------------------------------------------------------------------------
/apps/users/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 |
3 | # Register your models here.
4 |
--------------------------------------------------------------------------------
/apps/users/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class UserConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'apps.users'
7 |
--------------------------------------------------------------------------------
/apps/users/forms.py:
--------------------------------------------------------------------------------
1 | from django import forms
2 | from django.contrib.auth.models import User
3 |
4 | # 登录
5 | class Login(forms.Form):
6 | username = forms.CharField(max_length=32, min_length=3, error_messages={'required': '账号不能为空', 'max_length': '账号最大长度为32位', 'min_length': '账号最小长度为4位'})
7 | password = forms.CharField(max_length=32, min_length=3, error_messages={'required': '密码不能为空', 'max_length': '密码最大长度为32位', 'min_length': '密码最小长度为4位'})
8 | code = forms.CharField(required=False, max_length=4, error_messages={'required': '验证码错误', 'max_length': '验证码错误'})
9 |
10 | # 判断账号是否存在
11 | def clean_username(self):
12 | username = self.cleaned_data.get('username').strip().lower()
13 | user_info = User.objects.filter(username=username).first()
14 | if not user_info:
15 | raise forms.ValidationError(message='该 %s 用户不存在' % username)
16 | self.cleaned_data.update({
17 | 'user_info': user_info
18 | })
19 | return username
20 |
21 | # 处理密码
22 | def clean_password(self):
23 | password = self.cleaned_data.get('password').strip()
24 | return password
25 |
--------------------------------------------------------------------------------
/apps/users/management/commands/init_db.py:
--------------------------------------------------------------------------------
1 | from django.core.management.base import BaseCommand
2 | from django.core.management import execute_from_command_line
3 | from django.conf import settings
4 |
5 | class Command(BaseCommand):
6 | help = '初始化/更新数据库'
7 |
8 | def handle(self, *args, **options):
9 | args = ['manage.py', 'makemigrations']
10 | apps = [x.split('.')[-1] for x in settings.INSTALLED_APPS if x.startswith('apps.')]
11 | execute_from_command_line(args + apps)
12 | execute_from_command_line(['manage.py', 'migrate'])
13 | self.stdout.write(self.style.SUCCESS(' 初始化/更新成功'))
--------------------------------------------------------------------------------
/apps/users/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 |
3 | # Create your models here.
4 |
--------------------------------------------------------------------------------
/apps/users/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 | from apps.users import views
3 |
4 | urlpatterns = [
5 | path('login', views.Login, name="UserLogin"),
6 | path('info', views.Info, name="UserInfo"),
7 | ]
8 |
--------------------------------------------------------------------------------
/apps/users/views.py:
--------------------------------------------------------------------------------
1 | from django.http import JsonResponse
2 | from django.core.cache import cache
3 |
4 | from django.contrib.auth.models import User
5 | from django.contrib.auth import authenticate
6 | from apps.users import forms
7 |
8 | # Create your views here.
9 | import time
10 |
11 | from libs.utils import md5
12 | # 判断是否登录
13 | def is_token(func):
14 | def inner(request, *args, **kwargs):
15 | token = request.META.get('HTTP_X_TOKEN', False)
16 | if not token:
17 | return JsonResponse({'code': 50008, 'message': '登录会话失效,请重新的登录'})
18 |
19 | user = cache.get(token, False)
20 | if not user or not user.is_active or not user.is_superuser:
21 | return JsonResponse({'code': 50008, 'message': '登录会话失效,请重新的登录'})
22 | request.user = user
23 | return func(request, *args, **kwargs)
24 | return inner
25 |
26 |
27 | # 登录
28 | def Login(request):
29 | if request.method == "POST":
30 | input_data = forms.Login(request.POST)
31 | if input_data.is_valid():
32 | data = input_data.clean()
33 | user_info = data.get('user_info')
34 | username = data.get('username')
35 | password = data.get('password')
36 |
37 | if not user_info.is_active:
38 | return JsonResponse({'code': 20002, 'message': '该用户禁止登录'})
39 |
40 | user = authenticate(username=username, password=password)
41 |
42 | if not user: return JsonResponse({'code': 20002, 'message': '登录密码错误'})
43 |
44 | token = md5("%s%s" %(user.username, time.time())).upper()
45 | cache.set(token, user, 172800)
46 | res_data = {'code': 20000, 'message': '登录成功', 'data': {'token': token}}
47 | return JsonResponse(res_data)
48 | return JsonResponse({'code': 20001, 'message': '登录失败', 'error_data': input_data.errors})
49 |
50 | # 获取用户信息
51 | @is_token
52 | def Info(request):
53 | userinfo = User.objects.filter(username=request.user.username).first()
54 | if not userinfo:
55 | return JsonResponse({'code': 50008, 'message': '用户信息不存在,请重新登录'})
56 | data = {
57 | 'avatar': 'https://t1.picb.cc/uploads/2021/10/05/wXMX1y.th.jpg',
58 | 'name': userinfo.username,
59 | 'username': userinfo.username,
60 | 'create_time': userinfo.date_joined.strftime("%Y-%m-%d %H:%M:%S"),
61 | 'roles': ['user']
62 | }
63 | if userinfo.is_superuser:
64 | # 管理员
65 | data.update({'roles': ['admin'], 'introduction': '.'})
66 |
67 | return JsonResponse({'code': 20000, 'message': '获取成功', 'data': data})
68 |
69 | # 退出
70 | def Logout(request):
71 | cache.set(request.token, '', 0)
72 | return JsonResponse({'code': 20000, 'data': 'success'})
--------------------------------------------------------------------------------
/config/nginx.conf:
--------------------------------------------------------------------------------
1 | worker_processes auto;
2 | events {
3 | worker_connections 51200;
4 | }
5 | http {
6 | include mime.types;
7 | default_type application/octet-stream;
8 | sendfile on;
9 | keepalive_timeout 65;
10 | server {
11 | listen 80;
12 | server_name localhost;
13 | root /home/python/cloudpanel/web;
14 | index index.html;
15 | location /api {
16 | proxy_set_header Accept-Encoding '';
17 | proxy_set_header Host $http_host;
18 | proxy_set_header Referer $http_referer;
19 | proxy_set_header X-Real-IP $remote_addr;
20 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
21 | proxy_set_header X-Forwarded-Proto $scheme;
22 | proxy_pass http://127.0.0.1:887;
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | /etc/init.d/redis-server start
4 | /etc/init.d/nginx start
5 | /etc/init.d/supervisor start
6 |
7 | tail -F /home/python/cloudpanel/django.log
--------------------------------------------------------------------------------
/libs/utils.py:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | # 分页
5 | def Pagination(page, limit, dataLen=999):
6 | if page == 1 or page == 0:
7 | return 0, limit
8 | a = int(limit) * int(page)
9 | if dataLen < int(limit):
10 | return 0, a
11 | return a - int(limit), a
12 |
13 |
14 | def DateTimeToStr(_datetime):
15 | try:
16 | return _datetime.strftime("%Y-%m-%d %H:%M:%S")
17 | except:
18 | return str(_datetime)
19 |
20 | def is_ipv4(ip: str) -> bool:
21 | return True if [1] * 4 == [x.isdigit() and 0 <= int(x) <= 255 for x in ip.split(".")] else False
22 |
23 |
24 | def md5(str):
25 | import hashlib
26 | m2 = hashlib.md5()
27 | m2.update(str.encode("utf-8"))
28 | return m2.hexdigest()
29 |
30 |
31 | def traffic_format(traffic):
32 | if traffic < 1024 * 8:
33 | return str(int(traffic)) + "B"
34 |
35 | if traffic < 1024 * 1024:
36 | return str(round((traffic / 1024.0), 1)) + "KB"
37 |
38 | if traffic < 1024 * 1024 * 1024:
39 | return str(round((traffic / (1024.0 * 1024)), 1)) + "MB"
40 |
41 | if traffic < 1024 * 1024 * 1024 * 1024 * 1024:
42 | return str(round((traffic / (1024.0 * 1024 * 1024 * 1024)), 1)) + "PB"
43 |
44 | return str(round((traffic / 1073741824.0), 1)) + "GB"
45 |
46 | if __name__ == '__main__':
47 | print('Hello CDNTIP')
--------------------------------------------------------------------------------
/manage.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | """Django's command-line utility for administrative tasks."""
3 | import os
4 | import sys
5 |
6 |
7 | def main():
8 | """Run administrative tasks."""
9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'CloudPanel.settings')
10 | try:
11 | from django.core.management import execute_from_command_line
12 | except ImportError as exc:
13 | raise ImportError(
14 | "Couldn't import Django. Are you sure it's installed and "
15 | "available on your PYTHONPATH environment variable? Did you "
16 | "forget to activate a virtual environment?"
17 | ) from exc
18 | execute_from_command_line(sys.argv)
19 |
20 |
21 | if __name__ == '__main__':
22 | main()
23 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdntip/cloudpanel/a093fd3d4b3c5ed9fbca72a8ca4080d412691976/requirements.txt
--------------------------------------------------------------------------------
/scripts/celery-beat.conf:
--------------------------------------------------------------------------------
1 | [program:celery-beat]
2 | process_name=%(program_name)s_%(process_num)02d
3 | command=celery -A CloudPanel beat -l info
4 | directory=/home/python/cloudpanel/
5 | autostart=true
6 | autorestart=true
7 | user=root
8 | redirect_stderr=true
9 | stdout_logfile=/home/python/cloudpanel/beat.log
--------------------------------------------------------------------------------
/scripts/celery-worker.conf:
--------------------------------------------------------------------------------
1 | [program:celery-worker]
2 | process_name=%(program_name)s_%(process_num)02d
3 | command=celery -A CloudPanel worker -l info
4 | directory=/home/python/cloudpanel/
5 | autostart=true
6 | autorestart=true
7 | user=root
8 | redirect_stderr=true
9 | stdout_logfile=/home/python/cloudpanel/worker.log
--------------------------------------------------------------------------------
/scripts/django.conf:
--------------------------------------------------------------------------------
1 | [program:django]
2 | process_name=%(program_name)s_%(process_num)02d
3 | command=python3 manage.py runserver 0.0.0.0:887
4 | directory=/home/python/cloudpanel/
5 | autostart=true
6 | autorestart=true
7 | user=root
8 | redirect_stderr=true
9 | stdout_logfile=/home/python/cloudpanel/django.log
--------------------------------------------------------------------------------
/web/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdntip/cloudpanel/a093fd3d4b3c5ed9fbca72a8ca4080d412691976/web/favicon.ico
--------------------------------------------------------------------------------
/web/index.html:
--------------------------------------------------------------------------------
1 |
Cloud Panel - CDNTIP
--------------------------------------------------------------------------------
/web/static/admin/css/changelists.css:
--------------------------------------------------------------------------------
1 | /* CHANGELISTS */
2 |
3 | #changelist {
4 | display: flex;
5 | align-items: flex-start;
6 | justify-content: space-between;
7 | }
8 |
9 | #changelist .changelist-form-container {
10 | flex: 1 1 auto;
11 | min-width: 0;
12 | }
13 |
14 | #changelist table {
15 | width: 100%;
16 | }
17 |
18 | .change-list .hiddenfields { display:none; }
19 |
20 | .change-list .filtered table {
21 | border-right: none;
22 | }
23 |
24 | .change-list .filtered {
25 | min-height: 400px;
26 | }
27 |
28 | .change-list .filtered .results, .change-list .filtered .paginator,
29 | .filtered #toolbar, .filtered div.xfull {
30 | width: auto;
31 | }
32 |
33 | .change-list .filtered table tbody th {
34 | padding-right: 1em;
35 | }
36 |
37 | #changelist-form .results {
38 | overflow-x: auto;
39 | width: 100%;
40 | }
41 |
42 | #changelist .toplinks {
43 | border-bottom: 1px solid var(--hairline-color);
44 | }
45 |
46 | #changelist .paginator {
47 | color: var(--body-quiet-color);
48 | border-bottom: 1px solid var(--hairline-color);
49 | background: var(--body-bg);
50 | overflow: hidden;
51 | }
52 |
53 | /* CHANGELIST TABLES */
54 |
55 | #changelist table thead th {
56 | padding: 0;
57 | white-space: nowrap;
58 | vertical-align: middle;
59 | }
60 |
61 | #changelist table thead th.action-checkbox-column {
62 | width: 1.5em;
63 | text-align: center;
64 | }
65 |
66 | #changelist table tbody td.action-checkbox {
67 | text-align: center;
68 | }
69 |
70 | #changelist table tfoot {
71 | color: var(--body-quiet-color);
72 | }
73 |
74 | /* TOOLBAR */
75 |
76 | #toolbar {
77 | padding: 8px 10px;
78 | margin-bottom: 15px;
79 | border-top: 1px solid var(--hairline-color);
80 | border-bottom: 1px solid var(--hairline-color);
81 | background: var(--darkened-bg);
82 | color: var(--body-quiet-color);
83 | }
84 |
85 | #toolbar form input {
86 | border-radius: 4px;
87 | font-size: 14px;
88 | padding: 5px;
89 | color: var(--body-fg);
90 | }
91 |
92 | #toolbar #searchbar {
93 | height: 19px;
94 | border: 1px solid var(--border-color);
95 | padding: 2px 5px;
96 | margin: 0;
97 | vertical-align: top;
98 | font-size: 13px;
99 | max-width: 100%;
100 | }
101 |
102 | #toolbar #searchbar:focus {
103 | border-color: var(--body-quiet-color);
104 | }
105 |
106 | #toolbar form input[type="submit"] {
107 | border: 1px solid var(--border-color);
108 | font-size: 13px;
109 | padding: 4px 8px;
110 | margin: 0;
111 | vertical-align: middle;
112 | background: var(--body-bg);
113 | box-shadow: 0 -15px 20px -10px rgba(0, 0, 0, 0.15) inset;
114 | cursor: pointer;
115 | color: var(--body-fg);
116 | }
117 |
118 | #toolbar form input[type="submit"]:focus,
119 | #toolbar form input[type="submit"]:hover {
120 | border-color: var(--body-quiet-color);
121 | }
122 |
123 | #changelist-search img {
124 | vertical-align: middle;
125 | margin-right: 4px;
126 | }
127 |
128 | /* FILTER COLUMN */
129 |
130 | #changelist-filter {
131 | flex: 0 0 240px;
132 | order: 1;
133 | background: var(--darkened-bg);
134 | border-left: none;
135 | margin: 0 0 0 30px;
136 | }
137 |
138 | #changelist-filter h2 {
139 | font-size: 14px;
140 | text-transform: uppercase;
141 | letter-spacing: 0.5px;
142 | padding: 5px 15px;
143 | margin-bottom: 12px;
144 | border-bottom: none;
145 | }
146 |
147 | #changelist-filter h3 {
148 | font-weight: 400;
149 | padding: 0 15px;
150 | margin-bottom: 10px;
151 | }
152 |
153 | #changelist-filter ul {
154 | margin: 5px 0;
155 | padding: 0 15px 15px;
156 | border-bottom: 1px solid var(--hairline-color);
157 | }
158 |
159 | #changelist-filter ul:last-child {
160 | border-bottom: none;
161 | }
162 |
163 | #changelist-filter li {
164 | list-style-type: none;
165 | margin-left: 0;
166 | padding-left: 0;
167 | }
168 |
169 | #changelist-filter a {
170 | display: block;
171 | color: var(--body-quiet-color);
172 | text-overflow: ellipsis;
173 | overflow-x: hidden;
174 | }
175 |
176 | #changelist-filter li.selected {
177 | border-left: 5px solid var(--hairline-color);
178 | padding-left: 10px;
179 | margin-left: -15px;
180 | }
181 |
182 | #changelist-filter li.selected a {
183 | color: var(--link-selected-fg);
184 | }
185 |
186 | #changelist-filter a:focus, #changelist-filter a:hover,
187 | #changelist-filter li.selected a:focus,
188 | #changelist-filter li.selected a:hover {
189 | color: var(--link-hover-color);
190 | }
191 |
192 | #changelist-filter #changelist-filter-clear a {
193 | font-size: 13px;
194 | padding-bottom: 10px;
195 | border-bottom: 1px solid var(--hairline-color);
196 | }
197 |
198 | /* DATE DRILLDOWN */
199 |
200 | .change-list ul.toplinks {
201 | display: block;
202 | float: left;
203 | padding: 0;
204 | margin: 0;
205 | width: 100%;
206 | }
207 |
208 | .change-list ul.toplinks li {
209 | padding: 3px 6px;
210 | font-weight: bold;
211 | list-style-type: none;
212 | display: inline-block;
213 | }
214 |
215 | .change-list ul.toplinks .date-back a {
216 | color: var(--body-quiet-color);
217 | }
218 |
219 | .change-list ul.toplinks .date-back a:focus,
220 | .change-list ul.toplinks .date-back a:hover {
221 | color: var(--link-hover-color);
222 | }
223 |
224 | /* PAGINATOR */
225 |
226 | .paginator {
227 | font-size: 13px;
228 | padding-top: 10px;
229 | padding-bottom: 10px;
230 | line-height: 22px;
231 | margin: 0;
232 | border-top: 1px solid var(--hairline-color);
233 | width: 100%;
234 | }
235 |
236 | .paginator a:link, .paginator a:visited {
237 | padding: 2px 6px;
238 | background: var(--button-bg);
239 | text-decoration: none;
240 | color: var(--button-fg);
241 | }
242 |
243 | .paginator a.showall {
244 | border: none;
245 | background: none;
246 | color: var(--link-fg);
247 | }
248 |
249 | .paginator a.showall:focus, .paginator a.showall:hover {
250 | background: none;
251 | color: var(--link-hover-color);
252 | }
253 |
254 | .paginator .end {
255 | margin-right: 6px;
256 | }
257 |
258 | .paginator .this-page {
259 | padding: 2px 6px;
260 | font-weight: bold;
261 | font-size: 13px;
262 | vertical-align: top;
263 | }
264 |
265 | .paginator a:focus, .paginator a:hover {
266 | color: white;
267 | background: var(--link-hover-color);
268 | }
269 |
270 | /* ACTIONS */
271 |
272 | .filtered .actions {
273 | border-right: none;
274 | }
275 |
276 | #changelist table input {
277 | margin: 0;
278 | vertical-align: baseline;
279 | }
280 |
281 | #changelist table tbody tr.selected {
282 | background-color: var(--selected-row);
283 | }
284 |
285 | #changelist .actions {
286 | padding: 10px;
287 | background: var(--body-bg);
288 | border-top: none;
289 | border-bottom: none;
290 | line-height: 24px;
291 | color: var(--body-quiet-color);
292 | width: 100%;
293 | }
294 |
295 | #changelist .actions.selected { /* XXX Probably unused? */
296 | background: var(--body-bg);
297 | border-top: 1px solid var(--body-bg);
298 | border-bottom: 1px solid #edecd6;
299 | }
300 |
301 | #changelist .actions span.all,
302 | #changelist .actions span.action-counter,
303 | #changelist .actions span.clear,
304 | #changelist .actions span.question {
305 | font-size: 13px;
306 | margin: 0 0.5em;
307 | }
308 |
309 | #changelist .actions:last-child {
310 | border-bottom: none;
311 | }
312 |
313 | #changelist .actions select {
314 | vertical-align: top;
315 | height: 24px;
316 | color: var(--body-fg);
317 | border: 1px solid var(--border-color);
318 | border-radius: 4px;
319 | font-size: 14px;
320 | padding: 0 0 0 4px;
321 | margin: 0;
322 | margin-left: 10px;
323 | }
324 |
325 | #changelist .actions select:focus {
326 | border-color: var(--body-quiet-color);
327 | }
328 |
329 | #changelist .actions label {
330 | display: inline-block;
331 | vertical-align: middle;
332 | font-size: 13px;
333 | }
334 |
335 | #changelist .actions .button {
336 | font-size: 13px;
337 | border: 1px solid var(--border-color);
338 | border-radius: 4px;
339 | background: var(--body-bg);
340 | box-shadow: 0 -15px 20px -10px rgba(0, 0, 0, 0.15) inset;
341 | cursor: pointer;
342 | height: 24px;
343 | line-height: 1;
344 | padding: 4px 8px;
345 | margin: 0;
346 | color: var(--body-fg);
347 | }
348 |
349 | #changelist .actions .button:focus, #changelist .actions .button:hover {
350 | border-color: var(--body-quiet-color);
351 | }
352 |
--------------------------------------------------------------------------------
/web/static/admin/css/dashboard.css:
--------------------------------------------------------------------------------
1 | /* DASHBOARD */
2 |
3 | .dashboard .module table th {
4 | width: 100%;
5 | }
6 |
7 | .dashboard .module table td {
8 | white-space: nowrap;
9 | }
10 |
11 | .dashboard .module table td a {
12 | display: block;
13 | padding-right: .6em;
14 | }
15 |
16 | /* RECENT ACTIONS MODULE */
17 |
18 | .module ul.actionlist {
19 | margin-left: 0;
20 | }
21 |
22 | ul.actionlist li {
23 | list-style-type: none;
24 | overflow: hidden;
25 | text-overflow: ellipsis;
26 | }
27 |
--------------------------------------------------------------------------------
/web/static/admin/css/fonts.css:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: 'Roboto';
3 | src: url('../fonts/Roboto-Bold-webfont.woff');
4 | font-weight: 700;
5 | font-style: normal;
6 | }
7 |
8 | @font-face {
9 | font-family: 'Roboto';
10 | src: url('../fonts/Roboto-Regular-webfont.woff');
11 | font-weight: 400;
12 | font-style: normal;
13 | }
14 |
15 | @font-face {
16 | font-family: 'Roboto';
17 | src: url('../fonts/Roboto-Light-webfont.woff');
18 | font-weight: 300;
19 | font-style: normal;
20 | }
21 |
--------------------------------------------------------------------------------
/web/static/admin/css/login.css:
--------------------------------------------------------------------------------
1 | /* LOGIN FORM */
2 |
3 | .login {
4 | background: var(--darkened-bg);
5 | height: auto;
6 | }
7 |
8 | .login #header {
9 | height: auto;
10 | padding: 15px 16px;
11 | justify-content: center;
12 | }
13 |
14 | .login #header h1 {
15 | font-size: 18px;
16 | }
17 |
18 | .login #header h1 a {
19 | color: var(--header-link-color);
20 | }
21 |
22 | .login #content {
23 | padding: 20px 20px 0;
24 | }
25 |
26 | .login #container {
27 | background: var(--body-bg);
28 | border: 1px solid var(--hairline-color);
29 | border-radius: 4px;
30 | overflow: hidden;
31 | width: 28em;
32 | min-width: 300px;
33 | margin: 100px auto;
34 | height: auto;
35 | }
36 |
37 | .login .form-row {
38 | padding: 4px 0;
39 | }
40 |
41 | .login .form-row label {
42 | display: block;
43 | line-height: 2em;
44 | }
45 |
46 | .login .form-row #id_username, .login .form-row #id_password {
47 | padding: 8px;
48 | width: 100%;
49 | box-sizing: border-box;
50 | }
51 |
52 | .login .submit-row {
53 | padding: 1em 0 0 0;
54 | margin: 0;
55 | text-align: center;
56 | }
57 |
58 | .login .password-reset-link {
59 | text-align: center;
60 | }
61 |
--------------------------------------------------------------------------------
/web/static/admin/css/nav_sidebar.css:
--------------------------------------------------------------------------------
1 | .sticky {
2 | position: sticky;
3 | top: 0;
4 | max-height: 100vh;
5 | }
6 |
7 | .toggle-nav-sidebar {
8 | z-index: 20;
9 | left: 0;
10 | display: flex;
11 | align-items: center;
12 | justify-content: center;
13 | flex: 0 0 23px;
14 | width: 23px;
15 | border: 0;
16 | border-right: 1px solid var(--hairline-color);
17 | background-color: var(--body-bg);
18 | cursor: pointer;
19 | font-size: 20px;
20 | color: var(--link-fg);
21 | padding: 0;
22 | }
23 |
24 | [dir="rtl"] .toggle-nav-sidebar {
25 | border-left: 1px solid var(--hairline-color);
26 | border-right: 0;
27 | }
28 |
29 | .toggle-nav-sidebar:hover,
30 | .toggle-nav-sidebar:focus {
31 | background-color: var(--darkened-bg);
32 | }
33 |
34 | #nav-sidebar {
35 | z-index: 15;
36 | flex: 0 0 275px;
37 | left: -276px;
38 | margin-left: -276px;
39 | border-top: 1px solid transparent;
40 | border-right: 1px solid var(--hairline-color);
41 | background-color: var(--body-bg);
42 | overflow: auto;
43 | }
44 |
45 | [dir="rtl"] #nav-sidebar {
46 | border-left: 1px solid var(--hairline-color);
47 | border-right: 0;
48 | left: 0;
49 | margin-left: 0;
50 | right: -276px;
51 | margin-right: -276px;
52 | }
53 |
54 | .toggle-nav-sidebar::before {
55 | content: '\00BB';
56 | }
57 |
58 | .main.shifted .toggle-nav-sidebar::before {
59 | content: '\00AB';
60 | }
61 |
62 | .main.shifted > #nav-sidebar {
63 | left: 24px;
64 | margin-left: 0;
65 | }
66 |
67 | [dir="rtl"] .main.shifted > #nav-sidebar {
68 | left: 0;
69 | right: 24px;
70 | margin-right: 0;
71 | }
72 |
73 | #nav-sidebar .module th {
74 | width: 100%;
75 | overflow-wrap: anywhere;
76 | }
77 |
78 | #nav-sidebar .module th,
79 | #nav-sidebar .module caption {
80 | padding-left: 16px;
81 | }
82 |
83 | #nav-sidebar .module td {
84 | white-space: nowrap;
85 | }
86 |
87 | [dir="rtl"] #nav-sidebar .module th,
88 | [dir="rtl"] #nav-sidebar .module caption {
89 | padding-left: 8px;
90 | padding-right: 16px;
91 | }
92 |
93 | #nav-sidebar .current-app .section:link,
94 | #nav-sidebar .current-app .section:visited {
95 | color: var(--header-color);
96 | font-weight: bold;
97 | }
98 |
99 | #nav-sidebar .current-model {
100 | background: var(--selected-row);
101 | }
102 |
103 | .main > #nav-sidebar + .content {
104 | max-width: calc(100% - 23px);
105 | }
106 |
107 | .main.shifted > #nav-sidebar + .content {
108 | max-width: calc(100% - 299px);
109 | }
110 |
111 | @media (max-width: 767px) {
112 | #nav-sidebar, #toggle-nav-sidebar {
113 | display: none;
114 | }
115 |
116 | .main > #nav-sidebar + .content,
117 | .main.shifted > #nav-sidebar + .content {
118 | max-width: 100%;
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/web/static/admin/css/responsive_rtl.css:
--------------------------------------------------------------------------------
1 | /* TABLETS */
2 |
3 | @media (max-width: 1024px) {
4 | [dir="rtl"] .colMS {
5 | margin-right: 0;
6 | }
7 |
8 | [dir="rtl"] #user-tools {
9 | text-align: right;
10 | }
11 |
12 | [dir="rtl"] #changelist .actions label {
13 | padding-left: 10px;
14 | padding-right: 0;
15 | }
16 |
17 | [dir="rtl"] #changelist .actions select {
18 | margin-left: 0;
19 | margin-right: 15px;
20 | }
21 |
22 | [dir="rtl"] .change-list .filtered .results,
23 | [dir="rtl"] .change-list .filtered .paginator,
24 | [dir="rtl"] .filtered #toolbar,
25 | [dir="rtl"] .filtered div.xfull,
26 | [dir="rtl"] .filtered .actions,
27 | [dir="rtl"] #changelist-filter {
28 | margin-left: 0;
29 | }
30 |
31 | [dir="rtl"] .inline-group ul.tools a.add,
32 | [dir="rtl"] .inline-group div.add-row a,
33 | [dir="rtl"] .inline-group .tabular tr.add-row td a {
34 | padding: 8px 26px 8px 10px;
35 | background-position: calc(100% - 8px) 9px;
36 | }
37 |
38 | [dir="rtl"] .related-widget-wrapper-link + .selector {
39 | margin-right: 0;
40 | margin-left: 15px;
41 | }
42 |
43 | [dir="rtl"] .selector .selector-filter label {
44 | margin-right: 0;
45 | margin-left: 8px;
46 | }
47 |
48 | [dir="rtl"] .object-tools li {
49 | float: right;
50 | }
51 |
52 | [dir="rtl"] .object-tools li + li {
53 | margin-left: 0;
54 | margin-right: 15px;
55 | }
56 |
57 | [dir="rtl"] .dashboard .module table td a {
58 | padding-left: 0;
59 | padding-right: 16px;
60 | }
61 | }
62 |
63 | /* MOBILE */
64 |
65 | @media (max-width: 767px) {
66 | [dir="rtl"] .aligned .related-lookup,
67 | [dir="rtl"] .aligned .datetimeshortcuts {
68 | margin-left: 0;
69 | margin-right: 15px;
70 | }
71 |
72 | [dir="rtl"] .aligned ul {
73 | margin-right: 0;
74 | }
75 |
76 | [dir="rtl"] #changelist-filter {
77 | margin-left: 0;
78 | margin-right: 0;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/web/static/admin/css/rtl.css:
--------------------------------------------------------------------------------
1 | /* GLOBAL */
2 |
3 | th {
4 | text-align: right;
5 | }
6 |
7 | .module h2, .module caption {
8 | text-align: right;
9 | }
10 |
11 | .module ul, .module ol {
12 | margin-left: 0;
13 | margin-right: 1.5em;
14 | }
15 |
16 | .viewlink, .addlink, .changelink {
17 | padding-left: 0;
18 | padding-right: 16px;
19 | background-position: 100% 1px;
20 | }
21 |
22 | .deletelink {
23 | padding-left: 0;
24 | padding-right: 16px;
25 | background-position: 100% 1px;
26 | }
27 |
28 | .object-tools {
29 | float: left;
30 | }
31 |
32 | thead th:first-child,
33 | tfoot td:first-child {
34 | border-left: none;
35 | }
36 |
37 | /* LAYOUT */
38 |
39 | #user-tools {
40 | right: auto;
41 | left: 0;
42 | text-align: left;
43 | }
44 |
45 | div.breadcrumbs {
46 | text-align: right;
47 | }
48 |
49 | #content-main {
50 | float: right;
51 | }
52 |
53 | #content-related {
54 | float: left;
55 | margin-left: -300px;
56 | margin-right: auto;
57 | }
58 |
59 | .colMS {
60 | margin-left: 300px;
61 | margin-right: 0;
62 | }
63 |
64 | /* SORTABLE TABLES */
65 |
66 | table thead th.sorted .sortoptions {
67 | float: left;
68 | }
69 |
70 | thead th.sorted .text {
71 | padding-right: 0;
72 | padding-left: 42px;
73 | }
74 |
75 | /* dashboard styles */
76 |
77 | .dashboard .module table td a {
78 | padding-left: .6em;
79 | padding-right: 16px;
80 | }
81 |
82 | /* changelists styles */
83 |
84 | .change-list .filtered table {
85 | border-left: none;
86 | border-right: 0px none;
87 | }
88 |
89 | #changelist-filter {
90 | border-left: none;
91 | border-right: none;
92 | margin-left: 0;
93 | margin-right: 30px;
94 | }
95 |
96 | #changelist-filter li.selected {
97 | border-left: none;
98 | padding-left: 10px;
99 | margin-left: 0;
100 | border-right: 5px solid var(--hairline-color);
101 | padding-right: 10px;
102 | margin-right: -15px;
103 | }
104 |
105 | #changelist table tbody td:first-child, #changelist table tbody th:first-child {
106 | border-right: none;
107 | border-left: none;
108 | }
109 |
110 | /* FORMS */
111 |
112 | .aligned label {
113 | padding: 0 0 3px 1em;
114 | float: right;
115 | }
116 |
117 | .submit-row {
118 | text-align: left
119 | }
120 |
121 | .submit-row p.deletelink-box {
122 | float: right;
123 | }
124 |
125 | .submit-row input.default {
126 | margin-left: 0;
127 | }
128 |
129 | .vDateField, .vTimeField {
130 | margin-left: 2px;
131 | }
132 |
133 | .aligned .form-row input {
134 | margin-left: 5px;
135 | }
136 |
137 | form .aligned p.help, form .aligned div.help {
138 | clear: right;
139 | }
140 |
141 | form .aligned ul {
142 | margin-right: 163px;
143 | margin-left: 0;
144 | }
145 |
146 | form ul.inline li {
147 | float: right;
148 | padding-right: 0;
149 | padding-left: 7px;
150 | }
151 |
152 | input[type=submit].default, .submit-row input.default {
153 | float: left;
154 | }
155 |
156 | fieldset .fieldBox {
157 | float: right;
158 | margin-left: 20px;
159 | margin-right: 0;
160 | }
161 |
162 | .errorlist li {
163 | background-position: 100% 12px;
164 | padding: 0;
165 | }
166 |
167 | .errornote {
168 | background-position: 100% 12px;
169 | padding: 10px 12px;
170 | }
171 |
172 | /* WIDGETS */
173 |
174 | .calendarnav-previous {
175 | top: 0;
176 | left: auto;
177 | right: 10px;
178 | }
179 |
180 | .calendarnav-next {
181 | top: 0;
182 | right: auto;
183 | left: 10px;
184 | }
185 |
186 | .calendar caption, .calendarbox h2 {
187 | text-align: center;
188 | }
189 |
190 | .selector {
191 | float: right;
192 | }
193 |
194 | .selector .selector-filter {
195 | text-align: right;
196 | }
197 |
198 | .inline-deletelink {
199 | float: left;
200 | }
201 |
202 | form .form-row p.datetime {
203 | overflow: hidden;
204 | }
205 |
206 | .related-widget-wrapper {
207 | float: right;
208 | }
209 |
210 | /* MISC */
211 |
212 | .inline-related h2, .inline-group h2 {
213 | text-align: right
214 | }
215 |
216 | .inline-related h3 span.delete {
217 | padding-right: 20px;
218 | padding-left: inherit;
219 | left: 10px;
220 | right: inherit;
221 | float:left;
222 | }
223 |
224 | .inline-related h3 span.delete label {
225 | margin-left: inherit;
226 | margin-right: 2px;
227 | }
228 |
--------------------------------------------------------------------------------
/web/static/admin/css/vendor/select2/LICENSE-SELECT2.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2012-2017 Kevin Brown, Igor Vaynberg, and Select2 contributors
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/web/static/admin/fonts/README.txt:
--------------------------------------------------------------------------------
1 | Roboto webfont source: https://www.google.com/fonts/specimen/Roboto
2 | WOFF files extracted using https://github.com/majodev/google-webfonts-helper
3 | Weights used in this project: Light (300), Regular (400), Bold (700)
4 |
--------------------------------------------------------------------------------
/web/static/admin/fonts/Roboto-Bold-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdntip/cloudpanel/a093fd3d4b3c5ed9fbca72a8ca4080d412691976/web/static/admin/fonts/Roboto-Bold-webfont.woff
--------------------------------------------------------------------------------
/web/static/admin/fonts/Roboto-Light-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdntip/cloudpanel/a093fd3d4b3c5ed9fbca72a8ca4080d412691976/web/static/admin/fonts/Roboto-Light-webfont.woff
--------------------------------------------------------------------------------
/web/static/admin/fonts/Roboto-Regular-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdntip/cloudpanel/a093fd3d4b3c5ed9fbca72a8ca4080d412691976/web/static/admin/fonts/Roboto-Regular-webfont.woff
--------------------------------------------------------------------------------
/web/static/admin/img/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Code Charm Ltd
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/web/static/admin/img/README.txt:
--------------------------------------------------------------------------------
1 | All icons are taken from Font Awesome (http://fontawesome.io/) project.
2 | The Font Awesome font is licensed under the SIL OFL 1.1:
3 | - https://scripts.sil.org/OFL
4 |
5 | SVG icons source: https://github.com/encharm/Font-Awesome-SVG-PNG
6 | Font-Awesome-SVG-PNG is licensed under the MIT license (see file license
7 | in current folder).
8 |
--------------------------------------------------------------------------------
/web/static/admin/img/calendar-icons.svg:
--------------------------------------------------------------------------------
1 |
15 |
--------------------------------------------------------------------------------
/web/static/admin/img/gis/move_vertex_off.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web/static/admin/img/gis/move_vertex_on.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web/static/admin/img/icon-addlink.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/web/static/admin/img/icon-alert.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/web/static/admin/img/icon-calendar.svg:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/web/static/admin/img/icon-changelink.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/web/static/admin/img/icon-clock.svg:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/web/static/admin/img/icon-deletelink.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/web/static/admin/img/icon-no.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/web/static/admin/img/icon-unknown-alt.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/web/static/admin/img/icon-unknown.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/web/static/admin/img/icon-viewlink.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/web/static/admin/img/icon-yes.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/web/static/admin/img/inline-delete.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/web/static/admin/img/search.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/web/static/admin/img/selector-icons.svg:
--------------------------------------------------------------------------------
1 |
35 |
--------------------------------------------------------------------------------
/web/static/admin/img/sorting-icons.svg:
--------------------------------------------------------------------------------
1 |
20 |
--------------------------------------------------------------------------------
/web/static/admin/img/tooltag-add.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/web/static/admin/img/tooltag-arrowright.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/web/static/admin/js/SelectBox.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | {
3 | const SelectBox = {
4 | cache: {},
5 | init: function(id) {
6 | const box = document.getElementById(id);
7 | SelectBox.cache[id] = [];
8 | const cache = SelectBox.cache[id];
9 | for (const node of box.options) {
10 | cache.push({value: node.value, text: node.text, displayed: 1});
11 | }
12 | },
13 | redisplay: function(id) {
14 | // Repopulate HTML select box from cache
15 | const box = document.getElementById(id);
16 | const scroll_value_from_top = box.scrollTop;
17 | box.innerHTML = '';
18 | for (const node of SelectBox.cache[id]) {
19 | if (node.displayed) {
20 | const new_option = new Option(node.text, node.value, false, false);
21 | // Shows a tooltip when hovering over the option
22 | new_option.title = node.text;
23 | box.appendChild(new_option);
24 | }
25 | }
26 | box.scrollTop = scroll_value_from_top;
27 | },
28 | filter: function(id, text) {
29 | // Redisplay the HTML select box, displaying only the choices containing ALL
30 | // the words in text. (It's an AND search.)
31 | const tokens = text.toLowerCase().split(/\s+/);
32 | for (const node of SelectBox.cache[id]) {
33 | node.displayed = 1;
34 | const node_text = node.text.toLowerCase();
35 | for (const token of tokens) {
36 | if (!node_text.includes(token)) {
37 | node.displayed = 0;
38 | break; // Once the first token isn't found we're done
39 | }
40 | }
41 | }
42 | SelectBox.redisplay(id);
43 | },
44 | delete_from_cache: function(id, value) {
45 | let delete_index = null;
46 | const cache = SelectBox.cache[id];
47 | for (const [i, node] of cache.entries()) {
48 | if (node.value === value) {
49 | delete_index = i;
50 | break;
51 | }
52 | }
53 | cache.splice(delete_index, 1);
54 | },
55 | add_to_cache: function(id, option) {
56 | SelectBox.cache[id].push({value: option.value, text: option.text, displayed: 1});
57 | },
58 | cache_contains: function(id, value) {
59 | // Check if an item is contained in the cache
60 | for (const node of SelectBox.cache[id]) {
61 | if (node.value === value) {
62 | return true;
63 | }
64 | }
65 | return false;
66 | },
67 | move: function(from, to) {
68 | const from_box = document.getElementById(from);
69 | for (const option of from_box.options) {
70 | const option_value = option.value;
71 | if (option.selected && SelectBox.cache_contains(from, option_value)) {
72 | SelectBox.add_to_cache(to, {value: option_value, text: option.text, displayed: 1});
73 | SelectBox.delete_from_cache(from, option_value);
74 | }
75 | }
76 | SelectBox.redisplay(from);
77 | SelectBox.redisplay(to);
78 | },
79 | move_all: function(from, to) {
80 | const from_box = document.getElementById(from);
81 | for (const option of from_box.options) {
82 | const option_value = option.value;
83 | if (SelectBox.cache_contains(from, option_value)) {
84 | SelectBox.add_to_cache(to, {value: option_value, text: option.text, displayed: 1});
85 | SelectBox.delete_from_cache(from, option_value);
86 | }
87 | }
88 | SelectBox.redisplay(from);
89 | SelectBox.redisplay(to);
90 | },
91 | sort: function(id) {
92 | SelectBox.cache[id].sort(function(a, b) {
93 | a = a.text.toLowerCase();
94 | b = b.text.toLowerCase();
95 | if (a > b) {
96 | return 1;
97 | }
98 | if (a < b) {
99 | return -1;
100 | }
101 | return 0;
102 | } );
103 | },
104 | select_all: function(id) {
105 | const box = document.getElementById(id);
106 | for (const option of box.options) {
107 | option.selected = true;
108 | }
109 | }
110 | };
111 | window.SelectBox = SelectBox;
112 | }
113 |
--------------------------------------------------------------------------------
/web/static/admin/js/actions.js:
--------------------------------------------------------------------------------
1 | /*global gettext, interpolate, ngettext*/
2 | 'use strict';
3 | {
4 | function show(selector) {
5 | document.querySelectorAll(selector).forEach(function(el) {
6 | el.classList.remove('hidden');
7 | });
8 | }
9 |
10 | function hide(selector) {
11 | document.querySelectorAll(selector).forEach(function(el) {
12 | el.classList.add('hidden');
13 | });
14 | }
15 |
16 | function showQuestion(options) {
17 | hide(options.acrossClears);
18 | show(options.acrossQuestions);
19 | hide(options.allContainer);
20 | }
21 |
22 | function showClear(options) {
23 | show(options.acrossClears);
24 | hide(options.acrossQuestions);
25 | document.querySelector(options.actionContainer).classList.remove(options.selectedClass);
26 | show(options.allContainer);
27 | hide(options.counterContainer);
28 | }
29 |
30 | function reset(options) {
31 | hide(options.acrossClears);
32 | hide(options.acrossQuestions);
33 | hide(options.allContainer);
34 | show(options.counterContainer);
35 | }
36 |
37 | function clearAcross(options) {
38 | reset(options);
39 | document.querySelector(options.acrossInput).value = 0;
40 | document.querySelector(options.actionContainer).classList.remove(options.selectedClass);
41 | }
42 |
43 | function checker(actionCheckboxes, options, checked) {
44 | if (checked) {
45 | showQuestion(options);
46 | } else {
47 | reset(options);
48 | }
49 | actionCheckboxes.forEach(function(el) {
50 | el.checked = checked;
51 | el.closest('tr').classList.toggle(options.selectedClass, checked);
52 | });
53 | }
54 |
55 | function updateCounter(actionCheckboxes, options) {
56 | const sel = Array.from(actionCheckboxes).filter(function(el) {
57 | return el.checked;
58 | }).length;
59 | const counter = document.querySelector(options.counterContainer);
60 | // data-actions-icnt is defined in the generated HTML
61 | // and contains the total amount of objects in the queryset
62 | const actions_icnt = Number(counter.dataset.actionsIcnt);
63 | counter.textContent = interpolate(
64 | ngettext('%(sel)s of %(cnt)s selected', '%(sel)s of %(cnt)s selected', sel), {
65 | sel: sel,
66 | cnt: actions_icnt
67 | }, true);
68 | const allToggle = document.getElementById(options.allToggleId);
69 | allToggle.checked = sel === actionCheckboxes.length;
70 | if (allToggle.checked) {
71 | showQuestion(options);
72 | } else {
73 | clearAcross(options);
74 | }
75 | }
76 |
77 | const defaults = {
78 | actionContainer: "div.actions",
79 | counterContainer: "span.action-counter",
80 | allContainer: "div.actions span.all",
81 | acrossInput: "div.actions input.select-across",
82 | acrossQuestions: "div.actions span.question",
83 | acrossClears: "div.actions span.clear",
84 | allToggleId: "action-toggle",
85 | selectedClass: "selected"
86 | };
87 |
88 | window.Actions = function(actionCheckboxes, options) {
89 | options = Object.assign({}, defaults, options);
90 | let list_editable_changed = false;
91 | let lastChecked = null;
92 | let shiftPressed = false;
93 |
94 | document.addEventListener('keydown', (event) => {
95 | shiftPressed = event.shiftKey;
96 | });
97 |
98 | document.addEventListener('keyup', (event) => {
99 | shiftPressed = event.shiftKey;
100 | });
101 |
102 | document.getElementById(options.allToggleId).addEventListener('click', function(event) {
103 | checker(actionCheckboxes, options, this.checked);
104 | updateCounter(actionCheckboxes, options);
105 | });
106 |
107 | document.querySelectorAll(options.acrossQuestions + " a").forEach(function(el) {
108 | el.addEventListener('click', function(event) {
109 | event.preventDefault();
110 | const acrossInput = document.querySelector(options.acrossInput);
111 | acrossInput.value = 1;
112 | showClear(options);
113 | });
114 | });
115 |
116 | document.querySelectorAll(options.acrossClears + " a").forEach(function(el) {
117 | el.addEventListener('click', function(event) {
118 | event.preventDefault();
119 | document.getElementById(options.allToggleId).checked = false;
120 | clearAcross(options);
121 | checker(actionCheckboxes, options, false);
122 | updateCounter(actionCheckboxes, options);
123 | });
124 | });
125 |
126 | function affectedCheckboxes(target, withModifier) {
127 | const multiSelect = (lastChecked && withModifier && lastChecked !== target);
128 | if (!multiSelect) {
129 | return [target];
130 | }
131 | const checkboxes = Array.from(actionCheckboxes);
132 | const targetIndex = checkboxes.findIndex(el => el === target);
133 | const lastCheckedIndex = checkboxes.findIndex(el => el === lastChecked);
134 | const startIndex = Math.min(targetIndex, lastCheckedIndex);
135 | const endIndex = Math.max(targetIndex, lastCheckedIndex);
136 | const filtered = checkboxes.filter((el, index) => (startIndex <= index) && (index <= endIndex));
137 | return filtered;
138 | };
139 |
140 | Array.from(document.getElementById('result_list').tBodies).forEach(function(el) {
141 | el.addEventListener('change', function(event) {
142 | const target = event.target;
143 | if (target.classList.contains('action-select')) {
144 | const checkboxes = affectedCheckboxes(target, shiftPressed);
145 | checker(checkboxes, options, target.checked);
146 | updateCounter(actionCheckboxes, options);
147 | lastChecked = target;
148 | } else {
149 | list_editable_changed = true;
150 | }
151 | });
152 | });
153 |
154 | document.querySelector('#changelist-form button[name=index]').addEventListener('click', function() {
155 | if (list_editable_changed) {
156 | const confirmed = confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."));
157 | if (!confirmed) {
158 | event.preventDefault();
159 | }
160 | }
161 | });
162 |
163 | const el = document.querySelector('#changelist-form input[name=_save]');
164 | // The button does not exist if no fields are editable.
165 | if (el) {
166 | el.addEventListener('click', function(event) {
167 | if (document.querySelector('[name=action]').value) {
168 | const text = list_editable_changed
169 | ? gettext("You have selected an action, but you haven’t saved your changes to individual fields yet. Please click OK to save. You’ll need to re-run the action.")
170 | : gettext("You have selected an action, and you haven’t made any changes on individual fields. You’re probably looking for the Go button rather than the Save button.");
171 | if (!confirm(text)) {
172 | event.preventDefault();
173 | }
174 | }
175 | });
176 | }
177 | };
178 |
179 | // Call function fn when the DOM is loaded and ready. If it is already
180 | // loaded, call the function now.
181 | // http://youmightnotneedjquery.com/#ready
182 | function ready(fn) {
183 | if (document.readyState !== 'loading') {
184 | fn();
185 | } else {
186 | document.addEventListener('DOMContentLoaded', fn);
187 | }
188 | }
189 |
190 | ready(function() {
191 | const actionsEls = document.querySelectorAll('tr input.action-select');
192 | if (actionsEls.length > 0) {
193 | Actions(actionsEls);
194 | }
195 | });
196 | }
197 |
--------------------------------------------------------------------------------
/web/static/admin/js/admin/RelatedObjectLookups.js:
--------------------------------------------------------------------------------
1 | /*global SelectBox, interpolate*/
2 | // Handles related-objects functionality: lookup link for raw_id_fields
3 | // and Add Another links.
4 | 'use strict';
5 | {
6 | const $ = django.jQuery;
7 |
8 | function showAdminPopup(triggeringLink, name_regexp, add_popup) {
9 | const name = triggeringLink.id.replace(name_regexp, '');
10 | const href = new URL(triggeringLink.href);
11 | if (add_popup) {
12 | href.searchParams.set('_popup', 1);
13 | }
14 | const win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');
15 | win.focus();
16 | return false;
17 | }
18 |
19 | function showRelatedObjectLookupPopup(triggeringLink) {
20 | return showAdminPopup(triggeringLink, /^lookup_/, true);
21 | }
22 |
23 | function dismissRelatedLookupPopup(win, chosenId) {
24 | const name = win.name;
25 | const elem = document.getElementById(name);
26 | if (elem.classList.contains('vManyToManyRawIdAdminField') && elem.value) {
27 | elem.value += ',' + chosenId;
28 | } else {
29 | document.getElementById(name).value = chosenId;
30 | }
31 | win.close();
32 | }
33 |
34 | function showRelatedObjectPopup(triggeringLink) {
35 | return showAdminPopup(triggeringLink, /^(change|add|delete)_/, false);
36 | }
37 |
38 | function updateRelatedObjectLinks(triggeringLink) {
39 | const $this = $(triggeringLink);
40 | const siblings = $this.nextAll('.view-related, .change-related, .delete-related');
41 | if (!siblings.length) {
42 | return;
43 | }
44 | const value = $this.val();
45 | if (value) {
46 | siblings.each(function() {
47 | const elm = $(this);
48 | elm.attr('href', elm.attr('data-href-template').replace('__fk__', value));
49 | });
50 | } else {
51 | siblings.removeAttr('href');
52 | }
53 | }
54 |
55 | function dismissAddRelatedObjectPopup(win, newId, newRepr) {
56 | const name = win.name;
57 | const elem = document.getElementById(name);
58 | if (elem) {
59 | const elemName = elem.nodeName.toUpperCase();
60 | if (elemName === 'SELECT') {
61 | elem.options[elem.options.length] = new Option(newRepr, newId, true, true);
62 | } else if (elemName === 'INPUT') {
63 | if (elem.classList.contains('vManyToManyRawIdAdminField') && elem.value) {
64 | elem.value += ',' + newId;
65 | } else {
66 | elem.value = newId;
67 | }
68 | }
69 | // Trigger a change event to update related links if required.
70 | $(elem).trigger('change');
71 | } else {
72 | const toId = name + "_to";
73 | const o = new Option(newRepr, newId);
74 | SelectBox.add_to_cache(toId, o);
75 | SelectBox.redisplay(toId);
76 | }
77 | win.close();
78 | }
79 |
80 | function dismissChangeRelatedObjectPopup(win, objId, newRepr, newId) {
81 | const id = win.name.replace(/^edit_/, '');
82 | const selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]);
83 | const selects = $(selectsSelector);
84 | selects.find('option').each(function() {
85 | if (this.value === objId) {
86 | this.textContent = newRepr;
87 | this.value = newId;
88 | }
89 | });
90 | selects.next().find('.select2-selection__rendered').each(function() {
91 | // The element can have a clear button as a child.
92 | // Use the lastChild to modify only the displayed value.
93 | this.lastChild.textContent = newRepr;
94 | this.title = newRepr;
95 | });
96 | win.close();
97 | }
98 |
99 | function dismissDeleteRelatedObjectPopup(win, objId) {
100 | const id = win.name.replace(/^delete_/, '');
101 | const selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]);
102 | const selects = $(selectsSelector);
103 | selects.find('option').each(function() {
104 | if (this.value === objId) {
105 | $(this).remove();
106 | }
107 | }).trigger('change');
108 | win.close();
109 | }
110 |
111 | window.showRelatedObjectLookupPopup = showRelatedObjectLookupPopup;
112 | window.dismissRelatedLookupPopup = dismissRelatedLookupPopup;
113 | window.showRelatedObjectPopup = showRelatedObjectPopup;
114 | window.updateRelatedObjectLinks = updateRelatedObjectLinks;
115 | window.dismissAddRelatedObjectPopup = dismissAddRelatedObjectPopup;
116 | window.dismissChangeRelatedObjectPopup = dismissChangeRelatedObjectPopup;
117 | window.dismissDeleteRelatedObjectPopup = dismissDeleteRelatedObjectPopup;
118 |
119 | // Kept for backward compatibility
120 | window.showAddAnotherPopup = showRelatedObjectPopup;
121 | window.dismissAddAnotherPopup = dismissAddRelatedObjectPopup;
122 |
123 | $(document).ready(function() {
124 | $("a[data-popup-opener]").on('click', function(event) {
125 | event.preventDefault();
126 | opener.dismissRelatedLookupPopup(window, $(this).data("popup-opener"));
127 | });
128 | $('body').on('click', '.related-widget-wrapper-link', function(e) {
129 | e.preventDefault();
130 | if (this.href) {
131 | const event = $.Event('django:show-related', {href: this.href});
132 | $(this).trigger(event);
133 | if (!event.isDefaultPrevented()) {
134 | showRelatedObjectPopup(this);
135 | }
136 | }
137 | });
138 | $('body').on('change', '.related-widget-wrapper select', function(e) {
139 | const event = $.Event('django:update-related');
140 | $(this).trigger(event);
141 | if (!event.isDefaultPrevented()) {
142 | updateRelatedObjectLinks(this);
143 | }
144 | });
145 | $('.related-widget-wrapper select').trigger('change');
146 | $('body').on('click', '.related-lookup', function(e) {
147 | e.preventDefault();
148 | const event = $.Event('django:lookup-related');
149 | $(this).trigger(event);
150 | if (!event.isDefaultPrevented()) {
151 | showRelatedObjectLookupPopup(this);
152 | }
153 | });
154 | });
155 | }
156 |
--------------------------------------------------------------------------------
/web/static/admin/js/autocomplete.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | {
3 | const $ = django.jQuery;
4 | const init = function($element, options) {
5 | const settings = $.extend({
6 | ajax: {
7 | data: function(params) {
8 | return {
9 | term: params.term,
10 | page: params.page,
11 | app_label: $element.data('app-label'),
12 | model_name: $element.data('model-name'),
13 | field_name: $element.data('field-name')
14 | };
15 | }
16 | }
17 | }, options);
18 | $element.select2(settings);
19 | };
20 |
21 | $.fn.djangoAdminSelect2 = function(options) {
22 | const settings = $.extend({}, options);
23 | $.each(this, function(i, element) {
24 | const $element = $(element);
25 | init($element, settings);
26 | });
27 | return this;
28 | };
29 |
30 | $(function() {
31 | // Initialize all autocomplete widgets except the one in the template
32 | // form used when a new formset is added.
33 | $('.admin-autocomplete').not('[name*=__prefix__]').djangoAdminSelect2();
34 | });
35 |
36 | $(document).on('formset:added', (function() {
37 | return function(event, $newFormset) {
38 | return $newFormset.find('.admin-autocomplete').djangoAdminSelect2();
39 | };
40 | })(this));
41 | }
42 |
--------------------------------------------------------------------------------
/web/static/admin/js/calendar.js:
--------------------------------------------------------------------------------
1 | /*global gettext, pgettext, get_format, quickElement, removeChildren*/
2 | /*
3 | calendar.js - Calendar functions by Adrian Holovaty
4 | depends on core.js for utility functions like removeChildren or quickElement
5 | */
6 | 'use strict';
7 | {
8 | // CalendarNamespace -- Provides a collection of HTML calendar-related helper functions
9 | const CalendarNamespace = {
10 | monthsOfYear: [
11 | gettext('January'),
12 | gettext('February'),
13 | gettext('March'),
14 | gettext('April'),
15 | gettext('May'),
16 | gettext('June'),
17 | gettext('July'),
18 | gettext('August'),
19 | gettext('September'),
20 | gettext('October'),
21 | gettext('November'),
22 | gettext('December')
23 | ],
24 | monthsOfYearAbbrev: [
25 | pgettext('abbrev. month January', 'Jan'),
26 | pgettext('abbrev. month February', 'Feb'),
27 | pgettext('abbrev. month March', 'Mar'),
28 | pgettext('abbrev. month April', 'Apr'),
29 | pgettext('abbrev. month May', 'May'),
30 | pgettext('abbrev. month June', 'Jun'),
31 | pgettext('abbrev. month July', 'Jul'),
32 | pgettext('abbrev. month August', 'Aug'),
33 | pgettext('abbrev. month September', 'Sep'),
34 | pgettext('abbrev. month October', 'Oct'),
35 | pgettext('abbrev. month November', 'Nov'),
36 | pgettext('abbrev. month December', 'Dec')
37 | ],
38 | daysOfWeek: [
39 | pgettext('one letter Sunday', 'S'),
40 | pgettext('one letter Monday', 'M'),
41 | pgettext('one letter Tuesday', 'T'),
42 | pgettext('one letter Wednesday', 'W'),
43 | pgettext('one letter Thursday', 'T'),
44 | pgettext('one letter Friday', 'F'),
45 | pgettext('one letter Saturday', 'S')
46 | ],
47 | firstDayOfWeek: parseInt(get_format('FIRST_DAY_OF_WEEK')),
48 | isLeapYear: function(year) {
49 | return (((year % 4) === 0) && ((year % 100) !== 0 ) || ((year % 400) === 0));
50 | },
51 | getDaysInMonth: function(month, year) {
52 | let days;
53 | if (month === 1 || month === 3 || month === 5 || month === 7 || month === 8 || month === 10 || month === 12) {
54 | days = 31;
55 | }
56 | else if (month === 4 || month === 6 || month === 9 || month === 11) {
57 | days = 30;
58 | }
59 | else if (month === 2 && CalendarNamespace.isLeapYear(year)) {
60 | days = 29;
61 | }
62 | else {
63 | days = 28;
64 | }
65 | return days;
66 | },
67 | draw: function(month, year, div_id, callback, selected) { // month = 1-12, year = 1-9999
68 | const today = new Date();
69 | const todayDay = today.getDate();
70 | const todayMonth = today.getMonth() + 1;
71 | const todayYear = today.getFullYear();
72 | let todayClass = '';
73 |
74 | // Use UTC functions here because the date field does not contain time
75 | // and using the UTC function variants prevent the local time offset
76 | // from altering the date, specifically the day field. For example:
77 | //
78 | // ```
79 | // var x = new Date('2013-10-02');
80 | // var day = x.getDate();
81 | // ```
82 | //
83 | // The day variable above will be 1 instead of 2 in, say, US Pacific time
84 | // zone.
85 | let isSelectedMonth = false;
86 | if (typeof selected !== 'undefined') {
87 | isSelectedMonth = (selected.getUTCFullYear() === year && (selected.getUTCMonth() + 1) === month);
88 | }
89 |
90 | month = parseInt(month);
91 | year = parseInt(year);
92 | const calDiv = document.getElementById(div_id);
93 | removeChildren(calDiv);
94 | const calTable = document.createElement('table');
95 | quickElement('caption', calTable, CalendarNamespace.monthsOfYear[month - 1] + ' ' + year);
96 | const tableBody = quickElement('tbody', calTable);
97 |
98 | // Draw days-of-week header
99 | let tableRow = quickElement('tr', tableBody);
100 | for (let i = 0; i < 7; i++) {
101 | quickElement('th', tableRow, CalendarNamespace.daysOfWeek[(i + CalendarNamespace.firstDayOfWeek) % 7]);
102 | }
103 |
104 | const startingPos = new Date(year, month - 1, 1 - CalendarNamespace.firstDayOfWeek).getDay();
105 | const days = CalendarNamespace.getDaysInMonth(month, year);
106 |
107 | let nonDayCell;
108 |
109 | // Draw blanks before first of month
110 | tableRow = quickElement('tr', tableBody);
111 | for (let i = 0; i < startingPos; i++) {
112 | nonDayCell = quickElement('td', tableRow, ' ');
113 | nonDayCell.className = "nonday";
114 | }
115 |
116 | function calendarMonth(y, m) {
117 | function onClick(e) {
118 | e.preventDefault();
119 | callback(y, m, this.textContent);
120 | }
121 | return onClick;
122 | }
123 |
124 | // Draw days of month
125 | let currentDay = 1;
126 | for (let i = startingPos; currentDay <= days; i++) {
127 | if (i % 7 === 0 && currentDay !== 1) {
128 | tableRow = quickElement('tr', tableBody);
129 | }
130 | if ((currentDay === todayDay) && (month === todayMonth) && (year === todayYear)) {
131 | todayClass = 'today';
132 | } else {
133 | todayClass = '';
134 | }
135 |
136 | // use UTC function; see above for explanation.
137 | if (isSelectedMonth && currentDay === selected.getUTCDate()) {
138 | if (todayClass !== '') {
139 | todayClass += " ";
140 | }
141 | todayClass += "selected";
142 | }
143 |
144 | const cell = quickElement('td', tableRow, '', 'class', todayClass);
145 | const link = quickElement('a', cell, currentDay, 'href', '#');
146 | link.addEventListener('click', calendarMonth(year, month));
147 | currentDay++;
148 | }
149 |
150 | // Draw blanks after end of month (optional, but makes for valid code)
151 | while (tableRow.childNodes.length < 7) {
152 | nonDayCell = quickElement('td', tableRow, ' ');
153 | nonDayCell.className = "nonday";
154 | }
155 |
156 | calDiv.appendChild(calTable);
157 | }
158 | };
159 |
160 | // Calendar -- A calendar instance
161 | function Calendar(div_id, callback, selected) {
162 | // div_id (string) is the ID of the element in which the calendar will
163 | // be displayed
164 | // callback (string) is the name of a JavaScript function that will be
165 | // called with the parameters (year, month, day) when a day in the
166 | // calendar is clicked
167 | this.div_id = div_id;
168 | this.callback = callback;
169 | this.today = new Date();
170 | this.currentMonth = this.today.getMonth() + 1;
171 | this.currentYear = this.today.getFullYear();
172 | if (typeof selected !== 'undefined') {
173 | this.selected = selected;
174 | }
175 | }
176 | Calendar.prototype = {
177 | drawCurrent: function() {
178 | CalendarNamespace.draw(this.currentMonth, this.currentYear, this.div_id, this.callback, this.selected);
179 | },
180 | drawDate: function(month, year, selected) {
181 | this.currentMonth = month;
182 | this.currentYear = year;
183 |
184 | if(selected) {
185 | this.selected = selected;
186 | }
187 |
188 | this.drawCurrent();
189 | },
190 | drawPreviousMonth: function() {
191 | if (this.currentMonth === 1) {
192 | this.currentMonth = 12;
193 | this.currentYear--;
194 | }
195 | else {
196 | this.currentMonth--;
197 | }
198 | this.drawCurrent();
199 | },
200 | drawNextMonth: function() {
201 | if (this.currentMonth === 12) {
202 | this.currentMonth = 1;
203 | this.currentYear++;
204 | }
205 | else {
206 | this.currentMonth++;
207 | }
208 | this.drawCurrent();
209 | },
210 | drawPreviousYear: function() {
211 | this.currentYear--;
212 | this.drawCurrent();
213 | },
214 | drawNextYear: function() {
215 | this.currentYear++;
216 | this.drawCurrent();
217 | }
218 | };
219 | window.Calendar = Calendar;
220 | window.CalendarNamespace = CalendarNamespace;
221 | }
222 |
--------------------------------------------------------------------------------
/web/static/admin/js/cancel.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | {
3 | // Call function fn when the DOM is loaded and ready. If it is already
4 | // loaded, call the function now.
5 | // http://youmightnotneedjquery.com/#ready
6 | function ready(fn) {
7 | if (document.readyState !== 'loading') {
8 | fn();
9 | } else {
10 | document.addEventListener('DOMContentLoaded', fn);
11 | }
12 | }
13 |
14 | ready(function() {
15 | function handleClick(event) {
16 | event.preventDefault();
17 | const params = new URLSearchParams(window.location.search);
18 | if (params.has('_popup')) {
19 | window.close(); // Close the popup.
20 | } else {
21 | window.history.back(); // Otherwise, go back.
22 | }
23 | }
24 |
25 | document.querySelectorAll('.cancel-link').forEach(function(el) {
26 | el.addEventListener('click', handleClick);
27 | });
28 | });
29 | }
30 |
--------------------------------------------------------------------------------
/web/static/admin/js/change_form.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | {
3 | const inputTags = ['BUTTON', 'INPUT', 'SELECT', 'TEXTAREA'];
4 | const modelName = document.getElementById('django-admin-form-add-constants').dataset.modelName;
5 | if (modelName) {
6 | const form = document.getElementById(modelName + '_form');
7 | for (const element of form.elements) {
8 | // HTMLElement.offsetParent returns null when the element is not
9 | // rendered.
10 | if (inputTags.includes(element.tagName) && !element.disabled && element.offsetParent) {
11 | element.focus();
12 | break;
13 | }
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/web/static/admin/js/collapse.js:
--------------------------------------------------------------------------------
1 | /*global gettext*/
2 | 'use strict';
3 | {
4 | window.addEventListener('load', function() {
5 | // Add anchor tag for Show/Hide link
6 | const fieldsets = document.querySelectorAll('fieldset.collapse');
7 | for (const [i, elem] of fieldsets.entries()) {
8 | // Don't hide if fields in this fieldset have errors
9 | if (elem.querySelectorAll('div.errors, ul.errorlist').length === 0) {
10 | elem.classList.add('collapsed');
11 | const h2 = elem.querySelector('h2');
12 | const link = document.createElement('a');
13 | link.id = 'fieldsetcollapser' + i;
14 | link.className = 'collapse-toggle';
15 | link.href = '#';
16 | link.textContent = gettext('Show');
17 | h2.appendChild(document.createTextNode(' ('));
18 | h2.appendChild(link);
19 | h2.appendChild(document.createTextNode(')'));
20 | }
21 | }
22 | // Add toggle to hide/show anchor tag
23 | const toggleFunc = function(ev) {
24 | if (ev.target.matches('.collapse-toggle')) {
25 | ev.preventDefault();
26 | ev.stopPropagation();
27 | const fieldset = ev.target.closest('fieldset');
28 | if (fieldset.classList.contains('collapsed')) {
29 | // Show
30 | ev.target.textContent = gettext('Hide');
31 | fieldset.classList.remove('collapsed');
32 | } else {
33 | // Hide
34 | ev.target.textContent = gettext('Show');
35 | fieldset.classList.add('collapsed');
36 | }
37 | }
38 | };
39 | document.querySelectorAll('fieldset.module').forEach(function(el) {
40 | el.addEventListener('click', toggleFunc);
41 | });
42 | });
43 | }
44 |
--------------------------------------------------------------------------------
/web/static/admin/js/core.js:
--------------------------------------------------------------------------------
1 | // Core javascript helper functions
2 | 'use strict';
3 |
4 | // quickElement(tagType, parentReference [, textInChildNode, attribute, attributeValue ...]);
5 | function quickElement() {
6 | const obj = document.createElement(arguments[0]);
7 | if (arguments[2]) {
8 | const textNode = document.createTextNode(arguments[2]);
9 | obj.appendChild(textNode);
10 | }
11 | const len = arguments.length;
12 | for (let i = 3; i < len; i += 2) {
13 | obj.setAttribute(arguments[i], arguments[i + 1]);
14 | }
15 | arguments[1].appendChild(obj);
16 | return obj;
17 | }
18 |
19 | // "a" is reference to an object
20 | function removeChildren(a) {
21 | while (a.hasChildNodes()) {
22 | a.removeChild(a.lastChild);
23 | }
24 | }
25 |
26 | // ----------------------------------------------------------------------------
27 | // Find-position functions by PPK
28 | // See https://www.quirksmode.org/js/findpos.html
29 | // ----------------------------------------------------------------------------
30 | function findPosX(obj) {
31 | let curleft = 0;
32 | if (obj.offsetParent) {
33 | while (obj.offsetParent) {
34 | curleft += obj.offsetLeft - obj.scrollLeft;
35 | obj = obj.offsetParent;
36 | }
37 | } else if (obj.x) {
38 | curleft += obj.x;
39 | }
40 | return curleft;
41 | }
42 |
43 | function findPosY(obj) {
44 | let curtop = 0;
45 | if (obj.offsetParent) {
46 | while (obj.offsetParent) {
47 | curtop += obj.offsetTop - obj.scrollTop;
48 | obj = obj.offsetParent;
49 | }
50 | } else if (obj.y) {
51 | curtop += obj.y;
52 | }
53 | return curtop;
54 | }
55 |
56 | //-----------------------------------------------------------------------------
57 | // Date object extensions
58 | // ----------------------------------------------------------------------------
59 | {
60 | Date.prototype.getTwelveHours = function() {
61 | return this.getHours() % 12 || 12;
62 | };
63 |
64 | Date.prototype.getTwoDigitMonth = function() {
65 | return (this.getMonth() < 9) ? '0' + (this.getMonth() + 1) : (this.getMonth() + 1);
66 | };
67 |
68 | Date.prototype.getTwoDigitDate = function() {
69 | return (this.getDate() < 10) ? '0' + this.getDate() : this.getDate();
70 | };
71 |
72 | Date.prototype.getTwoDigitTwelveHour = function() {
73 | return (this.getTwelveHours() < 10) ? '0' + this.getTwelveHours() : this.getTwelveHours();
74 | };
75 |
76 | Date.prototype.getTwoDigitHour = function() {
77 | return (this.getHours() < 10) ? '0' + this.getHours() : this.getHours();
78 | };
79 |
80 | Date.prototype.getTwoDigitMinute = function() {
81 | return (this.getMinutes() < 10) ? '0' + this.getMinutes() : this.getMinutes();
82 | };
83 |
84 | Date.prototype.getTwoDigitSecond = function() {
85 | return (this.getSeconds() < 10) ? '0' + this.getSeconds() : this.getSeconds();
86 | };
87 |
88 | Date.prototype.getAbbrevMonthName = function() {
89 | return typeof window.CalendarNamespace === "undefined"
90 | ? this.getTwoDigitMonth()
91 | : window.CalendarNamespace.monthsOfYearAbbrev[this.getMonth()];
92 | };
93 |
94 | Date.prototype.getFullMonthName = function() {
95 | return typeof window.CalendarNamespace === "undefined"
96 | ? this.getTwoDigitMonth()
97 | : window.CalendarNamespace.monthsOfYear[this.getMonth()];
98 | };
99 |
100 | Date.prototype.strftime = function(format) {
101 | const fields = {
102 | b: this.getAbbrevMonthName(),
103 | B: this.getFullMonthName(),
104 | c: this.toString(),
105 | d: this.getTwoDigitDate(),
106 | H: this.getTwoDigitHour(),
107 | I: this.getTwoDigitTwelveHour(),
108 | m: this.getTwoDigitMonth(),
109 | M: this.getTwoDigitMinute(),
110 | p: (this.getHours() >= 12) ? 'PM' : 'AM',
111 | S: this.getTwoDigitSecond(),
112 | w: '0' + this.getDay(),
113 | x: this.toLocaleDateString(),
114 | X: this.toLocaleTimeString(),
115 | y: ('' + this.getFullYear()).substr(2, 4),
116 | Y: '' + this.getFullYear(),
117 | '%': '%'
118 | };
119 | let result = '', i = 0;
120 | while (i < format.length) {
121 | if (format.charAt(i) === '%') {
122 | result = result + fields[format.charAt(i + 1)];
123 | ++i;
124 | }
125 | else {
126 | result = result + format.charAt(i);
127 | }
128 | ++i;
129 | }
130 | return result;
131 | };
132 |
133 | // ----------------------------------------------------------------------------
134 | // String object extensions
135 | // ----------------------------------------------------------------------------
136 | String.prototype.strptime = function(format) {
137 | const split_format = format.split(/[.\-/]/);
138 | const date = this.split(/[.\-/]/);
139 | let i = 0;
140 | let day, month, year;
141 | while (i < split_format.length) {
142 | switch (split_format[i]) {
143 | case "%d":
144 | day = date[i];
145 | break;
146 | case "%m":
147 | month = date[i] - 1;
148 | break;
149 | case "%Y":
150 | year = date[i];
151 | break;
152 | case "%y":
153 | // A %y value in the range of [00, 68] is in the current
154 | // century, while [69, 99] is in the previous century,
155 | // according to the Open Group Specification.
156 | if (parseInt(date[i], 10) >= 69) {
157 | year = date[i];
158 | } else {
159 | year = (new Date(Date.UTC(date[i], 0))).getUTCFullYear() + 100;
160 | }
161 | break;
162 | }
163 | ++i;
164 | }
165 | // Create Date object from UTC since the parsed value is supposed to be
166 | // in UTC, not local time. Also, the calendar uses UTC functions for
167 | // date extraction.
168 | return new Date(Date.UTC(year, month, day));
169 | };
170 | }
171 |
--------------------------------------------------------------------------------
/web/static/admin/js/jquery.init.js:
--------------------------------------------------------------------------------
1 | /*global jQuery:false*/
2 | 'use strict';
3 | /* Puts the included jQuery into our own namespace using noConflict and passing
4 | * it 'true'. This ensures that the included jQuery doesn't pollute the global
5 | * namespace (i.e. this preserves pre-existing values for both window.$ and
6 | * window.jQuery).
7 | */
8 | window.django = {jQuery: jQuery.noConflict(true)};
9 |
--------------------------------------------------------------------------------
/web/static/admin/js/nav_sidebar.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | {
3 | const toggleNavSidebar = document.getElementById('toggle-nav-sidebar');
4 | if (toggleNavSidebar !== null) {
5 | const navLinks = document.querySelectorAll('#nav-sidebar a');
6 | function disableNavLinkTabbing() {
7 | for (const navLink of navLinks) {
8 | navLink.tabIndex = -1;
9 | }
10 | }
11 | function enableNavLinkTabbing() {
12 | for (const navLink of navLinks) {
13 | navLink.tabIndex = 0;
14 | }
15 | }
16 |
17 | const main = document.getElementById('main');
18 | let navSidebarIsOpen = localStorage.getItem('django.admin.navSidebarIsOpen');
19 | if (navSidebarIsOpen === null) {
20 | navSidebarIsOpen = 'true';
21 | }
22 | if (navSidebarIsOpen === 'false') {
23 | disableNavLinkTabbing();
24 | }
25 | main.classList.toggle('shifted', navSidebarIsOpen === 'true');
26 |
27 | toggleNavSidebar.addEventListener('click', function() {
28 | if (navSidebarIsOpen === 'true') {
29 | navSidebarIsOpen = 'false';
30 | disableNavLinkTabbing();
31 | } else {
32 | navSidebarIsOpen = 'true';
33 | enableNavLinkTabbing();
34 | }
35 | localStorage.setItem('django.admin.navSidebarIsOpen', navSidebarIsOpen);
36 | main.classList.toggle('shifted');
37 | });
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/web/static/admin/js/popup_response.js:
--------------------------------------------------------------------------------
1 | /*global opener */
2 | 'use strict';
3 | {
4 | const initData = JSON.parse(document.getElementById('django-admin-popup-response-constants').dataset.popupResponse);
5 | switch(initData.action) {
6 | case 'change':
7 | opener.dismissChangeRelatedObjectPopup(window, initData.value, initData.obj, initData.new_value);
8 | break;
9 | case 'delete':
10 | opener.dismissDeleteRelatedObjectPopup(window, initData.value);
11 | break;
12 | default:
13 | opener.dismissAddRelatedObjectPopup(window, initData.value, initData.obj);
14 | break;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/web/static/admin/js/prepopulate.js:
--------------------------------------------------------------------------------
1 | /*global URLify*/
2 | 'use strict';
3 | {
4 | const $ = django.jQuery;
5 | $.fn.prepopulate = function(dependencies, maxLength, allowUnicode) {
6 | /*
7 | Depends on urlify.js
8 | Populates a selected field with the values of the dependent fields,
9 | URLifies and shortens the string.
10 | dependencies - array of dependent fields ids
11 | maxLength - maximum length of the URLify'd string
12 | allowUnicode - Unicode support of the URLify'd string
13 | */
14 | return this.each(function() {
15 | const prepopulatedField = $(this);
16 |
17 | const populate = function() {
18 | // Bail if the field's value has been changed by the user
19 | if (prepopulatedField.data('_changed')) {
20 | return;
21 | }
22 |
23 | const values = [];
24 | $.each(dependencies, function(i, field) {
25 | field = $(field);
26 | if (field.val().length > 0) {
27 | values.push(field.val());
28 | }
29 | });
30 | prepopulatedField.val(URLify(values.join(' '), maxLength, allowUnicode));
31 | };
32 |
33 | prepopulatedField.data('_changed', false);
34 | prepopulatedField.on('change', function() {
35 | prepopulatedField.data('_changed', true);
36 | });
37 |
38 | if (!prepopulatedField.val()) {
39 | $(dependencies.join(',')).on('keyup change focus', populate);
40 | }
41 | });
42 | };
43 | }
44 |
--------------------------------------------------------------------------------
/web/static/admin/js/prepopulate_init.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | {
3 | const $ = django.jQuery;
4 | const fields = $('#django-admin-prepopulated-fields-constants').data('prepopulatedFields');
5 | $.each(fields, function(index, field) {
6 | $('.empty-form .form-row .field-' + field.name + ', .empty-form.form-row .field-' + field.name).addClass('prepopulated_field');
7 | $(field.id).data('dependency_list', field.dependency_list).prepopulate(
8 | field.dependency_ids, field.maxLength, field.allowUnicode
9 | );
10 | });
11 | }
12 |
--------------------------------------------------------------------------------
/web/static/admin/js/urlify.js:
--------------------------------------------------------------------------------
1 | /*global XRegExp*/
2 | 'use strict';
3 | {
4 | const LATIN_MAP = {
5 | 'À': 'A', 'Á': 'A', 'Â': 'A', 'Ã': 'A', 'Ä': 'A', 'Å': 'A', 'Æ': 'AE',
6 | 'Ç': 'C', 'È': 'E', 'É': 'E', 'Ê': 'E', 'Ë': 'E', 'Ì': 'I', 'Í': 'I',
7 | 'Î': 'I', 'Ï': 'I', 'Ð': 'D', 'Ñ': 'N', 'Ò': 'O', 'Ó': 'O', 'Ô': 'O',
8 | 'Õ': 'O', 'Ö': 'O', 'Ő': 'O', 'Ø': 'O', 'Ù': 'U', 'Ú': 'U', 'Û': 'U',
9 | 'Ü': 'U', 'Ű': 'U', 'Ý': 'Y', 'Þ': 'TH', 'Ÿ': 'Y', 'ß': 'ss', 'à': 'a',
10 | 'á': 'a', 'â': 'a', 'ã': 'a', 'ä': 'a', 'å': 'a', 'æ': 'ae', 'ç': 'c',
11 | 'è': 'e', 'é': 'e', 'ê': 'e', 'ë': 'e', 'ì': 'i', 'í': 'i', 'î': 'i',
12 | 'ï': 'i', 'ð': 'd', 'ñ': 'n', 'ò': 'o', 'ó': 'o', 'ô': 'o', 'õ': 'o',
13 | 'ö': 'o', 'ő': 'o', 'ø': 'o', 'ù': 'u', 'ú': 'u', 'û': 'u', 'ü': 'u',
14 | 'ű': 'u', 'ý': 'y', 'þ': 'th', 'ÿ': 'y'
15 | };
16 | const LATIN_SYMBOLS_MAP = {
17 | '©': '(c)'
18 | };
19 | const GREEK_MAP = {
20 | 'α': 'a', 'β': 'b', 'γ': 'g', 'δ': 'd', 'ε': 'e', 'ζ': 'z', 'η': 'h',
21 | 'θ': '8', 'ι': 'i', 'κ': 'k', 'λ': 'l', 'μ': 'm', 'ν': 'n', 'ξ': '3',
22 | 'ο': 'o', 'π': 'p', 'ρ': 'r', 'σ': 's', 'τ': 't', 'υ': 'y', 'φ': 'f',
23 | 'χ': 'x', 'ψ': 'ps', 'ω': 'w', 'ά': 'a', 'έ': 'e', 'ί': 'i', 'ό': 'o',
24 | 'ύ': 'y', 'ή': 'h', 'ώ': 'w', 'ς': 's', 'ϊ': 'i', 'ΰ': 'y', 'ϋ': 'y',
25 | 'ΐ': 'i', 'Α': 'A', 'Β': 'B', 'Γ': 'G', 'Δ': 'D', 'Ε': 'E', 'Ζ': 'Z',
26 | 'Η': 'H', 'Θ': '8', 'Ι': 'I', 'Κ': 'K', 'Λ': 'L', 'Μ': 'M', 'Ν': 'N',
27 | 'Ξ': '3', 'Ο': 'O', 'Π': 'P', 'Ρ': 'R', 'Σ': 'S', 'Τ': 'T', 'Υ': 'Y',
28 | 'Φ': 'F', 'Χ': 'X', 'Ψ': 'PS', 'Ω': 'W', 'Ά': 'A', 'Έ': 'E', 'Ί': 'I',
29 | 'Ό': 'O', 'Ύ': 'Y', 'Ή': 'H', 'Ώ': 'W', 'Ϊ': 'I', 'Ϋ': 'Y'
30 | };
31 | const TURKISH_MAP = {
32 | 'ş': 's', 'Ş': 'S', 'ı': 'i', 'İ': 'I', 'ç': 'c', 'Ç': 'C', 'ü': 'u',
33 | 'Ü': 'U', 'ö': 'o', 'Ö': 'O', 'ğ': 'g', 'Ğ': 'G'
34 | };
35 | const ROMANIAN_MAP = {
36 | 'ă': 'a', 'î': 'i', 'ș': 's', 'ț': 't', 'â': 'a',
37 | 'Ă': 'A', 'Î': 'I', 'Ș': 'S', 'Ț': 'T', 'Â': 'A'
38 | };
39 | const RUSSIAN_MAP = {
40 | 'а': 'a', 'б': 'b', 'в': 'v', 'г': 'g', 'д': 'd', 'е': 'e', 'ё': 'yo',
41 | 'ж': 'zh', 'з': 'z', 'и': 'i', 'й': 'j', 'к': 'k', 'л': 'l', 'м': 'm',
42 | 'н': 'n', 'о': 'o', 'п': 'p', 'р': 'r', 'с': 's', 'т': 't', 'у': 'u',
43 | 'ф': 'f', 'х': 'h', 'ц': 'c', 'ч': 'ch', 'ш': 'sh', 'щ': 'sh', 'ъ': '',
44 | 'ы': 'y', 'ь': '', 'э': 'e', 'ю': 'yu', 'я': 'ya',
45 | 'А': 'A', 'Б': 'B', 'В': 'V', 'Г': 'G', 'Д': 'D', 'Е': 'E', 'Ё': 'Yo',
46 | 'Ж': 'Zh', 'З': 'Z', 'И': 'I', 'Й': 'J', 'К': 'K', 'Л': 'L', 'М': 'M',
47 | 'Н': 'N', 'О': 'O', 'П': 'P', 'Р': 'R', 'С': 'S', 'Т': 'T', 'У': 'U',
48 | 'Ф': 'F', 'Х': 'H', 'Ц': 'C', 'Ч': 'Ch', 'Ш': 'Sh', 'Щ': 'Sh', 'Ъ': '',
49 | 'Ы': 'Y', 'Ь': '', 'Э': 'E', 'Ю': 'Yu', 'Я': 'Ya'
50 | };
51 | const UKRAINIAN_MAP = {
52 | 'Є': 'Ye', 'І': 'I', 'Ї': 'Yi', 'Ґ': 'G', 'є': 'ye', 'і': 'i',
53 | 'ї': 'yi', 'ґ': 'g'
54 | };
55 | const CZECH_MAP = {
56 | 'č': 'c', 'ď': 'd', 'ě': 'e', 'ň': 'n', 'ř': 'r', 'š': 's', 'ť': 't',
57 | 'ů': 'u', 'ž': 'z', 'Č': 'C', 'Ď': 'D', 'Ě': 'E', 'Ň': 'N', 'Ř': 'R',
58 | 'Š': 'S', 'Ť': 'T', 'Ů': 'U', 'Ž': 'Z'
59 | };
60 | const SLOVAK_MAP = {
61 | 'á': 'a', 'ä': 'a', 'č': 'c', 'ď': 'd', 'é': 'e', 'í': 'i', 'ľ': 'l',
62 | 'ĺ': 'l', 'ň': 'n', 'ó': 'o', 'ô': 'o', 'ŕ': 'r', 'š': 's', 'ť': 't',
63 | 'ú': 'u', 'ý': 'y', 'ž': 'z',
64 | 'Á': 'a', 'Ä': 'A', 'Č': 'C', 'Ď': 'D', 'É': 'E', 'Í': 'I', 'Ľ': 'L',
65 | 'Ĺ': 'L', 'Ň': 'N', 'Ó': 'O', 'Ô': 'O', 'Ŕ': 'R', 'Š': 'S', 'Ť': 'T',
66 | 'Ú': 'U', 'Ý': 'Y', 'Ž': 'Z'
67 | };
68 | const POLISH_MAP = {
69 | 'ą': 'a', 'ć': 'c', 'ę': 'e', 'ł': 'l', 'ń': 'n', 'ó': 'o', 'ś': 's',
70 | 'ź': 'z', 'ż': 'z',
71 | 'Ą': 'A', 'Ć': 'C', 'Ę': 'E', 'Ł': 'L', 'Ń': 'N', 'Ó': 'O', 'Ś': 'S',
72 | 'Ź': 'Z', 'Ż': 'Z'
73 | };
74 | const LATVIAN_MAP = {
75 | 'ā': 'a', 'č': 'c', 'ē': 'e', 'ģ': 'g', 'ī': 'i', 'ķ': 'k', 'ļ': 'l',
76 | 'ņ': 'n', 'š': 's', 'ū': 'u', 'ž': 'z',
77 | 'Ā': 'A', 'Č': 'C', 'Ē': 'E', 'Ģ': 'G', 'Ī': 'I', 'Ķ': 'K', 'Ļ': 'L',
78 | 'Ņ': 'N', 'Š': 'S', 'Ū': 'U', 'Ž': 'Z'
79 | };
80 | const ARABIC_MAP = {
81 | 'أ': 'a', 'ب': 'b', 'ت': 't', 'ث': 'th', 'ج': 'g', 'ح': 'h', 'خ': 'kh', 'د': 'd',
82 | 'ذ': 'th', 'ر': 'r', 'ز': 'z', 'س': 's', 'ش': 'sh', 'ص': 's', 'ض': 'd', 'ط': 't',
83 | 'ظ': 'th', 'ع': 'aa', 'غ': 'gh', 'ف': 'f', 'ق': 'k', 'ك': 'k', 'ل': 'l', 'م': 'm',
84 | 'ن': 'n', 'ه': 'h', 'و': 'o', 'ي': 'y'
85 | };
86 | const LITHUANIAN_MAP = {
87 | 'ą': 'a', 'č': 'c', 'ę': 'e', 'ė': 'e', 'į': 'i', 'š': 's', 'ų': 'u',
88 | 'ū': 'u', 'ž': 'z',
89 | 'Ą': 'A', 'Č': 'C', 'Ę': 'E', 'Ė': 'E', 'Į': 'I', 'Š': 'S', 'Ų': 'U',
90 | 'Ū': 'U', 'Ž': 'Z'
91 | };
92 | const SERBIAN_MAP = {
93 | 'ђ': 'dj', 'ј': 'j', 'љ': 'lj', 'њ': 'nj', 'ћ': 'c', 'џ': 'dz',
94 | 'đ': 'dj', 'Ђ': 'Dj', 'Ј': 'j', 'Љ': 'Lj', 'Њ': 'Nj', 'Ћ': 'C',
95 | 'Џ': 'Dz', 'Đ': 'Dj'
96 | };
97 | const AZERBAIJANI_MAP = {
98 | 'ç': 'c', 'ə': 'e', 'ğ': 'g', 'ı': 'i', 'ö': 'o', 'ş': 's', 'ü': 'u',
99 | 'Ç': 'C', 'Ə': 'E', 'Ğ': 'G', 'İ': 'I', 'Ö': 'O', 'Ş': 'S', 'Ü': 'U'
100 | };
101 | const GEORGIAN_MAP = {
102 | 'ა': 'a', 'ბ': 'b', 'გ': 'g', 'დ': 'd', 'ე': 'e', 'ვ': 'v', 'ზ': 'z',
103 | 'თ': 't', 'ი': 'i', 'კ': 'k', 'ლ': 'l', 'მ': 'm', 'ნ': 'n', 'ო': 'o',
104 | 'პ': 'p', 'ჟ': 'j', 'რ': 'r', 'ს': 's', 'ტ': 't', 'უ': 'u', 'ფ': 'f',
105 | 'ქ': 'q', 'ღ': 'g', 'ყ': 'y', 'შ': 'sh', 'ჩ': 'ch', 'ც': 'c', 'ძ': 'dz',
106 | 'წ': 'w', 'ჭ': 'ch', 'ხ': 'x', 'ჯ': 'j', 'ჰ': 'h'
107 | };
108 |
109 | const ALL_DOWNCODE_MAPS = [
110 | LATIN_MAP,
111 | LATIN_SYMBOLS_MAP,
112 | GREEK_MAP,
113 | TURKISH_MAP,
114 | ROMANIAN_MAP,
115 | RUSSIAN_MAP,
116 | UKRAINIAN_MAP,
117 | CZECH_MAP,
118 | SLOVAK_MAP,
119 | POLISH_MAP,
120 | LATVIAN_MAP,
121 | ARABIC_MAP,
122 | LITHUANIAN_MAP,
123 | SERBIAN_MAP,
124 | AZERBAIJANI_MAP,
125 | GEORGIAN_MAP
126 | ];
127 |
128 | const Downcoder = {
129 | 'Initialize': function() {
130 | if (Downcoder.map) { // already made
131 | return;
132 | }
133 | Downcoder.map = {};
134 | for (const lookup of ALL_DOWNCODE_MAPS) {
135 | Object.assign(Downcoder.map, lookup);
136 | }
137 | Downcoder.regex = new RegExp(Object.keys(Downcoder.map).join('|'), 'g');
138 | }
139 | };
140 |
141 | function downcode(slug) {
142 | Downcoder.Initialize();
143 | return slug.replace(Downcoder.regex, function(m) {
144 | return Downcoder.map[m];
145 | });
146 | }
147 |
148 |
149 | function URLify(s, num_chars, allowUnicode) {
150 | // changes, e.g., "Petty theft" to "petty-theft"
151 | if (!allowUnicode) {
152 | s = downcode(s);
153 | }
154 | s = s.toLowerCase(); // convert to lowercase
155 | // if downcode doesn't hit, the char will be stripped here
156 | if (allowUnicode) {
157 | // Keep Unicode letters including both lowercase and uppercase
158 | // characters, whitespace, and dash; remove other characters.
159 | s = XRegExp.replace(s, XRegExp('[^-_\\p{L}\\p{N}\\s]', 'g'), '');
160 | } else {
161 | s = s.replace(/[^-\w\s]/g, ''); // remove unneeded chars
162 | }
163 | s = s.replace(/^\s+|\s+$/g, ''); // trim leading/trailing spaces
164 | s = s.replace(/[-\s]+/g, '-'); // convert spaces to hyphens
165 | s = s.substring(0, num_chars); // trim to first num_chars chars
166 | s = s.replace(/-+$/g, ''); // trim any trailing hyphens
167 | return s;
168 | }
169 | window.URLify = URLify;
170 | }
171 |
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/jquery/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright JS Foundation and other contributors, https://js.foundation/
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2012-2017 Kevin Brown, Igor Vaynberg, and Select2 contributors
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/af.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/af",[],function(){return{errorLoading:function(){return"Die resultate kon nie gelaai word nie."},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Verwyders asseblief "+n+" character";return 1!=n&&(r+="s"),r},inputTooShort:function(e){return"Voer asseblief "+(e.minimum-e.input.length)+" of meer karakters"},loadingMore:function(){return"Meer resultate word gelaai…"},maximumSelected:function(e){var n="Kies asseblief net "+e.maximum+" item";return 1!=e.maximum&&(n+="s"),n},noResults:function(){return"Geen resultate gevind"},searching:function(){return"Besig…"},removeAllItems:function(){return"Verwyder alle items"}}}),e.define,e.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/ar.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ar",[],function(){return{errorLoading:function(){return"لا يمكن تحميل النتائج"},inputTooLong:function(n){return"الرجاء حذف "+(n.input.length-n.maximum)+" عناصر"},inputTooShort:function(n){return"الرجاء إضافة "+(n.minimum-n.input.length)+" عناصر"},loadingMore:function(){return"جاري تحميل نتائج إضافية..."},maximumSelected:function(n){return"تستطيع إختيار "+n.maximum+" بنود فقط"},noResults:function(){return"لم يتم العثور على أي نتائج"},searching:function(){return"جاري البحث…"},removeAllItems:function(){return"قم بإزالة كل العناصر"}}}),n.define,n.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/az.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/az",[],function(){return{inputTooLong:function(n){return n.input.length-n.maximum+" simvol silin"},inputTooShort:function(n){return n.minimum-n.input.length+" simvol daxil edin"},loadingMore:function(){return"Daha çox nəticə yüklənir…"},maximumSelected:function(n){return"Sadəcə "+n.maximum+" element seçə bilərsiniz"},noResults:function(){return"Nəticə tapılmadı"},searching:function(){return"Axtarılır…"},removeAllItems:function(){return"Bütün elementləri sil"}}}),n.define,n.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/bg.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/bg",[],function(){return{inputTooLong:function(n){var e=n.input.length-n.maximum,u="Моля въведете с "+e+" по-малко символ";return e>1&&(u+="a"),u},inputTooShort:function(n){var e=n.minimum-n.input.length,u="Моля въведете още "+e+" символ";return e>1&&(u+="a"),u},loadingMore:function(){return"Зареждат се още…"},maximumSelected:function(n){var e="Можете да направите до "+n.maximum+" ";return n.maximum>1?e+="избора":e+="избор",e},noResults:function(){return"Няма намерени съвпадения"},searching:function(){return"Търсене…"},removeAllItems:function(){return"Премахнете всички елементи"}}}),n.define,n.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/bn.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/bn",[],function(){return{errorLoading:function(){return"ফলাফলগুলি লোড করা যায়নি।"},inputTooLong:function(n){var e=n.input.length-n.maximum,u="অনুগ্রহ করে "+e+" টি অক্ষর মুছে দিন।";return 1!=e&&(u="অনুগ্রহ করে "+e+" টি অক্ষর মুছে দিন।"),u},inputTooShort:function(n){return n.minimum-n.input.length+" টি অক্ষর অথবা অধিক অক্ষর লিখুন।"},loadingMore:function(){return"আরো ফলাফল লোড হচ্ছে ..."},maximumSelected:function(n){var e=n.maximum+" টি আইটেম নির্বাচন করতে পারবেন।";return 1!=n.maximum&&(e=n.maximum+" টি আইটেম নির্বাচন করতে পারবেন।"),e},noResults:function(){return"কোন ফলাফল পাওয়া যায়নি।"},searching:function(){return"অনুসন্ধান করা হচ্ছে ..."}}}),n.define,n.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/bs.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/bs",[],function(){function e(e,n,r,t){return e%10==1&&e%100!=11?n:e%10>=2&&e%10<=4&&(e%100<12||e%100>14)?r:t}return{errorLoading:function(){return"Preuzimanje nije uspijelo."},inputTooLong:function(n){var r=n.input.length-n.maximum,t="Obrišite "+r+" simbol";return t+=e(r,"","a","a")},inputTooShort:function(n){var r=n.minimum-n.input.length,t="Ukucajte bar još "+r+" simbol";return t+=e(r,"","a","a")},loadingMore:function(){return"Preuzimanje još rezultata…"},maximumSelected:function(n){var r="Možete izabrati samo "+n.maximum+" stavk";return r+=e(n.maximum,"u","e","i")},noResults:function(){return"Ništa nije pronađeno"},searching:function(){return"Pretraga…"},removeAllItems:function(){return"Uklonite sve stavke"}}}),e.define,e.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/ca.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/ca",[],function(){return{errorLoading:function(){return"La càrrega ha fallat"},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Si us plau, elimina "+n+" car";return r+=1==n?"àcter":"àcters"},inputTooShort:function(e){var n=e.minimum-e.input.length,r="Si us plau, introdueix "+n+" car";return r+=1==n?"àcter":"àcters"},loadingMore:function(){return"Carregant més resultats…"},maximumSelected:function(e){var n="Només es pot seleccionar "+e.maximum+" element";return 1!=e.maximum&&(n+="s"),n},noResults:function(){return"No s'han trobat resultats"},searching:function(){return"Cercant…"},removeAllItems:function(){return"Treu tots els elements"}}}),e.define,e.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/cs.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/cs",[],function(){function e(e,n){switch(e){case 2:return n?"dva":"dvě";case 3:return"tři";case 4:return"čtyři"}return""}return{errorLoading:function(){return"Výsledky nemohly být načteny."},inputTooLong:function(n){var t=n.input.length-n.maximum;return 1==t?"Prosím, zadejte o jeden znak méně.":t<=4?"Prosím, zadejte o "+e(t,!0)+" znaky méně.":"Prosím, zadejte o "+t+" znaků méně."},inputTooShort:function(n){var t=n.minimum-n.input.length;return 1==t?"Prosím, zadejte ještě jeden znak.":t<=4?"Prosím, zadejte ještě další "+e(t,!0)+" znaky.":"Prosím, zadejte ještě dalších "+t+" znaků."},loadingMore:function(){return"Načítají se další výsledky…"},maximumSelected:function(n){var t=n.maximum;return 1==t?"Můžete zvolit jen jednu položku.":t<=4?"Můžete zvolit maximálně "+e(t,!1)+" položky.":"Můžete zvolit maximálně "+t+" položek."},noResults:function(){return"Nenalezeny žádné položky."},searching:function(){return"Vyhledávání…"},removeAllItems:function(){return"Odstraňte všechny položky"}}}),e.define,e.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/da.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/da",[],function(){return{errorLoading:function(){return"Resultaterne kunne ikke indlæses."},inputTooLong:function(e){return"Angiv venligst "+(e.input.length-e.maximum)+" tegn mindre"},inputTooShort:function(e){return"Angiv venligst "+(e.minimum-e.input.length)+" tegn mere"},loadingMore:function(){return"Indlæser flere resultater…"},maximumSelected:function(e){var n="Du kan kun vælge "+e.maximum+" emne";return 1!=e.maximum&&(n+="r"),n},noResults:function(){return"Ingen resultater fundet"},searching:function(){return"Søger…"},removeAllItems:function(){return"Fjern alle elementer"}}}),e.define,e.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/de.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/de",[],function(){return{errorLoading:function(){return"Die Ergebnisse konnten nicht geladen werden."},inputTooLong:function(e){return"Bitte "+(e.input.length-e.maximum)+" Zeichen weniger eingeben"},inputTooShort:function(e){return"Bitte "+(e.minimum-e.input.length)+" Zeichen mehr eingeben"},loadingMore:function(){return"Lade mehr Ergebnisse…"},maximumSelected:function(e){var n="Sie können nur "+e.maximum+" Element";return 1!=e.maximum&&(n+="e"),n+=" auswählen"},noResults:function(){return"Keine Übereinstimmungen gefunden"},searching:function(){return"Suche…"},removeAllItems:function(){return"Entferne alle Elemente"}}}),e.define,e.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/dsb.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/dsb",[],function(){var n=["znamuško","znamušce","znamuška","znamuškow"],e=["zapisk","zapiska","zapiski","zapiskow"],u=function(n,e){return 1===n?e[0]:2===n?e[1]:n>2&&n<=4?e[2]:n>=5?e[3]:void 0};return{errorLoading:function(){return"Wuslědki njejsu se dali zacytaś."},inputTooLong:function(e){var a=e.input.length-e.maximum;return"Pšosym lašuj "+a+" "+u(a,n)},inputTooShort:function(e){var a=e.minimum-e.input.length;return"Pšosym zapódaj nanejmjenjej "+a+" "+u(a,n)},loadingMore:function(){return"Dalšne wuslědki se zacytaju…"},maximumSelected:function(n){return"Móžoš jano "+n.maximum+" "+u(n.maximum,e)+"wubraś."},noResults:function(){return"Žedne wuslědki namakane"},searching:function(){return"Pyta se…"},removeAllItems:function(){return"Remove all items"}}}),n.define,n.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/el.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/el",[],function(){return{errorLoading:function(){return"Τα αποτελέσματα δεν μπόρεσαν να φορτώσουν."},inputTooLong:function(n){var e=n.input.length-n.maximum,u="Παρακαλώ διαγράψτε "+e+" χαρακτήρ";return 1==e&&(u+="α"),1!=e&&(u+="ες"),u},inputTooShort:function(n){return"Παρακαλώ συμπληρώστε "+(n.minimum-n.input.length)+" ή περισσότερους χαρακτήρες"},loadingMore:function(){return"Φόρτωση περισσότερων αποτελεσμάτων…"},maximumSelected:function(n){var e="Μπορείτε να επιλέξετε μόνο "+n.maximum+" επιλογ";return 1==n.maximum&&(e+="ή"),1!=n.maximum&&(e+="ές"),e},noResults:function(){return"Δεν βρέθηκαν αποτελέσματα"},searching:function(){return"Αναζήτηση…"},removeAllItems:function(){return"Καταργήστε όλα τα στοιχεία"}}}),n.define,n.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/en.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/en",[],function(){return{errorLoading:function(){return"The results could not be loaded."},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Please delete "+n+" character";return 1!=n&&(r+="s"),r},inputTooShort:function(e){return"Please enter "+(e.minimum-e.input.length)+" or more characters"},loadingMore:function(){return"Loading more results…"},maximumSelected:function(e){var n="You can only select "+e.maximum+" item";return 1!=e.maximum&&(n+="s"),n},noResults:function(){return"No results found"},searching:function(){return"Searching…"},removeAllItems:function(){return"Remove all items"}}}),e.define,e.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/es.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/es",[],function(){return{errorLoading:function(){return"No se pudieron cargar los resultados"},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Por favor, elimine "+n+" car";return r+=1==n?"ácter":"acteres"},inputTooShort:function(e){var n=e.minimum-e.input.length,r="Por favor, introduzca "+n+" car";return r+=1==n?"ácter":"acteres"},loadingMore:function(){return"Cargando más resultados…"},maximumSelected:function(e){var n="Sólo puede seleccionar "+e.maximum+" elemento";return 1!=e.maximum&&(n+="s"),n},noResults:function(){return"No se encontraron resultados"},searching:function(){return"Buscando…"},removeAllItems:function(){return"Eliminar todos los elementos"}}}),e.define,e.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/et.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/et",[],function(){return{inputTooLong:function(e){var n=e.input.length-e.maximum,t="Sisesta "+n+" täht";return 1!=n&&(t+="e"),t+=" vähem"},inputTooShort:function(e){var n=e.minimum-e.input.length,t="Sisesta "+n+" täht";return 1!=n&&(t+="e"),t+=" rohkem"},loadingMore:function(){return"Laen tulemusi…"},maximumSelected:function(e){var n="Saad vaid "+e.maximum+" tulemus";return 1==e.maximum?n+="e":n+="t",n+=" valida"},noResults:function(){return"Tulemused puuduvad"},searching:function(){return"Otsin…"},removeAllItems:function(){return"Eemalda kõik esemed"}}}),e.define,e.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/eu.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/eu",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="Idatzi ";return n+=1==t?"karaktere bat":t+" karaktere",n+=" gutxiago"},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Idatzi ";return n+=1==t?"karaktere bat":t+" karaktere",n+=" gehiago"},loadingMore:function(){return"Emaitza gehiago kargatzen…"},maximumSelected:function(e){return 1===e.maximum?"Elementu bakarra hauta dezakezu":e.maximum+" elementu hauta ditzakezu soilik"},noResults:function(){return"Ez da bat datorrenik aurkitu"},searching:function(){return"Bilatzen…"},removeAllItems:function(){return"Kendu elementu guztiak"}}}),e.define,e.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/fa.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/fa",[],function(){return{errorLoading:function(){return"امکان بارگذاری نتایج وجود ندارد."},inputTooLong:function(n){return"لطفاً "+(n.input.length-n.maximum)+" کاراکتر را حذف نمایید"},inputTooShort:function(n){return"لطفاً تعداد "+(n.minimum-n.input.length)+" کاراکتر یا بیشتر وارد نمایید"},loadingMore:function(){return"در حال بارگذاری نتایج بیشتر..."},maximumSelected:function(n){return"شما تنها میتوانید "+n.maximum+" آیتم را انتخاب نمایید"},noResults:function(){return"هیچ نتیجهای یافت نشد"},searching:function(){return"در حال جستجو..."},removeAllItems:function(){return"همه موارد را حذف کنید"}}}),n.define,n.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/fi.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/fi",[],function(){return{errorLoading:function(){return"Tuloksia ei saatu ladattua."},inputTooLong:function(n){return"Ole hyvä ja anna "+(n.input.length-n.maximum)+" merkkiä vähemmän"},inputTooShort:function(n){return"Ole hyvä ja anna "+(n.minimum-n.input.length)+" merkkiä lisää"},loadingMore:function(){return"Ladataan lisää tuloksia…"},maximumSelected:function(n){return"Voit valita ainoastaan "+n.maximum+" kpl"},noResults:function(){return"Ei tuloksia"},searching:function(){return"Haetaan…"},removeAllItems:function(){return"Poista kaikki kohteet"}}}),n.define,n.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/fr.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/fr",[],function(){return{errorLoading:function(){return"Les résultats ne peuvent pas être chargés."},inputTooLong:function(e){var n=e.input.length-e.maximum;return"Supprimez "+n+" caractère"+(n>1?"s":"")},inputTooShort:function(e){var n=e.minimum-e.input.length;return"Saisissez au moins "+n+" caractère"+(n>1?"s":"")},loadingMore:function(){return"Chargement de résultats supplémentaires…"},maximumSelected:function(e){return"Vous pouvez seulement sélectionner "+e.maximum+" élément"+(e.maximum>1?"s":"")},noResults:function(){return"Aucun résultat trouvé"},searching:function(){return"Recherche en cours…"},removeAllItems:function(){return"Supprimer tous les éléments"}}}),e.define,e.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/gl.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/gl",[],function(){return{errorLoading:function(){return"Non foi posíbel cargar os resultados."},inputTooLong:function(e){var n=e.input.length-e.maximum;return 1===n?"Elimine un carácter":"Elimine "+n+" caracteres"},inputTooShort:function(e){var n=e.minimum-e.input.length;return 1===n?"Engada un carácter":"Engada "+n+" caracteres"},loadingMore:function(){return"Cargando máis resultados…"},maximumSelected:function(e){return 1===e.maximum?"Só pode seleccionar un elemento":"Só pode seleccionar "+e.maximum+" elementos"},noResults:function(){return"Non se atoparon resultados"},searching:function(){return"Buscando…"},removeAllItems:function(){return"Elimina todos os elementos"}}}),e.define,e.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/he.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/he",[],function(){return{errorLoading:function(){return"שגיאה בטעינת התוצאות"},inputTooLong:function(n){var e=n.input.length-n.maximum,r="נא למחוק ";return r+=1===e?"תו אחד":e+" תווים"},inputTooShort:function(n){var e=n.minimum-n.input.length,r="נא להכניס ";return r+=1===e?"תו אחד":e+" תווים",r+=" או יותר"},loadingMore:function(){return"טוען תוצאות נוספות…"},maximumSelected:function(n){var e="באפשרותך לבחור עד ";return 1===n.maximum?e+="פריט אחד":e+=n.maximum+" פריטים",e},noResults:function(){return"לא נמצאו תוצאות"},searching:function(){return"מחפש…"},removeAllItems:function(){return"הסר את כל הפריטים"}}}),n.define,n.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/hi.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/hi",[],function(){return{errorLoading:function(){return"परिणामों को लोड नहीं किया जा सका।"},inputTooLong:function(n){var e=n.input.length-n.maximum,r=e+" अक्षर को हटा दें";return e>1&&(r=e+" अक्षरों को हटा दें "),r},inputTooShort:function(n){return"कृपया "+(n.minimum-n.input.length)+" या अधिक अक्षर दर्ज करें"},loadingMore:function(){return"अधिक परिणाम लोड हो रहे है..."},maximumSelected:function(n){return"आप केवल "+n.maximum+" आइटम का चयन कर सकते हैं"},noResults:function(){return"कोई परिणाम नहीं मिला"},searching:function(){return"खोज रहा है..."},removeAllItems:function(){return"सभी वस्तुओं को हटा दें"}}}),n.define,n.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/hr.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/hr",[],function(){function n(n){var e=" "+n+" znak";return n%10<5&&n%10>0&&(n%100<5||n%100>19)?n%10>1&&(e+="a"):e+="ova",e}return{errorLoading:function(){return"Preuzimanje nije uspjelo."},inputTooLong:function(e){return"Unesite "+n(e.input.length-e.maximum)},inputTooShort:function(e){return"Unesite još "+n(e.minimum-e.input.length)},loadingMore:function(){return"Učitavanje rezultata…"},maximumSelected:function(n){return"Maksimalan broj odabranih stavki je "+n.maximum},noResults:function(){return"Nema rezultata"},searching:function(){return"Pretraga…"},removeAllItems:function(){return"Ukloni sve stavke"}}}),n.define,n.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/hsb.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/hsb",[],function(){var n=["znamješko","znamješce","znamješka","znamješkow"],e=["zapisk","zapiskaj","zapiski","zapiskow"],u=function(n,e){return 1===n?e[0]:2===n?e[1]:n>2&&n<=4?e[2]:n>=5?e[3]:void 0};return{errorLoading:function(){return"Wuslědki njedachu so začitać."},inputTooLong:function(e){var a=e.input.length-e.maximum;return"Prošu zhašej "+a+" "+u(a,n)},inputTooShort:function(e){var a=e.minimum-e.input.length;return"Prošu zapodaj znajmjeńša "+a+" "+u(a,n)},loadingMore:function(){return"Dalše wuslědki so začitaja…"},maximumSelected:function(n){return"Móžeš jenož "+n.maximum+" "+u(n.maximum,e)+"wubrać"},noResults:function(){return"Žane wuslědki namakane"},searching:function(){return"Pyta so…"},removeAllItems:function(){return"Remove all items"}}}),n.define,n.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/hu.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/hu",[],function(){return{errorLoading:function(){return"Az eredmények betöltése nem sikerült."},inputTooLong:function(e){return"Túl hosszú. "+(e.input.length-e.maximum)+" karakterrel több, mint kellene."},inputTooShort:function(e){return"Túl rövid. Még "+(e.minimum-e.input.length)+" karakter hiányzik."},loadingMore:function(){return"Töltés…"},maximumSelected:function(e){return"Csak "+e.maximum+" elemet lehet kiválasztani."},noResults:function(){return"Nincs találat."},searching:function(){return"Keresés…"},removeAllItems:function(){return"Távolítson el minden elemet"}}}),e.define,e.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/hy.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/hy",[],function(){return{errorLoading:function(){return"Արդյունքները հնարավոր չէ բեռնել։"},inputTooLong:function(n){return"Խնդրում ենք հեռացնել "+(n.input.length-n.maximum)+" նշան"},inputTooShort:function(n){return"Խնդրում ենք մուտքագրել "+(n.minimum-n.input.length)+" կամ ավել նշաններ"},loadingMore:function(){return"Բեռնվում են նոր արդյունքներ․․․"},maximumSelected:function(n){return"Դուք կարող եք ընտրել առավելագույնը "+n.maximum+" կետ"},noResults:function(){return"Արդյունքներ չեն գտնվել"},searching:function(){return"Որոնում․․․"},removeAllItems:function(){return"Հեռացնել բոլոր տարրերը"}}}),n.define,n.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/id.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/id",[],function(){return{errorLoading:function(){return"Data tidak boleh diambil."},inputTooLong:function(n){return"Hapuskan "+(n.input.length-n.maximum)+" huruf"},inputTooShort:function(n){return"Masukkan "+(n.minimum-n.input.length)+" huruf lagi"},loadingMore:function(){return"Mengambil data…"},maximumSelected:function(n){return"Anda hanya dapat memilih "+n.maximum+" pilihan"},noResults:function(){return"Tidak ada data yang sesuai"},searching:function(){return"Mencari…"},removeAllItems:function(){return"Hapus semua item"}}}),n.define,n.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/is.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/is",[],function(){return{inputTooLong:function(n){var t=n.input.length-n.maximum,e="Vinsamlegast styttið texta um "+t+" staf";return t<=1?e:e+"i"},inputTooShort:function(n){var t=n.minimum-n.input.length,e="Vinsamlegast skrifið "+t+" staf";return t>1&&(e+="i"),e+=" í viðbót"},loadingMore:function(){return"Sæki fleiri niðurstöður…"},maximumSelected:function(n){return"Þú getur aðeins valið "+n.maximum+" atriði"},noResults:function(){return"Ekkert fannst"},searching:function(){return"Leita…"},removeAllItems:function(){return"Fjarlægðu öll atriði"}}}),n.define,n.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/it.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/it",[],function(){return{errorLoading:function(){return"I risultati non possono essere caricati."},inputTooLong:function(e){var n=e.input.length-e.maximum,t="Per favore cancella "+n+" caratter";return t+=1!==n?"i":"e"},inputTooShort:function(e){return"Per favore inserisci "+(e.minimum-e.input.length)+" o più caratteri"},loadingMore:function(){return"Caricando più risultati…"},maximumSelected:function(e){var n="Puoi selezionare solo "+e.maximum+" element";return 1!==e.maximum?n+="i":n+="o",n},noResults:function(){return"Nessun risultato trovato"},searching:function(){return"Sto cercando…"},removeAllItems:function(){return"Rimuovi tutti gli oggetti"}}}),e.define,e.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/ja.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ja",[],function(){return{errorLoading:function(){return"結果が読み込まれませんでした"},inputTooLong:function(n){return n.input.length-n.maximum+" 文字を削除してください"},inputTooShort:function(n){return"少なくとも "+(n.minimum-n.input.length)+" 文字を入力してください"},loadingMore:function(){return"読み込み中…"},maximumSelected:function(n){return n.maximum+" 件しか選択できません"},noResults:function(){return"対象が見つかりません"},searching:function(){return"検索しています…"},removeAllItems:function(){return"すべてのアイテムを削除"}}}),n.define,n.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/ka.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ka",[],function(){return{errorLoading:function(){return"მონაცემების ჩატვირთვა შეუძლებელია."},inputTooLong:function(n){return"გთხოვთ აკრიფეთ "+(n.input.length-n.maximum)+" სიმბოლოთი ნაკლები"},inputTooShort:function(n){return"გთხოვთ აკრიფეთ "+(n.minimum-n.input.length)+" სიმბოლო ან მეტი"},loadingMore:function(){return"მონაცემების ჩატვირთვა…"},maximumSelected:function(n){return"თქვენ შეგიძლიათ აირჩიოთ არაუმეტეს "+n.maximum+" ელემენტი"},noResults:function(){return"რეზულტატი არ მოიძებნა"},searching:function(){return"ძიება…"},removeAllItems:function(){return"ამოიღე ყველა ელემენტი"}}}),n.define,n.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/km.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/km",[],function(){return{errorLoading:function(){return"មិនអាចទាញយកទិន្នន័យ"},inputTooLong:function(n){return"សូមលុបចេញ "+(n.input.length-n.maximum)+" អក្សរ"},inputTooShort:function(n){return"សូមបញ្ចូល"+(n.minimum-n.input.length)+" អក្សរ រឺ ច្រើនជាងនេះ"},loadingMore:function(){return"កំពុងទាញយកទិន្នន័យបន្ថែម..."},maximumSelected:function(n){return"អ្នកអាចជ្រើសរើសបានតែ "+n.maximum+" ជម្រើសប៉ុណ្ណោះ"},noResults:function(){return"មិនមានលទ្ធផល"},searching:function(){return"កំពុងស្វែងរក..."},removeAllItems:function(){return"លុបធាតុទាំងអស់"}}}),n.define,n.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/ko.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ko",[],function(){return{errorLoading:function(){return"결과를 불러올 수 없습니다."},inputTooLong:function(n){return"너무 깁니다. "+(n.input.length-n.maximum)+" 글자 지워주세요."},inputTooShort:function(n){return"너무 짧습니다. "+(n.minimum-n.input.length)+" 글자 더 입력해주세요."},loadingMore:function(){return"불러오는 중…"},maximumSelected:function(n){return"최대 "+n.maximum+"개까지만 선택 가능합니다."},noResults:function(){return"결과가 없습니다."},searching:function(){return"검색 중…"},removeAllItems:function(){return"모든 항목 삭제"}}}),n.define,n.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/lt.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/lt",[],function(){function n(n,e,i,t){return n%10==1&&(n%100<11||n%100>19)?e:n%10>=2&&n%10<=9&&(n%100<11||n%100>19)?i:t}return{inputTooLong:function(e){var i=e.input.length-e.maximum,t="Pašalinkite "+i+" simbol";return t+=n(i,"į","ius","ių")},inputTooShort:function(e){var i=e.minimum-e.input.length,t="Įrašykite dar "+i+" simbol";return t+=n(i,"į","ius","ių")},loadingMore:function(){return"Kraunama daugiau rezultatų…"},maximumSelected:function(e){var i="Jūs galite pasirinkti tik "+e.maximum+" element";return i+=n(e.maximum,"ą","us","ų")},noResults:function(){return"Atitikmenų nerasta"},searching:function(){return"Ieškoma…"},removeAllItems:function(){return"Pašalinti visus elementus"}}}),n.define,n.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/lv.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/lv",[],function(){function e(e,n,u,i){return 11===e?n:e%10==1?u:i}return{inputTooLong:function(n){var u=n.input.length-n.maximum,i="Lūdzu ievadiet par "+u;return(i+=" simbol"+e(u,"iem","u","iem"))+" mazāk"},inputTooShort:function(n){var u=n.minimum-n.input.length,i="Lūdzu ievadiet vēl "+u;return i+=" simbol"+e(u,"us","u","us")},loadingMore:function(){return"Datu ielāde…"},maximumSelected:function(n){var u="Jūs varat izvēlēties ne vairāk kā "+n.maximum;return u+=" element"+e(n.maximum,"us","u","us")},noResults:function(){return"Sakritību nav"},searching:function(){return"Meklēšana…"},removeAllItems:function(){return"Noņemt visus vienumus"}}}),e.define,e.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/mk.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/mk",[],function(){return{inputTooLong:function(n){var e=(n.input.length,n.maximum,"Ве молиме внесете "+n.maximum+" помалку карактер");return 1!==n.maximum&&(e+="и"),e},inputTooShort:function(n){var e=(n.minimum,n.input.length,"Ве молиме внесете уште "+n.maximum+" карактер");return 1!==n.maximum&&(e+="и"),e},loadingMore:function(){return"Вчитување резултати…"},maximumSelected:function(n){var e="Можете да изберете само "+n.maximum+" ставк";return 1===n.maximum?e+="а":e+="и",e},noResults:function(){return"Нема пронајдено совпаѓања"},searching:function(){return"Пребарување…"},removeAllItems:function(){return"Отстрани ги сите предмети"}}}),n.define,n.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/ms.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ms",[],function(){return{errorLoading:function(){return"Keputusan tidak berjaya dimuatkan."},inputTooLong:function(n){return"Sila hapuskan "+(n.input.length-n.maximum)+" aksara"},inputTooShort:function(n){return"Sila masukkan "+(n.minimum-n.input.length)+" atau lebih aksara"},loadingMore:function(){return"Sedang memuatkan keputusan…"},maximumSelected:function(n){return"Anda hanya boleh memilih "+n.maximum+" pilihan"},noResults:function(){return"Tiada padanan yang ditemui"},searching:function(){return"Mencari…"},removeAllItems:function(){return"Keluarkan semua item"}}}),n.define,n.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/nb.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/nb",[],function(){return{errorLoading:function(){return"Kunne ikke hente resultater."},inputTooLong:function(e){return"Vennligst fjern "+(e.input.length-e.maximum)+" tegn"},inputTooShort:function(e){return"Vennligst skriv inn "+(e.minimum-e.input.length)+" tegn til"},loadingMore:function(){return"Laster flere resultater…"},maximumSelected:function(e){return"Du kan velge maks "+e.maximum+" elementer"},noResults:function(){return"Ingen treff"},searching:function(){return"Søker…"},removeAllItems:function(){return"Fjern alle elementer"}}}),e.define,e.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/ne.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ne",[],function(){return{errorLoading:function(){return"नतिजाहरु देखाउन सकिएन।"},inputTooLong:function(n){var e=n.input.length-n.maximum,u="कृपया "+e+" अक्षर मेटाउनुहोस्।";return 1!=e&&(u+="कृपया "+e+" अक्षरहरु मेटाउनुहोस्।"),u},inputTooShort:function(n){return"कृपया बाँकी रहेका "+(n.minimum-n.input.length)+" वा अरु धेरै अक्षरहरु भर्नुहोस्।"},loadingMore:function(){return"अरु नतिजाहरु भरिँदैछन् …"},maximumSelected:function(n){var e="तँपाई "+n.maximum+" वस्तु मात्र छान्न पाउँनुहुन्छ।";return 1!=n.maximum&&(e="तँपाई "+n.maximum+" वस्तुहरु मात्र छान्न पाउँनुहुन्छ।"),e},noResults:function(){return"कुनै पनि नतिजा भेटिएन।"},searching:function(){return"खोजि हुँदैछ…"}}}),n.define,n.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/nl.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/nl",[],function(){return{errorLoading:function(){return"De resultaten konden niet worden geladen."},inputTooLong:function(e){return"Gelieve "+(e.input.length-e.maximum)+" karakters te verwijderen"},inputTooShort:function(e){return"Gelieve "+(e.minimum-e.input.length)+" of meer karakters in te voeren"},loadingMore:function(){return"Meer resultaten laden…"},maximumSelected:function(e){var n=1==e.maximum?"kan":"kunnen",r="Er "+n+" maar "+e.maximum+" item";return 1!=e.maximum&&(r+="s"),r+=" worden geselecteerd"},noResults:function(){return"Geen resultaten gevonden…"},searching:function(){return"Zoeken…"},removeAllItems:function(){return"Verwijder alle items"}}}),e.define,e.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/pl.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/pl",[],function(){var n=["znak","znaki","znaków"],e=["element","elementy","elementów"],r=function(n,e){return 1===n?e[0]:n>1&&n<=4?e[1]:n>=5?e[2]:void 0};return{errorLoading:function(){return"Nie można załadować wyników."},inputTooLong:function(e){var t=e.input.length-e.maximum;return"Usuń "+t+" "+r(t,n)},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Podaj przynajmniej "+t+" "+r(t,n)},loadingMore:function(){return"Trwa ładowanie…"},maximumSelected:function(n){return"Możesz zaznaczyć tylko "+n.maximum+" "+r(n.maximum,e)},noResults:function(){return"Brak wyników"},searching:function(){return"Trwa wyszukiwanie…"},removeAllItems:function(){return"Usuń wszystkie przedmioty"}}}),n.define,n.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/ps.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ps",[],function(){return{errorLoading:function(){return"پايلي نه سي ترلاسه کېدای"},inputTooLong:function(n){var e=n.input.length-n.maximum,r="د مهربانۍ لمخي "+e+" توری ړنګ کړئ";return 1!=e&&(r=r.replace("توری","توري")),r},inputTooShort:function(n){return"لږ تر لږه "+(n.minimum-n.input.length)+" يا ډېر توري وليکئ"},loadingMore:function(){return"نوري پايلي ترلاسه کيږي..."},maximumSelected:function(n){var e="تاسو يوازي "+n.maximum+" قلم په نښه کولای سی";return 1!=n.maximum&&(e=e.replace("قلم","قلمونه")),e},noResults:function(){return"پايلي و نه موندل سوې"},searching:function(){return"لټول کيږي..."},removeAllItems:function(){return"ټول توکي لرې کړئ"}}}),n.define,n.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/pt-BR.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/pt-BR",[],function(){return{errorLoading:function(){return"Os resultados não puderam ser carregados."},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Apague "+n+" caracter";return 1!=n&&(r+="es"),r},inputTooShort:function(e){return"Digite "+(e.minimum-e.input.length)+" ou mais caracteres"},loadingMore:function(){return"Carregando mais resultados…"},maximumSelected:function(e){var n="Você só pode selecionar "+e.maximum+" ite";return 1==e.maximum?n+="m":n+="ns",n},noResults:function(){return"Nenhum resultado encontrado"},searching:function(){return"Buscando…"},removeAllItems:function(){return"Remover todos os itens"}}}),e.define,e.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/pt.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/pt",[],function(){return{errorLoading:function(){return"Os resultados não puderam ser carregados."},inputTooLong:function(e){var r=e.input.length-e.maximum,n="Por favor apague "+r+" ";return n+=1!=r?"caracteres":"caractere"},inputTooShort:function(e){return"Introduza "+(e.minimum-e.input.length)+" ou mais caracteres"},loadingMore:function(){return"A carregar mais resultados…"},maximumSelected:function(e){var r="Apenas pode seleccionar "+e.maximum+" ";return r+=1!=e.maximum?"itens":"item"},noResults:function(){return"Sem resultados"},searching:function(){return"A procurar…"},removeAllItems:function(){return"Remover todos os itens"}}}),e.define,e.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/ro.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/ro",[],function(){return{errorLoading:function(){return"Rezultatele nu au putut fi incărcate."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Vă rugăm să ștergeți"+t+" caracter";return 1!==t&&(n+="e"),n},inputTooShort:function(e){return"Vă rugăm să introduceți "+(e.minimum-e.input.length)+" sau mai multe caractere"},loadingMore:function(){return"Se încarcă mai multe rezultate…"},maximumSelected:function(e){var t="Aveți voie să selectați cel mult "+e.maximum;return t+=" element",1!==e.maximum&&(t+="e"),t},noResults:function(){return"Nu au fost găsite rezultate"},searching:function(){return"Căutare…"},removeAllItems:function(){return"Eliminați toate elementele"}}}),e.define,e.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/ru.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ru",[],function(){function n(n,e,r,u){return n%10<5&&n%10>0&&n%100<5||n%100>20?n%10>1?r:e:u}return{errorLoading:function(){return"Невозможно загрузить результаты"},inputTooLong:function(e){var r=e.input.length-e.maximum,u="Пожалуйста, введите на "+r+" символ";return u+=n(r,"","a","ов"),u+=" меньше"},inputTooShort:function(e){var r=e.minimum-e.input.length,u="Пожалуйста, введите ещё хотя бы "+r+" символ";return u+=n(r,"","a","ов")},loadingMore:function(){return"Загрузка данных…"},maximumSelected:function(e){var r="Вы можете выбрать не более "+e.maximum+" элемент";return r+=n(e.maximum,"","a","ов")},noResults:function(){return"Совпадений не найдено"},searching:function(){return"Поиск…"},removeAllItems:function(){return"Удалить все элементы"}}}),n.define,n.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/sk.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/sk",[],function(){var e={2:function(e){return e?"dva":"dve"},3:function(){return"tri"},4:function(){return"štyri"}};return{errorLoading:function(){return"Výsledky sa nepodarilo načítať."},inputTooLong:function(n){var t=n.input.length-n.maximum;return 1==t?"Prosím, zadajte o jeden znak menej":t>=2&&t<=4?"Prosím, zadajte o "+e[t](!0)+" znaky menej":"Prosím, zadajte o "+t+" znakov menej"},inputTooShort:function(n){var t=n.minimum-n.input.length;return 1==t?"Prosím, zadajte ešte jeden znak":t<=4?"Prosím, zadajte ešte ďalšie "+e[t](!0)+" znaky":"Prosím, zadajte ešte ďalších "+t+" znakov"},loadingMore:function(){return"Načítanie ďalších výsledkov…"},maximumSelected:function(n){return 1==n.maximum?"Môžete zvoliť len jednu položku":n.maximum>=2&&n.maximum<=4?"Môžete zvoliť najviac "+e[n.maximum](!1)+" položky":"Môžete zvoliť najviac "+n.maximum+" položiek"},noResults:function(){return"Nenašli sa žiadne položky"},searching:function(){return"Vyhľadávanie…"},removeAllItems:function(){return"Odstráňte všetky položky"}}}),e.define,e.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/sl.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/sl",[],function(){return{errorLoading:function(){return"Zadetkov iskanja ni bilo mogoče naložiti."},inputTooLong:function(e){var n=e.input.length-e.maximum,t="Prosim zbrišite "+n+" znak";return 2==n?t+="a":1!=n&&(t+="e"),t},inputTooShort:function(e){var n=e.minimum-e.input.length,t="Prosim vpišite še "+n+" znak";return 2==n?t+="a":1!=n&&(t+="e"),t},loadingMore:function(){return"Nalagam več zadetkov…"},maximumSelected:function(e){var n="Označite lahko največ "+e.maximum+" predmet";return 2==e.maximum?n+="a":1!=e.maximum&&(n+="e"),n},noResults:function(){return"Ni zadetkov."},searching:function(){return"Iščem…"},removeAllItems:function(){return"Odstranite vse elemente"}}}),e.define,e.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/sq.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/sq",[],function(){return{errorLoading:function(){return"Rezultatet nuk mund të ngarkoheshin."},inputTooLong:function(e){var n=e.input.length-e.maximum,t="Të lutem fshi "+n+" karakter";return 1!=n&&(t+="e"),t},inputTooShort:function(e){return"Të lutem shkruaj "+(e.minimum-e.input.length)+" ose më shumë karaktere"},loadingMore:function(){return"Duke ngarkuar më shumë rezultate…"},maximumSelected:function(e){var n="Mund të zgjedhësh vetëm "+e.maximum+" element";return 1!=e.maximum&&(n+="e"),n},noResults:function(){return"Nuk u gjet asnjë rezultat"},searching:function(){return"Duke kërkuar…"},removeAllItems:function(){return"Hiq të gjitha sendet"}}}),e.define,e.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/sr-Cyrl.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/sr-Cyrl",[],function(){function n(n,e,r,u){return n%10==1&&n%100!=11?e:n%10>=2&&n%10<=4&&(n%100<12||n%100>14)?r:u}return{errorLoading:function(){return"Преузимање није успело."},inputTooLong:function(e){var r=e.input.length-e.maximum,u="Обришите "+r+" симбол";return u+=n(r,"","а","а")},inputTooShort:function(e){var r=e.minimum-e.input.length,u="Укуцајте бар још "+r+" симбол";return u+=n(r,"","а","а")},loadingMore:function(){return"Преузимање још резултата…"},maximumSelected:function(e){var r="Можете изабрати само "+e.maximum+" ставк";return r+=n(e.maximum,"у","е","и")},noResults:function(){return"Ништа није пронађено"},searching:function(){return"Претрага…"},removeAllItems:function(){return"Уклоните све ставке"}}}),n.define,n.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/sr.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/sr",[],function(){function n(n,e,r,t){return n%10==1&&n%100!=11?e:n%10>=2&&n%10<=4&&(n%100<12||n%100>14)?r:t}return{errorLoading:function(){return"Preuzimanje nije uspelo."},inputTooLong:function(e){var r=e.input.length-e.maximum,t="Obrišite "+r+" simbol";return t+=n(r,"","a","a")},inputTooShort:function(e){var r=e.minimum-e.input.length,t="Ukucajte bar još "+r+" simbol";return t+=n(r,"","a","a")},loadingMore:function(){return"Preuzimanje još rezultata…"},maximumSelected:function(e){var r="Možete izabrati samo "+e.maximum+" stavk";return r+=n(e.maximum,"u","e","i")},noResults:function(){return"Ništa nije pronađeno"},searching:function(){return"Pretraga…"},removeAllItems:function(){return"Уклоните све ставке"}}}),n.define,n.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/sv.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/sv",[],function(){return{errorLoading:function(){return"Resultat kunde inte laddas."},inputTooLong:function(n){return"Vänligen sudda ut "+(n.input.length-n.maximum)+" tecken"},inputTooShort:function(n){return"Vänligen skriv in "+(n.minimum-n.input.length)+" eller fler tecken"},loadingMore:function(){return"Laddar fler resultat…"},maximumSelected:function(n){return"Du kan max välja "+n.maximum+" element"},noResults:function(){return"Inga träffar"},searching:function(){return"Söker…"},removeAllItems:function(){return"Ta bort alla objekt"}}}),n.define,n.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/th.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/th",[],function(){return{errorLoading:function(){return"ไม่สามารถค้นข้อมูลได้"},inputTooLong:function(n){return"โปรดลบออก "+(n.input.length-n.maximum)+" ตัวอักษร"},inputTooShort:function(n){return"โปรดพิมพ์เพิ่มอีก "+(n.minimum-n.input.length)+" ตัวอักษร"},loadingMore:function(){return"กำลังค้นข้อมูลเพิ่ม…"},maximumSelected:function(n){return"คุณสามารถเลือกได้ไม่เกิน "+n.maximum+" รายการ"},noResults:function(){return"ไม่พบข้อมูล"},searching:function(){return"กำลังค้นข้อมูล…"},removeAllItems:function(){return"ลบรายการทั้งหมด"}}}),n.define,n.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/tk.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/tk",[],function(){return{errorLoading:function(){return"Netije ýüklenmedi."},inputTooLong:function(e){return e.input.length-e.maximum+" harp bozuň."},inputTooShort:function(e){return"Ýene-de iň az "+(e.minimum-e.input.length)+" harp ýazyň."},loadingMore:function(){return"Köpräk netije görkezilýär…"},maximumSelected:function(e){return"Diňe "+e.maximum+" sanysyny saýlaň."},noResults:function(){return"Netije tapylmady."},searching:function(){return"Gözlenýär…"},removeAllItems:function(){return"Remove all items"}}}),e.define,e.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/tr.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/tr",[],function(){return{errorLoading:function(){return"Sonuç yüklenemedi"},inputTooLong:function(n){return n.input.length-n.maximum+" karakter daha girmelisiniz"},inputTooShort:function(n){return"En az "+(n.minimum-n.input.length)+" karakter daha girmelisiniz"},loadingMore:function(){return"Daha fazla…"},maximumSelected:function(n){return"Sadece "+n.maximum+" seçim yapabilirsiniz"},noResults:function(){return"Sonuç bulunamadı"},searching:function(){return"Aranıyor…"},removeAllItems:function(){return"Tüm öğeleri kaldır"}}}),n.define,n.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/uk.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/uk",[],function(){function n(n,e,u,r){return n%100>10&&n%100<15?r:n%10==1?e:n%10>1&&n%10<5?u:r}return{errorLoading:function(){return"Неможливо завантажити результати"},inputTooLong:function(e){return"Будь ласка, видаліть "+(e.input.length-e.maximum)+" "+n(e.maximum,"літеру","літери","літер")},inputTooShort:function(n){return"Будь ласка, введіть "+(n.minimum-n.input.length)+" або більше літер"},loadingMore:function(){return"Завантаження інших результатів…"},maximumSelected:function(e){return"Ви можете вибрати лише "+e.maximum+" "+n(e.maximum,"пункт","пункти","пунктів")},noResults:function(){return"Нічого не знайдено"},searching:function(){return"Пошук…"},removeAllItems:function(){return"Видалити всі елементи"}}}),n.define,n.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/vi.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/vi",[],function(){return{inputTooLong:function(n){return"Vui lòng xóa bớt "+(n.input.length-n.maximum)+" ký tự"},inputTooShort:function(n){return"Vui lòng nhập thêm từ "+(n.minimum-n.input.length)+" ký tự trở lên"},loadingMore:function(){return"Đang lấy thêm kết quả…"},maximumSelected:function(n){return"Chỉ có thể chọn được "+n.maximum+" lựa chọn"},noResults:function(){return"Không tìm thấy kết quả"},searching:function(){return"Đang tìm…"},removeAllItems:function(){return"Xóa tất cả các mục"}}}),n.define,n.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/zh-CN.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/zh-CN",[],function(){return{errorLoading:function(){return"无法载入结果。"},inputTooLong:function(n){return"请删除"+(n.input.length-n.maximum)+"个字符"},inputTooShort:function(n){return"请再输入至少"+(n.minimum-n.input.length)+"个字符"},loadingMore:function(){return"载入更多结果…"},maximumSelected:function(n){return"最多只能选择"+n.maximum+"个项目"},noResults:function(){return"未找到结果"},searching:function(){return"搜索中…"},removeAllItems:function(){return"删除所有项目"}}}),n.define,n.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/select2/i18n/zh-TW.js:
--------------------------------------------------------------------------------
1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
2 |
3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/zh-TW",[],function(){return{inputTooLong:function(n){return"請刪掉"+(n.input.length-n.maximum)+"個字元"},inputTooShort:function(n){return"請再輸入"+(n.minimum-n.input.length)+"個字元"},loadingMore:function(){return"載入中…"},maximumSelected:function(n){return"你只能選擇最多"+n.maximum+"項"},noResults:function(){return"沒有找到相符的項目"},searching:function(){return"搜尋中…"},removeAllItems:function(){return"刪除所有項目"}}}),n.define,n.require}();
--------------------------------------------------------------------------------
/web/static/admin/js/vendor/xregexp/LICENSE.txt:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2007-2017 Steven Levithan
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/web/static/css/chunk-0475a8a9.c54cc8a5.css:
--------------------------------------------------------------------------------
1 | .pagination-container[data-v-6a2bc7ec]{background:#fff;padding:32px 16px}.pagination-container.hidden[data-v-6a2bc7ec]{display:none}.detail-base .el-form-item{margin-bottom:2px}.demo-table-expand[data-v-81cf5baa]{font-size:0}.demo-table-expand label[data-v-81cf5baa]{width:120px;color:#99a9bf}.demo-table-expand .el-form-item[data-v-81cf5baa]{margin-right:0;margin-bottom:0;width:50%}.el-dropdown-link[data-v-81cf5baa],.to-console[data-v-81cf5baa]{cursor:pointer;font-size:12px;color:#1890ff;margin-left:10px}.el-icon-arrow-down[data-v-81cf5baa]{font-size:12px}
--------------------------------------------------------------------------------
/web/static/css/chunk-1f940af7.6bb20c54.css:
--------------------------------------------------------------------------------
1 | @supports (-webkit-mask:none) and (not (cater-color:#fff)){.login-container .el-input input{color:#fff}}.login-container .el-input{display:inline-block;height:47px;width:85%}.login-container .el-input input{background:transparent;border:0;-webkit-appearance:none;border-radius:0;padding:12px 5px 12px 15px;color:#fff;height:47px;caret-color:#fff}.login-container .el-input input:-webkit-autofill{-webkit-box-shadow:0 0 0 1000px #283443 inset!important;box-shadow:inset 0 0 0 1000px #283443!important;-webkit-text-fill-color:#fff!important}.login-container .el-form-item{border:1px solid hsla(0,0%,100%,.1);background:rgba(0,0,0,.1);border-radius:5px;color:#454545}.login-container[data-v-5f1ca375]{min-height:100%;width:100%;background-color:#2d3a4b;overflow:hidden}.login-container .login-form[data-v-5f1ca375]{position:relative;width:520px;max-width:100%;padding:160px 35px 0;margin:0 auto;overflow:hidden}.login-container .tips[data-v-5f1ca375]{font-size:14px;color:#fff;margin-bottom:10px}.login-container .tips span[data-v-5f1ca375]:first-of-type{margin-right:16px}.login-container .svg-container[data-v-5f1ca375]{padding:6px 5px 6px 15px;color:#889aa4;vertical-align:middle;width:30px;display:inline-block}.login-container .title-container[data-v-5f1ca375]{position:relative}.login-container .title-container .title[data-v-5f1ca375]{font-size:26px;color:#eee;margin:0 auto 40px auto;text-align:center;font-weight:700}.login-container .show-pwd[data-v-5f1ca375]{position:absolute;right:10px;top:7px;font-size:16px;color:#889aa4;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.login-container .thirdparty-button[data-v-5f1ca375]{position:absolute;right:0;bottom:6px}@media only screen and (max-width:470px){.login-container .thirdparty-button[data-v-5f1ca375]{display:none}}
--------------------------------------------------------------------------------
/web/static/css/chunk-50499323.e2ce212c.css:
--------------------------------------------------------------------------------
1 | .wscn-http404-container[data-v-26fcd89f]{-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);position:absolute;top:40%;left:50%}.wscn-http404[data-v-26fcd89f]{position:relative;width:1200px;padding:0 50px;overflow:hidden}.wscn-http404 .pic-404[data-v-26fcd89f]{position:relative;float:left;width:600px;overflow:hidden}.wscn-http404 .pic-404__parent[data-v-26fcd89f]{width:100%}.wscn-http404 .pic-404__child[data-v-26fcd89f]{position:absolute}.wscn-http404 .pic-404__child.left[data-v-26fcd89f]{width:80px;top:17px;left:220px;opacity:0;-webkit-animation-name:cloudLeft-data-v-26fcd89f;animation-name:cloudLeft-data-v-26fcd89f;-webkit-animation-duration:2s;animation-duration:2s;-webkit-animation-timing-function:linear;animation-timing-function:linear;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-delay:1s;animation-delay:1s}.wscn-http404 .pic-404__child.mid[data-v-26fcd89f]{width:46px;top:10px;left:420px;opacity:0;-webkit-animation-name:cloudMid-data-v-26fcd89f;animation-name:cloudMid-data-v-26fcd89f;-webkit-animation-duration:2s;animation-duration:2s;-webkit-animation-timing-function:linear;animation-timing-function:linear;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-delay:1.2s;animation-delay:1.2s}.wscn-http404 .pic-404__child.right[data-v-26fcd89f]{width:62px;top:100px;left:500px;opacity:0;-webkit-animation-name:cloudRight-data-v-26fcd89f;animation-name:cloudRight-data-v-26fcd89f;-webkit-animation-duration:2s;animation-duration:2s;-webkit-animation-timing-function:linear;animation-timing-function:linear;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-delay:1s;animation-delay:1s}@-webkit-keyframes cloudLeft-data-v-26fcd89f{0%{top:17px;left:220px;opacity:0}20%{top:33px;left:188px;opacity:1}80%{top:81px;left:92px;opacity:1}to{top:97px;left:60px;opacity:0}}@keyframes cloudLeft-data-v-26fcd89f{0%{top:17px;left:220px;opacity:0}20%{top:33px;left:188px;opacity:1}80%{top:81px;left:92px;opacity:1}to{top:97px;left:60px;opacity:0}}@-webkit-keyframes cloudMid-data-v-26fcd89f{0%{top:10px;left:420px;opacity:0}20%{top:40px;left:360px;opacity:1}70%{top:130px;left:180px;opacity:1}to{top:160px;left:120px;opacity:0}}@keyframes cloudMid-data-v-26fcd89f{0%{top:10px;left:420px;opacity:0}20%{top:40px;left:360px;opacity:1}70%{top:130px;left:180px;opacity:1}to{top:160px;left:120px;opacity:0}}@-webkit-keyframes cloudRight-data-v-26fcd89f{0%{top:100px;left:500px;opacity:0}20%{top:120px;left:460px;opacity:1}80%{top:180px;left:340px;opacity:1}to{top:200px;left:300px;opacity:0}}@keyframes cloudRight-data-v-26fcd89f{0%{top:100px;left:500px;opacity:0}20%{top:120px;left:460px;opacity:1}80%{top:180px;left:340px;opacity:1}to{top:200px;left:300px;opacity:0}}.wscn-http404 .bullshit[data-v-26fcd89f]{position:relative;float:left;width:300px;padding:30px 0;overflow:hidden}.wscn-http404 .bullshit__oops[data-v-26fcd89f]{font-size:32px;line-height:40px;color:#1482f0;margin-bottom:20px;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}.wscn-http404 .bullshit__headline[data-v-26fcd89f],.wscn-http404 .bullshit__oops[data-v-26fcd89f]{font-weight:700;opacity:0;-webkit-animation-name:slideUp-data-v-26fcd89f;animation-name:slideUp-data-v-26fcd89f;-webkit-animation-duration:.5s;animation-duration:.5s}.wscn-http404 .bullshit__headline[data-v-26fcd89f]{font-size:20px;line-height:24px;color:#222;margin-bottom:10px;-webkit-animation-delay:.1s;animation-delay:.1s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}.wscn-http404 .bullshit__info[data-v-26fcd89f]{font-size:13px;line-height:21px;color:grey;margin-bottom:30px;-webkit-animation-delay:.2s;animation-delay:.2s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}.wscn-http404 .bullshit__info[data-v-26fcd89f],.wscn-http404 .bullshit__return-home[data-v-26fcd89f]{opacity:0;-webkit-animation-name:slideUp-data-v-26fcd89f;animation-name:slideUp-data-v-26fcd89f;-webkit-animation-duration:.5s;animation-duration:.5s}.wscn-http404 .bullshit__return-home[data-v-26fcd89f]{display:block;float:left;width:110px;height:36px;background:#1482f0;border-radius:100px;text-align:center;color:#fff;font-size:14px;line-height:36px;cursor:pointer;-webkit-animation-delay:.3s;animation-delay:.3s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}@-webkit-keyframes slideUp-data-v-26fcd89f{0%{-webkit-transform:translateY(60px);transform:translateY(60px);opacity:0}to{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}}@keyframes slideUp-data-v-26fcd89f{0%{-webkit-transform:translateY(60px);transform:translateY(60px);opacity:0}to{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}}
--------------------------------------------------------------------------------
/web/static/css/chunk-5786617a.310d8994.css:
--------------------------------------------------------------------------------
1 | .errPage-container[data-v-6fb1594e]{width:800px;max-width:100%;margin:100px auto}.errPage-container .pan-back-btn[data-v-6fb1594e]{background:#008489;color:#fff;border:none!important}.errPage-container .pan-gif[data-v-6fb1594e]{margin:0 auto;display:block}.errPage-container .pan-img[data-v-6fb1594e]{display:block;margin:0 auto;width:100%}.errPage-container .text-jumbo[data-v-6fb1594e]{font-size:60px;font-weight:700;color:#484848}.errPage-container .list-unstyled[data-v-6fb1594e]{font-size:14px}.errPage-container .list-unstyled li[data-v-6fb1594e]{padding-bottom:5px}.errPage-container .list-unstyled a[data-v-6fb1594e]{color:#008489;text-decoration:none}.errPage-container .list-unstyled a[data-v-6fb1594e]:hover{text-decoration:underline}
--------------------------------------------------------------------------------
/web/static/css/chunk-6146664d.d855fcd7.css:
--------------------------------------------------------------------------------
1 | @supports (-webkit-mask:none) and (not (cater-color:#fff)){.login-container .el-input input{color:#fff}}.login-container .el-input{display:inline-block;height:47px;width:85%}.login-container .el-input input{background:transparent;border:0;-webkit-appearance:none;border-radius:0;padding:12px 5px 12px 15px;color:#fff;height:47px;caret-color:#fff}.login-container .el-input input:-webkit-autofill{-webkit-box-shadow:0 0 0 1000px #283443 inset!important;box-shadow:inset 0 0 0 1000px #283443!important;-webkit-text-fill-color:#fff!important}.login-container .el-form-item{border:1px solid hsla(0,0%,100%,.1);background:rgba(0,0,0,.1);border-radius:5px;color:#454545}.login-container[data-v-21a0965a]{min-height:100%;width:100%;background-color:#2d3a4b;overflow:hidden}.login-container .login-form[data-v-21a0965a]{position:relative;width:520px;max-width:100%;padding:160px 35px 0;margin:0 auto;overflow:hidden}.login-container .tips[data-v-21a0965a]{font-size:14px;color:#fff;margin-bottom:10px}.login-container .tips span[data-v-21a0965a]:first-of-type{margin-right:16px}.login-container .svg-container[data-v-21a0965a]{padding:6px 5px 6px 15px;color:#889aa4;vertical-align:middle;width:30px;display:inline-block}.login-container .title-container[data-v-21a0965a]{position:relative}.login-container .title-container .title[data-v-21a0965a]{font-size:26px;color:#eee;margin:0 auto 40px auto;text-align:center;font-weight:700}.login-container .show-pwd[data-v-21a0965a]{position:absolute;right:10px;top:7px;font-size:16px;color:#889aa4;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.login-container .thirdparty-button[data-v-21a0965a]{position:absolute;right:0;bottom:6px}@media only screen and (max-width:470px){.login-container .thirdparty-button[data-v-21a0965a]{display:none}}
--------------------------------------------------------------------------------
/web/static/css/chunk-714ebfa6.0f43044d.css:
--------------------------------------------------------------------------------
1 | .pagination-container[data-v-6a2bc7ec]{background:#fff;padding:32px 16px}.pagination-container.hidden[data-v-6a2bc7ec]{display:none}.demo-table-expand{font-size:0}.demo-table-expand label{width:120px;color:#99a9bf}.demo-table-expand .el-form-item{margin-right:0;margin-bottom:0;width:50%}.boxtext{margin-left:2px;color:red;cursor:pointer}.el-dropdown-link,.to-console{cursor:pointer;font-size:12px;color:#1890ff;margin-left:10px}.el-icon-arrow-down{font-size:12px}
--------------------------------------------------------------------------------
/web/static/css/chunk-libs.3dfb7769.css:
--------------------------------------------------------------------------------
1 | /*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:inherit;font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{-webkit-box-sizing:border-box;box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{display:inline-block;vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{-webkit-box-sizing:border-box;box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details,menu{display:block}summary{display:list-item}canvas{display:inline-block}[hidden],template{display:none}#nprogress{pointer-events:none}#nprogress .bar{background:#29d;position:fixed;z-index:1031;top:0;left:0;width:100%;height:2px}#nprogress .peg{display:block;position:absolute;right:0;width:100px;height:100%;-webkit-box-shadow:0 0 10px #29d,0 0 5px #29d;box-shadow:0 0 10px #29d,0 0 5px #29d;opacity:1;-webkit-transform:rotate(3deg) translateY(-4px);transform:rotate(3deg) translateY(-4px)}#nprogress .spinner{display:block;position:fixed;z-index:1031;top:15px;right:15px}#nprogress .spinner-icon{width:18px;height:18px;-webkit-box-sizing:border-box;box-sizing:border-box;border:2px solid transparent;border-top-color:#29d;border-left-color:#29d;border-radius:50%;-webkit-animation:nprogress-spinner .4s linear infinite;animation:nprogress-spinner .4s linear infinite}.nprogress-custom-parent{overflow:hidden;position:relative}.nprogress-custom-parent #nprogress .bar,.nprogress-custom-parent #nprogress .spinner{position:absolute}@-webkit-keyframes nprogress-spinner{0%{-webkit-transform:rotate(0deg)}to{-webkit-transform:rotate(1turn)}}@keyframes nprogress-spinner{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}
--------------------------------------------------------------------------------
/web/static/fonts/element-icons.535877f5.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdntip/cloudpanel/a093fd3d4b3c5ed9fbca72a8ca4080d412691976/web/static/fonts/element-icons.535877f5.woff
--------------------------------------------------------------------------------
/web/static/fonts/element-icons.732389de.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdntip/cloudpanel/a093fd3d4b3c5ed9fbca72a8ca4080d412691976/web/static/fonts/element-icons.732389de.ttf
--------------------------------------------------------------------------------
/web/static/img/401.089007e7.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdntip/cloudpanel/a093fd3d4b3c5ed9fbca72a8ca4080d412691976/web/static/img/401.089007e7.gif
--------------------------------------------------------------------------------
/web/static/img/404.a57b6f31.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdntip/cloudpanel/a093fd3d4b3c5ed9fbca72a8ca4080d412691976/web/static/img/404.a57b6f31.png
--------------------------------------------------------------------------------
/web/static/img/404_cloud.0f4bc32b.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdntip/cloudpanel/a093fd3d4b3c5ed9fbca72a8ca4080d412691976/web/static/img/404_cloud.0f4bc32b.png
--------------------------------------------------------------------------------
/web/static/js/chunk-1f940af7.6ecba6b3.js:
--------------------------------------------------------------------------------
1 | (window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-1f940af7"],{"324a":function(e,r,o){},"3e05":function(e,r,o){"use strict";var s=o("324a"),t=o.n(s);t.a},9683:function(e,r,o){},afb8:function(e,r,o){"use strict";var s=o("9683"),t=o.n(s);t.a},f667:function(e,r,o){"use strict";o.r(r);var s=function(){var e=this,r=e.$createElement,o=e._self._c||r;return o("div",{staticClass:"login-container"},[o("el-form",{ref:"regForm",staticClass:"login-form",attrs:{model:e.loginForm,rules:e.loginRules,autocomplete:"on","label-position":"left"}},[o("div",{staticClass:"title-container"},[o("h3",{staticClass:"title"},[e._v("注册账号")])]),e._v(" "),o("el-form-item",{attrs:{prop:"username",error:e.errorRegForm.username}},[o("span",{staticClass:"svg-container"},[o("svg-icon",{attrs:{"icon-class":"user"}})],1),e._v(" "),o("el-input",{ref:"username",attrs:{placeholder:"登录账号",name:"username",type:"text",autocomplete:"on"},model:{value:e.loginForm.username,callback:function(r){e.$set(e.loginForm,"username",r)},expression:"loginForm.username"}})],1),e._v(" "),o("el-form-item",{attrs:{prop:"email",error:e.errorRegForm.email}},[o("span",{staticClass:"svg-container"},[o("svg-icon",{attrs:{"icon-class":"email"}})],1),e._v(" "),o("el-input",{ref:"email",attrs:{placeholder:"注册邮箱",name:"email",type:"text",autocomplete:"on"},model:{value:e.loginForm.email,callback:function(r){e.$set(e.loginForm,"email",r)},expression:"loginForm.email"}})],1),e._v(" "),o("el-form-item",{attrs:{prop:"password",error:e.errorRegForm.password}},[o("span",{staticClass:"svg-container"},[o("svg-icon",{attrs:{"icon-class":"password"}})],1),e._v(" "),o("el-input",{key:e.passwordType,ref:"password",attrs:{type:e.passwordType,placeholder:"登录密码"},model:{value:e.loginForm.password,callback:function(r){e.$set(e.loginForm,"password",r)},expression:"loginForm.password"}}),e._v(" "),o("span",{staticClass:"show-pwd",on:{click:e.showPwd}},[o("svg-icon",{attrs:{"icon-class":"password"===e.passwordType?"eye":"eye-open"}})],1)],1),e._v(" "),o("el-form-item",{attrs:{prop:"password2",error:e.errorRegForm.password2}},[o("span",{staticClass:"svg-container"},[o("svg-icon",{attrs:{"icon-class":"password"}})],1),e._v(" "),o("el-input",{key:e.passwordType,ref:"password2",attrs:{type:e.passwordType,placeholder:"确认密码",name:"password2",autocomplete:"on"},on:{blur:function(r){e.capsTooltip=!1}},nativeOn:{keyup:[function(r){return e.checkCapslock(r)},function(r){return!r.type.indexOf("key")&&e._k(r.keyCode,"enter",13,r.key,"Enter")?null:e.onSubmit(r)}]},model:{value:e.loginForm.password2,callback:function(r){e.$set(e.loginForm,"password2",r)},expression:"loginForm.password2"}}),e._v(" "),o("span",{staticClass:"show-pwd",on:{click:e.showPwd}},[o("svg-icon",{attrs:{"icon-class":"password"===e.passwordType?"eye":"eye-open"}})],1)],1),e._v(" "),o("el-button",{staticStyle:{width:"100%","margin-bottom":"30px"},attrs:{loading:e.loading,type:"primary"},nativeOn:{click:function(r){return r.preventDefault(),e.onSubmit(r)}}},[e._v("注册")]),e._v(" "),o("div",{staticStyle:{"font-size":"13px"}},[o("span",{staticStyle:{color:"#ffffff"}},[e._v("已经注册? "),o("router-link",{staticStyle:{color:"#4A9FF9"},attrs:{to:"/login"}},[e._v("返回登录")])],1)])],1)],1)},t=[],a=(o("ac6a"),o("456d"),o("c24f")),n=o("4328"),i=o.n(n),l={name:"Login",data:function(){return{loginForm:{email:"",username:"",password:"",password2:""},loginRules:{username:[{required:!0,message:"登录账号必须填写",trigger:"blur"}],password:[{required:!0,message:"登录密码必须填写",trigger:"blur"}],password2:[{required:!0,message:"确认密码必须填写",trigger:"blur"}],email:[{required:!0,message:"邮件地址必须填写",trigger:"blur"}]},passwordType:"password",capsTooltip:!1,loading:!1,showDialog:!1,redirect:void 0,errorRegForm:{},otherQuery:{}}},watch:{$route:{handler:function(e){var r=e.query;r&&(this.redirect=r.redirect,this.otherQuery=this.getOtherQuery(r))},immediate:!0}},created:function(){},mounted:function(){""===this.loginForm.username?this.$refs.username.focus():""===this.loginForm.password&&this.$refs.password.focus()},destroyed:function(){},methods:{checkCapslock:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=e.shiftKey,o=e.key;o&&1===o.length&&(this.capsTooltip=!!(r&&o>="a"&&o<="z"||!r&&o>="A"&&o<="Z")),"CapsLock"===o&&!0===this.capsTooltip&&(this.capsTooltip=!1)},showPwd:function(){var e=this;"password"===this.passwordType?this.passwordType="":this.passwordType="password",this.$nextTick(function(){e.$refs.password.focus()})},handleLogin:function(){var e=this;this.$refs.loginForm.validate(function(r){if(!r)return console.log("error submit!!"),!1;e.loading=!0,e.$store.dispatch("user/login",e.loginForm).then(function(){e.$router.push({path:e.redirect||"/",query:e.otherQuery}),e.loading=!1}).catch(function(){e.loading=!1})})},onSubmit:function(){var e=this;this.errorRegForm={username:"",email:"",password2:"",password:""},this.$refs.regForm.validate(function(r){Object(a["register"])(i.a.stringify(e.loginForm)).then(function(r){e.$notify({title:r.title,message:r.message,type:"success",duration:2e3}),e.showDialog=!1,e.$router.push("/login")}).catch(function(r){if(e.dialogLoading=!1,r.error_data)for(var o in r.error_data){var s=r.error_data[o][0];e.errorRegForm[o]=s}})})},getOtherQuery:function(e){return Object.keys(e).reduce(function(r,o){return"redirect"!==o&&(r[o]=e[o]),r},{})}}},c=l,p=(o("3e05"),o("afb8"),o("2877")),u=Object(p["a"])(c,s,t,!1,null,"5f1ca375",null);r["default"]=u.exports}}]);
--------------------------------------------------------------------------------
/web/static/js/chunk-2d2105d3.8eb9d2f2.js:
--------------------------------------------------------------------------------
1 | (window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d2105d3"],{b829:function(n,e,o){"use strict";o.r(e);o("386d");var t,c,a={name:"AuthRedirect",created:function(){var n=window.location.search.slice(1);window.localStorage&&(window.localStorage.setItem("x-admin-oauth-code",n),window.close())},render:function(n){return n()}},d=a,i=o("2877"),l=Object(i["a"])(d,t,c,!1,null,null,null);e["default"]=l.exports}}]);
--------------------------------------------------------------------------------
/web/static/js/chunk-2d230fe7.fcb684d8.js:
--------------------------------------------------------------------------------
1 | (window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d230fe7"],{ef3c:function(e,r,n){"use strict";n.r(r);n("a481");var t,u,a={created:function(){var e=this.$route,r=e.params,n=e.query,t=r.path;this.$router.replace({path:"/"+t,query:n})},render:function(e){return e()}},c=a,o=n("2877"),p=Object(o["a"])(c,t,u,!1,null,null,null);r["default"]=p.exports}}]);
--------------------------------------------------------------------------------
/web/static/js/chunk-50499323.0282e3c3.js:
--------------------------------------------------------------------------------
1 | (window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-50499323"],{"1db4":function(t,s,a){"use strict";a.r(s);var e=function(){var t=this,s=t.$createElement,a=t._self._c||s;return a("div",{staticClass:"wscn-http404-container"},[a("div",{staticClass:"wscn-http404"},[t._m(0),t._v(" "),a("div",{staticClass:"bullshit"},[a("div",{staticClass:"bullshit__oops"},[t._v("OOPS!")]),t._v(" "),t._m(1),t._v(" "),a("div",{staticClass:"bullshit__headline"},[t._v(t._s(t.message))]),t._v(" "),a("div",{staticClass:"bullshit__info"},[t._v("Please check that the URL you entered is correct, or click the button below to return to the homepage.")]),t._v(" "),a("a",{staticClass:"bullshit__return-home",attrs:{href:""}},[t._v("Back to home")])])])])},c=[function(){var t=this,s=t.$createElement,e=t._self._c||s;return e("div",{staticClass:"pic-404"},[e("img",{staticClass:"pic-404__parent",attrs:{src:a("a36b"),alt:"404"}}),t._v(" "),e("img",{staticClass:"pic-404__child left",attrs:{src:a("26fc"),alt:"404"}}),t._v(" "),e("img",{staticClass:"pic-404__child mid",attrs:{src:a("26fc"),alt:"404"}}),t._v(" "),e("img",{staticClass:"pic-404__child right",attrs:{src:a("26fc"),alt:"404"}})])},function(){var t=this,s=t.$createElement,a=t._self._c||s;return a("div",{staticClass:"bullshit__info"},[t._v("All rights reserved\n "),a("a",{staticStyle:{color:"#20a0ff"},attrs:{href:"https://wallstreetcn.com",target:"_blank"}},[t._v("wallstreetcn")])])}],i={name:"Page404",computed:{message:function(){return"The webmaster said that you can not enter this page..."}}},l=i,n=(a("35e7"),a("2877")),r=Object(n["a"])(l,e,c,!1,null,"26fcd89f",null);s["default"]=r.exports},"26fc":function(t,s,a){t.exports=a.p+"static/img/404_cloud.0f4bc32b.png"},"35e7":function(t,s,a){"use strict";var e=a("5254"),c=a.n(e);c.a},5254:function(t,s,a){},a36b:function(t,s,a){t.exports=a.p+"static/img/404.a57b6f31.png"}}]);
--------------------------------------------------------------------------------
/web/static/js/chunk-5786617a.f4a2e354.js:
--------------------------------------------------------------------------------
1 | (window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-5786617a"],{"24e2":function(t,a,e){"use strict";e.r(a);var i=function(){var t=this,a=t.$createElement,e=t._self._c||a;return e("div",{staticClass:"errPage-container"},[e("el-button",{staticClass:"pan-back-btn",attrs:{icon:"arrow-left"},on:{click:t.back}},[t._v("\n 返回\n ")]),t._v(" "),e("el-row",[e("el-col",{attrs:{span:12}},[e("h1",{staticClass:"text-jumbo text-ginormous"},[t._v("\n Oops!\n ")]),t._v("\n gif来源"),e("a",{attrs:{href:"https://zh.airbnb.com/",target:"_blank"}},[t._v("airbnb")]),t._v(" 页面\n "),e("h2",[t._v("你没有权限去该页面")]),t._v(" "),e("h6",[t._v("如有不满请联系你领导")]),t._v(" "),e("ul",{staticClass:"list-unstyled"},[e("li",[t._v("或者你可以去:")]),t._v(" "),e("li",{staticClass:"link-type"},[e("router-link",{attrs:{to:"/dashboard"}},[t._v("\n 回首页\n ")])],1),t._v(" "),e("li",{staticClass:"link-type"},[e("a",{attrs:{href:"https://www.taobao.com/"}},[t._v("随便看看")])]),t._v(" "),e("li",[e("a",{attrs:{href:"#"},on:{click:function(a){a.preventDefault(),t.dialogVisible=!0}}},[t._v("点我看图")])])])]),t._v(" "),e("el-col",{attrs:{span:12}},[e("img",{attrs:{src:t.errGif,width:"313",height:"428",alt:"Girl has dropped her ice cream."}})])],1),t._v(" "),e("el-dialog",{attrs:{visible:t.dialogVisible,title:"随便看"},on:{"update:visible":function(a){t.dialogVisible=a}}},[e("img",{staticClass:"pan-img",attrs:{src:t.ewizardClap}})])],1)},s=[],n=e("cc6c"),r=e.n(n),l={name:"Page401",data:function(){return{errGif:r.a+"?"+ +new Date,ewizardClap:"https://wpimg.wallstcn.com/007ef517-bafd-4066-aae4-6883632d9646",dialogVisible:!1}},methods:{back:function(){this.$route.query.noGoBack?this.$router.push({path:"/dashboard"}):this.$router.go(-1)}}},c=l,o=(e("4f2e"),e("2877")),u=Object(o["a"])(c,i,s,!1,null,"6fb1594e",null);a["default"]=u.exports},"4f2e":function(t,a,e){"use strict";var i=e("cbee"),s=e.n(i);s.a},cbee:function(t,a,e){},cc6c:function(t,a,e){t.exports=e.p+"static/img/401.089007e7.gif"}}]);
--------------------------------------------------------------------------------
/web/static/js/chunk-6146664d.515324ec.js:
--------------------------------------------------------------------------------
1 | (window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-6146664d"],{"0338":function(e,r,t){"use strict";t.r(r);var o=function(){var e=this,r=e.$createElement,t=e._self._c||r;return t("div",{staticStyle:{height:"100%"}},[t("div",{staticClass:"login-container"},[t("el-form",{ref:"loginForm",staticClass:"login-form",attrs:{model:e.loginForm,rules:e.loginRules,autocomplete:"on","label-position":"left"}},[t("div",{staticClass:"title-container"},[t("h3",{staticClass:"title"},[e._v("登 录")])]),e._v(" "),t("el-form-item",{attrs:{prop:"username",error:e.errorLogForm.username}},[t("span",{staticClass:"svg-container"},[t("svg-icon",{attrs:{"icon-class":"user"}})],1),e._v(" "),t("el-input",{ref:"username",attrs:{placeholder:"登录账号",name:"username",type:"text",tabindex:"1",autocomplete:"on"},model:{value:e.loginForm.username,callback:function(r){e.$set(e.loginForm,"username",r)},expression:"loginForm.username"}})],1),e._v(" "),t("el-tooltip",{attrs:{content:"Caps lock is On",placement:"right",manual:""},model:{value:e.capsTooltip,callback:function(r){e.capsTooltip=r},expression:"capsTooltip"}},[t("el-form-item",{attrs:{prop:"password",error:e.errorLogForm.password}},[t("span",{staticClass:"svg-container"},[t("svg-icon",{attrs:{"icon-class":"password"}})],1),e._v(" "),t("el-input",{key:e.passwordType,ref:"password",attrs:{type:e.passwordType,placeholder:"登录密码",name:"password",tabindex:"2",autocomplete:"on"},on:{blur:function(r){e.capsTooltip=!1}},nativeOn:{keyup:[function(r){return e.checkCapslock(r)},function(r){return!r.type.indexOf("key")&&e._k(r.keyCode,"enter",13,r.key,"Enter")?null:e.handleLogin(r)}]},model:{value:e.loginForm.password,callback:function(r){e.$set(e.loginForm,"password",r)},expression:"loginForm.password"}}),e._v(" "),t("span",{staticClass:"show-pwd",on:{click:e.showPwd}},[t("svg-icon",{attrs:{"icon-class":"password"===e.passwordType?"eye":"eye-open"}})],1)],1)],1),e._v(" "),t("el-button",{staticStyle:{width:"100%","margin-bottom":"10px"},attrs:{loading:e.loading,type:"primary"},nativeOn:{click:function(r){return r.preventDefault(),e.handleLogin(r)}}},[e._v("登 录")]),e._v(" "),t("div",{staticStyle:{"font-size":"13px"}},[t("span",{staticStyle:{color:"#ffffff"}},[e._v("该程序为 CDNTIP 免费提供, 请不要相信任何收费. ")])])],1)],1)])},s=[],a=(t("ac6a"),t("456d"),t("c24f")),n=t("4328"),i=t.n(n),c={name:"Login",data:function(){return{reg_form:{username:"",email:"",password:"",password2:""},errorLogForm:{username:"",password:""},errorRegForm:{username:"",email:"",password2:"",password:""},rules:{username:[{required:!0,message:"登录账号必须填写",trigger:"blur"}],password:[{required:!0,message:"登录密码必须填写",trigger:"blur"}],email:[{required:!0,message:"邮件地址必须填写",trigger:"blur"}],password2:[{required:!0,message:"确认密码必须填写",trigger:"blur"}]},loginForm:{},formInline:{user:"",region:""},loginRules:{username:[{required:!0,trigger:"blur",message:"登录账号必须填写"}],password:[{required:!0,trigger:"blur",message:"登录密码必须填写"}]},passwordType:"password",capsTooltip:!1,loading:!1,showDialog:!1,redirect:void 0,otherQuery:{}}},watch:{$route:{handler:function(e){var r=e.query;r&&(this.redirect=r.redirect,this.otherQuery=this.getOtherQuery(r))},immediate:!0}},created:function(){},mounted:function(){""===this.loginForm.username?this.$refs.username.focus():""===this.loginForm.password&&this.$refs.password.focus()},destroyed:function(){},methods:{checkCapslock:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=e.shiftKey,t=e.key;t&&1===t.length&&(this.capsTooltip=!!(r&&t>="a"&&t<="z"||!r&&t>="A"&&t<="Z")),"CapsLock"===t&&!0===this.capsTooltip&&(this.capsTooltip=!1)},resetPassword:function(){var e=this;this.$prompt("请输入邮箱或者账号","提示",{confirmButtonText:"确定",cancelButtonText:"取消"}).then(function(r){var t=r.value;Object(a["sendResetPassword"])(i.a.stringify({wd:t})).then(function(r){e.$notify({title:r.title,message:r.message,type:"success",duration:2e3})}).catch(function(r){e.$notify({title:r.title,message:r.message,type:"error",duration:2e3})})})},showPwd:function(){var e=this;"password"===this.passwordType?this.passwordType="":this.passwordType="password",this.$nextTick(function(){e.$refs.password.focus()})},handleLogin:function(){var e=this;this.errorLogForm={username:"",password:""},this.$refs.loginForm.validate(function(r){if(!r)return console.log("error submit!!"),!1;e.loading=!0,e.$store.dispatch("user/login",e.loginForm).then(function(){e.$router.push({path:e.redirect||"/",query:e.otherQuery}),e.loading=!1}).catch(function(r){if(e.loading=!1,r.error_data&&r.error_data)for(var t in r.error_data){var o=r.error_data[t][0];e.errorLogForm[t]=o}})})},handleReg:function(){var e=this;this.showDialog=!0,this.$nextTick(function(){e.$refs["regForm"].clearValidate()})},onSubmit:function(){var e=this;this.errorRegForm={username:"",email:"",password2:"",password:""},this.$refs.regForm.validate(function(r){Object(a["register"])(i.a.stringify(e.reg_form)).then(function(r){e.$notify({title:r.title,message:r.message,type:"success",duration:2e3}),e.showDialog=!1}).catch(function(r){if(e.dialogLoading=!1,r.error_data)for(var t in r.error_data){var o=r.error_data[t][0];e.errorRegForm[t]=o}})})},closeModal:function(){this.errorForm={},this.reg_form={}},getOtherQuery:function(e){return Object.keys(e).reduce(function(r,t){return"redirect"!==t&&(r[t]=e[t]),r},{})}}},l=c,u=(t("da58"),t("0541"),t("2877")),d=Object(u["a"])(l,o,s,!1,null,"21a0965a",null);r["default"]=d.exports},"0541":function(e,r,t){"use strict";var o=t("bbca"),s=t.n(o);s.a},"201d":function(e,r,t){},bbca:function(e,r,t){},da58:function(e,r,t){"use strict";var o=t("201d"),s=t.n(o);s.a}}]);
--------------------------------------------------------------------------------