作者 wanweibin

first commit

要显示太多修改。

为保证性能只显示 46 of 46+ 个文件。

  1 +venv
  2 +runtime/log/*
  3 +db.sqlite3
  1 +# Default ignored files
  2 +/workspace.xml
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project version="4">
  3 + <component name="PublishConfigData">
  4 + <serverData>
  5 + <paths name="10.1.10.113">
  6 + <serverdata>
  7 + <mappings>
  8 + <mapping local="$PROJECT_DIR$" web="/" />
  9 + </mappings>
  10 + </serverdata>
  11 + </paths>
  12 + <paths name="192.168.26.59">
  13 + <serverdata>
  14 + <mappings>
  15 + <mapping local="$PROJECT_DIR$" web="/" />
  16 + </mappings>
  17 + </serverdata>
  18 + </paths>
  19 + </serverData>
  20 + </component>
  21 +</project>
  1 +<component name="ProjectDictionaryState">
  2 + <dictionary name="a2">
  3 + <words>
  4 + <w>blocksize</w>
  5 + <w>corsheaders</w>
  6 + <w>usercenter</w>
  7 + <w>vanwhebin</w>
  8 + <w>xlsx</w>
  9 + </words>
  10 + </dictionary>
  11 +</component>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<module type="PYTHON_MODULE" version="4">
  3 + <component name="FacetManager">
  4 + <facet type="django" name="Django">
  5 + <configuration>
  6 + <option name="rootFolder" value="$MODULE_DIR$/wxProject" />
  7 + <option name="settingsModule" value="wxProject/settings.py" />
  8 + <option name="manageScript" value="manage.py" />
  9 + <option name="environment" value="&lt;map/&gt;" />
  10 + <option name="doNotUseTestRunner" value="false" />
  11 + <option name="trackFilePattern" value="" />
  12 + </configuration>
  13 + </facet>
  14 + </component>
  15 + <component name="NewModuleRootManager">
  16 + <content url="file://$MODULE_DIR$" />
  17 + <orderEntry type="jdk" jdkName="Python 3.8 (end)" jdkType="Python SDK" />
  18 + <orderEntry type="sourceFolder" forTests="false" />
  19 + <orderEntry type="library" name="Django Lib" level="project" />
  20 + </component>
  21 + <component name="TemplatesService">
  22 + <option name="TEMPLATE_CONFIGURATION" value="Django" />
  23 + <option name="TEMPLATE_FOLDERS">
  24 + <list>
  25 + <option value="$MODULE_DIR$/venv/Lib/site-packages/django/forms/templates" />
  26 + </list>
  27 + </option>
  28 + </component>
  29 +</module>
  1 +<component name="InspectionProjectProfileManager">
  2 + <settings>
  3 + <option name="USE_PROJECT_PROFILE" value="false" />
  4 + <version value="1.0" />
  5 + </settings>
  6 +</component>
  1 +<component name="libraryTable">
  2 + <library name="Django Lib">
  3 + <CLASSES>
  4 + <root url="file://$PROJECT_DIR$/venv/Lib/site-packages" />
  5 + </CLASSES>
  6 + <SOURCES />
  7 + </library>
  8 +</component>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project version="4">
  3 + <component name="JavaScriptSettings">
  4 + <option name="languageLevel" value="ES6" />
  5 + </component>
  6 + <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8 (end)" project-jdk-type="Python SDK" />
  7 +</project>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project version="4">
  3 + <component name="ProjectModuleManager">
  4 + <modules>
  5 + <module fileurl="file://$PROJECT_DIR$/.idea/end.iml" filepath="$PROJECT_DIR$/.idea/end.iml" />
  6 + </modules>
  7 + </component>
  8 +</project>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project version="4">
  3 + <component name="VcsDirectoryMappings">
  4 + <mapping directory="$PROJECT_DIR$" vcs="Git" />
  5 + </component>
  6 +</project>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<module type="PYTHON_MODULE" version="4">
  3 + <component name="FacetManager">
  4 + <facet type="django" name="Django">
  5 + <configuration>
  6 + <option name="rootFolder" value="$MODULE_DIR$" />
  7 + <option name="settingsModule" value="wxProject/settings.py" />
  8 + <option name="manageScript" value="$MODULE_DIR$/manage.py" />
  9 + <option name="environment" value="&lt;map/&gt;" />
  10 + <option name="doNotUseTestRunner" value="false" />
  11 + <option name="trackFilePattern" value="migrations" />
  12 + </configuration>
  13 + </facet>
  14 + </component>
  15 + <component name="NewModuleRootManager">
  16 + <content url="file://$MODULE_DIR$" />
  17 + <orderEntry type="inheritedJdk" />
  18 + <orderEntry type="sourceFolder" forTests="false" />
  19 + <orderEntry type="library" name="Django Lib" level="project" />
  20 + </component>
  21 + <component name="PyDocumentationSettings">
  22 + <option name="format" value="PLAIN" />
  23 + <option name="myDocStringFormat" value="Plain" />
  24 + </component>
  25 + <component name="TemplatesService">
  26 + <option name="TEMPLATE_CONFIGURATION" value="Django" />
  27 + <option name="TEMPLATE_FOLDERS">
  28 + <list>
  29 + <option value="$MODULE_DIR$/venv/Lib/site-packages/django/forms/templates" />
  30 + </list>
  31 + </option>
  32 + </component>
  33 +</module>
  1 +#!/usr/bin/env python
  2 +# -*- coding:utf-8 -*-
  3 +##
  4 +# Copyright (C) 2018 All rights reserved.
  5 +#
  6 +# @File AbstractApi.py
  7 +# @Brief
  8 +# @Author abelzhu, abelzhu@tencent.com
  9 +# @Version 1.0
  10 +# @Date 2018-02-24
  11 +#
  12 +#
  13 +
  14 +import sys
  15 +import os
  16 +import re
  17 +
  18 +import json
  19 +import requests
  20 +
  21 +
  22 +from .conf import DEBUG
  23 +
  24 +
  25 +class ApiException(Exception):
  26 + def __init__(self, errCode, errMsg):
  27 + self.errCode = errCode
  28 + self.errMsg = errMsg
  29 +
  30 +
  31 +class AbstractApi(object):
  32 + def __init__(self):
  33 + return
  34 +
  35 + def getAccessToken(self):
  36 + raise NotImplementedError
  37 +
  38 + def refreshAccessToken(self):
  39 + raise NotImplementedError
  40 +
  41 + def getSuiteAccessToken(self):
  42 + raise NotImplementedError
  43 +
  44 + def refreshSuiteAccessToken(self):
  45 + raise NotImplementedError
  46 +
  47 + def getProviderAccessToken(self):
  48 + raise NotImplementedError
  49 +
  50 + def refreshProviderAccessToken(self):
  51 + raise NotImplementedError
  52 +
  53 + def httpCall(self, urlType, args=None):
  54 + shortUrl = urlType[0]
  55 + method = urlType[1]
  56 + response = {}
  57 + for retryCnt in range(0, 3):
  58 + if 'POST' == method:
  59 + url = self.__makeUrl(shortUrl)
  60 + response = self.__httpPost(url, args)
  61 + elif 'GET' == method:
  62 + url = self.__makeUrl(shortUrl)
  63 + url = self.__appendArgs(url, args)
  64 + response = self.__httpGet(url)
  65 + else:
  66 + raise ApiException(-1, "unknown method type")
  67 +
  68 + # check if token expired
  69 + if self.__tokenExpired(response.get('errcode')):
  70 + self.__refreshToken(shortUrl)
  71 + retryCnt += 1
  72 + continue
  73 + else:
  74 + break
  75 +
  76 + return self.__checkResponse(response)
  77 +
  78 + @staticmethod
  79 + def __appendArgs(url, args):
  80 + if args is None:
  81 + return url
  82 +
  83 + for key, value in args.items():
  84 + if '?' in url:
  85 + url += ('&' + key + '=' + value)
  86 + else:
  87 + url += ('?' + key + '=' + value)
  88 + return url
  89 +
  90 + @staticmethod
  91 + def __makeUrl(shortUrl):
  92 + base = "https://qyapi.weixin.qq.com"
  93 + if shortUrl[0] == '/':
  94 + return base + shortUrl
  95 + else:
  96 + return base + '/' + shortUrl
  97 +
  98 + def __appendToken(self, url):
  99 + if 'SUITE_ACCESS_TOKEN' in url:
  100 + return url.replace('SUITE_ACCESS_TOKEN', self.getSuiteAccessToken())
  101 + elif 'PROVIDER_ACCESS_TOKEN' in url:
  102 + return url.replace('PROVIDER_ACCESS_TOKEN', self.getProviderAccessToken())
  103 + elif 'ACCESS_TOKEN' in url:
  104 + return url.replace('ACCESS_TOKEN', self.getAccessToken())
  105 + else:
  106 + return url
  107 +
  108 + def __httpPost(self, url, args):
  109 + realUrl = self.__appendToken(url)
  110 +
  111 + if DEBUG is True:
  112 + print(realUrl, args)
  113 +
  114 + return requests.post(realUrl, data=json.dumps(args, ensure_ascii=False).encode('utf-8'), verify=False).json()
  115 +
  116 + def __httpGet(self, url):
  117 + realUrl = self.__appendToken(url)
  118 +
  119 + if DEBUG is True:
  120 + print(realUrl)
  121 +
  122 + return requests.get(realUrl, verify=False).json()
  123 +
  124 + def __post_file(self, url, media_file):
  125 + return requests.post(url, file=media_file).json()
  126 +
  127 + @staticmethod
  128 + def __checkResponse(response):
  129 + errCode = response.get('errcode')
  130 + errMsg = response.get('errmsg')
  131 +
  132 + if errCode is 0:
  133 + return response
  134 + else:
  135 + raise ApiException(errCode, errMsg)
  136 +
  137 + @staticmethod
  138 + def __tokenExpired(errCode):
  139 + if errCode == 40014 or errCode == 42001 or errCode == 42007 or errCode == 42009:
  140 + return True
  141 + else:
  142 + return False
  143 +
  144 + def __refreshToken(self, url):
  145 + if 'SUITE_ACCESS_TOKEN' in url:
  146 + self.refreshSuiteAccessToken()
  147 + elif 'PROVIDER_ACCESS_TOKEN' in url:
  148 + self.refreshProviderAccessToken()
  149 + elif 'ACCESS_TOKEN' in url:
  150 + self.refreshAccessToken()
  1 +#!/usr/bin/env python
  2 +# -*- coding:utf-8 -*-
  3 +##
  4 +# Copyright (C) 2018 All rights reserved.
  5 +#
  6 +# @File CorpApi.py
  7 +# @Brief
  8 +# @Author abelzhu, abelzhu@tencent.com
  9 +# @Version 1.0
  10 +# @Date 2018-02-24
  11 +#
  12 +#
  13 +from abc import ABC
  14 +
  15 +from .AbstractApi import *
  16 +
  17 +CORP_API_TYPE = {
  18 + 'GET_ACCESS_TOKEN': ['/cgi-bin/gettoken', 'GET'],
  19 + 'USER_CREATE': ['/cgi-bin/user/create?access_token=ACCESS_TOKEN', 'POST'],
  20 + 'USER_GET': ['/cgi-bin/user/get?access_token=ACCESS_TOKEN', 'GET'],
  21 + 'USER_UPDATE': ['/cgi-bin/user/update?access_token=ACCESS_TOKEN', 'POST'],
  22 + 'USER_DELETE': ['/cgi-bin/user/delete?access_token=ACCESS_TOKEN', 'GET'],
  23 + 'USER_BATCH_DELETE': ['/cgi-bin/user/batchdelete?access_token=ACCESS_TOKEN', 'POST'],
  24 + 'USER_SIMPLE_LIST ': ['/cgi-bin/user/simplelist?access_token=ACCESS_TOKEN', 'GET'],
  25 + 'USER_LIST': ['/cgi-bin/user/list?access_token=ACCESS_TOKEN', 'GET'],
  26 + 'USERID_TO_OPENID': ['/cgi-bin/user/convert_to_openid?access_token=ACCESS_TOKEN', 'POST'],
  27 + 'OPENID_TO_USERID': ['/cgi-bin/user/convert_to_userid?access_token=ACCESS_TOKEN', 'POST'],
  28 + 'USER_AUTH_SUCCESS': ['/cgi-bin/user/authsucc?access_token=ACCESS_TOKEN', 'GET'],
  29 +
  30 + 'DEPARTMENT_CREATE': ['/cgi-bin/department/create?access_token=ACCESS_TOKEN', 'POST'],
  31 + 'DEPARTMENT_UPDATE': ['/cgi-bin/department/update?access_token=ACCESS_TOKEN', 'POST'],
  32 + 'DEPARTMENT_DELETE': ['/cgi-bin/department/delete?access_token=ACCESS_TOKEN', 'GET'],
  33 + 'DEPARTMENT_LIST': ['/cgi-bin/department/list?access_token=ACCESS_TOKEN', 'GET'],
  34 +
  35 + 'TAG_CREATE': ['/cgi-bin/tag/create?access_token=ACCESS_TOKEN', 'POST'],
  36 + 'TAG_UPDATE': ['/cgi-bin/tag/update?access_token=ACCESS_TOKEN', 'POST'],
  37 + 'TAG_DELETE': ['/cgi-bin/tag/delete?access_token=ACCESS_TOKEN', 'GET'],
  38 + 'TAG_GET_USER': ['/cgi-bin/tag/get?access_token=ACCESS_TOKEN', 'GET'],
  39 + 'TAG_ADD_USER': ['/cgi-bin/tag/addtagusers?access_token=ACCESS_TOKEN', 'POST'],
  40 + 'TAG_DELETE_USER': ['/cgi-bin/tag/deltagusers?access_token=ACCESS_TOKEN', 'POST'],
  41 + 'TAG_GET_LIST': ['/cgi-bin/tag/list?access_token=ACCESS_TOKEN', 'GET'],
  42 +
  43 + 'BATCH_JOB_GET_RESULT': ['/cgi-bin/batch/getresult?access_token=ACCESS_TOKEN', 'GET'],
  44 +
  45 + 'BATCH_INVITE': ['/cgi-bin/batch/invite?access_token=ACCESS_TOKEN', 'POST'],
  46 +
  47 + 'AGENT_GET': ['/cgi-bin/agent/get?access_token=ACCESS_TOKEN', 'GET'],
  48 + 'AGENT_SET': ['/cgi-bin/agent/set?access_token=ACCESS_TOKEN', 'POST'],
  49 + 'AGENT_GET_LIST': ['/cgi-bin/agent/list?access_token=ACCESS_TOKEN', 'GET'],
  50 +
  51 + 'MENU_CREATE': ['/cgi-bin/menu/create?access_token=ACCESS_TOKEN', 'POST'], ## TODO
  52 + 'MENU_GET': ['/cgi-bin/menu/get?access_token=ACCESS_TOKEN', 'GET'],
  53 + 'MENU_DELETE': ['/cgi-bin/menu/delete?access_token=ACCESS_TOKEN', 'GET'],
  54 +
  55 + 'MESSAGE_SEND': ['/cgi-bin/message/send?access_token=ACCESS_TOKEN', 'POST'],
  56 + 'MESSAGE_REVOKE': ['/cgi-bin/message/revoke?access_token=ACCESS_TOKEN', 'POST'],
  57 +
  58 + 'MEDIA_GET': ['/cgi-bin/media/get?access_token=ACCESS_TOKEN', 'GET'],
  59 +
  60 + 'GET_USER_INFO_BY_CODE': ['/cgi-bin/user/getuserinfo?access_token=ACCESS_TOKEN', 'GET'],
  61 + 'GET_USER_DETAIL': ['/cgi-bin/user/getuserdetail?access_token=ACCESS_TOKEN', 'POST'],
  62 +
  63 + 'GET_TICKET': ['/cgi-bin/ticket/get?access_token=ACCESS_TOKEN', 'GET'],
  64 + 'GET_JSAPI_TICKET': ['/cgi-bin/get_jsapi_ticket?access_token=ACCESS_TOKEN', 'GET'],
  65 +
  66 + 'GET_CHECKIN_OPTION': ['/cgi-bin/checkin/getcheckinoption?access_token=ACCESS_TOKEN', 'POST'],
  67 + 'GET_CHECKIN_DATA': ['/cgi-bin/checkin/getcheckindata?access_token=ACCESS_TOKEN', 'POST'],
  68 + 'GET_APPROVAL_DATA': ['/cgi-bin/corp/getapprovaldata?access_token=ACCESS_TOKEN', 'POST'],
  69 +
  70 + 'GET_INVOICE_INFO': ['/cgi-bin/card/invoice/reimburse/getinvoiceinfo?access_token=ACCESS_TOKEN', 'POST'],
  71 + 'UPDATE_INVOICE_STATUS':
  72 + ['/cgi-bin/card/invoice/reimburse/updateinvoicestatus?access_token=ACCESS_TOKEN', 'POST'],
  73 + 'BATCH_UPDATE_INVOICE_STATUS':
  74 + ['/cgi-bin/card/invoice/reimburse/updatestatusbatch?access_token=ACCESS_TOKEN', 'POST'],
  75 + 'BATCH_GET_INVOICE_INFO':
  76 + ['/cgi-bin/card/invoice/reimburse/getinvoiceinfobatch?access_token=ACCESS_TOKEN', 'POST'],
  77 +
  78 + 'APP_CHAT_CREATE': ['/cgi-bin/appchat/create?access_token=ACCESS_TOKEN', 'POST'],
  79 + 'APP_CHAT_GET': ['/cgi-bin/appchat/get?access_token=ACCESS_TOKEN', 'GET'],
  80 + 'APP_CHAT_UPDATE': ['/cgi-bin/appchat/update?access_token=ACCESS_TOKEN', 'POST'],
  81 + 'APP_CHAT_SEND': ['/cgi-bin/appchat/send?access_token=ACCESS_TOKEN', 'POST'],
  82 +
  83 + 'MINIPROGRAM_CODE_TO_SESSION_KEY': ['/cgi-bin/miniprogram/jscode2session?access_token=ACCESS_TOKEN', 'GET'],
  84 +}
  85 +
  86 +
  87 +class CorpApi(AbstractApi, ABC):
  88 + def __init__(self, corpid, secret):
  89 + super().__init__()
  90 + self.corpid = corpid
  91 + self.secret = secret
  92 + self.access_token = None
  93 +
  94 + def getAccessToken(self):
  95 + if self.access_token is None:
  96 + self.refreshAccessToken()
  97 + return self.access_token
  98 +
  99 + def refreshAccessToken(self):
  100 + response = self.httpCall(
  101 + CORP_API_TYPE['GET_ACCESS_TOKEN'],
  102 + {
  103 + 'corpid': self.corpid,
  104 + 'corpsecret': self.secret,
  105 + })
  106 + self.access_token = response.get('access_token')
  1 +#!/usr/bin/env python
  2 +# -*- coding:utf-8 -*-
  3 +##
  4 +# Copyright (C) 2018 All rights reserved.
  5 +#
  6 +# @File ServiceCorp.py
  7 +# @Brief
  8 +# @Author abelzhu, abelzhu@tencent.com
  9 +# @Version 1.0
  10 +# @Date 2018-02-24
  11 +#
  12 +#
  13 +
  14 +from .CorpApi import *
  15 +
  16 +SERVICE_CORP_API_TYPE = {
  17 + 'GET_CORP_TOKEN': ['/cgi-bin/service/get_corp_token?suite_access_token=SUITE_ACCESS_TOKEN', 'POST'],
  18 + 'GET_SUITE_TOKEN': ['/cgi-bin/service/get_suite_token', 'POST'],
  19 + 'GET_PRE_AUTH_CODE': ['/cgi-bin/service/get_pre_auth_code?suite_access_token=SUITE_ACCESS_TOKEN', 'GET'],
  20 + 'SET_SESSION_INFO': ['/cgi-bin/service/set_session_info?suite_access_token=SUITE_ACCESS_TOKEN', 'POST'],
  21 + 'GET_PERMANENT_CODE': ['/cgi-bin/service/get_permanent_code?suite_access_token=SUITE_ACCESS_TOKEN', 'POST'],
  22 + 'GET_AUTH_INFO': ['/cgi-bin/service/get_auth_info?suite_access_token=SUITE_ACCESS_TOKEN', 'POST'],
  23 + 'GET_ADMIN_LIST': ['/cgi-bin/service/get_admin_list?suite_access_token=SUITE_ACCESS_TOKEN', 'POST'],
  24 + 'GET_USER_INFO_BY_3RD': ['/cgi-bin/service/getuserinfo3rd?suite_access_token=SUITE_ACCESS_TOKEN', 'GET'],
  25 + 'GET_USER_DETAIL_BY_3RD': ['/cgi-bin/service/getuserdetail3rd?suite_access_token=SUITE_ACCESS_TOKEN', 'POST'],
  26 +}
  27 +
  28 +
  29 +class ServiceCorpApi(CorpApi):
  30 + def __init__(self, suite_id, suite_secret, suite_ticket, auth_corpid=None, permanent_code=None):
  31 + self.suite_id = suite_id
  32 + self.suite_secret = suite_secret
  33 + self.suite_ticket = suite_ticket
  34 +
  35 + # 调用 CorpAPI 的function, 需要设置这两个参数
  36 + self.auth_corpid = auth_corpid
  37 + self.permanent_code = permanent_code
  38 +
  39 + self.access_token = None
  40 + self.suite_access_token = None
  41 +
  42 + ## override CorpApi 的 refreshAccessToken, 使用第三方服务商的方法
  43 + def getAccessToken(self):
  44 + if self.access_token is None:
  45 + self.refreshAccessToken()
  46 + return self.access_token
  47 +
  48 + def refreshAccessToken(self):
  49 + response = self.httpCall(
  50 + SERVICE_CORP_API_TYPE['GET_CORP_TOKEN'],
  51 + {
  52 + "auth_corpid": self.auth_corpid,
  53 + "permanent_code": self.permanent_code,
  54 + })
  55 + self.access_token = response.get('access_token')
  56 +
  57 + ##
  58 +
  59 + def getSuiteAccessToken(self):
  60 + if self.suite_access_token is None:
  61 + self.refreshSuiteAccessToken()
  62 + return self.suite_access_token
  63 +
  64 + def refreshSuiteAccessToken(self):
  65 + response = self.httpCall(
  66 + SERVICE_CORP_API_TYPE['GET_SUITE_TOKEN'],
  67 + {
  68 + "suite_id": self.suite_id,
  69 + "suite_secret": self.suite_secret,
  70 + "suite_ticket": self.suite_ticket,
  71 + })
  72 + self.suite_access_token = response.get('suite_access_token')
  1 +#!/usr/bin/env python
  2 +# -*- coding:utf-8 -*-
  3 +##
  4 +# Copyright (C) 2018 All rights reserved.
  5 +#
  6 +# @File ServiceProviderApi.py
  7 +# @Brief
  8 +# @Author abelzhu, abelzhu@tencent.com
  9 +# @Version 1.0
  10 +# @Date 2018-02-26
  11 +#
  12 +#
  13 +
  14 +from .AbstractApi import *
  15 +
  16 +SERVICE_PROVIDER_API_TYPE = {
  17 + 'GET_PROVIDER_TOKEN': ['/cgi-bin/service/get_provider_token', 'POST'],
  18 + 'GET_LOGIN_INFO': ['/cgi-bin/service/get_login_info?access_token=PROVIDER_ACCESS_TOKEN', 'POST'],
  19 + 'GET_REGISTER_CODE': ['/cgi-bin/service/get_register_code?provider_access_token=PROVIDER_ACCESS_TOKEN', 'POST'],
  20 + 'GET_REGISTER_INFO': ['/cgi-bin/service/get_register_info?provider_access_token=PROVIDER_ACCESS_TOKEN', 'POST'],
  21 + 'SET_AGENT_SCOPE': ['/cgi-bin/agent/set_scope', 'POST'], ### TODO
  22 + 'SET_CONTACT_SYNC_SUCCESS': ['/cgi-bin/sync/contact_sync_success', 'GET'],
  23 +}
  24 +
  25 +
  26 +class ServiceProviderApi(AbstractApi):
  27 + def __init__(self, corpid, provider_secret):
  28 + self.corpid = corpid
  29 + self.provider_secret = provider_secret
  30 +
  31 + self.provider_access_token = None
  32 +
  33 + def getProviderAccessToken(self):
  34 + if self.provider_access_token is None:
  35 + self.refreshProviderAccessToken()
  36 + return self.provider_access_token
  37 +
  38 + def refreshProviderAccessToken(self):
  39 + response = self.httpCall(
  40 + SERVICE_PROVIDER_API_TYPE['GET_PROVIDER_TOKEN'],
  41 + {
  42 + 'corpid': self.corpid,
  43 + 'provider_secret': self.provider_secret,
  44 + })
  45 + self.provider_access_token = response.get('provider_access_token')
  1 +# -*- coding:utf-8 -*-
  2 +# Copyright (C) 2018 All rights reserved.
  3 +#
  4 +# @File conf.py
  5 +# @Brief
  6 +# @Author abelzhu, abelzhu@tencent.com
  7 +# @Version 1.0
  8 +# @Date 2018-02-23
  9 +
  10 +# 设置为true会打印一些调试信息
  11 +from wxProject.wxProject.settings import DEBUG
  12 +
  13 +DEBUG = DEBUG
  14 +
  15 +
  16 +# 企业微信的一些配置项
  17 +Conf = {
  18 + # 企业的id,在管理端->"我的企业" 可以看到
  19 + "CORP_ID": "ww0f3efc2873ad11c3",
  20 +
  21 + # "通讯录同步"应用的secret, 开启api接口同步后,可以在管理端->"通讯录同步"看到
  22 + "CONTACT_SYNC_SECRET": "xWPfryWX7Fv1BcJSpivflpPQXC_v5iH0HY2zfu1soTA",
  23 +
  24 + # 运维组ID
  25 + "OPS_DEP_ID": '346',
  26 +
  27 + # 某个自建应用的id及secret, 在管理端 -> 企业应用 -> 自建应用, 点进相应应用可以看到
  28 + "APP_ID": '1000078',
  29 + "APP_SECRET": "7MHpdQICiegx9rIc4iZrEPunb1aYUqdJYKSW9v7a1A8",
  30 +
  31 + # 打卡应用的 id 及secrete, 在管理端 -> 企业应用 -> 基础应用 -> 打卡,
  32 + # 点进去,有个"api"按钮,点开后,会看到
  33 + "CHECKIN_APP_ID": 0,
  34 + "CHECKIN_APP_SECRET": "",
  35 +
  36 + # 审批应用的 id 及secrete, 在管理端 -> 企业应用 -> 基础应用 -> 审批,
  37 + # 点进去,有个"api"按钮,点开后,会看到
  38 + "APPROVAL_APP_ID": 0,
  39 + "APPROVAL_APP_SECRET": "",
  40 +}
  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', 'wxProject.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()
  1 +__pycache__
  1 +from django.contrib import admin
  2 +
  3 +# Register your models here.
  1 +from django.apps import AppConfig
  2 +
  3 +
  4 +class ProjectConfig(AppConfig):
  5 + name = 'project'
  1 +# Generated by Django 3.1.1 on 2020-09-30 07:38
  2 +
  3 +from django.db import migrations, models
  4 +import django.db.models.deletion
  5 +
  6 +
  7 +class Migration(migrations.Migration):
  8 +
  9 + initial = True
  10 +
  11 + dependencies = [
  12 + ]
  13 +
  14 + operations = [
  15 + migrations.CreateModel(
  16 + name='Auditor',
  17 + fields=[
  18 + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
  19 + ('leader', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='p', to='project.auditor', verbose_name='上级领导')),
  20 + ],
  21 + ),
  22 + migrations.CreateModel(
  23 + name='Program',
  24 + fields=[
  25 + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
  26 + ('category', models.CharField(default='', max_length=100, verbose_name='产品类目')),
  27 + ('model_type', models.CharField(default='', max_length=50, verbose_name='产品型号')),
  28 + ('market_share_analysis', models.TextField(default='', verbose_name='产品市场占有率分析')),
  29 + ('context_analysis', models.TextField(default='', verbose_name='产品场景分析')),
  30 + ('attachments', models.CharField(default='', max_length=800, verbose_name='附件地址')),
  31 + ('create_time', models.DateTimeField(auto_now_add=True)),
  32 + ('auditor', models.ManyToManyField(related_name='auditor', to='project.Auditor', verbose_name='审核人员')),
  33 + ],
  34 + options={
  35 + 'ordering': ('-create_time',),
  36 + },
  37 + ),
  38 + ]
  1 +# Generated by Django 3.1.1 on 2020-09-30 07:38
  2 +
  3 +from django.conf import settings
  4 +from django.db import migrations, models
  5 +import django.db.models.deletion
  6 +
  7 +
  8 +class Migration(migrations.Migration):
  9 +
  10 + initial = True
  11 +
  12 + dependencies = [
  13 + ('project', '0001_initial'),
  14 + migrations.swappable_dependency(settings.AUTH_USER_MODEL),
  15 + ]
  16 +
  17 + operations = [
  18 + migrations.AddField(
  19 + model_name='auditor',
  20 + name='user',
  21 + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='aud', to=settings.AUTH_USER_MODEL, verbose_name='审批人员'),
  22 + ),
  23 + ]
  1 +# Generated by Django 3.1.1 on 2020-09-30 08:07
  2 +
  3 +from django.db import migrations, models
  4 +
  5 +
  6 +class Migration(migrations.Migration):
  7 +
  8 + dependencies = [
  9 + ('project', '0002_auditor_user'),
  10 + ]
  11 +
  12 + operations = [
  13 + migrations.AlterField(
  14 + model_name='program',
  15 + name='auditor',
  16 + field=models.ManyToManyField(related_name='project_auditor', to='project.Auditor', verbose_name='审核人员'),
  17 + ),
  18 + ]
  1 +# Generated by Django 3.1.1 on 2020-09-30 08:43
  2 +
  3 +from django.db import migrations, models
  4 +
  5 +
  6 +class Migration(migrations.Migration):
  7 +
  8 + dependencies = [
  9 + ('project', '0003_auto_20200930_1607'),
  10 + ]
  11 +
  12 + operations = [
  13 + migrations.AlterField(
  14 + model_name='auditor',
  15 + name='user',
  16 + field=models.CharField(choices=[('admin', 'admin')], max_length=100, verbose_name='审批人员'),
  17 + ),
  18 + ]
  1 +# Generated by Django 3.1.1 on 2020-09-30 09:21
  2 +
  3 +from django.conf import settings
  4 +from django.db import migrations, models
  5 +import django.db.models.deletion
  6 +
  7 +
  8 +class Migration(migrations.Migration):
  9 +
  10 + dependencies = [
  11 + migrations.swappable_dependency(settings.AUTH_USER_MODEL),
  12 + ('project', '0004_auto_20200930_1643'),
  13 + ]
  14 +
  15 + operations = [
  16 + migrations.AlterField(
  17 + model_name='auditor',
  18 + name='user',
  19 + field=models.ForeignKey(choices=[{'id': 1, 'username': 'admin'}, {'id': 2, 'username': 'wanweibin'}, {'id': 3, 'username': 'wanweibin1'}], on_delete=django.db.models.deletion.CASCADE, related_name='aud', to=settings.AUTH_USER_MODEL, verbose_name='审批人员'),
  20 + ),
  21 + ]
  1 +# Generated by Django 3.1.1 on 2020-09-30 09:45
  2 +
  3 +from django.conf import settings
  4 +from django.db import migrations, models
  5 +import django.db.models.deletion
  6 +
  7 +
  8 +class Migration(migrations.Migration):
  9 +
  10 + dependencies = [
  11 + migrations.swappable_dependency(settings.AUTH_USER_MODEL),
  12 + ('project', '0005_auto_20200930_1721'),
  13 + ]
  14 +
  15 + operations = [
  16 + migrations.AlterField(
  17 + model_name='auditor',
  18 + name='user',
  19 + field=models.ForeignKey(choices=[(1, 'admin'), (2, 'wanweibin'), (3, 'wanweibin1')], on_delete=django.db.models.deletion.CASCADE, related_name='aud', to=settings.AUTH_USER_MODEL, verbose_name='审批人员'),
  20 + ),
  21 + migrations.RenameModel(
  22 + old_name='Program',
  23 + new_name='Project',
  24 + ),
  25 + migrations.CreateModel(
  26 + name='Result',
  27 + fields=[
  28 + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
  29 + ('is_accept', models.CharField(choices=[('accept', '通过'), ('reject', '否决')], max_length=10, null=True, verbose_name='审核项目')),
  30 + ('memo', models.CharField(blank=True, default='', max_length=300, verbose_name='审核结果陈述')),
  31 + ('create_time', models.DateTimeField(auto_now_add=True)),
  32 + ('auditor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='result_auditor', to='project.auditor', verbose_name='审核人员')),
  33 + ('program', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='result_project', to='project.project', verbose_name='审核项目')),
  34 + ],
  35 + options={
  36 + 'ordering': ('-create_time',),
  37 + },
  38 + ),
  39 + ]
  1 +from django.db import models
  2 +from usercenter.models import User
  3 +
  4 +users = User.objects.filter(is_active=True).values('username', 'id').all()
  5 +AUDITOR_CHOICE = [(i['id'], i['username']) for i in users]
  6 +
  7 +
  8 +class Auditor(models.Model):
  9 + # user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="aud", verbose_name="审批人员")
  10 + user = models.ForeignKey(
  11 + User,
  12 + on_delete=models.CASCADE,
  13 + related_name="aud",
  14 + choices=AUDITOR_CHOICE,
  15 + verbose_name="审批人员")
  16 + leader = models.ForeignKey(
  17 + 'self',
  18 + on_delete=models.CASCADE,
  19 + related_name="p",
  20 + null=True,
  21 + blank=True,
  22 + verbose_name="上级领导")
  23 +
  24 + def __str__(self):
  25 + return self.user.username
  26 +
  27 +
  28 +class Project(models.Model):
  29 + category = models.CharField(max_length=100, default="", verbose_name="产品类目")
  30 + model_type = models.CharField(max_length=50, default="", verbose_name="产品型号")
  31 + market_share_analysis = models.TextField(default="", verbose_name="产品市场占有率分析")
  32 + context_analysis = models.TextField(default="", verbose_name="产品场景分析")
  33 + attachments = models.CharField(max_length=800, default="", verbose_name="附件地址")
  34 + auditor = models.ManyToManyField(Auditor, related_name="project_auditor", verbose_name="审核人员")
  35 + create_time = models.DateTimeField(auto_now_add=True)
  36 +
  37 + def __str__(self):
  38 + return self.category + '-' + self.model_type
  39 +
  40 + class Meta:
  41 + ordering = ('-create_time',)
  42 +
  43 +
  44 +class Result(models.Model):
  45 + ACCEPT_CHOICES = (
  46 + ('accept', '通过'),
  47 + ('reject', '否决')
  48 + )
  49 +
  50 + auditor = models.ForeignKey(Auditor, on_delete=models.CASCADE, related_name="result_auditor", verbose_name="审核人员")
  51 + program = models.ForeignKey(Project, on_delete=models.CASCADE, related_name="result_project", verbose_name="审核项目")
  52 + is_accept = models.CharField(max_length=10, null=True, choices=ACCEPT_CHOICES, verbose_name="审核项目")
  53 + memo = models.CharField(max_length=300, blank=True, default="", verbose_name="审核结果陈述")
  54 + create_time = models.DateTimeField(auto_now_add=True)
  55 +
  56 + def __str__(self):
  57 + return self.is_accept
  58 +
  59 + class Meta:
  60 + ordering = ('-create_time', )
  61 +
  1 +# _*_ coding: utf-8 _*_
  2 +# @Time : 2020/9/30 11:02
  3 +# @Author vanwhebin
  4 +from rest_framework import serializers
  5 +
  6 +from .models import Auditor, Project
  7 +from usercenter.serializers import UserSerializer
  8 +
  9 +
  10 +class AuditorSerializer(serializers.ModelSerializer):
  11 +
  12 + class Meta:
  13 + model = Auditor
  14 + # fields = ("user", "leader")
  15 + fields = '__all__'
  16 + depth = 1
  17 +
  18 +
  19 +class ProgramSerializer(serializers.ModelSerializer):
  20 + class Meta:
  21 + model = Project
  22 + fields = '__all__'
  23 +
  24 +
  1 +from django.test import TestCase
  2 +
  3 +# Create your tests here.
  1 +# _*_ coding: utf-8 _*_
  2 +# @Time : 2020/9/30 11:18
  3 +# @Author vanwhebin
  4 +
  5 +from django.urls import re_path, include
  6 +from rest_framework import routers
  7 +
  8 +from .views import AuditorViewSet, ProgramViewSet, AuditorListView
  9 +
  10 +router = routers.DefaultRouter()
  11 +router.register(r'auditor', AuditorViewSet, basename="auditor")
  12 +router.register(r'program', ProgramViewSet, basename="program")
  13 +
  14 +app_name = "project"
  15 +
  16 +urlpatterns = [
  17 + re_path('', include(router.urls)),
  18 + # re_path(r'auditor', AuditorListView.as_view()),
  19 + # re_path(r'auditor/<int:pk>', AuditorListView.as_view()),
  20 +]
  1 +# _*_ coding: utf-8 _*_
  2 +# @Time : 2020/9/30 11:02
  3 +# @Author vanwhebin
  4 +from rest_framework import viewsets, generics, views
  5 +from .models import Auditor, Project
  6 +from .serializers import AuditorSerializer, ProgramSerializer
  7 +from rest_framework.permissions import IsAuthenticated, IsAuthenticatedOrReadOnly
  8 +
  9 +
  10 +class AuditorViewSet(viewsets.ModelViewSet):
  11 + queryset = Auditor.objects.all()
  12 + serializer_class = AuditorSerializer
  13 + permission_classes = (IsAuthenticated,)
  14 +
  15 +
  16 +class AuditorListView(generics.ListCreateAPIView):
  17 + queryset = Auditor.objects.all()
  18 + serializer_class = AuditorSerializer
  19 + permission_classes = (IsAuthenticated,)
  20 +
  21 + def perform_create(self, serializer):
  22 + serializer.save(user=self.request.user)
  23 +
  24 + # def create(self, request, *args, **kwargs):
  25 + # pass
  26 +
  27 +
  28 +class AuditorDetailView(generics.RetrieveDestroyAPIView):
  29 + def get(self, request, *args, **kwargs):
  30 + pass
  31 +
  32 + def destroy(self, request, *args, **kwargs):
  33 + pass
  34 +
  35 +
  36 +class ProgramViewSet(viewsets.ModelViewSet):
  37 + queryset = Project.objects.all()
  38 + serializer_class = ProgramSerializer
  39 + permission_classes = (IsAuthenticated, )
  40 +
  1 +asgiref==3.2.10
  2 +Django==3.1.1
  3 +django-cors-headers==3.5.0
  4 +django-filter==2.4.0
  5 +djangorestframework==3.12.1
  6 +djangorestframework-simplejwt==4.4.0
  7 +mysqlclient==2.0.1
  8 +Pillow==7.2.0
  9 +PyJWT==1.7.1
  10 +pytz==2020.1
  11 +sqlparse==0.3.1
  1 +select.admin-autocomplete {
  2 + width: 20em;
  3 +}
  4 +
  5 +.select2-container--admin-autocomplete.select2-container {
  6 + min-height: 30px;
  7 +}
  8 +
  9 +.select2-container--admin-autocomplete .select2-selection--single,
  10 +.select2-container--admin-autocomplete .select2-selection--multiple {
  11 + min-height: 30px;
  12 + padding: 0;
  13 +}
  14 +
  15 +.select2-container--admin-autocomplete.select2-container--focus .select2-selection,
  16 +.select2-container--admin-autocomplete.select2-container--open .select2-selection {
  17 + border-color: #999;
  18 + min-height: 30px;
  19 +}
  20 +
  21 +.select2-container--admin-autocomplete.select2-container--focus .select2-selection.select2-selection--single,
  22 +.select2-container--admin-autocomplete.select2-container--open .select2-selection.select2-selection--single {
  23 + padding: 0;
  24 +}
  25 +
  26 +.select2-container--admin-autocomplete.select2-container--focus .select2-selection.select2-selection--multiple,
  27 +.select2-container--admin-autocomplete.select2-container--open .select2-selection.select2-selection--multiple {
  28 + padding: 0;
  29 +}
  30 +
  31 +.select2-container--admin-autocomplete .select2-selection--single {
  32 + background-color: #fff;
  33 + border: 1px solid #ccc;
  34 + border-radius: 4px;
  35 +}
  36 +
  37 +.select2-container--admin-autocomplete .select2-selection--single .select2-selection__rendered {
  38 + color: #444;
  39 + line-height: 30px;
  40 +}
  41 +
  42 +.select2-container--admin-autocomplete .select2-selection--single .select2-selection__clear {
  43 + cursor: pointer;
  44 + float: right;
  45 + font-weight: bold;
  46 +}
  47 +
  48 +.select2-container--admin-autocomplete .select2-selection--single .select2-selection__placeholder {
  49 + color: #999;
  50 +}
  51 +
  52 +.select2-container--admin-autocomplete .select2-selection--single .select2-selection__arrow {
  53 + height: 26px;
  54 + position: absolute;
  55 + top: 1px;
  56 + right: 1px;
  57 + width: 20px;
  58 +}
  59 +
  60 +.select2-container--admin-autocomplete .select2-selection--single .select2-selection__arrow b {
  61 + border-color: #888 transparent transparent transparent;
  62 + border-style: solid;
  63 + border-width: 5px 4px 0 4px;
  64 + height: 0;
  65 + left: 50%;
  66 + margin-left: -4px;
  67 + margin-top: -2px;
  68 + position: absolute;
  69 + top: 50%;
  70 + width: 0;
  71 +}
  72 +
  73 +.select2-container--admin-autocomplete[dir="rtl"] .select2-selection--single .select2-selection__clear {
  74 + float: left;
  75 +}
  76 +
  77 +.select2-container--admin-autocomplete[dir="rtl"] .select2-selection--single .select2-selection__arrow {
  78 + left: 1px;
  79 + right: auto;
  80 +}
  81 +
  82 +.select2-container--admin-autocomplete.select2-container--disabled .select2-selection--single {
  83 + background-color: #eee;
  84 + cursor: default;
  85 +}
  86 +
  87 +.select2-container--admin-autocomplete.select2-container--disabled .select2-selection--single .select2-selection__clear {
  88 + display: none;
  89 +}
  90 +
  91 +.select2-container--admin-autocomplete.select2-container--open .select2-selection--single .select2-selection__arrow b {
  92 + border-color: transparent transparent #888 transparent;
  93 + border-width: 0 4px 5px 4px;
  94 +}
  95 +
  96 +.select2-container--admin-autocomplete .select2-selection--multiple {
  97 + background-color: white;
  98 + border: 1px solid #ccc;
  99 + border-radius: 4px;
  100 + cursor: text;
  101 +}
  102 +
  103 +.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__rendered {
  104 + box-sizing: border-box;
  105 + list-style: none;
  106 + margin: 0;
  107 + padding: 0 5px;
  108 + width: 100%;
  109 +}
  110 +
  111 +.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__rendered li {
  112 + list-style: none;
  113 +}
  114 +
  115 +.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__placeholder {
  116 + color: #999;
  117 + margin-top: 5px;
  118 + float: left;
  119 +}
  120 +
  121 +.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__clear {
  122 + cursor: pointer;
  123 + float: right;
  124 + font-weight: bold;
  125 + margin: 5px;
  126 +}
  127 +
  128 +.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__choice {
  129 + background-color: #e4e4e4;
  130 + border: 1px solid #ccc;
  131 + border-radius: 4px;
  132 + cursor: default;
  133 + float: left;
  134 + margin-right: 5px;
  135 + margin-top: 5px;
  136 + padding: 0 5px;
  137 +}
  138 +
  139 +.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__choice__remove {
  140 + color: #999;
  141 + cursor: pointer;
  142 + display: inline-block;
  143 + font-weight: bold;
  144 + margin-right: 2px;
  145 +}
  146 +
  147 +.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__choice__remove:hover {
  148 + color: #333;
  149 +}
  150 +
  151 +.select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder, .select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-search--inline {
  152 + float: right;
  153 +}
  154 +
  155 +.select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
  156 + margin-left: 5px;
  157 + margin-right: auto;
  158 +}
  159 +
  160 +.select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove {
  161 + margin-left: 2px;
  162 + margin-right: auto;
  163 +}
  164 +
  165 +.select2-container--admin-autocomplete.select2-container--focus .select2-selection--multiple {
  166 + border: solid #999 1px;
  167 + outline: 0;
  168 +}
  169 +
  170 +.select2-container--admin-autocomplete.select2-container--disabled .select2-selection--multiple {
  171 + background-color: #eee;
  172 + cursor: default;
  173 +}
  174 +
  175 +.select2-container--admin-autocomplete.select2-container--disabled .select2-selection__choice__remove {
  176 + display: none;
  177 +}
  178 +
  179 +.select2-container--admin-autocomplete.select2-container--open.select2-container--above .select2-selection--single, .select2-container--admin-autocomplete.select2-container--open.select2-container--above .select2-selection--multiple {
  180 + border-top-left-radius: 0;
  181 + border-top-right-radius: 0;
  182 +}
  183 +
  184 +.select2-container--admin-autocomplete.select2-container--open.select2-container--below .select2-selection--single, .select2-container--admin-autocomplete.select2-container--open.select2-container--below .select2-selection--multiple {
  185 + border-bottom-left-radius: 0;
  186 + border-bottom-right-radius: 0;
  187 +}
  188 +
  189 +.select2-container--admin-autocomplete .select2-search--dropdown .select2-search__field {
  190 + border: 1px solid #ccc;
  191 +}
  192 +
  193 +.select2-container--admin-autocomplete .select2-search--inline .select2-search__field {
  194 + background: transparent;
  195 + border: none;
  196 + outline: 0;
  197 + box-shadow: none;
  198 + -webkit-appearance: textfield;
  199 +}
  200 +
  201 +.select2-container--admin-autocomplete .select2-results > .select2-results__options {
  202 + max-height: 200px;
  203 + overflow-y: auto;
  204 +}
  205 +
  206 +.select2-container--admin-autocomplete .select2-results__option[role=group] {
  207 + padding: 0;
  208 +}
  209 +
  210 +.select2-container--admin-autocomplete .select2-results__option[aria-disabled=true] {
  211 + color: #999;
  212 +}
  213 +
  214 +.select2-container--admin-autocomplete .select2-results__option[aria-selected=true] {
  215 + background-color: #ddd;
  216 +}
  217 +
  218 +.select2-container--admin-autocomplete .select2-results__option .select2-results__option {
  219 + padding-left: 1em;
  220 +}
  221 +
  222 +.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__group {
  223 + padding-left: 0;
  224 +}
  225 +
  226 +.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option {
  227 + margin-left: -1em;
  228 + padding-left: 2em;
  229 +}
  230 +
  231 +.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
  232 + margin-left: -2em;
  233 + padding-left: 3em;
  234 +}
  235 +
  236 +.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
  237 + margin-left: -3em;
  238 + padding-left: 4em;
  239 +}
  240 +
  241 +.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
  242 + margin-left: -4em;
  243 + padding-left: 5em;
  244 +}
  245 +
  246 +.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
  247 + margin-left: -5em;
  248 + padding-left: 6em;
  249 +}
  250 +
  251 +.select2-container--admin-autocomplete .select2-results__option--highlighted[aria-selected] {
  252 + background-color: #79aec8;
  253 + color: white;
  254 +}
  255 +
  256 +.select2-container--admin-autocomplete .select2-results__group {
  257 + cursor: default;
  258 + display: block;
  259 + padding: 6px;
  260 +}
  1 +/*
  2 + DJANGO Admin styles
  3 +*/
  4 +
  5 +@import url(fonts.css);
  6 +
  7 +html, body {
  8 + height: 100%;
  9 +}
  10 +
  11 +body {
  12 + margin: 0;
  13 + padding: 0;
  14 + font-size: 14px;
  15 + font-family: "Roboto","Lucida Grande","DejaVu Sans","Bitstream Vera Sans",Verdana,Arial,sans-serif;
  16 + color: #333;
  17 + background: #fff;
  18 +}
  19 +
  20 +/* LINKS */
  21 +
  22 +a:link, a:visited {
  23 + color: #447e9b;
  24 + text-decoration: none;
  25 +}
  26 +
  27 +a:focus, a:hover {
  28 + color: #036;
  29 +}
  30 +
  31 +a:focus {
  32 + text-decoration: underline;
  33 +}
  34 +
  35 +a img {
  36 + border: none;
  37 +}
  38 +
  39 +a.section:link, a.section:visited {
  40 + color: #fff;
  41 + text-decoration: none;
  42 +}
  43 +
  44 +a.section:focus, a.section:hover {
  45 + text-decoration: underline;
  46 +}
  47 +
  48 +/* GLOBAL DEFAULTS */
  49 +
  50 +p, ol, ul, dl {
  51 + margin: .2em 0 .8em 0;
  52 +}
  53 +
  54 +p {
  55 + padding: 0;
  56 + line-height: 140%;
  57 +}
  58 +
  59 +h1,h2,h3,h4,h5 {
  60 + font-weight: bold;
  61 +}
  62 +
  63 +h1 {
  64 + margin: 0 0 20px;
  65 + font-weight: 300;
  66 + font-size: 20px;
  67 + color: #666;
  68 +}
  69 +
  70 +h2 {
  71 + font-size: 16px;
  72 + margin: 1em 0 .5em 0;
  73 +}
  74 +
  75 +h2.subhead {
  76 + font-weight: normal;
  77 + margin-top: 0;
  78 +}
  79 +
  80 +h3 {
  81 + font-size: 14px;
  82 + margin: .8em 0 .3em 0;
  83 + color: #666;
  84 + font-weight: bold;
  85 +}
  86 +
  87 +h4 {
  88 + font-size: 12px;
  89 + margin: 1em 0 .8em 0;
  90 + padding-bottom: 3px;
  91 +}
  92 +
  93 +h5 {
  94 + font-size: 10px;
  95 + margin: 1.5em 0 .5em 0;
  96 + color: #666;
  97 + text-transform: uppercase;
  98 + letter-spacing: 1px;
  99 +}
  100 +
  101 +ul > li {
  102 + list-style-type: square;
  103 + padding: 1px 0;
  104 +}
  105 +
  106 +li ul {
  107 + margin-bottom: 0;
  108 +}
  109 +
  110 +li, dt, dd {
  111 + font-size: 13px;
  112 + line-height: 20px;
  113 +}
  114 +
  115 +dt {
  116 + font-weight: bold;
  117 + margin-top: 4px;
  118 +}
  119 +
  120 +dd {
  121 + margin-left: 0;
  122 +}
  123 +
  124 +form {
  125 + margin: 0;
  126 + padding: 0;
  127 +}
  128 +
  129 +fieldset {
  130 + margin: 0;
  131 + min-width: 0;
  132 + padding: 0;
  133 + border: none;
  134 + border-top: 1px solid #eee;
  135 +}
  136 +
  137 +blockquote {
  138 + font-size: 11px;
  139 + color: #777;
  140 + margin-left: 2px;
  141 + padding-left: 10px;
  142 + border-left: 5px solid #ddd;
  143 +}
  144 +
  145 +code, pre {
  146 + font-family: "Bitstream Vera Sans Mono", Monaco, "Courier New", Courier, monospace;
  147 + color: #666;
  148 + font-size: 12px;
  149 + overflow-x: auto;
  150 +}
  151 +
  152 +pre.literal-block {
  153 + margin: 10px;
  154 + background: #eee;
  155 + padding: 6px 8px;
  156 +}
  157 +
  158 +code strong {
  159 + color: #930;
  160 +}
  161 +
  162 +hr {
  163 + clear: both;
  164 + color: #eee;
  165 + background-color: #eee;
  166 + height: 1px;
  167 + border: none;
  168 + margin: 0;
  169 + padding: 0;
  170 + font-size: 1px;
  171 + line-height: 1px;
  172 +}
  173 +
  174 +/* TEXT STYLES & MODIFIERS */
  175 +
  176 +.small {
  177 + font-size: 11px;
  178 +}
  179 +
  180 +.mini {
  181 + font-size: 10px;
  182 +}
  183 +
  184 +.help, p.help, form p.help, div.help, form div.help, div.help li {
  185 + font-size: 11px;
  186 + color: #999;
  187 +}
  188 +
  189 +div.help ul {
  190 + margin-bottom: 0;
  191 +}
  192 +
  193 +.help-tooltip {
  194 + cursor: help;
  195 +}
  196 +
  197 +p img, h1 img, h2 img, h3 img, h4 img, td img {
  198 + vertical-align: middle;
  199 +}
  200 +
  201 +.quiet, a.quiet:link, a.quiet:visited {
  202 + color: #999;
  203 + font-weight: normal;
  204 +}
  205 +
  206 +.clear {
  207 + clear: both;
  208 +}
  209 +
  210 +.nowrap {
  211 + white-space: nowrap;
  212 +}
  213 +
  214 +/* TABLES */
  215 +
  216 +table {
  217 + border-collapse: collapse;
  218 + border-color: #ccc;
  219 +}
  220 +
  221 +td, th {
  222 + font-size: 13px;
  223 + line-height: 16px;
  224 + border-bottom: 1px solid #eee;
  225 + vertical-align: top;
  226 + padding: 8px;
  227 + font-family: "Roboto", "Lucida Grande", Verdana, Arial, sans-serif;
  228 +}
  229 +
  230 +th {
  231 + font-weight: 600;
  232 + text-align: left;
  233 +}
  234 +
  235 +thead th,
  236 +tfoot td {
  237 + color: #666;
  238 + padding: 5px 10px;
  239 + font-size: 11px;
  240 + background: #fff;
  241 + border: none;
  242 + border-top: 1px solid #eee;
  243 + border-bottom: 1px solid #eee;
  244 +}
  245 +
  246 +tfoot td {
  247 + border-bottom: none;
  248 + border-top: 1px solid #eee;
  249 +}
  250 +
  251 +thead th.required {
  252 + color: #000;
  253 +}
  254 +
  255 +tr.alt {
  256 + background: #f6f6f6;
  257 +}
  258 +
  259 +tr:nth-child(odd), .row-form-errors {
  260 + background: #fff;
  261 +}
  262 +
  263 +tr:nth-child(even),
  264 +tr:nth-child(even) .errorlist,
  265 +tr:nth-child(odd) + .row-form-errors,
  266 +tr:nth-child(odd) + .row-form-errors .errorlist {
  267 + background: #f9f9f9;
  268 +}
  269 +
  270 +/* SORTABLE TABLES */
  271 +
  272 +thead th {
  273 + padding: 5px 10px;
  274 + line-height: normal;
  275 + text-transform: uppercase;
  276 + background: #f6f6f6;
  277 +}
  278 +
  279 +thead th a:link, thead th a:visited {
  280 + color: #666;
  281 +}
  282 +
  283 +thead th.sorted {
  284 + background: #eee;
  285 +}
  286 +
  287 +thead th.sorted .text {
  288 + padding-right: 42px;
  289 +}
  290 +
  291 +table thead th .text span {
  292 + padding: 8px 10px;
  293 + display: block;
  294 +}
  295 +
  296 +table thead th .text a {
  297 + display: block;
  298 + cursor: pointer;
  299 + padding: 8px 10px;
  300 +}
  301 +
  302 +table thead th .text a:focus, table thead th .text a:hover {
  303 + background: #eee;
  304 +}
  305 +
  306 +thead th.sorted a.sortremove {
  307 + visibility: hidden;
  308 +}
  309 +
  310 +table thead th.sorted:hover a.sortremove {
  311 + visibility: visible;
  312 +}
  313 +
  314 +table thead th.sorted .sortoptions {
  315 + display: block;
  316 + padding: 9px 5px 0 5px;
  317 + float: right;
  318 + text-align: right;
  319 +}
  320 +
  321 +table thead th.sorted .sortpriority {
  322 + font-size: .8em;
  323 + min-width: 12px;
  324 + text-align: center;
  325 + vertical-align: 3px;
  326 + margin-left: 2px;
  327 + margin-right: 2px;
  328 +}
  329 +
  330 +table thead th.sorted .sortoptions a {
  331 + position: relative;
  332 + width: 14px;
  333 + height: 14px;
  334 + display: inline-block;
  335 + background: url(../img/sorting-icons.svg) 0 0 no-repeat;
  336 + background-size: 14px auto;
  337 +}
  338 +
  339 +table thead th.sorted .sortoptions a.sortremove {
  340 + background-position: 0 0;
  341 +}
  342 +
  343 +table thead th.sorted .sortoptions a.sortremove:after {
  344 + content: '\\';
  345 + position: absolute;
  346 + top: -6px;
  347 + left: 3px;
  348 + font-weight: 200;
  349 + font-size: 18px;
  350 + color: #999;
  351 +}
  352 +
  353 +table thead th.sorted .sortoptions a.sortremove:focus:after,
  354 +table thead th.sorted .sortoptions a.sortremove:hover:after {
  355 + color: #447e9b;
  356 +}
  357 +
  358 +table thead th.sorted .sortoptions a.sortremove:focus,
  359 +table thead th.sorted .sortoptions a.sortremove:hover {
  360 + background-position: 0 -14px;
  361 +}
  362 +
  363 +table thead th.sorted .sortoptions a.ascending {
  364 + background-position: 0 -28px;
  365 +}
  366 +
  367 +table thead th.sorted .sortoptions a.ascending:focus,
  368 +table thead th.sorted .sortoptions a.ascending:hover {
  369 + background-position: 0 -42px;
  370 +}
  371 +
  372 +table thead th.sorted .sortoptions a.descending {
  373 + top: 1px;
  374 + background-position: 0 -56px;
  375 +}
  376 +
  377 +table thead th.sorted .sortoptions a.descending:focus,
  378 +table thead th.sorted .sortoptions a.descending:hover {
  379 + background-position: 0 -70px;
  380 +}
  381 +
  382 +/* FORM DEFAULTS */
  383 +
  384 +input, textarea, select, .form-row p, form .button {
  385 + margin: 2px 0;
  386 + padding: 2px 3px;
  387 + vertical-align: middle;
  388 + font-family: "Roboto", "Lucida Grande", Verdana, Arial, sans-serif;
  389 + font-weight: normal;
  390 + font-size: 13px;
  391 +}
  392 +.form-row div.help {
  393 + padding: 2px 3px;
  394 +}
  395 +
  396 +textarea {
  397 + vertical-align: top;
  398 +}
  399 +
  400 +input[type=text], input[type=password], input[type=email], input[type=url],
  401 +input[type=number], input[type=tel], textarea, select, .vTextField {
  402 + border: 1px solid #ccc;
  403 + border-radius: 4px;
  404 + padding: 5px 6px;
  405 + margin-top: 0;
  406 +}
  407 +
  408 +input[type=text]:focus, input[type=password]:focus, input[type=email]:focus,
  409 +input[type=url]:focus, input[type=number]:focus, input[type=tel]:focus,
  410 +textarea:focus, select:focus, .vTextField:focus {
  411 + border-color: #999;
  412 +}
  413 +
  414 +select {
  415 + height: 30px;
  416 +}
  417 +
  418 +select[multiple] {
  419 + /* Allow HTML size attribute to override the height in the rule above. */
  420 + height: auto;
  421 + min-height: 150px;
  422 +}
  423 +
  424 +/* FORM BUTTONS */
  425 +
  426 +.button, input[type=submit], input[type=button], .submit-row input, a.button {
  427 + background: #79aec8;
  428 + padding: 10px 15px;
  429 + border: none;
  430 + border-radius: 4px;
  431 + color: #fff;
  432 + cursor: pointer;
  433 +}
  434 +
  435 +a.button {
  436 + padding: 4px 5px;
  437 +}
  438 +
  439 +.button:active, input[type=submit]:active, input[type=button]:active,
  440 +.button:focus, input[type=submit]:focus, input[type=button]:focus,
  441 +.button:hover, input[type=submit]:hover, input[type=button]:hover {
  442 + background: #609ab6;
  443 +}
  444 +
  445 +.button[disabled], input[type=submit][disabled], input[type=button][disabled] {
  446 + opacity: 0.4;
  447 +}
  448 +
  449 +.button.default, input[type=submit].default, .submit-row input.default {
  450 + float: right;
  451 + border: none;
  452 + font-weight: 400;
  453 + background: #417690;
  454 +}
  455 +
  456 +.button.default:active, input[type=submit].default:active,
  457 +.button.default:focus, input[type=submit].default:focus,
  458 +.button.default:hover, input[type=submit].default:hover {
  459 + background: #205067;
  460 +}
  461 +
  462 +.button[disabled].default,
  463 +input[type=submit][disabled].default,
  464 +input[type=button][disabled].default {
  465 + opacity: 0.4;
  466 +}
  467 +
  468 +
  469 +/* MODULES */
  470 +
  471 +.module {
  472 + border: none;
  473 + margin-bottom: 30px;
  474 + background: #fff;
  475 +}
  476 +
  477 +.module p, .module ul, .module h3, .module h4, .module dl, .module pre {
  478 + padding-left: 10px;
  479 + padding-right: 10px;
  480 +}
  481 +
  482 +.module blockquote {
  483 + margin-left: 12px;
  484 +}
  485 +
  486 +.module ul, .module ol {
  487 + margin-left: 1.5em;
  488 +}
  489 +
  490 +.module h3 {
  491 + margin-top: .6em;
  492 +}
  493 +
  494 +.module h2, .module caption, .inline-group h2 {
  495 + margin: 0;
  496 + padding: 8px;
  497 + font-weight: 400;
  498 + font-size: 13px;
  499 + text-align: left;
  500 + background: #79aec8;
  501 + color: #fff;
  502 +}
  503 +
  504 +.module caption,
  505 +.inline-group h2 {
  506 + font-size: 12px;
  507 + letter-spacing: 0.5px;
  508 + text-transform: uppercase;
  509 +}
  510 +
  511 +.module table {
  512 + border-collapse: collapse;
  513 +}
  514 +
  515 +/* MESSAGES & ERRORS */
  516 +
  517 +ul.messagelist {
  518 + padding: 0;
  519 + margin: 0;
  520 +}
  521 +
  522 +ul.messagelist li {
  523 + display: block;
  524 + font-weight: 400;
  525 + font-size: 13px;
  526 + padding: 10px 10px 10px 65px;
  527 + margin: 0 0 10px 0;
  528 + background: #dfd url(../img/icon-yes.svg) 40px 12px no-repeat;
  529 + background-size: 16px auto;
  530 + color: #333;
  531 +}
  532 +
  533 +ul.messagelist li.warning {
  534 + background: #ffc url(../img/icon-alert.svg) 40px 14px no-repeat;
  535 + background-size: 14px auto;
  536 +}
  537 +
  538 +ul.messagelist li.error {
  539 + background: #ffefef url(../img/icon-no.svg) 40px 12px no-repeat;
  540 + background-size: 16px auto;
  541 +}
  542 +
  543 +.errornote {
  544 + font-size: 14px;
  545 + font-weight: 700;
  546 + display: block;
  547 + padding: 10px 12px;
  548 + margin: 0 0 10px 0;
  549 + color: #ba2121;
  550 + border: 1px solid #ba2121;
  551 + border-radius: 4px;
  552 + background-color: #fff;
  553 + background-position: 5px 12px;
  554 +}
  555 +
  556 +ul.errorlist {
  557 + margin: 0 0 4px;
  558 + padding: 0;
  559 + color: #ba2121;
  560 + background: #fff;
  561 +}
  562 +
  563 +ul.errorlist li {
  564 + font-size: 13px;
  565 + display: block;
  566 + margin-bottom: 4px;
  567 +}
  568 +
  569 +ul.errorlist li:first-child {
  570 + margin-top: 0;
  571 +}
  572 +
  573 +ul.errorlist li a {
  574 + color: inherit;
  575 + text-decoration: underline;
  576 +}
  577 +
  578 +td ul.errorlist {
  579 + margin: 0;
  580 + padding: 0;
  581 +}
  582 +
  583 +td ul.errorlist li {
  584 + margin: 0;
  585 +}
  586 +
  587 +.form-row.errors {
  588 + margin: 0;
  589 + border: none;
  590 + border-bottom: 1px solid #eee;
  591 + background: none;
  592 +}
  593 +
  594 +.form-row.errors ul.errorlist li {
  595 + padding-left: 0;
  596 +}
  597 +
  598 +.errors input, .errors select, .errors textarea,
  599 +td ul.errorlist + input, td ul.errorlist + select, td ul.errorlist + textarea {
  600 + border: 1px solid #ba2121;
  601 +}
  602 +
  603 +.description {
  604 + font-size: 12px;
  605 + padding: 5px 0 0 12px;
  606 +}
  607 +
  608 +/* BREADCRUMBS */
  609 +
  610 +div.breadcrumbs {
  611 + background: #79aec8;
  612 + padding: 10px 40px;
  613 + border: none;
  614 + font-size: 14px;
  615 + color: #c4dce8;
  616 + text-align: left;
  617 +}
  618 +
  619 +div.breadcrumbs a {
  620 + color: #fff;
  621 +}
  622 +
  623 +div.breadcrumbs a:focus, div.breadcrumbs a:hover {
  624 + color: #c4dce8;
  625 +}
  626 +
  627 +/* ACTION ICONS */
  628 +
  629 +.viewlink, .inlineviewlink {
  630 + padding-left: 16px;
  631 + background: url(../img/icon-viewlink.svg) 0 1px no-repeat;
  632 +}
  633 +
  634 +.addlink {
  635 + padding-left: 16px;
  636 + background: url(../img/icon-addlink.svg) 0 1px no-repeat;
  637 +}
  638 +
  639 +.changelink, .inlinechangelink {
  640 + padding-left: 16px;
  641 + background: url(../img/icon-changelink.svg) 0 1px no-repeat;
  642 +}
  643 +
  644 +.deletelink {
  645 + padding-left: 16px;
  646 + background: url(../img/icon-deletelink.svg) 0 1px no-repeat;
  647 +}
  648 +
  649 +a.deletelink:link, a.deletelink:visited {
  650 + color: #CC3434;
  651 +}
  652 +
  653 +a.deletelink:focus, a.deletelink:hover {
  654 + color: #993333;
  655 + text-decoration: none;
  656 +}
  657 +
  658 +/* OBJECT TOOLS */
  659 +
  660 +.object-tools {
  661 + font-size: 10px;
  662 + font-weight: bold;
  663 + padding-left: 0;
  664 + float: right;
  665 + position: relative;
  666 + margin-top: -48px;
  667 +}
  668 +
  669 +.form-row .object-tools {
  670 + margin-top: 5px;
  671 + margin-bottom: 5px;
  672 + float: none;
  673 + height: 2em;
  674 + padding-left: 3.5em;
  675 +}
  676 +
  677 +.object-tools li {
  678 + display: block;
  679 + float: left;
  680 + margin-left: 5px;
  681 + height: 16px;
  682 +}
  683 +
  684 +.object-tools a {
  685 + border-radius: 15px;
  686 +}
  687 +
  688 +.object-tools a:link, .object-tools a:visited {
  689 + display: block;
  690 + float: left;
  691 + padding: 3px 12px;
  692 + background: #999;
  693 + font-weight: 400;
  694 + font-size: 11px;
  695 + text-transform: uppercase;
  696 + letter-spacing: 0.5px;
  697 + color: #fff;
  698 +}
  699 +
  700 +.object-tools a:focus, .object-tools a:hover {
  701 + background-color: #417690;
  702 +}
  703 +
  704 +.object-tools a:focus{
  705 + text-decoration: none;
  706 +}
  707 +
  708 +.object-tools a.viewsitelink, .object-tools a.golink,.object-tools a.addlink {
  709 + background-repeat: no-repeat;
  710 + background-position: right 7px center;
  711 + padding-right: 26px;
  712 +}
  713 +
  714 +.object-tools a.viewsitelink, .object-tools a.golink {
  715 + background-image: url(../img/tooltag-arrowright.svg);
  716 +}
  717 +
  718 +.object-tools a.addlink {
  719 + background-image: url(../img/tooltag-add.svg);
  720 +}
  721 +
  722 +/* OBJECT HISTORY */
  723 +
  724 +table#change-history {
  725 + width: 100%;
  726 +}
  727 +
  728 +table#change-history tbody th {
  729 + width: 16em;
  730 +}
  731 +
  732 +/* PAGE STRUCTURE */
  733 +
  734 +#container {
  735 + position: relative;
  736 + width: 100%;
  737 + min-width: 980px;
  738 + padding: 0;
  739 + display: flex;
  740 + flex-direction: column;
  741 + height: 100%;
  742 +}
  743 +
  744 +#container > div {
  745 + flex-shrink: 0;
  746 +}
  747 +
  748 +#container > .main {
  749 + display: flex;
  750 + flex: 1 0 auto;
  751 +}
  752 +
  753 +.main > .content {
  754 + flex: 1 0;
  755 + max-width: 100%;
  756 +}
  757 +
  758 +#content {
  759 + padding: 20px 40px;
  760 +}
  761 +
  762 +.dashboard #content {
  763 + width: 600px;
  764 +}
  765 +
  766 +#content-main {
  767 + float: left;
  768 + width: 100%;
  769 +}
  770 +
  771 +#content-related {
  772 + float: right;
  773 + width: 260px;
  774 + position: relative;
  775 + margin-right: -300px;
  776 +}
  777 +
  778 +#footer {
  779 + clear: both;
  780 + padding: 10px;
  781 +}
  782 +
  783 +/* COLUMN TYPES */
  784 +
  785 +.colMS {
  786 + margin-right: 300px;
  787 +}
  788 +
  789 +.colSM {
  790 + margin-left: 300px;
  791 +}
  792 +
  793 +.colSM #content-related {
  794 + float: left;
  795 + margin-right: 0;
  796 + margin-left: -300px;
  797 +}
  798 +
  799 +.colSM #content-main {
  800 + float: right;
  801 +}
  802 +
  803 +.popup .colM {
  804 + width: auto;
  805 +}
  806 +
  807 +/* HEADER */
  808 +
  809 +#header {
  810 + width: auto;
  811 + height: auto;
  812 + display: flex;
  813 + justify-content: space-between;
  814 + align-items: center;
  815 + padding: 10px 40px;
  816 + background: #417690;
  817 + color: #ffc;
  818 + overflow: hidden;
  819 +}
  820 +
  821 +#header a:link, #header a:visited {
  822 + color: #fff;
  823 +}
  824 +
  825 +#header a:focus , #header a:hover {
  826 + text-decoration: underline;
  827 +}
  828 +
  829 +#branding {
  830 + float: left;
  831 +}
  832 +
  833 +#branding h1 {
  834 + padding: 0;
  835 + margin: 0 20px 0 0;
  836 + font-weight: 300;
  837 + font-size: 24px;
  838 + color: #f5dd5d;
  839 +}
  840 +
  841 +#branding h1, #branding h1 a:link, #branding h1 a:visited {
  842 + color: #f5dd5d;
  843 +}
  844 +
  845 +#branding h2 {
  846 + padding: 0 10px;
  847 + font-size: 14px;
  848 + margin: -8px 0 8px 0;
  849 + font-weight: normal;
  850 + color: #ffc;
  851 +}
  852 +
  853 +#branding a:hover {
  854 + text-decoration: none;
  855 +}
  856 +
  857 +#user-tools {
  858 + float: right;
  859 + padding: 0;
  860 + margin: 0 0 0 20px;
  861 + font-weight: 300;
  862 + font-size: 11px;
  863 + letter-spacing: 0.5px;
  864 + text-transform: uppercase;
  865 + text-align: right;
  866 +}
  867 +
  868 +#user-tools a {
  869 + border-bottom: 1px solid rgba(255, 255, 255, 0.25);
  870 +}
  871 +
  872 +#user-tools a:focus, #user-tools a:hover {
  873 + text-decoration: none;
  874 + border-bottom-color: #79aec8;
  875 + color: #79aec8;
  876 +}
  877 +
  878 +/* SIDEBAR */
  879 +
  880 +#content-related {
  881 + background: #f8f8f8;
  882 +}
  883 +
  884 +#content-related .module {
  885 + background: none;
  886 +}
  887 +
  888 +#content-related h3 {
  889 + font-size: 14px;
  890 + color: #666;
  891 + padding: 0 16px;
  892 + margin: 0 0 16px;
  893 +}
  894 +
  895 +#content-related h4 {
  896 + font-size: 13px;
  897 +}
  898 +
  899 +#content-related p {
  900 + padding-left: 16px;
  901 + padding-right: 16px;
  902 +}
  903 +
  904 +#content-related .actionlist {
  905 + padding: 0;
  906 + margin: 16px;
  907 +}
  908 +
  909 +#content-related .actionlist li {
  910 + line-height: 1.2;
  911 + margin-bottom: 10px;
  912 + padding-left: 18px;
  913 +}
  914 +
  915 +#content-related .module h2 {
  916 + background: none;
  917 + padding: 16px;
  918 + margin-bottom: 16px;
  919 + border-bottom: 1px solid #eaeaea;
  920 + font-size: 18px;
  921 + color: #333;
  922 +}
  923 +
  924 +.delete-confirmation form input[type="submit"] {
  925 + background: #ba2121;
  926 + border-radius: 4px;
  927 + padding: 10px 15px;
  928 + color: #fff;
  929 +}
  930 +
  931 +.delete-confirmation form input[type="submit"]:active,
  932 +.delete-confirmation form input[type="submit"]:focus,
  933 +.delete-confirmation form input[type="submit"]:hover {
  934 + background: #a41515;
  935 +}
  936 +
  937 +.delete-confirmation form .cancel-link {
  938 + display: inline-block;
  939 + vertical-align: middle;
  940 + height: 15px;
  941 + line-height: 15px;
  942 + background: #ddd;
  943 + border-radius: 4px;
  944 + padding: 10px 15px;
  945 + color: #333;
  946 + margin: 0 0 0 10px;
  947 +}
  948 +
  949 +.delete-confirmation form .cancel-link:active,
  950 +.delete-confirmation form .cancel-link:focus,
  951 +.delete-confirmation form .cancel-link:hover {
  952 + background: #ccc;
  953 +}
  954 +
  955 +/* POPUP */
  956 +.popup #content {
  957 + padding: 20px;
  958 +}
  959 +
  960 +.popup #container {
  961 + min-width: 0;
  962 +}
  963 +
  964 +.popup #header {
  965 + padding: 10px 20px;
  966 +}
  1 +/* CHANGELISTS */
  2 +
  3 +#changelist {
  4 + position: relative;
  5 + width: 100%;
  6 +}
  7 +
  8 +#changelist table {
  9 + width: 100%;
  10 +}
  11 +
  12 +.change-list .hiddenfields { display:none; }
  13 +
  14 +.change-list .filtered table {
  15 + border-right: none;
  16 +}
  17 +
  18 +.change-list .filtered {
  19 + min-height: 400px;
  20 +}
  21 +
  22 +.change-list .filtered .results, .change-list .filtered .paginator,
  23 +.filtered #toolbar, .filtered div.xfull {
  24 + margin-right: 280px;
  25 + width: auto;
  26 +}
  27 +
  28 +.change-list .filtered table tbody th {
  29 + padding-right: 1em;
  30 +}
  31 +
  32 +#changelist-form .results {
  33 + overflow-x: auto;
  34 +}
  35 +
  36 +#changelist .toplinks {
  37 + border-bottom: 1px solid #ddd;
  38 +}
  39 +
  40 +#changelist .paginator {
  41 + color: #666;
  42 + border-bottom: 1px solid #eee;
  43 + background: #fff;
  44 + overflow: hidden;
  45 +}
  46 +
  47 +/* CHANGELIST TABLES */
  48 +
  49 +#changelist table thead th {
  50 + padding: 0;
  51 + white-space: nowrap;
  52 + vertical-align: middle;
  53 +}
  54 +
  55 +#changelist table thead th.action-checkbox-column {
  56 + width: 1.5em;
  57 + text-align: center;
  58 +}
  59 +
  60 +#changelist table tbody td.action-checkbox {
  61 + text-align: center;
  62 +}
  63 +
  64 +#changelist table tfoot {
  65 + color: #666;
  66 +}
  67 +
  68 +/* TOOLBAR */
  69 +
  70 +#changelist #toolbar {
  71 + padding: 8px 10px;
  72 + margin-bottom: 15px;
  73 + border-top: 1px solid #eee;
  74 + border-bottom: 1px solid #eee;
  75 + background: #f8f8f8;
  76 + color: #666;
  77 +}
  78 +
  79 +#changelist #toolbar form input {
  80 + border-radius: 4px;
  81 + font-size: 14px;
  82 + padding: 5px;
  83 + color: #333;
  84 +}
  85 +
  86 +#changelist #toolbar form #searchbar {
  87 + height: 19px;
  88 + border: 1px solid #ccc;
  89 + padding: 2px 5px;
  90 + margin: 0;
  91 + vertical-align: top;
  92 + font-size: 13px;
  93 + max-width: 230px;
  94 +}
  95 +
  96 +#changelist #toolbar form #searchbar:focus {
  97 + border-color: #999;
  98 +}
  99 +
  100 +#changelist #toolbar form input[type="submit"] {
  101 + border: 1px solid #ccc;
  102 + font-size: 13px;
  103 + padding: 4px 8px;
  104 + margin: 0;
  105 + vertical-align: middle;
  106 + background: #fff;
  107 + box-shadow: 0 -15px 20px -10px rgba(0, 0, 0, 0.15) inset;
  108 + cursor: pointer;
  109 + color: #333;
  110 +}
  111 +
  112 +#changelist #toolbar form input[type="submit"]:focus,
  113 +#changelist #toolbar form input[type="submit"]:hover {
  114 + border-color: #999;
  115 +}
  116 +
  117 +#changelist #changelist-search img {
  118 + vertical-align: middle;
  119 + margin-right: 4px;
  120 +}
  121 +
  122 +/* FILTER COLUMN */
  123 +
  124 +#changelist-filter {
  125 + position: absolute;
  126 + top: 0;
  127 + right: 0;
  128 + z-index: 1000;
  129 + width: 240px;
  130 + background: #f8f8f8;
  131 + border-left: none;
  132 + margin: 0;
  133 +}
  134 +
  135 +#changelist-filter h2 {
  136 + font-size: 14px;
  137 + text-transform: uppercase;
  138 + letter-spacing: 0.5px;
  139 + padding: 5px 15px;
  140 + margin-bottom: 12px;
  141 + border-bottom: none;
  142 +}
  143 +
  144 +#changelist-filter h3 {
  145 + font-weight: 400;
  146 + font-size: 14px;
  147 + padding: 0 15px;
  148 + margin-bottom: 10px;
  149 +}
  150 +
  151 +#changelist-filter ul {
  152 + margin: 5px 0;
  153 + padding: 0 15px 15px;
  154 + border-bottom: 1px solid #eaeaea;
  155 +}
  156 +
  157 +#changelist-filter ul:last-child {
  158 + border-bottom: none;
  159 +}
  160 +
  161 +#changelist-filter li {
  162 + list-style-type: none;
  163 + margin-left: 0;
  164 + padding-left: 0;
  165 +}
  166 +
  167 +#changelist-filter a {
  168 + display: block;
  169 + color: #999;
  170 + text-overflow: ellipsis;
  171 + overflow-x: hidden;
  172 +}
  173 +
  174 +#changelist-filter li.selected {
  175 + border-left: 5px solid #eaeaea;
  176 + padding-left: 10px;
  177 + margin-left: -15px;
  178 +}
  179 +
  180 +#changelist-filter li.selected a {
  181 + color: #5b80b2;
  182 +}
  183 +
  184 +#changelist-filter a:focus, #changelist-filter a:hover,
  185 +#changelist-filter li.selected a:focus,
  186 +#changelist-filter li.selected a:hover {
  187 + color: #036;
  188 +}
  189 +
  190 +#changelist-filter #changelist-filter-clear a {
  191 + font-size: 13px;
  192 + padding-bottom: 10px;
  193 + border-bottom: 1px solid #eaeaea;
  194 +}
  195 +
  196 +/* DATE DRILLDOWN */
  197 +
  198 +.change-list ul.toplinks {
  199 + display: block;
  200 + float: left;
  201 + padding: 0;
  202 + margin: 0;
  203 + width: 100%;
  204 +}
  205 +
  206 +.change-list ul.toplinks li {
  207 + padding: 3px 6px;
  208 + font-weight: bold;
  209 + list-style-type: none;
  210 + display: inline-block;
  211 +}
  212 +
  213 +.change-list ul.toplinks .date-back a {
  214 + color: #999;
  215 +}
  216 +
  217 +.change-list ul.toplinks .date-back a:focus,
  218 +.change-list ul.toplinks .date-back a:hover {
  219 + color: #036;
  220 +}
  221 +
  222 +/* PAGINATOR */
  223 +
  224 +.paginator {
  225 + font-size: 13px;
  226 + padding-top: 10px;
  227 + padding-bottom: 10px;
  228 + line-height: 22px;
  229 + margin: 0;
  230 + border-top: 1px solid #ddd;
  231 +}
  232 +
  233 +.paginator a:link, .paginator a:visited {
  234 + padding: 2px 6px;
  235 + background: #79aec8;
  236 + text-decoration: none;
  237 + color: #fff;
  238 +}
  239 +
  240 +.paginator a.showall {
  241 + border: none;
  242 + background: none;
  243 + color: #5b80b2;
  244 +}
  245 +
  246 +.paginator a.showall:focus, .paginator a.showall:hover {
  247 + background: none;
  248 + color: #036;
  249 +}
  250 +
  251 +.paginator .end {
  252 + margin-right: 6px;
  253 +}
  254 +
  255 +.paginator .this-page {
  256 + padding: 2px 6px;
  257 + font-weight: bold;
  258 + font-size: 13px;
  259 + vertical-align: top;
  260 +}
  261 +
  262 +.paginator a:focus, .paginator a:hover {
  263 + color: white;
  264 + background: #036;
  265 +}
  266 +
  267 +/* ACTIONS */
  268 +
  269 +.filtered .actions {
  270 + margin-right: 280px;
  271 + border-right: none;
  272 +}
  273 +
  274 +#changelist table input {
  275 + margin: 0;
  276 + vertical-align: baseline;
  277 +}
  278 +
  279 +#changelist table tbody tr.selected {
  280 + background-color: #FFFFCC;
  281 +}
  282 +
  283 +#changelist .actions {
  284 + padding: 10px;
  285 + background: #fff;
  286 + border-top: none;
  287 + border-bottom: none;
  288 + line-height: 24px;
  289 + color: #999;
  290 +}
  291 +
  292 +#changelist .actions.selected {
  293 + background: #fffccf;
  294 + border-top: 1px solid #fffee8;
  295 + border-bottom: 1px solid #edecd6;
  296 +}
  297 +
  298 +#changelist .actions span.all,
  299 +#changelist .actions span.action-counter,
  300 +#changelist .actions span.clear,
  301 +#changelist .actions span.question {
  302 + font-size: 13px;
  303 + margin: 0 0.5em;
  304 + display: none;
  305 +}
  306 +
  307 +#changelist .actions:last-child {
  308 + border-bottom: none;
  309 +}
  310 +
  311 +#changelist .actions select {
  312 + vertical-align: top;
  313 + height: 24px;
  314 + background: none;
  315 + color: #000;
  316 + border: 1px solid #ccc;
  317 + border-radius: 4px;
  318 + font-size: 14px;
  319 + padding: 0 0 0 4px;
  320 + margin: 0;
  321 + margin-left: 10px;
  322 +}
  323 +
  324 +#changelist .actions select:focus {
  325 + border-color: #999;
  326 +}
  327 +
  328 +#changelist .actions label {
  329 + display: inline-block;
  330 + vertical-align: middle;
  331 + font-size: 13px;
  332 +}
  333 +
  334 +#changelist .actions .button {
  335 + font-size: 13px;
  336 + border: 1px solid #ccc;
  337 + border-radius: 4px;
  338 + background: #fff;
  339 + box-shadow: 0 -15px 20px -10px rgba(0, 0, 0, 0.15) inset;
  340 + cursor: pointer;
  341 + height: 24px;
  342 + line-height: 1;
  343 + padding: 4px 8px;
  344 + margin: 0;
  345 + color: #333;
  346 +}
  347 +
  348 +#changelist .actions .button:focus, #changelist .actions .button:hover {
  349 + border-color: #999;
  350 +}
  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 +}
  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 +}
  1 +@import url('widgets.css');
  2 +
  3 +/* FORM ROWS */
  4 +
  5 +.form-row {
  6 + overflow: hidden;
  7 + padding: 10px;
  8 + font-size: 13px;
  9 + border-bottom: 1px solid #eee;
  10 +}
  11 +
  12 +.form-row img, .form-row input {
  13 + vertical-align: middle;
  14 +}
  15 +
  16 +.form-row label input[type="checkbox"] {
  17 + margin-top: 0;
  18 + vertical-align: 0;
  19 +}
  20 +
  21 +form .form-row p {
  22 + padding-left: 0;
  23 +}
  24 +
  25 +.hidden {
  26 + display: none;
  27 +}
  28 +
  29 +/* FORM LABELS */
  30 +
  31 +label {
  32 + font-weight: normal;
  33 + color: #666;
  34 + font-size: 13px;
  35 +}
  36 +
  37 +.required label, label.required {
  38 + font-weight: bold;
  39 + color: #333;
  40 +}
  41 +
  42 +/* RADIO BUTTONS */
  43 +
  44 +form ul.radiolist li {
  45 + list-style-type: none;
  46 +}
  47 +
  48 +form ul.radiolist label {
  49 + float: none;
  50 + display: inline;
  51 +}
  52 +
  53 +form ul.radiolist input[type="radio"] {
  54 + margin: -2px 4px 0 0;
  55 + padding: 0;
  56 +}
  57 +
  58 +form ul.inline {
  59 + margin-left: 0;
  60 + padding: 0;
  61 +}
  62 +
  63 +form ul.inline li {
  64 + float: left;
  65 + padding-right: 7px;
  66 +}
  67 +
  68 +/* ALIGNED FIELDSETS */
  69 +
  70 +.aligned label {
  71 + display: block;
  72 + padding: 4px 10px 0 0;
  73 + float: left;
  74 + width: 160px;
  75 + word-wrap: break-word;
  76 + line-height: 1;
  77 +}
  78 +
  79 +.aligned label:not(.vCheckboxLabel):after {
  80 + content: '';
  81 + display: inline-block;
  82 + vertical-align: middle;
  83 + height: 26px;
  84 +}
  85 +
  86 +.aligned label + p, .aligned label + div.help, .aligned label + div.readonly {
  87 + padding: 6px 0;
  88 + margin-top: 0;
  89 + margin-bottom: 0;
  90 + margin-left: 170px;
  91 +}
  92 +
  93 +.aligned ul label {
  94 + display: inline;
  95 + float: none;
  96 + width: auto;
  97 +}
  98 +
  99 +.aligned .form-row input {
  100 + margin-bottom: 0;
  101 +}
  102 +
  103 +.colMS .aligned .vLargeTextField, .colMS .aligned .vXMLLargeTextField {
  104 + width: 350px;
  105 +}
  106 +
  107 +form .aligned ul {
  108 + margin-left: 160px;
  109 + padding-left: 10px;
  110 +}
  111 +
  112 +form .aligned ul.radiolist {
  113 + display: inline-block;
  114 + margin: 0;
  115 + padding: 0;
  116 +}
  117 +
  118 +form .aligned p.help,
  119 +form .aligned div.help {
  120 + clear: left;
  121 + margin-top: 0;
  122 + margin-left: 160px;
  123 + padding-left: 10px;
  124 +}
  125 +
  126 +form .aligned label + p.help,
  127 +form .aligned label + div.help {
  128 + margin-left: 0;
  129 + padding-left: 0;
  130 +}
  131 +
  132 +form .aligned p.help:last-child,
  133 +form .aligned div.help:last-child {
  134 + margin-bottom: 0;
  135 + padding-bottom: 0;
  136 +}
  137 +
  138 +form .aligned input + p.help,
  139 +form .aligned textarea + p.help,
  140 +form .aligned select + p.help,
  141 +form .aligned input + div.help,
  142 +form .aligned textarea + div.help,
  143 +form .aligned select + div.help {
  144 + margin-left: 160px;
  145 + padding-left: 10px;
  146 +}
  147 +
  148 +form .aligned ul li {
  149 + list-style: none;
  150 +}
  151 +
  152 +form .aligned table p {
  153 + margin-left: 0;
  154 + padding-left: 0;
  155 +}
  156 +
  157 +.aligned .vCheckboxLabel {
  158 + float: none;
  159 + width: auto;
  160 + display: inline-block;
  161 + vertical-align: -3px;
  162 + padding: 0 0 5px 5px;
  163 +}
  164 +
  165 +.aligned .vCheckboxLabel + p.help,
  166 +.aligned .vCheckboxLabel + div.help {
  167 + margin-top: -4px;
  168 +}
  169 +
  170 +.colM .aligned .vLargeTextField, .colM .aligned .vXMLLargeTextField {
  171 + width: 610px;
  172 +}
  173 +
  174 +.checkbox-row p.help,
  175 +.checkbox-row div.help {
  176 + margin-left: 0;
  177 + padding-left: 0;
  178 +}
  179 +
  180 +fieldset .fieldBox {
  181 + float: left;
  182 + margin-right: 20px;
  183 +}
  184 +
  185 +/* WIDE FIELDSETS */
  186 +
  187 +.wide label {
  188 + width: 200px;
  189 +}
  190 +
  191 +form .wide p,
  192 +form .wide input + p.help,
  193 +form .wide input + div.help {
  194 + margin-left: 200px;
  195 +}
  196 +
  197 +form .wide p.help,
  198 +form .wide div.help {
  199 + padding-left: 38px;
  200 +}
  201 +
  202 +form div.help ul {
  203 + padding-left: 0;
  204 + margin-left: 0;
  205 +}
  206 +
  207 +.colM fieldset.wide .vLargeTextField, .colM fieldset.wide .vXMLLargeTextField {
  208 + width: 450px;
  209 +}
  210 +
  211 +/* COLLAPSED FIELDSETS */
  212 +
  213 +fieldset.collapsed * {
  214 + display: none;
  215 +}
  216 +
  217 +fieldset.collapsed h2, fieldset.collapsed {
  218 + display: block;
  219 +}
  220 +
  221 +fieldset.collapsed {
  222 + border: 1px solid #eee;
  223 + border-radius: 4px;
  224 + overflow: hidden;
  225 +}
  226 +
  227 +fieldset.collapsed h2 {
  228 + background: #f8f8f8;
  229 + color: #666;
  230 +}
  231 +
  232 +fieldset .collapse-toggle {
  233 + color: #fff;
  234 +}
  235 +
  236 +fieldset.collapsed .collapse-toggle {
  237 + background: transparent;
  238 + display: inline;
  239 + color: #447e9b;
  240 +}
  241 +
  242 +/* MONOSPACE TEXTAREAS */
  243 +
  244 +fieldset.monospace textarea {
  245 + font-family: "Bitstream Vera Sans Mono", Monaco, "Courier New", Courier, monospace;
  246 +}
  247 +
  248 +/* SUBMIT ROW */
  249 +
  250 +.submit-row {
  251 + padding: 12px 14px;
  252 + margin: 0 0 20px;
  253 + background: #f8f8f8;
  254 + border: 1px solid #eee;
  255 + border-radius: 4px;
  256 + text-align: right;
  257 + overflow: hidden;
  258 +}
  259 +
  260 +body.popup .submit-row {
  261 + overflow: auto;
  262 +}
  263 +
  264 +.submit-row input {
  265 + height: 35px;
  266 + line-height: 15px;
  267 + margin: 0 0 0 5px;
  268 +}
  269 +
  270 +.submit-row input.default {
  271 + margin: 0 0 0 8px;
  272 + text-transform: uppercase;
  273 +}
  274 +
  275 +.submit-row p {
  276 + margin: 0.3em;
  277 +}
  278 +
  279 +.submit-row p.deletelink-box {
  280 + float: left;
  281 + margin: 0;
  282 +}
  283 +
  284 +.submit-row a.deletelink {
  285 + display: block;
  286 + background: #ba2121;
  287 + border-radius: 4px;
  288 + padding: 10px 15px;
  289 + height: 15px;
  290 + line-height: 15px;
  291 + color: #fff;
  292 +}
  293 +
  294 +.submit-row a.closelink {
  295 + display: inline-block;
  296 + background: #bbbbbb;
  297 + border-radius: 4px;
  298 + padding: 10px 15px;
  299 + height: 15px;
  300 + line-height: 15px;
  301 + margin: 0 0 0 5px;
  302 + color: #fff;
  303 +}
  304 +
  305 +.submit-row a.deletelink:focus,
  306 +.submit-row a.deletelink:hover,
  307 +.submit-row a.deletelink:active {
  308 + background: #a41515;
  309 +}
  310 +
  311 +.submit-row a.closelink:focus,
  312 +.submit-row a.closelink:hover,
  313 +.submit-row a.closelink:active {
  314 + background: #aaaaaa;
  315 +}
  316 +
  317 +/* CUSTOM FORM FIELDS */
  318 +
  319 +.vSelectMultipleField {
  320 + vertical-align: top;
  321 +}
  322 +
  323 +.vCheckboxField {
  324 + border: none;
  325 +}
  326 +
  327 +.vDateField, .vTimeField {
  328 + margin-right: 2px;
  329 + margin-bottom: 4px;
  330 +}
  331 +
  332 +.vDateField {
  333 + min-width: 6.85em;
  334 +}
  335 +
  336 +.vTimeField {
  337 + min-width: 4.7em;
  338 +}
  339 +
  340 +.vURLField {
  341 + width: 30em;
  342 +}
  343 +
  344 +.vLargeTextField, .vXMLLargeTextField {
  345 + width: 48em;
  346 +}
  347 +
  348 +.flatpages-flatpage #id_content {
  349 + height: 40.2em;
  350 +}
  351 +
  352 +.module table .vPositiveSmallIntegerField {
  353 + width: 2.2em;
  354 +}
  355 +
  356 +.vTextField, .vUUIDField {
  357 + width: 20em;
  358 +}
  359 +
  360 +.vIntegerField {
  361 + width: 5em;
  362 +}
  363 +
  364 +.vBigIntegerField {
  365 + width: 10em;
  366 +}
  367 +
  368 +.vForeignKeyRawIdAdminField {
  369 + width: 5em;
  370 +}
  371 +
  372 +/* INLINES */
  373 +
  374 +.inline-group {
  375 + padding: 0;
  376 + margin: 0 0 30px;
  377 +}
  378 +
  379 +.inline-group thead th {
  380 + padding: 8px 10px;
  381 +}
  382 +
  383 +.inline-group .aligned label {
  384 + width: 160px;
  385 +}
  386 +
  387 +.inline-related {
  388 + position: relative;
  389 +}
  390 +
  391 +.inline-related h3 {
  392 + margin: 0;
  393 + color: #666;
  394 + padding: 5px;
  395 + font-size: 13px;
  396 + background: #f8f8f8;
  397 + border-top: 1px solid #eee;
  398 + border-bottom: 1px solid #eee;
  399 +}
  400 +
  401 +.inline-related h3 span.delete {
  402 + float: right;
  403 +}
  404 +
  405 +.inline-related h3 span.delete label {
  406 + margin-left: 2px;
  407 + font-size: 11px;
  408 +}
  409 +
  410 +.inline-related fieldset {
  411 + margin: 0;
  412 + background: #fff;
  413 + border: none;
  414 + width: 100%;
  415 +}
  416 +
  417 +.inline-related fieldset.module h3 {
  418 + margin: 0;
  419 + padding: 2px 5px 3px 5px;
  420 + font-size: 11px;
  421 + text-align: left;
  422 + font-weight: bold;
  423 + background: #bcd;
  424 + color: #fff;
  425 +}
  426 +
  427 +.inline-group .tabular fieldset.module {
  428 + border: none;
  429 +}
  430 +
  431 +.inline-related.tabular fieldset.module table {
  432 + width: 100%;
  433 +}
  434 +
  435 +.last-related fieldset {
  436 + border: none;
  437 +}
  438 +
  439 +.inline-group .tabular tr.has_original td {
  440 + padding-top: 2em;
  441 +}
  442 +
  443 +.inline-group .tabular tr td.original {
  444 + padding: 2px 0 0 0;
  445 + width: 0;
  446 + _position: relative;
  447 +}
  448 +
  449 +.inline-group .tabular th.original {
  450 + width: 0px;
  451 + padding: 0;
  452 +}
  453 +
  454 +.inline-group .tabular td.original p {
  455 + position: absolute;
  456 + left: 0;
  457 + height: 1.1em;
  458 + padding: 2px 9px;
  459 + overflow: hidden;
  460 + font-size: 9px;
  461 + font-weight: bold;
  462 + color: #666;
  463 + _width: 700px;
  464 +}
  465 +
  466 +.inline-group ul.tools {
  467 + padding: 0;
  468 + margin: 0;
  469 + list-style: none;
  470 +}
  471 +
  472 +.inline-group ul.tools li {
  473 + display: inline;
  474 + padding: 0 5px;
  475 +}
  476 +
  477 +.inline-group div.add-row,
  478 +.inline-group .tabular tr.add-row td {
  479 + color: #666;
  480 + background: #f8f8f8;
  481 + padding: 8px 10px;
  482 + border-bottom: 1px solid #eee;
  483 +}
  484 +
  485 +.inline-group .tabular tr.add-row td {
  486 + padding: 8px 10px;
  487 + border-bottom: 1px solid #eee;
  488 +}
  489 +
  490 +.inline-group ul.tools a.add,
  491 +.inline-group div.add-row a,
  492 +.inline-group .tabular tr.add-row td a {
  493 + background: url(../img/icon-addlink.svg) 0 1px no-repeat;
  494 + padding-left: 16px;
  495 + font-size: 12px;
  496 +}
  497 +
  498 +.empty-form {
  499 + display: none;
  500 +}
  501 +
  502 +/* RELATED FIELD ADD ONE / LOOKUP */
  503 +
  504 +.related-lookup {
  505 + margin-left: 5px;
  506 + display: inline-block;
  507 + vertical-align: middle;
  508 + background-repeat: no-repeat;
  509 + background-size: 14px;
  510 +}
  511 +
  512 +.related-lookup {
  513 + width: 16px;
  514 + height: 16px;
  515 + background-image: url(../img/search.svg);
  516 +}
  517 +
  518 +form .related-widget-wrapper ul {
  519 + display: inline-block;
  520 + margin-left: 0;
  521 + padding-left: 0;
  522 +}
  523 +
  524 +.clearable-file-input input {
  525 + margin-top: 0;
  526 +}
  1 +/* LOGIN FORM */
  2 +
  3 +.login {
  4 + background: #f8f8f8;
  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: #fff;
  20 +}
  21 +
  22 +.login #content {
  23 + padding: 20px 20px 0;
  24 +}
  25 +
  26 +.login #container {
  27 + background: #fff;
  28 + border: 1px solid #eaeaea;
  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 #content-main {
  38 + width: 100%;
  39 +}
  40 +
  41 +.login .form-row {
  42 + padding: 4px 0;
  43 + float: left;
  44 + width: 100%;
  45 + border-bottom: none;
  46 +}
  47 +
  48 +.login .form-row label {
  49 + padding-right: 0.5em;
  50 + line-height: 2em;
  51 + font-size: 1em;
  52 + clear: both;
  53 + color: #333;
  54 +}
  55 +
  56 +.login .form-row #id_username, .login .form-row #id_password {
  57 + clear: both;
  58 + padding: 8px;
  59 + width: 100%;
  60 + box-sizing: border-box;
  61 +}
  62 +
  63 +.login span.help {
  64 + font-size: 10px;
  65 + display: block;
  66 +}
  67 +
  68 +.login .submit-row {
  69 + clear: both;
  70 + padding: 1em 0 0 9.4em;
  71 + margin: 0;
  72 + border: none;
  73 + background: none;
  74 + text-align: left;
  75 +}
  76 +
  77 +.login .password-reset-link {
  78 + text-align: center;
  79 +}
  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-right: 1px solid #eaeaea;
  16 + background-color: #ffffff;
  17 + cursor: pointer;
  18 + font-size: 20px;
  19 + color: #447e9b;
  20 + padding: 0;
  21 +}
  22 +
  23 +[dir="rtl"] .toggle-nav-sidebar {
  24 + border-left: 1px solid #eaeaea;
  25 + border-right: 0;
  26 +}
  27 +
  28 +.toggle-nav-sidebar:hover,
  29 +.toggle-nav-sidebar:focus {
  30 + background-color: #f6f6f6;
  31 +}
  32 +
  33 +#nav-sidebar {
  34 + z-index: 15;
  35 + flex: 0 0 275px;
  36 + left: -276px;
  37 + margin-left: -276px;
  38 + border-top: 1px solid transparent;
  39 + border-right: 1px solid #eaeaea;
  40 + background-color: #ffffff;
  41 + overflow: auto;
  42 +}
  43 +
  44 +[dir="rtl"] #nav-sidebar {
  45 + border-left: 1px solid #eaeaea;
  46 + border-right: 0;
  47 + left: 0;
  48 + margin-left: 0;
  49 + right: -276px;
  50 + margin-right: -276px;
  51 +}
  52 +
  53 +.toggle-nav-sidebar::before {
  54 + content: '\00BB';
  55 +}
  56 +
  57 +.main.shifted .toggle-nav-sidebar::before {
  58 + content: '\00AB';
  59 +}
  60 +
  61 +.main.shifted > #nav-sidebar {
  62 + left: 24px;
  63 + margin-left: 0;
  64 +}
  65 +
  66 +[dir="rtl"] .main.shifted > #nav-sidebar {
  67 + left: 0;
  68 + right: 24px;
  69 + margin-right: 0;
  70 +}
  71 +
  72 +#nav-sidebar .module th {
  73 + width: 100%;
  74 + overflow-wrap: anywhere;
  75 +}
  76 +
  77 +#nav-sidebar .module th,
  78 +#nav-sidebar .module caption {
  79 + padding-left: 16px;
  80 +}
  81 +
  82 +#nav-sidebar .module td {
  83 + white-space: nowrap;
  84 +}
  85 +
  86 +[dir="rtl"] #nav-sidebar .module th,
  87 +[dir="rtl"] #nav-sidebar .module caption {
  88 + padding-left: 8px;
  89 + padding-right: 16px;
  90 +}
  91 +
  92 +#nav-sidebar .current-app .section:link,
  93 +#nav-sidebar .current-app .section:visited {
  94 + color: #ffc;
  95 + font-weight: bold;
  96 +}
  97 +
  98 +#nav-sidebar .current-model {
  99 + background: #ffc;
  100 +}
  101 +
  102 +@media (max-width: 767px) {
  103 + #nav-sidebar, #toggle-nav-sidebar {
  104 + display: none;
  105 + }
  106 +}
  107 +
  108 +.change-list .main > #nav-sidebar+.content {
  109 + overflow: hidden;
  110 +}
  1 +/* Tablets */
  2 +
  3 +input[type="submit"], button {
  4 + -webkit-appearance: none;
  5 + appearance: none;
  6 +}
  7 +
  8 +@media (max-width: 1024px) {
  9 + /* Basic */
  10 +
  11 + html {
  12 + -webkit-text-size-adjust: 100%;
  13 + }
  14 +
  15 + td, th {
  16 + padding: 10px;
  17 + font-size: 14px;
  18 + }
  19 +
  20 + .small {
  21 + font-size: 12px;
  22 + }
  23 +
  24 + /* Layout */
  25 +
  26 + #container {
  27 + min-width: 0;
  28 + }
  29 +
  30 + #content {
  31 + padding: 20px 30px 30px;
  32 + }
  33 +
  34 + div.breadcrumbs {
  35 + padding: 10px 30px;
  36 + }
  37 +
  38 + /* Header */
  39 +
  40 + #header {
  41 + flex-direction: column;
  42 + padding: 15px 30px;
  43 + justify-content: flex-start;
  44 + }
  45 +
  46 + #branding h1 {
  47 + margin: 0 0 8px;
  48 + font-size: 20px;
  49 + line-height: 1.2;
  50 + }
  51 +
  52 + #user-tools {
  53 + margin: 0;
  54 + font-weight: 400;
  55 + line-height: 1.85;
  56 + text-align: left;
  57 + }
  58 +
  59 + #user-tools a {
  60 + display: inline-block;
  61 + line-height: 1.4;
  62 + }
  63 +
  64 + /* Dashboard */
  65 +
  66 + .dashboard #content {
  67 + width: auto;
  68 + }
  69 +
  70 + #content-related {
  71 + margin-right: -290px;
  72 + }
  73 +
  74 + .colSM #content-related {
  75 + margin-left: -290px;
  76 + }
  77 +
  78 + .colMS {
  79 + margin-right: 290px;
  80 + }
  81 +
  82 + .colSM {
  83 + margin-left: 290px;
  84 + }
  85 +
  86 + .dashboard .module table td a {
  87 + padding-right: 0;
  88 + }
  89 +
  90 + td .changelink, td .addlink {
  91 + font-size: 13px;
  92 + }
  93 +
  94 + /* Changelist */
  95 +
  96 + #changelist #toolbar {
  97 + border: none;
  98 + padding: 15px;
  99 + }
  100 +
  101 + #changelist-search > div {
  102 + display: flex;
  103 + flex-wrap: wrap;
  104 + max-width: 480px;
  105 + }
  106 +
  107 + #changelist-search label {
  108 + line-height: 22px;
  109 + }
  110 +
  111 + #changelist #toolbar form #searchbar {
  112 + flex: 1 0 auto;
  113 + width: 0;
  114 + height: 22px;
  115 + margin: 0 10px 0 6px;
  116 + }
  117 +
  118 + #changelist-search .quiet {
  119 + width: 100%;
  120 + margin: 5px 0 0 25px;
  121 + }
  122 +
  123 + #changelist .actions {
  124 + display: flex;
  125 + flex-wrap: wrap;
  126 + padding: 15px 0;
  127 + }
  128 +
  129 + #changelist .actions.selected {
  130 + border: none;
  131 + }
  132 +
  133 + #changelist .actions label {
  134 + display: flex;
  135 + }
  136 +
  137 + #changelist .actions select {
  138 + background: #fff;
  139 + }
  140 +
  141 + #changelist .actions .button {
  142 + min-width: 48px;
  143 + margin: 0 10px;
  144 + }
  145 +
  146 + #changelist .actions span.all,
  147 + #changelist .actions span.clear,
  148 + #changelist .actions span.question,
  149 + #changelist .actions span.action-counter {
  150 + font-size: 11px;
  151 + margin: 0 10px 0 0;
  152 + }
  153 +
  154 + #changelist-filter {
  155 + width: 200px;
  156 + }
  157 +
  158 + .change-list .filtered .results,
  159 + .change-list .filtered .paginator,
  160 + .filtered #toolbar,
  161 + .filtered .actions,
  162 + .filtered div.xfull {
  163 + margin-right: 230px;
  164 + }
  165 +
  166 + #changelist .paginator {
  167 + border-top-color: #eee;
  168 + }
  169 +
  170 + #changelist .results + .paginator {
  171 + border-top: none;
  172 + }
  173 +
  174 + /* Forms */
  175 +
  176 + label {
  177 + font-size: 14px;
  178 + }
  179 +
  180 + .form-row input[type=text],
  181 + .form-row input[type=password],
  182 + .form-row input[type=email],
  183 + .form-row input[type=url],
  184 + .form-row input[type=tel],
  185 + .form-row input[type=number],
  186 + .form-row textarea,
  187 + .form-row select,
  188 + .form-row .vTextField {
  189 + box-sizing: border-box;
  190 + margin: 0;
  191 + padding: 6px 8px;
  192 + min-height: 36px;
  193 + font-size: 14px;
  194 + }
  195 +
  196 + .form-row select {
  197 + height: 36px;
  198 + }
  199 +
  200 + .form-row select[multiple] {
  201 + height: auto;
  202 + min-height: 0;
  203 + }
  204 +
  205 + fieldset .fieldBox {
  206 + float: none;
  207 + margin: 0 -10px;
  208 + padding: 0 10px;
  209 + }
  210 +
  211 + fieldset .fieldBox + .fieldBox {
  212 + margin-top: 10px;
  213 + padding-top: 10px;
  214 + border-top: 1px solid #eee;
  215 + }
  216 +
  217 + textarea {
  218 + max-width: 518px;
  219 + max-height: 120px;
  220 + }
  221 +
  222 + .aligned label {
  223 + padding-top: 6px;
  224 + }
  225 +
  226 + .aligned .related-lookup,
  227 + .aligned .datetimeshortcuts,
  228 + .aligned .related-lookup + strong {
  229 + align-self: center;
  230 + margin-left: 15px;
  231 + }
  232 +
  233 + form .aligned ul.radiolist {
  234 + margin-left: 2px;
  235 + }
  236 +
  237 + /* Related widget */
  238 +
  239 + .related-widget-wrapper {
  240 + float: none;
  241 + }
  242 +
  243 + .related-widget-wrapper-link + .selector {
  244 + max-width: calc(100% - 30px);
  245 + margin-right: 15px;
  246 + }
  247 +
  248 + select + .related-widget-wrapper-link,
  249 + .related-widget-wrapper-link + .related-widget-wrapper-link {
  250 + margin-left: 10px;
  251 + }
  252 +
  253 + /* Selector */
  254 +
  255 + .selector {
  256 + display: flex;
  257 + width: 100%;
  258 + }
  259 +
  260 + .selector .selector-filter {
  261 + display: flex;
  262 + align-items: center;
  263 + }
  264 +
  265 + .selector .selector-filter label {
  266 + margin: 0 8px 0 0;
  267 + }
  268 +
  269 + .selector .selector-filter input {
  270 + width: auto;
  271 + min-height: 0;
  272 + flex: 1 1;
  273 + }
  274 +
  275 + .selector-available, .selector-chosen {
  276 + width: auto;
  277 + flex: 1 1;
  278 + display: flex;
  279 + flex-direction: column;
  280 + }
  281 +
  282 + .selector select {
  283 + width: 100%;
  284 + flex: 1 0 auto;
  285 + margin-bottom: 5px;
  286 + }
  287 +
  288 + .selector ul.selector-chooser {
  289 + width: 26px;
  290 + height: 52px;
  291 + padding: 2px 0;
  292 + margin: auto 15px;
  293 + border-radius: 20px;
  294 + transform: translateY(-10px);
  295 + }
  296 +
  297 + .selector-add, .selector-remove {
  298 + width: 20px;
  299 + height: 20px;
  300 + background-size: 20px auto;
  301 + }
  302 +
  303 + .selector-add {
  304 + background-position: 0 -120px;
  305 + }
  306 +
  307 + .selector-remove {
  308 + background-position: 0 -80px;
  309 + }
  310 +
  311 + a.selector-chooseall, a.selector-clearall {
  312 + align-self: center;
  313 + }
  314 +
  315 + .stacked {
  316 + flex-direction: column;
  317 + max-width: 480px;
  318 + }
  319 +
  320 + .stacked > * {
  321 + flex: 0 1 auto;
  322 + }
  323 +
  324 + .stacked select {
  325 + margin-bottom: 0;
  326 + }
  327 +
  328 + .stacked .selector-available, .stacked .selector-chosen {
  329 + width: auto;
  330 + }
  331 +
  332 + .stacked ul.selector-chooser {
  333 + width: 52px;
  334 + height: 26px;
  335 + padding: 0 2px;
  336 + margin: 15px auto;
  337 + transform: none;
  338 + }
  339 +
  340 + .stacked .selector-chooser li {
  341 + padding: 3px;
  342 + }
  343 +
  344 + .stacked .selector-add, .stacked .selector-remove {
  345 + background-size: 20px auto;
  346 + }
  347 +
  348 + .stacked .selector-add {
  349 + background-position: 0 -40px;
  350 + }
  351 +
  352 + .stacked .active.selector-add {
  353 + background-position: 0 -40px;
  354 + }
  355 +
  356 + .active.selector-add:focus, .active.selector-add:hover {
  357 + background-position: 0 -140px;
  358 + }
  359 +
  360 + .stacked .active.selector-add:focus, .stacked .active.selector-add:hover {
  361 + background-position: 0 -60px;
  362 + }
  363 +
  364 + .stacked .selector-remove {
  365 + background-position: 0 0;
  366 + }
  367 +
  368 + .stacked .active.selector-remove {
  369 + background-position: 0 0;
  370 + }
  371 +
  372 + .active.selector-remove:focus, .active.selector-remove:hover {
  373 + background-position: 0 -100px;
  374 + }
  375 +
  376 + .stacked .active.selector-remove:focus, .stacked .active.selector-remove:hover {
  377 + background-position: 0 -20px;
  378 + }
  379 +
  380 + .help-tooltip, .selector .help-icon {
  381 + display: none;
  382 + }
  383 +
  384 + form .form-row p.datetime {
  385 + width: 100%;
  386 + }
  387 +
  388 + .datetime input {
  389 + width: 50%;
  390 + max-width: 120px;
  391 + }
  392 +
  393 + .datetime span {
  394 + font-size: 13px;
  395 + }
  396 +
  397 + .datetime .timezonewarning {
  398 + display: block;
  399 + font-size: 11px;
  400 + color: #999;
  401 + }
  402 +
  403 + .datetimeshortcuts {
  404 + color: #ccc;
  405 + }
  406 +
  407 + .form-row .datetime input.vDateField, .form-row .datetime input.vTimeField {
  408 + width: 75%;
  409 + }
  410 +
  411 + .inline-group {
  412 + overflow: auto;
  413 + }
  414 +
  415 + /* Messages */
  416 +
  417 + ul.messagelist li {
  418 + padding-left: 55px;
  419 + background-position: 30px 12px;
  420 + }
  421 +
  422 + ul.messagelist li.error {
  423 + background-position: 30px 12px;
  424 + }
  425 +
  426 + ul.messagelist li.warning {
  427 + background-position: 30px 14px;
  428 + }
  429 +
  430 + /* Login */
  431 +
  432 + .login #header {
  433 + padding: 15px 20px;
  434 + }
  435 +
  436 + .login #branding h1 {
  437 + margin: 0;
  438 + }
  439 +
  440 + /* GIS */
  441 +
  442 + div.olMap {
  443 + max-width: calc(100vw - 30px);
  444 + max-height: 300px;
  445 + }
  446 +
  447 + .olMap + .clear_features {
  448 + display: block;
  449 + margin-top: 10px;
  450 + }
  451 +
  452 + /* Docs */
  453 +
  454 + .module table.xfull {
  455 + width: 100%;
  456 + }
  457 +
  458 + pre.literal-block {
  459 + overflow: auto;
  460 + }
  461 +}
  462 +
  463 +/* Mobile */
  464 +
  465 +@media (max-width: 767px) {
  466 + /* Layout */
  467 +
  468 + #header, #content, #footer {
  469 + padding: 15px;
  470 + }
  471 +
  472 + #footer:empty {
  473 + padding: 0;
  474 + }
  475 +
  476 + div.breadcrumbs {
  477 + padding: 10px 15px;
  478 + }
  479 +
  480 + /* Dashboard */
  481 +
  482 + .colMS, .colSM {
  483 + margin: 0;
  484 + }
  485 +
  486 + #content-related, .colSM #content-related {
  487 + width: 100%;
  488 + margin: 0;
  489 + }
  490 +
  491 + #content-related .module {
  492 + margin-bottom: 0;
  493 + }
  494 +
  495 + #content-related .module h2 {
  496 + padding: 10px 15px;
  497 + font-size: 16px;
  498 + }
  499 +
  500 + /* Changelist */
  501 +
  502 + #changelist {
  503 + display: flex;
  504 + flex-direction: column;
  505 + }
  506 +
  507 + #changelist #toolbar {
  508 + order: 1;
  509 + padding: 10px;
  510 + }
  511 +
  512 + #changelist .xfull {
  513 + order: 2;
  514 + }
  515 +
  516 + #changelist-form {
  517 + order: 3;
  518 + }
  519 +
  520 + #changelist-filter {
  521 + order: 4;
  522 + }
  523 +
  524 + #changelist .actions label {
  525 + flex: 1 1;
  526 + }
  527 +
  528 + #changelist .actions select {
  529 + flex: 1 0;
  530 + width: 100%;
  531 + }
  532 +
  533 + #changelist .actions span {
  534 + flex: 1 0 100%;
  535 + }
  536 +
  537 + .change-list .filtered .results, .change-list .filtered .paginator,
  538 + .filtered #toolbar, .filtered .actions, .filtered div.xfull {
  539 + margin-right: 0;
  540 + }
  541 +
  542 + #changelist-filter {
  543 + position: static;
  544 + width: auto;
  545 + margin-top: 30px;
  546 + }
  547 +
  548 + .object-tools {
  549 + float: none;
  550 + margin: 0 0 15px;
  551 + padding: 0;
  552 + overflow: hidden;
  553 + }
  554 +
  555 + .object-tools li {
  556 + height: auto;
  557 + margin-left: 0;
  558 + }
  559 +
  560 + .object-tools li + li {
  561 + margin-left: 15px;
  562 + }
  563 +
  564 + /* Forms */
  565 +
  566 + .form-row {
  567 + padding: 15px 0;
  568 + }
  569 +
  570 + .aligned .form-row,
  571 + .aligned .form-row > div {
  572 + display: flex;
  573 + flex-wrap: wrap;
  574 + max-width: 100vw;
  575 + }
  576 +
  577 + .aligned .form-row > div {
  578 + width: calc(100vw - 30px);
  579 + }
  580 +
  581 + textarea {
  582 + max-width: none;
  583 + }
  584 +
  585 + .vURLField {
  586 + width: auto;
  587 + }
  588 +
  589 + fieldset .fieldBox + .fieldBox {
  590 + margin-top: 15px;
  591 + padding-top: 15px;
  592 + }
  593 +
  594 + fieldset.collapsed .form-row {
  595 + display: none;
  596 + }
  597 +
  598 + .aligned label {
  599 + width: 100%;
  600 + padding: 0 0 10px;
  601 + }
  602 +
  603 + .aligned label:after {
  604 + max-height: 0;
  605 + }
  606 +
  607 + .aligned .form-row input,
  608 + .aligned .form-row select,
  609 + .aligned .form-row textarea {
  610 + flex: 1 1 auto;
  611 + max-width: 100%;
  612 + }
  613 +
  614 + .aligned .checkbox-row {
  615 + align-items: center;
  616 + }
  617 +
  618 + .aligned .checkbox-row input {
  619 + flex: 0 1 auto;
  620 + margin: 0;
  621 + }
  622 +
  623 + .aligned .vCheckboxLabel {
  624 + flex: 1 0;
  625 + padding: 1px 0 0 5px;
  626 + }
  627 +
  628 + .aligned label + p,
  629 + .aligned label + div.help,
  630 + .aligned label + div.readonly {
  631 + padding: 0;
  632 + margin-left: 0;
  633 + }
  634 +
  635 + .aligned p.file-upload {
  636 + margin-left: 0;
  637 + font-size: 13px;
  638 + }
  639 +
  640 + span.clearable-file-input {
  641 + margin-left: 15px;
  642 + }
  643 +
  644 + span.clearable-file-input label {
  645 + font-size: 13px;
  646 + padding-bottom: 0;
  647 + }
  648 +
  649 + .aligned .timezonewarning {
  650 + flex: 1 0 100%;
  651 + margin-top: 5px;
  652 + }
  653 +
  654 + form .aligned .form-row div.help {
  655 + width: 100%;
  656 + margin: 5px 0 0;
  657 + padding: 0;
  658 + }
  659 +
  660 + form .aligned ul {
  661 + margin-left: 0;
  662 + padding-left: 0;
  663 + }
  664 +
  665 + form .aligned ul.radiolist {
  666 + margin-right: 15px;
  667 + margin-bottom: -3px;
  668 + }
  669 +
  670 + form .aligned ul.radiolist li + li {
  671 + margin-top: 5px;
  672 + }
  673 +
  674 + /* Related widget */
  675 +
  676 + .related-widget-wrapper {
  677 + width: 100%;
  678 + display: flex;
  679 + align-items: flex-start;
  680 + }
  681 +
  682 + .related-widget-wrapper .selector {
  683 + order: 1;
  684 + }
  685 +
  686 + .related-widget-wrapper > a {
  687 + order: 2;
  688 + }
  689 +
  690 + .related-widget-wrapper .radiolist ~ a {
  691 + align-self: flex-end;
  692 + }
  693 +
  694 + .related-widget-wrapper > select ~ a {
  695 + align-self: center;
  696 + }
  697 +
  698 + select + .related-widget-wrapper-link,
  699 + .related-widget-wrapper-link + .related-widget-wrapper-link {
  700 + margin-left: 15px;
  701 + }
  702 +
  703 + /* Selector */
  704 +
  705 + .selector {
  706 + flex-direction: column;
  707 + }
  708 +
  709 + .selector > * {
  710 + float: none;
  711 + }
  712 +
  713 + .selector-available, .selector-chosen {
  714 + margin-bottom: 0;
  715 + flex: 1 1 auto;
  716 + }
  717 +
  718 + .selector select {
  719 + max-height: 96px;
  720 + }
  721 +
  722 + .selector ul.selector-chooser {
  723 + display: block;
  724 + float: none;
  725 + width: 52px;
  726 + height: 26px;
  727 + padding: 0 2px;
  728 + margin: 15px auto 20px;
  729 + transform: none;
  730 + }
  731 +
  732 + .selector ul.selector-chooser li {
  733 + float: left;
  734 + }
  735 +
  736 + .selector-remove {
  737 + background-position: 0 0;
  738 + }
  739 +
  740 + .active.selector-remove:focus, .active.selector-remove:hover {
  741 + background-position: 0 -20px;
  742 + }
  743 +
  744 + .selector-add {
  745 + background-position: 0 -40px;
  746 + }
  747 +
  748 + .active.selector-add:focus, .active.selector-add:hover {
  749 + background-position: 0 -60px;
  750 + }
  751 +
  752 + /* Inlines */
  753 +
  754 + .inline-group[data-inline-type="stacked"] .inline-related {
  755 + border: 2px solid #eee;
  756 + border-radius: 4px;
  757 + margin-top: 15px;
  758 + overflow: auto;
  759 + }
  760 +
  761 + .inline-group[data-inline-type="stacked"] .inline-related > * {
  762 + box-sizing: border-box;
  763 + }
  764 +
  765 + .inline-group[data-inline-type="stacked"] .inline-related + .inline-related {
  766 + margin-top: 30px;
  767 + }
  768 +
  769 + .inline-group[data-inline-type="stacked"] .inline-related .module {
  770 + padding: 0 10px;
  771 + }
  772 +
  773 + .inline-group[data-inline-type="stacked"] .inline-related .module .form-row:last-child {
  774 + border-bottom: none;
  775 + }
  776 +
  777 + .inline-group[data-inline-type="stacked"] .inline-related h3 {
  778 + padding: 10px;
  779 + border-top-width: 0;
  780 + border-bottom-width: 2px;
  781 + display: flex;
  782 + flex-wrap: wrap;
  783 + align-items: center;
  784 + }
  785 +
  786 + .inline-group[data-inline-type="stacked"] .inline-related h3 .inline_label {
  787 + margin-right: auto;
  788 + }
  789 +
  790 + .inline-group[data-inline-type="stacked"] .inline-related h3 span.delete {
  791 + float: none;
  792 + flex: 1 1 100%;
  793 + margin-top: 5px;
  794 + }
  795 +
  796 + .inline-group[data-inline-type="stacked"] .aligned .form-row > div:not([class]) {
  797 + width: 100%;
  798 + }
  799 +
  800 + .inline-group[data-inline-type="stacked"] .aligned label {
  801 + width: 100%;
  802 + }
  803 +
  804 + .inline-group[data-inline-type="stacked"] div.add-row {
  805 + margin-top: 15px;
  806 + border: 1px solid #eee;
  807 + border-radius: 4px;
  808 + }
  809 +
  810 + .inline-group div.add-row,
  811 + .inline-group .tabular tr.add-row td {
  812 + padding: 0;
  813 + }
  814 +
  815 + .inline-group div.add-row a,
  816 + .inline-group .tabular tr.add-row td a {
  817 + display: block;
  818 + padding: 8px 10px 8px 26px;
  819 + background-position: 8px 9px;
  820 + }
  821 +
  822 + /* Submit row */
  823 +
  824 + .submit-row {
  825 + padding: 10px 10px 0;
  826 + margin: 0 0 15px;
  827 + display: flex;
  828 + flex-direction: column;
  829 + }
  830 +
  831 + .submit-row > * {
  832 + width: 100%;
  833 + }
  834 +
  835 + .submit-row input, .submit-row input.default, .submit-row a, .submit-row a.closelink {
  836 + float: none;
  837 + margin: 0 0 10px;
  838 + text-align: center;
  839 + }
  840 +
  841 + .submit-row a.closelink {
  842 + padding: 10px 0;
  843 + }
  844 +
  845 + .submit-row p.deletelink-box {
  846 + order: 4;
  847 + }
  848 +
  849 + /* Messages */
  850 +
  851 + ul.messagelist li {
  852 + padding-left: 40px;
  853 + background-position: 15px 12px;
  854 + }
  855 +
  856 + ul.messagelist li.error {
  857 + background-position: 15px 12px;
  858 + }
  859 +
  860 + ul.messagelist li.warning {
  861 + background-position: 15px 14px;
  862 + }
  863 +
  864 + /* Paginator */
  865 +
  866 + .paginator .this-page, .paginator a:link, .paginator a:visited {
  867 + padding: 4px 10px;
  868 + }
  869 +
  870 + /* Login */
  871 +
  872 + body.login {
  873 + padding: 0 15px;
  874 + }
  875 +
  876 + .login #container {
  877 + width: auto;
  878 + max-width: 480px;
  879 + margin: 50px auto;
  880 + }
  881 +
  882 + .login #header,
  883 + .login #content {
  884 + padding: 15px;
  885 + }
  886 +
  887 + .login #content-main {
  888 + float: none;
  889 + }
  890 +
  891 + .login .form-row {
  892 + padding: 0;
  893 + }
  894 +
  895 + .login .form-row + .form-row {
  896 + margin-top: 15px;
  897 + }
  898 +
  899 + .login .form-row label {
  900 + display: block;
  901 + margin: 0 0 5px;
  902 + padding: 0;
  903 + line-height: 1.2;
  904 + }
  905 +
  906 + .login .submit-row {
  907 + padding: 15px 0 0;
  908 + }
  909 +
  910 + .login br, .login .submit-row label {
  911 + display: none;
  912 + }
  913 +
  914 + .login .submit-row input {
  915 + margin: 0;
  916 + text-transform: uppercase;
  917 + }
  918 +
  919 + .errornote {
  920 + margin: 0 0 20px;
  921 + padding: 8px 12px;
  922 + font-size: 13px;
  923 + }
  924 +
  925 + /* Calendar and clock */
  926 +
  927 + .calendarbox, .clockbox {
  928 + position: fixed !important;
  929 + top: 50% !important;
  930 + left: 50% !important;
  931 + transform: translate(-50%, -50%);
  932 + margin: 0;
  933 + border: none;
  934 + overflow: visible;
  935 + }
  936 +
  937 + .calendarbox:before, .clockbox:before {
  938 + content: '';
  939 + position: fixed;
  940 + top: 50%;
  941 + left: 50%;
  942 + width: 100vw;
  943 + height: 100vh;
  944 + background: rgba(0, 0, 0, 0.75);
  945 + transform: translate(-50%, -50%);
  946 + }
  947 +
  948 + .calendarbox > *, .clockbox > * {
  949 + position: relative;
  950 + z-index: 1;
  951 + }
  952 +
  953 + .calendarbox > div:first-child {
  954 + z-index: 2;
  955 + }
  956 +
  957 + .calendarbox .calendar, .clockbox h2 {
  958 + border-radius: 4px 4px 0 0;
  959 + overflow: hidden;
  960 + }
  961 +
  962 + .calendarbox .calendar-cancel, .clockbox .calendar-cancel {
  963 + border-radius: 0 0 4px 4px;
  964 + overflow: hidden;
  965 + }
  966 +
  967 + .calendar-shortcuts {
  968 + padding: 10px 0;
  969 + font-size: 12px;
  970 + line-height: 12px;
  971 + }
  972 +
  973 + .calendar-shortcuts a {
  974 + margin: 0 4px;
  975 + }
  976 +
  977 + .timelist a {
  978 + background: #fff;
  979 + padding: 4px;
  980 + }
  981 +
  982 + .calendar-cancel {
  983 + padding: 8px 10px;
  984 + }
  985 +
  986 + .clockbox h2 {
  987 + padding: 8px 15px;
  988 + }
  989 +
  990 + .calendar caption {
  991 + padding: 10px;
  992 + }
  993 +
  994 + .calendarbox .calendarnav-previous, .calendarbox .calendarnav-next {
  995 + z-index: 1;
  996 + top: 10px;
  997 + }
  998 +
  999 + /* History */
  1000 +
  1001 + table#change-history tbody th, table#change-history tbody td {
  1002 + font-size: 13px;
  1003 + word-break: break-word;
  1004 + }
  1005 +
  1006 + table#change-history tbody th {
  1007 + width: auto;
  1008 + }
  1009 +
  1010 + /* Docs */
  1011 +
  1012 + table.model tbody th, table.model tbody td {
  1013 + font-size: 13px;
  1014 + word-break: break-word;
  1015 + }
  1016 +}
  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 + margin-right: 0;
  28 + margin-left: 230px;
  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"] .change-list .filtered .results,
  67 + [dir="rtl"] .change-list .filtered .paginator,
  68 + [dir="rtl"] .filtered #toolbar,
  69 + [dir="rtl"] .filtered div.xfull,
  70 + [dir="rtl"] .filtered .actions {
  71 + margin-left: 0;
  72 + }
  73 +
  74 + [dir="rtl"] .aligned .related-lookup,
  75 + [dir="rtl"] .aligned .datetimeshortcuts {
  76 + margin-left: 0;
  77 + margin-right: 15px;
  78 + }
  79 +
  80 + [dir="rtl"] .aligned ul {
  81 + margin-right: 0;
  82 + }
  83 +}
  1 +body {
  2 + direction: rtl;
  3 +}
  4 +
  5 +/* LOGIN */
  6 +
  7 +.login .form-row {
  8 + float: right;
  9 +}
  10 +
  11 +.login .form-row label {
  12 + float: right;
  13 + padding-left: 0.5em;
  14 + padding-right: 0;
  15 + text-align: left;
  16 +}
  17 +
  18 +.login .submit-row {
  19 + clear: both;
  20 + padding: 1em 9.4em 0 0;
  21 +}
  22 +
  23 +/* GLOBAL */
  24 +
  25 +th {
  26 + text-align: right;
  27 +}
  28 +
  29 +.module h2, .module caption {
  30 + text-align: right;
  31 +}
  32 +
  33 +.module ul, .module ol {
  34 + margin-left: 0;
  35 + margin-right: 1.5em;
  36 +}
  37 +
  38 +.viewlink, .addlink, .changelink {
  39 + padding-left: 0;
  40 + padding-right: 16px;
  41 + background-position: 100% 1px;
  42 +}
  43 +
  44 +.deletelink {
  45 + padding-left: 0;
  46 + padding-right: 16px;
  47 + background-position: 100% 1px;
  48 +}
  49 +
  50 +.object-tools {
  51 + float: left;
  52 +}
  53 +
  54 +thead th:first-child,
  55 +tfoot td:first-child {
  56 + border-left: none;
  57 +}
  58 +
  59 +/* LAYOUT */
  60 +
  61 +#user-tools {
  62 + right: auto;
  63 + left: 0;
  64 + text-align: left;
  65 +}
  66 +
  67 +div.breadcrumbs {
  68 + text-align: right;
  69 +}
  70 +
  71 +#content-main {
  72 + float: right;
  73 +}
  74 +
  75 +#content-related {
  76 + float: left;
  77 + margin-left: -300px;
  78 + margin-right: auto;
  79 +}
  80 +
  81 +.colMS {
  82 + margin-left: 300px;
  83 + margin-right: 0;
  84 +}
  85 +
  86 +/* SORTABLE TABLES */
  87 +
  88 +table thead th.sorted .sortoptions {
  89 + float: left;
  90 +}
  91 +
  92 +thead th.sorted .text {
  93 + padding-right: 0;
  94 + padding-left: 42px;
  95 +}
  96 +
  97 +/* dashboard styles */
  98 +
  99 +.dashboard .module table td a {
  100 + padding-left: .6em;
  101 + padding-right: 16px;
  102 +}
  103 +
  104 +/* changelists styles */
  105 +
  106 +.change-list .filtered table {
  107 + border-left: none;
  108 + border-right: 0px none;
  109 +}
  110 +
  111 +#changelist-filter {
  112 + right: auto;
  113 + left: 0;
  114 + border-left: none;
  115 + border-right: none;
  116 +}
  117 +
  118 +.change-list .filtered .results, .change-list .filtered .paginator, .filtered #toolbar, .filtered div.xfull {
  119 + margin-right: 0;
  120 + margin-left: 280px;
  121 +}
  122 +
  123 +#changelist-filter li.selected {
  124 + border-left: none;
  125 + padding-left: 10px;
  126 + margin-left: 0;
  127 + border-right: 5px solid #eaeaea;
  128 + padding-right: 10px;
  129 + margin-right: -15px;
  130 +}
  131 +
  132 +.filtered .actions {
  133 + margin-left: 280px;
  134 + margin-right: 0;
  135 +}
  136 +
  137 +#changelist table tbody td:first-child, #changelist table tbody th:first-child {
  138 + border-right: none;
  139 + border-left: none;
  140 +}
  141 +
  142 +/* FORMS */
  143 +
  144 +.aligned label {
  145 + padding: 0 0 3px 1em;
  146 + float: right;
  147 +}
  148 +
  149 +.submit-row {
  150 + text-align: left
  151 +}
  152 +
  153 +.submit-row p.deletelink-box {
  154 + float: right;
  155 +}
  156 +
  157 +.submit-row input.default {
  158 + margin-left: 0;
  159 +}
  160 +
  161 +.vDateField, .vTimeField {
  162 + margin-left: 2px;
  163 +}
  164 +
  165 +.aligned .form-row input {
  166 + margin-left: 5px;
  167 +}
  168 +
  169 +form .aligned p.help, form .aligned div.help {
  170 + clear: right;
  171 +}
  172 +
  173 +form .aligned ul {
  174 + margin-right: 163px;
  175 + margin-left: 0;
  176 +}
  177 +
  178 +form ul.inline li {
  179 + float: right;
  180 + padding-right: 0;
  181 + padding-left: 7px;
  182 +}
  183 +
  184 +input[type=submit].default, .submit-row input.default {
  185 + float: left;
  186 +}
  187 +
  188 +fieldset .fieldBox {
  189 + float: right;
  190 + margin-left: 20px;
  191 + margin-right: 0;
  192 +}
  193 +
  194 +.errorlist li {
  195 + background-position: 100% 12px;
  196 + padding: 0;
  197 +}
  198 +
  199 +.errornote {
  200 + background-position: 100% 12px;
  201 + padding: 10px 12px;
  202 +}
  203 +
  204 +/* WIDGETS */
  205 +
  206 +.calendarnav-previous {
  207 + top: 0;
  208 + left: auto;
  209 + right: 10px;
  210 +}
  211 +
  212 +.calendarnav-next {
  213 + top: 0;
  214 + right: auto;
  215 + left: 10px;
  216 +}
  217 +
  218 +.calendar caption, .calendarbox h2 {
  219 + text-align: center;
  220 +}
  221 +
  222 +.selector {
  223 + float: right;
  224 +}
  225 +
  226 +.selector .selector-filter {
  227 + text-align: right;
  228 +}
  229 +
  230 +.inline-deletelink {
  231 + float: left;
  232 +}
  233 +
  234 +form .form-row p.datetime {
  235 + overflow: hidden;
  236 +}
  237 +
  238 +.related-widget-wrapper {
  239 + float: right;
  240 +}
  241 +
  242 +/* MISC */
  243 +
  244 +.inline-related h2, .inline-group h2 {
  245 + text-align: right
  246 +}
  247 +
  248 +.inline-related h3 span.delete {
  249 + padding-right: 20px;
  250 + padding-left: inherit;
  251 + left: 10px;
  252 + right: inherit;
  253 + float:left;
  254 +}
  255 +
  256 +.inline-related h3 span.delete label {
  257 + margin-left: inherit;
  258 + margin-right: 2px;
  259 +}
  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.