Browse Source

云计算期末展示

master
肖诗涵 4 years ago
parent
commit
54e01c2ee1
313 changed files with 84269 additions and 0 deletions
  1. +373
    -0
      README.md
  2. BIN
      master/.DS_Store
  3. +8
    -0
      master/.idea/.gitignore
  4. +34
    -0
      master/.idea/ForumSystem.iml
  5. +19
    -0
      master/.idea/dataSources.xml
  6. +3
    -0
      master/.idea/dictionaries/likunhong.xml
  7. +20
    -0
      master/.idea/inspectionProfiles/Project_Default.xml
  8. +6
    -0
      master/.idea/libraries/R_User_Library.xml
  9. +30
    -0
      master/.idea/misc.xml
  10. +8
    -0
      master/.idea/modules.xml
  11. +6
    -0
      master/.idea/vcs.xml
  12. +5
    -0
      master/ForumSystem/__init__.py
  13. BIN
      master/ForumSystem/__pycache__/__init__.cpython-36.pyc
  14. BIN
      master/ForumSystem/__pycache__/__init__.cpython-37.pyc
  15. BIN
      master/ForumSystem/__pycache__/settings.cpython-36.pyc
  16. BIN
      master/ForumSystem/__pycache__/settings.cpython-37.pyc
  17. BIN
      master/ForumSystem/__pycache__/urls.cpython-36.pyc
  18. BIN
      master/ForumSystem/__pycache__/urls.cpython-37.pyc
  19. BIN
      master/ForumSystem/__pycache__/wsgi.cpython-37.pyc
  20. +145
    -0
      master/ForumSystem/settings.py
  21. +36
    -0
      master/ForumSystem/urls.py
  22. +15
    -0
      master/ForumSystem/wsgi.py
  23. BIN
      master/__pycache__/manage.cpython-37.pyc
  24. +5
    -0
      master/app01/__init__.py
  25. BIN
      master/app01/__pycache__/__init__.cpython-36.pyc
  26. BIN
      master/app01/__pycache__/__init__.cpython-37.pyc
  27. BIN
      master/app01/__pycache__/admin.cpython-36.pyc
  28. BIN
      master/app01/__pycache__/admin.cpython-37.pyc
  29. BIN
      master/app01/__pycache__/apps.cpython-36.pyc
  30. BIN
      master/app01/__pycache__/apps.cpython-37.pyc
  31. BIN
      master/app01/__pycache__/models.cpython-36.pyc
  32. BIN
      master/app01/__pycache__/models.cpython-37.pyc
  33. BIN
      master/app01/__pycache__/views.cpython-36.pyc
  34. BIN
      master/app01/__pycache__/views.cpython-37.pyc
  35. +3
    -0
      master/app01/admin.py
  36. +5
    -0
      master/app01/apps.py
  37. +65
    -0
      master/app01/migrations/0001_initial.py
  38. +28
    -0
      master/app01/migrations/0002_auto_20190703_0151.py
  39. +25
    -0
      master/app01/migrations/0003_auto_20190703_0259.py
  40. +18
    -0
      master/app01/migrations/0004_topic_t_like.py
  41. +0
    -0
      master/app01/migrations/__init__.py
  42. BIN
      master/app01/migrations/__pycache__/0001_initial.cpython-36.pyc
  43. BIN
      master/app01/migrations/__pycache__/0001_initial.cpython-37.pyc
  44. BIN
      master/app01/migrations/__pycache__/0002_auto_20190703_0151.cpython-36.pyc
  45. BIN
      master/app01/migrations/__pycache__/0002_auto_20190703_0151.cpython-37.pyc
  46. BIN
      master/app01/migrations/__pycache__/0003_auto_20190703_0259.cpython-36.pyc
  47. BIN
      master/app01/migrations/__pycache__/0003_auto_20190703_0259.cpython-37.pyc
  48. BIN
      master/app01/migrations/__pycache__/0004_topic_t_like.cpython-36.pyc
  49. BIN
      master/app01/migrations/__pycache__/0004_topic_t_like.cpython-37.pyc
  50. BIN
      master/app01/migrations/__pycache__/__init__.cpython-36.pyc
  51. BIN
      master/app01/migrations/__pycache__/__init__.cpython-37.pyc
  52. +46
    -0
      master/app01/models.py
  53. +3
    -0
      master/app01/tests.py
  54. +565
    -0
      master/app01/views.py
  55. +19588
    -0
      master/logs/error.log
  56. +15
    -0
      master/manage.py
  57. +59
    -0
      master/requirements.txt
  58. BIN
      master/static/.DS_Store
  59. +260
    -0
      master/static/admin/css/autocomplete.css
  60. +966
    -0
      master/static/admin/css/base.css
  61. +354
    -0
      master/static/admin/css/changelists.css
  62. +26
    -0
      master/static/admin/css/dashboard.css
  63. +20
    -0
      master/static/admin/css/fonts.css
  64. +527
    -0
      master/static/admin/css/forms.css
  65. +79
    -0
      master/static/admin/css/login.css
  66. +119
    -0
      master/static/admin/css/nav_sidebar.css
  67. +1004
    -0
      master/static/admin/css/responsive.css
  68. +80
    -0
      master/static/admin/css/responsive_rtl.css
  69. +249
    -0
      master/static/admin/css/rtl.css
  70. +21
    -0
      master/static/admin/css/vendor/select2/LICENSE-SELECT2.md
  71. +481
    -0
      master/static/admin/css/vendor/select2/select2.css
  72. +1
    -0
      master/static/admin/css/vendor/select2/select2.min.css
  73. +574
    -0
      master/static/admin/css/widgets.css
  74. +202
    -0
      master/static/admin/fonts/LICENSE.txt
  75. +3
    -0
      master/static/admin/fonts/README.txt
  76. BIN
      master/static/admin/fonts/Roboto-Bold-webfont.woff
  77. BIN
      master/static/admin/fonts/Roboto-Light-webfont.woff
  78. BIN
      master/static/admin/fonts/Roboto-Regular-webfont.woff
  79. +20
    -0
      master/static/admin/img/LICENSE
  80. +7
    -0
      master/static/admin/img/README.txt
  81. +14
    -0
      master/static/admin/img/calendar-icons.svg
  82. +1
    -0
      master/static/admin/img/gis/move_vertex_off.svg
  83. +1
    -0
      master/static/admin/img/gis/move_vertex_on.svg
  84. +3
    -0
      master/static/admin/img/icon-addlink.svg
  85. +3
    -0
      master/static/admin/img/icon-alert.svg
  86. +9
    -0
      master/static/admin/img/icon-calendar.svg
  87. +3
    -0
      master/static/admin/img/icon-changelink.svg
  88. +9
    -0
      master/static/admin/img/icon-clock.svg
  89. +3
    -0
      master/static/admin/img/icon-deletelink.svg
  90. +3
    -0
      master/static/admin/img/icon-no.svg
  91. +3
    -0
      master/static/admin/img/icon-unknown-alt.svg
  92. +3
    -0
      master/static/admin/img/icon-unknown.svg
  93. +3
    -0
      master/static/admin/img/icon-viewlink.svg
  94. +3
    -0
      master/static/admin/img/icon-yes.svg
  95. +3
    -0
      master/static/admin/img/inline-delete.svg
  96. +3
    -0
      master/static/admin/img/search.svg
  97. +34
    -0
      master/static/admin/img/selector-icons.svg
  98. +19
    -0
      master/static/admin/img/sorting-icons.svg
  99. +3
    -0
      master/static/admin/img/tooltag-add.svg
  100. +3
    -0
      master/static/admin/img/tooltag-arrowright.svg

+ 373
- 0
README.md View File

@ -0,0 +1,373 @@
# ForumSystem
# 滑动师范大学论坛
### 环境配置
一、更新系统软件包
yum update -y
二、安装软件管理包和可能使用的依赖
yum -y groupinstall "Development tools"
yum install openssl-devel bzip2-devel expat-devel gdbm-devel readline-devel sqlite-devel psmisc libffi-devel
三、下载Pyhton3到/usr/local 目录
cd /usr/local
wget https://www.python.org/ftp/python/3.6.6/Python-3.6.6.tgz
解压
tar -zxvf Python-3.6.6.tgz
进入 Python-3.6.6路径
cd Python-3.6.6
编译安装到指定路径
./configure --prefix=/usr/local/python3
安装python3
make
make install
python3建立软连接:ln -s /usr/local/python3/bin/python3.6 /usr/bin/python3
同样给pip3建立软链接:ln -s /usr/local/python3/bin/pip3.6 /usr/bin/pip3
四、安装virtualenv
pip3 install virtualenv
建立软链接
ln -s /usr/local/python3/bin/virtualenv /usr/bin/virtualenv
五、下载并安装MySQL
wget -i -c http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm
yum -y install mysql57-community-release-el7-10.noarch.rpm
yum -y install mysql-community-server
MySQL数据库设置: systemctl start mysqld.service
grep "password" /var/log/mysqld.log
登录mysql:mysql -uroot -p
修改密码:ALTER USER 'root'@'localhost' IDENTIFIED BY 'new password';
创建数据库create database forum,并使用use forum;
创建/www/wwwroot/目录,并将项目解压至该目录
在master目录下创建虚拟环境virtualenv --python=/usr/bin/python3 master_venv
执行source ./master_venv/bin/activate
修改/master/ForumSystem下settings.py中数据库密码
回到master目录,在虚拟环境下安装pip3 install django pip3 install pgsql
pip3 install uwsgi pip3 install -r requirements.txt
安装requirements.txt出错
centos安装psycopg2时出错:Error: pg_config executable not found.解决方案
yum install postgresql-devel*
使用 pip install psycopg2-binary 安装即可
再执行pip3 install -r requirements.txt
六、配置uwsgi配置文件(master同目录下,已创建,可以修改端口)
[uwsgi]
master = true
processes = 1
threads = 2
chdir = /www/wwwroot/master
#wsgi-file= /www/wwwroot/master/
wsgi-file = /www/wwwroot/master/ForumSystem/wsgi.py
http = 0.0.0.0:8080
logto = /www/wwwroot/master/logs/error.log
chmod-socket = 660
vacuum = true
master = true
max-requests = 1000
static-map = /static=/www/wwwroot/master/static
在master目录下运行,进行数据库迁移:
python manage.py makemigrations
python manage.py migrate
在master目录下启动uwsgi
uwsgi --ini uwsgi.ini
浏览器输入网址http://ip地址:8080/login 安装成功
## 展示
### 用户端
登录
![image](http://ww1.sinaimg.cn/large/006tNc79ly1g4z46rpj9cj31k10u0drs.jpg)
主页
![](http://ww4.sinaimg.cn/large/006tNc79ly1g520s6ijl0j31kl0u0e81.jpg)
全部帖子
![](http://ww2.sinaimg.cn/large/006tNc79ly1g520t8nsslj31k10u0qv5.jpg)
发帖
![](http://ww1.sinaimg.cn/large/006tNc79ly1g520u2tfwfj31k90u0drc.jpg)
### 管理员端
帖子管理
![image](http://ww1.sinaimg.cn/large/006tNc79ly1g4z43fiddwj31jm0u0gy1.jpg)
公告管理
![image](http://ww2.sinaimg.cn/large/006tNc79ly1g4z43pup25j31k10u0136.jpg)
板块(分类)管理
![image](http://ww3.sinaimg.cn/large/006tNc79ly1g4z44l23y8j31jv0u0131.jpg)
## 功能
### 用户端功能
- 注册:用户在注册界面可以提交注册,暂不支持手机短信验证,直接注册。
- 登录:已注册的用户可以通过正确的用户名和密码登录。
- 欢迎:主页的导航栏会显示用户名并且欢迎。
- 查看公告:查看管理员发出的公告。
- 查看指南:显示在主页的指南。
- 推荐帖子:每个帖子可以选择推荐在首页显示。
- 查看类别:可以看到论坛里帖子所有的类别,点击可以查看对应下的帖子。
- 查看全部帖子:按照时间顺序,查看所有帖子。
- 帖子筛选:可以根据帖子分类、回复量、发布时间进行组合筛选。
- 帖子搜索:根据输入关键字查询相关帖子。
- 发帖:普通用户可以发帖。
- 查看帖子详细:可以看到帖子的发布时间,作者,类别,标题,简介,详细内容,所有留言信息。
- 留言:可以在帖子下面发表文字或者图片留言(评论),暂不支持回复评论。
## 系统说明
### 数据库
项目采用mysql进行存储,我使用的是mysql 8.0.16。表之间不采用任何外键关联,逻辑的管理都在控制层完成。每个表的id都由Django自动创建,也同时作为主键。
#### 表与字段
##### 用户表:User
字段名称 | 字段类型 | 字段说明
---|---|---
id | int | 编号,自增,主键
uid | vchar(16) | 用户名,唯一
password | vchar(16) | 密码
create_time | Date | 创建日期
##### 帖子表:Topic
字段名称 | 字段类型 | 字段说明
---|---|---
id | int | 编号,自增,主键
t_uid | vchar(16) | 帖子作者
t_kind | vchar(32) | 帖子类型
create_time | Date | 帖子发布日期
t_photo | vchar(128) | 帖子主页图,允许为空
t_content | vchar(3000) | 帖子内容
t_title | vchar(64) | 帖子标题
t_introduce | vchar(256) | 帖子介绍
recommend | boolean | 是否推荐到主页,默认false
##### 回复表:Reply
字段名称 | 字段类型 | 字段说明
---|---|---
id | int | 编号,自增,主键
r_tid | vchar(16) | 回复的帖子
r_uid | vchar(16) | 发表回复的人
r_time | Date | 回复时间
r_photo | vchar(128) | 回复图片,允许为空
r_content | vchar(256) | 回复内容
##### 分类表:Kind
字段名称 | 字段类型 | 字段说明
---|---|---
id | int | 编号,自增,主键
k_name | vchar(16) | 分类名称
##### 公告表:Announcement
字段名称 | 字段类型 | 字段说明
---|---|---
id | int | 编号,自增,主键
a_title | vchar(64) | 公告名称
a_content | vchar(3000) | 公告内容,允许为空
#### 数据库代码
数据库代码在模型(models)层:参见/ForumSystem/app01/models.py
### 用户端
#### 用户端前端
- 主页:
- 显示公告:模板和数据渲染生成
- 显示指南:html固定内容
- 显示导航栏
- 登陆后显示:主页、发帖、看帖、欢迎、退出
- 未登录显示:主页、发帖(点击会跳转到登录)、看帖、登录。
- 显示推荐帖子:模板和数据渲染生成
- 显示全部帖子按钮:页面固定
- 底部栏:显示名称和导航栏
- 登录&注册页面:
- 一个输入框:分为用户名和密码
- 两个按钮(登录/注册)
- 通过ajax发送登录或者注册请求
- 全部帖子页面:
- 论坛名称(左上角):固定显示
- 搜索框:固定,form表单post提交
- 导航栏:同上
- 组合筛选栏
- 分类筛选:模板和数据渲染得到所有分类显示
- 回复数量筛选:固定
- 发布时间筛选:固定
- 显示全部帖子:模板和数据渲染获取
- 帖子详情页面:模板和数据渲染获取
- 论坛名称:同上
- 导航栏:同上
- 帖子主图
- 帖子标题和详细内容
- 帖子作者、发布时间、分类
- 发表留言栏:form表单,post提交
- 显示所有留言:模板和数据渲染获取
- 公告详情页面:
- 公告标题
- 公告内容
- 发布帖子页面:
- 一个大form表单,包括帖子的标题、简介、内容、封面图、类别(下拉选择)。
- 修改密码页面:
- 用户名框(只显示,不可改)
- 原密码框
- 新密码框
- 确认新密码框
- 提交(成功后返回主页)、取消(返回主页)按钮
#### 用户端接口
##### 主页
- url:http://127.0.0.1:8000/home/
- GET请求
- 参数:无
- 返回值:10个最新公告列表,所有推荐贴列表,渲染好的**页面**。
##### 所有帖子
- url:http://127.0.0.1:8000/all-0-0-0
- GET请求
- url说明:后3个0指组合筛选不进行筛选
- 参数:无,也可以说是all后面的3个数字(kid, reply_limit, time_limit)
- 返回值:根据3个参数选择后的**帖子列表**
- POST请求:
- 参数
- keys:搜索关键字
- 返回值:根据关键字搜索到的**帖子列表**
##### 登录、注册
- url:http://127.0.0.1:8000/login/
- GET请求:
- 参数:无
- 返回值:登录页面
- POST请求:
- 参数:
- type:login 或者 register
- uid:用户名
- pwd:密码
- 返回值:
- msg:信息
- status:状态,成功与否
##### 发布帖子
- url:http://127.0.0.1:8000/publish/
- GET请求:
- 参数:无
- 返回值:发布帖子页面
- POST请求:
- 参数:
- t_title:标题
- t_introduce:介绍
- t_content:内容
- t_kind:类别
- t_photo:主图
- 返回值:
- 成功后重定向到单个帖子页面
##### 单个帖子
- url:http://127.0.0.1:8000/single/1/
- GET请求:
- url说明:1就是tid
- 参数:tid
- 返回值:帖子相关所有信息,渲染成单个帖子详情页面
- POST请求:主要用于评论的发表和删除
- 参数:
- type:类型,删除评论还是发表评论
- r_content:评论内容
- r_photo:评论图片
- r_id:回复id,删除已有回复才用到
- 返回值:
- msg:信息
- status:状态,成功与否
##### 修改密码
- url:http://127.0.0.1:8000/edit-pwd/
- GET请求:
- 参数:无
- 返回值:修改密码页面
- POST请求:
- 参数:
- old_pwd:旧密码
- new_pwd1:新密码
- new_pwd2:确认新密码
- 返回值:
- 成功后重定向到主页
### 管理员端
#### 管理员前端
- 管理员登录:
- 一个输入框:分为用户名和密码
- 两个按钮(登录/取消)
- 一个form表单,提交数据
- 帖子管理:
- 导航栏:帖子管理、公告管理、分类管理
- 欢迎头部
- 帖子列表:序号、名称、简介、推荐、操作
- 推荐操作:绑定ajax,刷新页面
- 取消推荐操作:ajax,刷新
- 查看操作:跳转帖子详情页面
- 删除操作:ajax,同时刷新
- 公告管理:
- 导航栏:帖子管理、公告管理、分类管理
- 欢迎头部
- 公告列表:序号、标题、操作
- 查看操作:跳转公告详情页面
- 删除操作:ajax,同时刷新
- 分类(板块)管理:
- 导航栏:帖子管理、公告管理、分类管理
- 欢迎头部
- 分类列表:序号、分类名称、操作
- 查看该分类下所有帖子操作:跳转到全部帖子下组合搜索出分类里的帖子
- 删除操作:ajax,同时刷新
#### 管理员接口
##### 登录
- url:http://127.0.0.1:8000/my-admin/
- GET请求:
- 参数:无
- 返回值:管理员登录页面
- POST请求:
- 参数:
- admin_id:管理员用户名
- admin_pwd:管理员密码
- 返回值:
- 成功后重定向到帖子管理页面
- 注意:管理员我没有做表去存放管理员账号密码,所以在程序里写死了管理员账号为guanliyuan,密码为123456
##### 帖子管理
- url:http://127.0.0.1:8000/admin-home/
- GET请求:
- 参数:无
- 返回值:所有帖子信息,渲染后的帖子管理页面,需要验证管理员是否登录(使用session)
- POST请求:
- 参数:
- type:post请求类型(以下为type可用的值)
- zhiding:置顶(推荐)
- qzhiding:取消置顶
- delete:删除
- t_id:帖子id,根据帖子id进行type操作
- 返回值:
- msg:信息
- status:成功与否状态
##### 公告管理
- url:http://127.0.0.1:8000/announcement/
- GET请求:
- 参数:无
- 返回值:所有公告信息,渲染后的公告管理页面,需要验证管理员是否登录(使用session)
- POST请求:
- 参数:
- type:post请求类型
- create:创建公告
- delete:删除公告
- a_id:公告id,如果type=delete需要公告id
- a_title:公告标题,如果type=create,需要公告标题
- a_content:公告内容,如果type=create,需要公告标题
- 返回值:
- msg:信息
- status:成功与否状态
##### 分类管理
- url:http://127.0.0.1:8000/kind-manage/
- GET请求:
- 参数:无
- 返回值:所有分类信息,渲染后的类别管理页面,需要验证管理员是否登录(使用session)
- POST请求:
- 参数:
- type:post请求类型(删除or创建)
- create:创建类别
- delete:删除类别
- k_id:类别id,如果type=delete需要类别id
- k_name:类别名称,如果type=create,需要类别名称
- 返回值:
- msg:信息
- status:成功与否状态

BIN
master/.DS_Store View File


+ 8
- 0
master/.idea/.gitignore View File

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/

+ 34
- 0
master/.idea/ForumSystem.iml View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="FacetManager">
<facet type="django" name="Django">
<configuration>
<option name="rootFolder" value="$MODULE_DIR$" />
<option name="settingsModule" value="ForumSystem/settings.py" />
<option name="manageScript" value="$MODULE_DIR$/manage.py" />
<option name="environment" value="&lt;map/&gt;" />
<option name="doNotUseTestRunner" value="false" />
<option name="trackFilePattern" value="migrations" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="Python 3.7 (visualization)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="R User Library" level="project" />
<orderEntry type="library" name="R Skeletons" level="application" />
</component>
<component name="TemplatesService">
<option name="TEMPLATE_CONFIGURATION" value="Django" />
<option name="TEMPLATE_FOLDERS">
<list>
<option value="$MODULE_DIR$/templates" />
</list>
</option>
</component>
<component name="TestRunnerService">
<option name="projectConfiguration" value="Twisted Trial" />
<option name="PROJECT_TEST_RUNNER" value="Twisted Trial" />
</component>
</module>

+ 19
- 0
master/.idea/dataSources.xml View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
<data-source source="LOCAL" name="MySQL - forum_system@localhost" uuid="47ae3cb6-5721-4752-aabd-d732b72e3838">
<driver-ref>mysql.8</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>com.mysql.cj.jdbc.Driver</jdbc-driver>
<jdbc-url>jdbc:mysql://localhost:3306/forum_system</jdbc-url>
<driver-properties>
<property name="autoReconnect" value="true" />
<property name="zeroDateTimeBehavior" value="CONVERT_TO_NULL" />
<property name="tinyInt1isBit" value="false" />
<property name="characterEncoding" value="utf8" />
<property name="characterSetResults" value="utf8" />
<property name="yearIsDateType" value="false" />
</driver-properties>
</data-source>
</component>
</project>

+ 3
- 0
master/.idea/dictionaries/likunhong.xml View File

@ -0,0 +1,3 @@
<component name="ProjectDictionaryState">
<dictionary name="likunhong" />
</component>

+ 20
- 0
master/.idea/inspectionProfiles/Project_Default.xml View File

@ -0,0 +1,20 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="PyPep8NamingInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<option name="ignoredErrors">
<list>
<option value="N806" />
<option value="N802" />
</list>
</option>
</inspection_tool>
<inspection_tool class="PyUnresolvedReferencesInspection" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoredIdentifiers">
<list>
<option value="float.__getitem__" />
</list>
</option>
</inspection_tool>
</profile>
</component>

+ 6
- 0
master/.idea/libraries/R_User_Library.xml View File

@ -0,0 +1,6 @@
<component name="libraryTable">
<library name="R User Library">
<CLASSES />
<SOURCES />
</library>
</component>

+ 30
- 0
master/.idea/misc.xml View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
<component name="ProjectInspectionProfilesVisibleTreeState">
<entry key="Project Default">
<profile-state>
<expanded-state>
<State />
<State>
<id>CSS</id>
</State>
<State>
<id>Probable bugsCSS</id>
</State>
<State>
<id>RELAX NG</id>
</State>
</expanded-state>
<selected-state>
<State>
<id>Angular</id>
</State>
</selected-state>
</profile-state>
</entry>
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7 (visualization)" project-jdk-type="Python SDK" />
</project>

+ 8
- 0
master/.idea/modules.xml View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/ForumSystem.iml" filepath="$PROJECT_DIR$/.idea/ForumSystem.iml" />
</modules>
</component>
</project>

+ 6
- 0
master/.idea/vcs.xml View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

+ 5
- 0
master/ForumSystem/__init__.py View File

@ -0,0 +1,5 @@
import pymysql
pymysql.version_info = (1, 4, 13, "final", 0)
pymysql.install_as_MySQLdb()

BIN
master/ForumSystem/__pycache__/__init__.cpython-36.pyc View File


BIN
master/ForumSystem/__pycache__/__init__.cpython-37.pyc View File


BIN
master/ForumSystem/__pycache__/settings.cpython-36.pyc View File


BIN
master/ForumSystem/__pycache__/settings.cpython-37.pyc View File


BIN
master/ForumSystem/__pycache__/urls.cpython-36.pyc View File


BIN
master/ForumSystem/__pycache__/urls.cpython-37.pyc View File


BIN
master/ForumSystem/__pycache__/wsgi.cpython-37.pyc View File


+ 145
- 0
master/ForumSystem/settings.py View File

@ -0,0 +1,145 @@
"""
Django settings for ForumSystem project.
Generated by 'django-admin startproject' using Django 2.1.4.
For more information on this file, see
https://docs.djangoproject.com/en/2.1/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.1/ref/settings/
"""
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'e(!)-kb_kqw5p@%u!6ak6u2$db5-4h@c#u)dwrcw^xp5m-q(q$'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = [
'*'
]
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01.apps.App01Config',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'ForumSystem.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')]
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'ForumSystem.wsgi.application'
# Database
# https://docs.djangoproject.com/en/2.1/ref/settings/#databases
# DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
# }
# }
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'HOST': '',
'NAME': 'forum', #你的数据库名称
'USER': 'root', #你的数据库用户名
'PASSWORD': 'xsh_123_XSH',
'PORT': '3306',
}
}
# Password validation
# https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/2.1/topics/i18n/
# LANGUAGE_CODE = 'en-us'
# TIME_ZONE = 'UTC'
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.1/howto/static-files/
STATIC_URL = '/static/'
# STATIC_ROOT = os.path.join(BASE_DIR,'static')
# STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, "static")
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)

+ 36
- 0
master/ForumSystem/urls.py View File

@ -0,0 +1,36 @@
"""ForumSystem URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/2.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from app01 import views
from django.conf.urls import url
urlpatterns = [
path('admin/', admin.site.urls),
# url(r'^all/', views.all_tie), # 全部帖子
url(r'^ownpublish-(?P<kid>\d+)-(?P<reply_limit>\d+)-(?P<time_limit>\d+)', views.ownpublish), # 按条件搜索自己帖子
url(r'^all-(?P<kid>\d+)-(?P<reply_limit>\d+)-(?P<time_limit>\d+)', views.all_tie), # 按条件搜索帖子
url(r'^home/', views.home), # 主页
url(r'^login/', views.login), # 登录注册
url(r'^publish/', views.publish), # 发布帖子
url(r'^single/(?P<tid>\d+)/', views.single), # 单个帖子
url(r'^edit-pwd/', views.edit_pwd), # 修改密码
url(r'^my-admin/', views.admin), # 修改密码
url(r'^announcement/', views.announcement), # 公告管理
url(r'^admin-home/', views.topic_manage), # 帖子管理,也是主页面
url(r'^kind-manage/', views.kind_manage), # 板块管理
url(r'^single-an-(?P<aid>\d+)/', views.single_an), # 单个公告显示
]

+ 15
- 0
master/ForumSystem/wsgi.py View File

@ -0,0 +1,15 @@
"""
WSGI config for ForumSystem project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/2.1/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'ForumSystem.settings')
application = get_wsgi_application()

BIN
master/__pycache__/manage.cpython-37.pyc View File


+ 5
- 0
master/app01/__init__.py View File

@ -0,0 +1,5 @@
import pymysql
pymysql.version_info = (1, 4, 13, "final", 0)
pymysql.install_as_MySQLdb()

BIN
master/app01/__pycache__/__init__.cpython-36.pyc View File


BIN
master/app01/__pycache__/__init__.cpython-37.pyc View File


BIN
master/app01/__pycache__/admin.cpython-36.pyc View File


BIN
master/app01/__pycache__/admin.cpython-37.pyc View File


BIN
master/app01/__pycache__/apps.cpython-36.pyc View File


BIN
master/app01/__pycache__/apps.cpython-37.pyc View File


BIN
master/app01/__pycache__/models.cpython-36.pyc View File


BIN
master/app01/__pycache__/models.cpython-37.pyc View File


BIN
master/app01/__pycache__/views.cpython-36.pyc View File


BIN
master/app01/__pycache__/views.cpython-37.pyc View File


+ 3
- 0
master/app01/admin.py View File

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

+ 5
- 0
master/app01/apps.py View File

@ -0,0 +1,5 @@
from django.apps import AppConfig
class App01Config(AppConfig):
name = 'app01'

+ 65
- 0
master/app01/migrations/0001_initial.py View File

@ -0,0 +1,65 @@
# Generated by Django 2.1.4 on 2019-07-02 04:07
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Announcement',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('a_id', models.CharField(max_length=16, verbose_name='公告id')),
('a_title', models.CharField(max_length=16, verbose_name='公告标题')),
('a_content', models.CharField(max_length=16, null=True, verbose_name='公告内容')),
],
),
migrations.CreateModel(
name='Kind',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('k_id', models.CharField(max_length=16, verbose_name='分类id')),
('k_name', models.CharField(max_length=16, verbose_name='分类名称')),
],
),
migrations.CreateModel(
name='Reply',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('r_tid', models.CharField(max_length=16, verbose_name='帖子id')),
('r_uid', models.CharField(max_length=16, verbose_name='发表者id')),
('r_photo', models.CharField(max_length=128, null=True, verbose_name='回复的图片')),
('r_time', models.DateField(auto_now_add=True, verbose_name='留言时间')),
('r_content', models.CharField(max_length=256, verbose_name='回复内容')),
],
),
migrations.CreateModel(
name='Topic',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('t_id', models.CharField(max_length=16, verbose_name='帖子id')),
('t_uid', models.CharField(max_length=16, verbose_name='帖子所属用户id')),
('t_kind', models.CharField(max_length=32, verbose_name='类别')),
('create_time', models.DateField(auto_now_add=True, verbose_name='创建时间')),
('t_photo', models.CharField(max_length=128, null=True, verbose_name='帖子图片')),
('t_content', models.CharField(max_length=3000, verbose_name='帖子正文')),
('t_title', models.CharField(max_length=64, verbose_name='帖子标题')),
('t_introduce', models.CharField(max_length=256, verbose_name='帖子简介')),
],
),
migrations.CreateModel(
name='User',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('uid', models.CharField(max_length=16, unique=True, verbose_name='电话/用户号')),
('password', models.CharField(max_length=16, verbose_name='密码')),
('create_time', models.DateField(auto_now_add=True, verbose_name='创建时间')),
],
),
]

+ 28
- 0
master/app01/migrations/0002_auto_20190703_0151.py View File

@ -0,0 +1,28 @@
# Generated by Django 2.1.4 on 2019-07-03 01:51
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('app01', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='topic',
name='recommend',
field=models.BooleanField(default=False, verbose_name='是否推荐'),
),
migrations.AlterField(
model_name='announcement',
name='a_content',
field=models.CharField(max_length=3000, null=True, verbose_name='公告内容'),
),
migrations.AlterField(
model_name='announcement',
name='a_title',
field=models.CharField(max_length=64, verbose_name='公告标题'),
),
]

+ 25
- 0
master/app01/migrations/0003_auto_20190703_0259.py View File

@ -0,0 +1,25 @@
# Generated by Django 2.1.4 on 2019-07-03 02:59
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('app01', '0002_auto_20190703_0151'),
]
operations = [
migrations.RemoveField(
model_name='announcement',
name='a_id',
),
migrations.RemoveField(
model_name='kind',
name='k_id',
),
migrations.RemoveField(
model_name='topic',
name='t_id',
),
]

+ 18
- 0
master/app01/migrations/0004_topic_t_like.py View File

@ -0,0 +1,18 @@
# Generated by Django 3.1.5 on 2021-01-13 09:16
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('app01', '0003_auto_20190703_0259'),
]
operations = [
migrations.AddField(
model_name='topic',
name='t_like',
field=models.IntegerField(default=0, verbose_name='点赞数量'),
),
]

+ 0
- 0
master/app01/migrations/__init__.py View File


BIN
master/app01/migrations/__pycache__/0001_initial.cpython-36.pyc View File


BIN
master/app01/migrations/__pycache__/0001_initial.cpython-37.pyc View File


BIN
master/app01/migrations/__pycache__/0002_auto_20190703_0151.cpython-36.pyc View File


BIN
master/app01/migrations/__pycache__/0002_auto_20190703_0151.cpython-37.pyc View File


BIN
master/app01/migrations/__pycache__/0003_auto_20190703_0259.cpython-36.pyc View File


BIN
master/app01/migrations/__pycache__/0003_auto_20190703_0259.cpython-37.pyc View File


BIN
master/app01/migrations/__pycache__/0004_topic_t_like.cpython-36.pyc View File


BIN
master/app01/migrations/__pycache__/0004_topic_t_like.cpython-37.pyc View File


BIN
master/app01/migrations/__pycache__/__init__.cpython-36.pyc View File


BIN
master/app01/migrations/__pycache__/__init__.cpython-37.pyc View File


+ 46
- 0
master/app01/models.py View File

@ -0,0 +1,46 @@
from django.db import models
# Create your models here.
# 用户表
class User(models.Model):
uid = models.CharField(verbose_name='电话/用户号', max_length=16, unique=True)
password = models.CharField(verbose_name='密码', max_length=16)
create_time = models.DateField(verbose_name='创建时间', auto_now_add=True)
# 帖子表
class Topic(models.Model):
#t_id = models.CharField(verbose_name='帖子id', max_length=16)
t_uid = models.CharField(verbose_name='帖子所属用户id', max_length=16)
t_kind = models.CharField(verbose_name='类别', max_length=32)
create_time = models.DateField(verbose_name='创建时间', auto_now_add=True)
t_photo = models.CharField(verbose_name='帖子图片', max_length=128, null=True)
t_content = models.CharField(verbose_name='帖子正文', max_length=3000)
t_title = models.CharField(verbose_name='帖子标题', max_length=64)
t_introduce = models.CharField(verbose_name='帖子简介', max_length=256)
recommend = models.BooleanField(verbose_name='是否推荐', default=False)
t_like = models.IntegerField(verbose_name='点赞数量',default=0)
# 回复表
class Reply(models.Model):
r_tid = models.CharField(verbose_name='帖子id', max_length=16)
r_uid = models.CharField(verbose_name='发表者id', max_length=16)
r_photo = models.CharField(verbose_name='回复的图片', max_length=128, null=True)
r_time = models.DateField(verbose_name='留言时间', auto_now_add=True)
r_content = models.CharField(verbose_name='回复内容', max_length=256)
# 分类表
class Kind(models.Model):
# k_id = models.CharField(verbose_name='分类id', max_length=16)
k_name = models.CharField(verbose_name='分类名称', max_length=16)
# 公告表
class Announcement(models.Model):
# a_id = models.CharField(verbose_name='公告id', max_length=16)
a_title = models.CharField(verbose_name='公告标题', max_length=64)
a_content = models.CharField(verbose_name='公告内容', max_length=3000, null=True)

+ 3
- 0
master/app01/tests.py View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

+ 565
- 0
master/app01/views.py View File

@ -0,0 +1,565 @@
from django.http import HttpResponse
from django.shortcuts import render, redirect
from app01 import models
import json
# Create your views here.
# 主页
def home(request):
if request.method == 'GET':
response = {}
# top 10(公告)的处理,筛选10个也要改
announcements = models.Announcement.objects.filter()
# 把这10个公告封装成字典
a_list = []
for a in announcements:
dic = {'a_id': a.id, 'a_title': a.a_title}
a_list.append(dic)
# 把列表装进回复字典里
n = 10 if len(a_list) < 10 else len(a_list)
response['a_list'] = a_list[::-1][0:n-1]
# 帖子推荐列表,推荐8个帖子,推荐8个要改
recommends = models.Topic.objects.filter(recommend=True)
# 推荐列表
r_list = []
for t in recommends:
dic = {'t_id': t.id, 't_title': t.t_title, 't_introduce': t.t_introduce, 't_photo': t.t_photo}
r_list.append(dic)
# 把列表装进response
response['r_list'] = r_list
# 把uid装进返回字典里
response['uid'] = request.session['uid']
# 把所有类别装入返回字典里
kinds = models.Kind.objects.filter()
response['kinds'] = kinds
return render(request, 'home.html', response)
# 所有帖子
def all_tie(request, kid, reply_limit, time_limit):
uid = request.session.get('uid')
if request.method == 'GET':
kinds = models.Kind.objects.filter()
if kid == '0' and reply_limit == '0' and time_limit == '0':
# 默认时间排序把帖子传过去
topics = models.Topic.objects.filter()
else:
# request.path_info # 获取当前url
# from django.urls import reverse
# reverse('all_tie', kwargs={'kid': '0', 'reply_limit': '0', 'time_limit': '0'})
topics = models.Topic.objects.filter()
# 筛选分类
if kid != '0':
topics = models.Topic.objects.filter(t_kind=kid)
# 筛选回复数量
tmp = []
for topic in topics:
# 查看每个帖子的回复数量
count = len(models.Reply.objects.filter(r_tid=topic.id))
# print(count)
print(reply_limit)
if reply_limit == '0':
pass
elif reply_limit == '1': # 1是大于100
print('到1了')
if count < 100:
print('到了')
continue
elif reply_limit == '2': # 2是30-100
if count < 30 or count > 100:
continue
elif reply_limit == '3': # 3是小于30
if count > 30:
continue
tmp.append(topic)
topics = tmp
print(topics)
# 筛选发布时间
tmp = []
for topic in topics:
if time_limit == '0': # 0是全部时间
pass
elif time_limit == '1': # 1是1个月内
# 如果在限制之前,就筛掉
pass
elif time_limit == '2': # 2是3个月内
# 如果在限制之前,就筛掉
pass
elif time_limit == '3': # 3是6个月内
# 如果在限制之前,就筛掉
pass
elif time_limit == '4': # 4是1年内
# 如果在限制之前,就筛掉
pass
tmp.append(topic)
topics = tmp
response = {
'topics': topics,
'kinds': kinds,
'kid': kid,
'time_limit': time_limit,
'reply_limit': reply_limit,
'uid': uid,
}
return render(request, 'all.html', response)
elif request.method == 'POST':
# 搜索接收一个字段,查询标题或者简介里有关键字的帖子
keys = request.POST.get('keys')
# 按关键字查询标题里含有关键字的
topics = models.Topic.objects.filter(t_title__icontains=keys)
kinds = models.Kind.objects.filter()
return render(request, 'all.html', {'topics': topics, 'kinds': kinds, 'uid': uid})
def ownpublish(request, kid, reply_limit, time_limit):
uid = request.session.get('uid')
if request.method == 'GET':
kinds = models.Kind.objects.filter()
if kid == '0' and reply_limit == '0' and time_limit == '0':
# 默认时间排序把帖子传过去
topics = models.Topic.objects.filter(t_uid = uid)
else:
# request.path_info # 获取当前url
# from django.urls import reverse
# reverse('all_tie', kwargs={'kid': '0', 'reply_limit': '0', 'time_limit': '0'})
topics = models.Topic.objects.filter(t_uid = uid)
# 筛选分类
if kid != '0':
topics = models.Topic.objects.filter(t_kind=kid,t_uid = uid)
# 筛选回复数量
tmp = []
for topic in topics:
# 查看每个帖子的回复数量
count = len(models.Reply.objects.filter(r_tid=topic.id))
# print(count)
print(reply_limit)
if reply_limit == '0':
pass
elif reply_limit == '1': # 1是大于100
print('到1了')
if count < 100:
print('到了')
continue
elif reply_limit == '2': # 2是30-100
if count < 30 or count > 100:
continue
elif reply_limit == '3': # 3是小于30
if count > 30:
continue
tmp.append(topic)
topics = tmp
print(topics)
# 筛选发布时间
tmp = []
for topic in topics:
if time_limit == '0': # 0是全部时间
pass
elif time_limit == '1': # 1是1个月内
# 如果在限制之前,就筛掉
pass
elif time_limit == '2': # 2是3个月内
# 如果在限制之前,就筛掉
pass
elif time_limit == '3': # 3是6个月内
# 如果在限制之前,就筛掉
pass
elif time_limit == '4': # 4是1年内
# 如果在限制之前,就筛掉
pass
tmp.append(topic)
topics = tmp
response = {
'topics': topics,
'kinds': kinds,
'kid': kid,
'time_limit': time_limit,
'reply_limit': reply_limit,
'uid': uid,
}
return render(request, 'ownpublish.html', response)
elif request.method == 'POST':
type1 = request.POST.get('type1')
if type1 == 'owndelete':
tid = request.POST.get('tid')
# 刪除帖子
response = {'msg': '', 'status': False}
r_id = request.POST.get('r_id')
models.Topic.objects.filter(id=tid).delete()
response['status'] = True
return HttpResponse(json.dumps(response))
else:
# 搜索接收一个字段,查询标题或者简介里有关键字的帖子
keys = request.POST.get('keys')
# 按关键字查询标题里含有关键字的
topics = models.Topic.objects.filter(t_title__icontains=keys,t_uid = uid)
kinds = models.Kind.objects.filter()
return render(request, 'ownpublish.html', {'topics': topics, 'kinds': kinds, 'uid': uid})
# 登录
def login(request):
if request.method == 'GET':
return render(request, 'login.html')
elif request.method == 'POST':
# 验证用户名密码是否正确,然后登陆存入session
type = request.POST.get('type')
response = {'msg': '', 'status': False}
uid = request.POST.get('uid')
pwd = request.POST.get('pwd')
if type == 'login':
if len(models.User.objects.filter(uid=uid, password=pwd)) != 0:
# 登录成功
response['status'] = True
request.session['uid'] = uid
return HttpResponse(json.dumps(response))
pass
else:
# 登录失败
response['msg'] = '用户名或者密码错误'
return HttpResponse(json.dumps(response))
pass
elif type == 'register':
models.User.objects.create(uid=uid, password=pwd)
response['status'] = True
request.session['uid'] = uid
return HttpResponse(json.dumps(response))
# 注册
def register(request):
if request.method == 'POST':
# 判断是否已有
uid = request.POST.get('uid')
pwd = request.POST.get('pwd')
if len(models.User.objects.filter(uid=uid)) != 0:
# 已被创建,返回错误
return render(request, 'login.html', {'message': '用户名已被创建'})
else:
# 插入数据
user = {
'uid': uid,
'password': pwd,
}
models.User.objects.create(**user)
return redirect('/home')
# 发布页
def publish(request):
if request.method == 'GET':
kinds = models.Kind.objects.filter()
response = {
'kinds': kinds
}
return render(request, 'publish.html', response)
elif request.method == 'POST':
# session获取uid
uid = request.session['uid']
# 提交发布的文章
t_title = request.POST.get('t_title')
t_introduce = request.POST.get('t_introduce')
t_content = request.POST.get('t_content')
t_kind = request.POST.get('t_kind')
print(t_title, t_introduce)
obj = models.Topic.objects.create(t_title=t_title, t_introduce=t_introduce,
t_content=t_content, t_kind=t_kind, t_uid=uid)
t_id = obj.id
# 存帖子图片
t_photo = request.FILES.get('t_photo', None)
#t_photo_path = 'static/img/t_photo/' + str(t_id) + '_' + t_photo.name
if t_photo:
t_photo_path = 'static/img/t_photo/' + str(t_id) + '_' + t_photo.name
# 保存文件
import os
f = open(os.path.join(t_photo_path), 'wb')
for line in t_photo.chunks():
f.write(line)
f.close()
else:
t_photo_path = 'static/img/t_photo/' + 'wrong.jpg'
# 吧图片路径存入数据库
models.Topic.objects.filter(id=t_id).update(t_photo='/'+t_photo_path)
return redirect('/single/' + str(t_id))
# 单个帖子页面
def single(request, tid):
if request.method == 'GET':
# 帖子内容
# 时间类别作者,标题,正文,图片path
try:
topic = models.Topic.objects.get(id = tid)
except Exception as e:
return redirect('/home')
t_time = topic.create_time
t_kind = topic.t_kind
# 根据类别 id 获得类别名称
kind = models.Kind.objects.get(id = t_kind)
t_kind = kind.k_name
t_title = topic.t_title
t_content = topic.t_content
t_photo = topic.t_photo
t_uid = topic.t_uid
t_introduce = topic.t_introduce
t_like = topic.t_like
uid = request.session['uid']
admin_uid = request.session.get('admin_uid')
response = {
'tid': tid,
't_uid': t_uid,
't_time': t_time,
't_kind': t_kind,
't_title': t_title,
't_content': t_content,
't_photo': t_photo,
't_introduce': t_introduce,
'uid': uid,
'admin_uid': admin_uid,
't_like':t_like
}
# 留言内容
# 留言者,留言时间,留言内容
replys = models.Reply.objects.filter(r_tid=tid)
reply_list = []
for reply in replys:
single_reply = {
'r_uid': reply.r_uid,
'r_time': reply.r_time,
'r_content': reply.r_content,
'r_id': reply.id,
'r_photo': reply.r_photo,
}
reply_list.append(single_reply)
response['reply_list'] = reply_list
return render(request, 'single.html', response)
elif request.method == 'POST':
type1 = request.POST.get('type1')
if type1 == 'like':
print("here")
tid = request.POST.get('tid')
response = {'msg': '', 'status': False}
# 点赞数量增加 1
orignal_like = models.Topic.objects.get(id=tid).t_like
models.Topic.objects.filter(id=tid).update(t_like=orignal_like + 1)
response['status'] = True
return HttpResponse(json.dumps(response))
# 判断是否登录
uid = request.session.get('uid')
# 删除回复,管理员才可以删除
p_type = request.POST.get('type2')
if p_type == 'delete':
response = {'msg': '', 'status': False}
r_id = request.POST.get('r_id')
uid = request.POST.get('uid')
r_uid = models.Reply.objects.get(id=r_id).r_uid
if uid == r_uid:
models.Reply.objects.filter(id=r_id).delete()
response['status'] = True
return HttpResponse(json.dumps(response))
if not uid:
return redirect('/login')
# 进行回复
r_content = request.POST.get('r_content')
# 提交数据库
obj = models.Reply.objects.create(r_tid=tid,r_uid=uid,r_content=r_content)
r_id = str(obj.id)
r_photo = request.FILES.get('r_photo')
if r_photo:
# 保存文件
r_photo_path = 'static/img/r_photo/' + r_id + '_' + r_photo.name
import os
f = open(os.path.join(r_photo_path), 'wb')
for line in r_photo.chunks():
f.write(line)
f.close()
models.Reply.objects.filter(id=r_id).update(r_photo='/'+r_photo_path)
#else:
#r_photo_path = 'static/img/t_photo/' + 'hungry.png'
# 吧图片路径存入数据库
#models.Reply.objects.filter(id=r_id).update(r_photo='/'+r_photo_path)
return redirect('/single/' + tid)
# 修改密码页面
def edit_pwd(request):
if request.method == 'GET':
uid = request.session.get('uid')
return render(request, 'edit-pwd.html', {'uid': uid})
if request.method == 'POST':
uid = request.session.get('uid')
old = request.POST.get('old_pwd')
new1 = request.POST.get('new_pwd1')
new2 = request.POST.get('new_pwd2')
if new1 == new2 and len(models.User.objects.filter(uid=uid, password=old)) != 0:
# 核对成功,修改密码
models.User.objects.filter(uid=uid).update(password=new1)
return redirect('/home')
# 管理员登录
def admin(request):
if request.method == 'GET':
return render(request, 'admin.html')
elif request.method == 'POST':
admin_uid = request.POST.get('admin_id')
admin_pwd = request.POST.get('admin_pwd')
response = {'msg': '', 'status': False}
if admin_uid == 'guanliyuan' and admin_pwd == '123456':
# 管理员登录成功
response['status'] = True
request.session['admin_uid'] = 'guanliyuan'
return HttpResponse(json.dumps(response))
else:
response['msg'] = '用户名或者密码错误'
return HttpResponse(json.dumps(response))
# 公告管理
def announcement(request):
if not request.session.get('admin_uid'):
return redirect('/my-admin')
# 查询所有公告
if request.method == 'GET':
announcements = models.Announcement.objects.filter()
response = {'announcements': announcements}
return render(request, 'announcement.html', response)
# 发公告,删公告
elif request.method == 'POST':
p_type = request.POST.get('type')
response = {'msg': '', 'status': False}
if p_type == 'delete':
a_id = request.POST.get('a_id')
models.Announcement.objects.filter(id=a_id).delete()
response['status'] = True
elif p_type == 'create':
# 添加一条公告
a_title = request.POST.get('a_title')
a_content = request.POST.get('a_content')
models.Announcement.objects.create(a_title=a_title, a_content=a_content)
response['status'] = True
return HttpResponse(json.dumps(response))
# 帖子管理:标题,简介,时间,
def topic_manage(request):
if not request.session.get('admin_uid'):
return redirect('/my-admin')
if request.method == 'GET':
topics = models.Topic.objects.filter()
response = {
'topics': topics,
}
return render(request, 'admin-home.html', response)
elif request.method == 'POST':
p_type = request.POST.get('type')
response = {'msg': '', 'status': False}
print(p_type)
# 删除帖子
if p_type == 'delete':
t_id = request.POST.get('t_id')
models.Topic.objects.filter(id=t_id).delete()
response['status'] = True
# 置顶(推荐)
if p_type == 'zhiding':
print('置顶')
t_id = request.POST.get('t_id')
models.Topic.objects.filter(id=t_id).update(recommend=True)
response['status'] = True
# 取消置顶(推荐)
if p_type == 'qzhiding':
t_id = request.POST.get('t_id')
models.Topic.objects.filter(id=t_id).update(recommend=False)
response['status'] = True
return HttpResponse(json.dumps(response))
# 类别管理(板块管理)
def kind_manage(request):
# 验证登录
if not request.session.get('admin_uid'):
return redirect('/my-admin')
if request.method == 'GET':
# get返回所有类别(板块)
kinds = models.Kind.objects.filter()
response = {
'kinds': kinds,
}
return render(request, 'kind-manage.html', response)
if request.method == 'POST':
p_type = request.POST.get('type')
response = {'msg': '', 'status': False}
# 删除类别
if p_type == 'delete':
k_id = request.POST.get('k_id')
models.Kind.objects.filter(id=k_id).delete()
response['status'] = True
# 添加类别
if p_type == 'create':
k_name = request.POST.get('k_name')
models.Kind.objects.create(k_name=k_name)
response['status'] = True
return HttpResponse(json.dumps(response))
# 公告页面
def single_an(request, aid):
if request.method == 'GET':
try:
an = models.Announcement.objects.get(id=aid)
except Exception as e:
return '/home'
a_title = an.a_title
a_content = an.a_content
response = {
'a_title': a_title,
'a_content': a_content,
}
return render(request, 'single-an.html', response)

+ 19588
- 0
master/logs/error.log
File diff suppressed because it is too large
View File


+ 15
- 0
master/manage.py View File

@ -0,0 +1,15 @@
#!/usr/bin/env python
import os
import sys
if __name__ == '__main__':
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'ForumSystem.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)

+ 59
- 0
master/requirements.txt View File

@ -0,0 +1,59 @@
appdirs==1.4.4
asgiref==3.3.1
atomicwrites==1.4.0
attrs==20.3.0
Automat==20.2.0
certifi==2020.12.5
cffi==1.14.4
cfgv==3.2.0
chardet==4.0.0
click==7.1.2
codecov==2.1.11
colorama==0.4.4
constantly==15.1.0
coverage==5.3.1
cryptography==3.3.1
cssselect==1.1.0
distlib==0.3.1
Django==3.1.5
filelock==3.0.12
Flask==1.1.2
hyperlink==20.0.1
identify==1.5.10
idna==2.10
incremental==17.5.0
iniconfig==1.1.1
itemadapter==0.2.0
itsdangerous==1.1.0
Jinja2==2.11.2
jmespath==0.10.0
lxml==4.6.2
MarkupSafe==1.1.1
nodeenv==1.5.0
packaging==20.8
parsel==1.6.0
pluggy==0.13.1
pre-commit==2.9.3
psycopg2==2.8.6
py==1.10.0
pyasn1==0.4.8
pyasn1-modules==0.2.8
pycparser==2.20
PyHamcrest==2.0.2
PyJWT==2.0.0
PyMySQL==0.10.1
pyparsing==2.4.7
pytest==6.2.1
pytz==2020.5
PyYAML==5.3.1
requests==2.25.1
simplejson==3.17.2
six==1.15.0
SQLAlchemy==1.3.22
sqlparse==0.4.1
toml==0.10.2
urllib3==1.26.2
virtualenv==20.2.2
w3lib==1.22.0
Werkzeug==1.0.1
zope.interface==5.2.0

BIN
master/static/.DS_Store View File


+ 260
- 0
master/static/admin/css/autocomplete.css View File

@ -0,0 +1,260 @@
select.admin-autocomplete {
width: 20em;
}
.select2-container--admin-autocomplete.select2-container {
min-height: 30px;
}
.select2-container--admin-autocomplete .select2-selection--single,
.select2-container--admin-autocomplete .select2-selection--multiple {
min-height: 30px;
padding: 0;
}
.select2-container--admin-autocomplete.select2-container--focus .select2-selection,
.select2-container--admin-autocomplete.select2-container--open .select2-selection {
border-color: #999;
min-height: 30px;
}
.select2-container--admin-autocomplete.select2-container--focus .select2-selection.select2-selection--single,
.select2-container--admin-autocomplete.select2-container--open .select2-selection.select2-selection--single {
padding: 0;
}
.select2-container--admin-autocomplete.select2-container--focus .select2-selection.select2-selection--multiple,
.select2-container--admin-autocomplete.select2-container--open .select2-selection.select2-selection--multiple {
padding: 0;
}
.select2-container--admin-autocomplete .select2-selection--single {
background-color: #fff;
border: 1px solid #ccc;
border-radius: 4px;
}
.select2-container--admin-autocomplete .select2-selection--single .select2-selection__rendered {
color: #444;
line-height: 30px;
}
.select2-container--admin-autocomplete .select2-selection--single .select2-selection__clear {
cursor: pointer;
float: right;
font-weight: bold;
}
.select2-container--admin-autocomplete .select2-selection--single .select2-selection__placeholder {
color: #999;
}
.select2-container--admin-autocomplete .select2-selection--single .select2-selection__arrow {
height: 26px;
position: absolute;
top: 1px;
right: 1px;
width: 20px;
}
.select2-container--admin-autocomplete .select2-selection--single .select2-selection__arrow b {
border-color: #888 transparent transparent transparent;
border-style: solid;
border-width: 5px 4px 0 4px;
height: 0;
left: 50%;
margin-left: -4px;
margin-top: -2px;
position: absolute;
top: 50%;
width: 0;
}
.select2-container--admin-autocomplete[dir="rtl"] .select2-selection--single .select2-selection__clear {
float: left;
}
.select2-container--admin-autocomplete[dir="rtl"] .select2-selection--single .select2-selection__arrow {
left: 1px;
right: auto;
}
.select2-container--admin-autocomplete.select2-container--disabled .select2-selection--single {
background-color: #eee;
cursor: default;
}
.select2-container--admin-autocomplete.select2-container--disabled .select2-selection--single .select2-selection__clear {
display: none;
}
.select2-container--admin-autocomplete.select2-container--open .select2-selection--single .select2-selection__arrow b {
border-color: transparent transparent #888 transparent;
border-width: 0 4px 5px 4px;
}
.select2-container--admin-autocomplete .select2-selection--multiple {
background-color: white;
border: 1px solid #ccc;
border-radius: 4px;
cursor: text;
}
.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__rendered {
box-sizing: border-box;
list-style: none;
margin: 0;
padding: 0 5px;
width: 100%;
}
.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__rendered li {
list-style: none;
}
.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__placeholder {
color: #999;
margin-top: 5px;
float: left;
}
.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__clear {
cursor: pointer;
float: right;
font-weight: bold;
margin: 5px;
}
.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__choice {
background-color: #e4e4e4;
border: 1px solid #ccc;
border-radius: 4px;
cursor: default;
float: left;
margin-right: 5px;
margin-top: 5px;
padding: 0 5px;
}
.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__choice__remove {
color: #999;
cursor: pointer;
display: inline-block;
font-weight: bold;
margin-right: 2px;
}
.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__choice__remove:hover {
color: #333;
}
.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 {
float: right;
}
.select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
margin-left: 5px;
margin-right: auto;
}
.select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove {
margin-left: 2px;
margin-right: auto;
}
.select2-container--admin-autocomplete.select2-container--focus .select2-selection--multiple {
border: solid #999 1px;
outline: 0;
}
.select2-container--admin-autocomplete.select2-container--disabled .select2-selection--multiple {
background-color: #eee;
cursor: default;
}
.select2-container--admin-autocomplete.select2-container--disabled .select2-selection__choice__remove {
display: none;
}
.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 {
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.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 {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
.select2-container--admin-autocomplete .select2-search--dropdown .select2-search__field {
border: 1px solid #ccc;
}
.select2-container--admin-autocomplete .select2-search--inline .select2-search__field {
background: transparent;
border: none;
outline: 0;
box-shadow: none;
-webkit-appearance: textfield;
}
.select2-container--admin-autocomplete .select2-results > .select2-results__options {
max-height: 200px;
overflow-y: auto;
}
.select2-container--admin-autocomplete .select2-results__option[role=group] {
padding: 0;
}
.select2-container--admin-autocomplete .select2-results__option[aria-disabled=true] {
color: #999;
}
.select2-container--admin-autocomplete .select2-results__option[aria-selected=true] {
background-color: #ddd;
}
.select2-container--admin-autocomplete .select2-results__option .select2-results__option {
padding-left: 1em;
}
.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__group {
padding-left: 0;
}
.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option {
margin-left: -1em;
padding-left: 2em;
}
.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -2em;
padding-left: 3em;
}
.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -3em;
padding-left: 4em;
}
.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -4em;
padding-left: 5em;
}
.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 {
margin-left: -5em;
padding-left: 6em;
}
.select2-container--admin-autocomplete .select2-results__option--highlighted[aria-selected] {
background-color: #79aec8;
color: white;
}
.select2-container--admin-autocomplete .select2-results__group {
cursor: default;
display: block;
padding: 6px;
}

+ 966
- 0
master/static/admin/css/base.css View File

@ -0,0 +1,966 @@
/*
DJANGO Admin styles
*/
@import url(fonts.css);
html, body {
height: 100%;
}
body {
margin: 0;
padding: 0;
font-size: 14px;
font-family: "Roboto","Lucida Grande","DejaVu Sans","Bitstream Vera Sans",Verdana,Arial,sans-serif;
color: #333;
background: #fff;
}
/* LINKS */
a:link, a:visited {
color: #447e9b;
text-decoration: none;
}
a:focus, a:hover {
color: #036;
}
a:focus {
text-decoration: underline;
}
a img {
border: none;
}
a.section:link, a.section:visited {
color: #fff;
text-decoration: none;
}
a.section:focus, a.section:hover {
text-decoration: underline;
}
/* GLOBAL DEFAULTS */
p, ol, ul, dl {
margin: .2em 0 .8em 0;
}
p {
padding: 0;
line-height: 140%;
}
h1,h2,h3,h4,h5 {
font-weight: bold;
}
h1 {
margin: 0 0 20px;
font-weight: 300;
font-size: 20px;
color: #666;
}
h2 {
font-size: 16px;
margin: 1em 0 .5em 0;
}
h2.subhead {
font-weight: normal;
margin-top: 0;
}
h3 {
font-size: 14px;
margin: .8em 0 .3em 0;
color: #666;
font-weight: bold;
}
h4 {
font-size: 12px;
margin: 1em 0 .8em 0;
padding-bottom: 3px;
}
h5 {
font-size: 10px;
margin: 1.5em 0 .5em 0;
color: #666;
text-transform: uppercase;
letter-spacing: 1px;
}
ul > li {
list-style-type: square;
padding: 1px 0;
}
li ul {
margin-bottom: 0;
}
li, dt, dd {
font-size: 13px;
line-height: 20px;
}
dt {
font-weight: bold;
margin-top: 4px;
}
dd {
margin-left: 0;
}
form {
margin: 0;
padding: 0;
}
fieldset {
margin: 0;
min-width: 0;
padding: 0;
border: none;
border-top: 1px solid #eee;
}
blockquote {
font-size: 11px;
color: #777;
margin-left: 2px;
padding-left: 10px;
border-left: 5px solid #ddd;
}
code, pre {
font-family: "Bitstream Vera Sans Mono", Monaco, "Courier New", Courier, monospace;
color: #666;
font-size: 12px;
overflow-x: auto;
}
pre.literal-block {
margin: 10px;
background: #eee;
padding: 6px 8px;
}
code strong {
color: #930;
}
hr {
clear: both;
color: #eee;
background-color: #eee;
height: 1px;
border: none;
margin: 0;
padding: 0;
font-size: 1px;
line-height: 1px;
}
/* TEXT STYLES & MODIFIERS */
.small {
font-size: 11px;
}
.mini {
font-size: 10px;
}
.help, p.help, form p.help, div.help, form div.help, div.help li {
font-size: 11px;
color: #999;
}
div.help ul {
margin-bottom: 0;
}
.help-tooltip {
cursor: help;
}
p img, h1 img, h2 img, h3 img, h4 img, td img {
vertical-align: middle;
}
.quiet, a.quiet:link, a.quiet:visited {
color: #999;
font-weight: normal;
}
.clear {
clear: both;
}
.nowrap {
white-space: nowrap;
}
/* TABLES */
table {
border-collapse: collapse;
border-color: #ccc;
}
td, th {
font-size: 13px;
line-height: 16px;
border-bottom: 1px solid #eee;
vertical-align: top;
padding: 8px;
font-family: "Roboto", "Lucida Grande", Verdana, Arial, sans-serif;
}
th {
font-weight: 600;
text-align: left;
}
thead th,
tfoot td {
color: #666;
padding: 5px 10px;
font-size: 11px;
background: #fff;
border: none;
border-top: 1px solid #eee;
border-bottom: 1px solid #eee;
}
tfoot td {
border-bottom: none;
border-top: 1px solid #eee;
}
thead th.required {
color: #000;
}
tr.alt {
background: #f6f6f6;
}
tr:nth-child(odd), .row-form-errors {
background: #fff;
}
tr:nth-child(even),
tr:nth-child(even) .errorlist,
tr:nth-child(odd) + .row-form-errors,
tr:nth-child(odd) + .row-form-errors .errorlist {
background: #f9f9f9;
}
/* SORTABLE TABLES */
thead th {
padding: 5px 10px;
line-height: normal;
text-transform: uppercase;
background: #f6f6f6;
}
thead th a:link, thead th a:visited {
color: #666;
}
thead th.sorted {
background: #eee;
}
thead th.sorted .text {
padding-right: 42px;
}
table thead th .text span {
padding: 8px 10px;
display: block;
}
table thead th .text a {
display: block;
cursor: pointer;
padding: 8px 10px;
}
table thead th .text a:focus, table thead th .text a:hover {
background: #eee;
}
thead th.sorted a.sortremove {
visibility: hidden;
}
table thead th.sorted:hover a.sortremove {
visibility: visible;
}
table thead th.sorted .sortoptions {
display: block;
padding: 9px 5px 0 5px;
float: right;
text-align: right;
}
table thead th.sorted .sortpriority {
font-size: .8em;
min-width: 12px;
text-align: center;
vertical-align: 3px;
margin-left: 2px;
margin-right: 2px;
}
table thead th.sorted .sortoptions a {
position: relative;
width: 14px;
height: 14px;
display: inline-block;
background: url(../img/sorting-icons.svg) 0 0 no-repeat;
background-size: 14px auto;
}
table thead th.sorted .sortoptions a.sortremove {
background-position: 0 0;
}
table thead th.sorted .sortoptions a.sortremove:after {
content: '\\';
position: absolute;
top: -6px;
left: 3px;
font-weight: 200;
font-size: 18px;
color: #999;
}
table thead th.sorted .sortoptions a.sortremove:focus:after,
table thead th.sorted .sortoptions a.sortremove:hover:after {
color: #447e9b;
}
table thead th.sorted .sortoptions a.sortremove:focus,
table thead th.sorted .sortoptions a.sortremove:hover {
background-position: 0 -14px;
}
table thead th.sorted .sortoptions a.ascending {
background-position: 0 -28px;
}
table thead th.sorted .sortoptions a.ascending:focus,
table thead th.sorted .sortoptions a.ascending:hover {
background-position: 0 -42px;
}
table thead th.sorted .sortoptions a.descending {
top: 1px;
background-position: 0 -56px;
}
table thead th.sorted .sortoptions a.descending:focus,
table thead th.sorted .sortoptions a.descending:hover {
background-position: 0 -70px;
}
/* FORM DEFAULTS */
input, textarea, select, .form-row p, form .button {
margin: 2px 0;
padding: 2px 3px;
vertical-align: middle;
font-family: "Roboto", "Lucida Grande", Verdana, Arial, sans-serif;
font-weight: normal;
font-size: 13px;
}
.form-row div.help {
padding: 2px 3px;
}
textarea {
vertical-align: top;
}
input[type=text], input[type=password], input[type=email], input[type=url],
input[type=number], input[type=tel], textarea, select, .vTextField {
border: 1px solid #ccc;
border-radius: 4px;
padding: 5px 6px;
margin-top: 0;
}
input[type=text]:focus, input[type=password]:focus, input[type=email]:focus,
input[type=url]:focus, input[type=number]:focus, input[type=tel]:focus,
textarea:focus, select:focus, .vTextField:focus {
border-color: #999;
}
select {
height: 30px;
}
select[multiple] {
/* Allow HTML size attribute to override the height in the rule above. */
height: auto;
min-height: 150px;
}
/* FORM BUTTONS */
.button, input[type=submit], input[type=button], .submit-row input, a.button {
background: #79aec8;
padding: 10px 15px;
border: none;
border-radius: 4px;
color: #fff;
cursor: pointer;
}
a.button {
padding: 4px 5px;
}
.button:active, input[type=submit]:active, input[type=button]:active,
.button:focus, input[type=submit]:focus, input[type=button]:focus,
.button:hover, input[type=submit]:hover, input[type=button]:hover {
background: #609ab6;
}
.button[disabled], input[type=submit][disabled], input[type=button][disabled] {
opacity: 0.4;
}
.button.default, input[type=submit].default, .submit-row input.default {
float: right;
border: none;
font-weight: 400;
background: #417690;
}
.button.default:active, input[type=submit].default:active,
.button.default:focus, input[type=submit].default:focus,
.button.default:hover, input[type=submit].default:hover {
background: #205067;
}
.button[disabled].default,
input[type=submit][disabled].default,
input[type=button][disabled].default {
opacity: 0.4;
}
/* MODULES */
.module {
border: none;
margin-bottom: 30px;
background: #fff;
}
.module p, .module ul, .module h3, .module h4, .module dl, .module pre {
padding-left: 10px;
padding-right: 10px;
}
.module blockquote {
margin-left: 12px;
}
.module ul, .module ol {
margin-left: 1.5em;
}
.module h3 {
margin-top: .6em;
}
.module h2, .module caption, .inline-group h2 {
margin: 0;
padding: 8px;
font-weight: 400;
font-size: 13px;
text-align: left;
background: #79aec8;
color: #fff;
}
.module caption,
.inline-group h2 {
font-size: 12px;
letter-spacing: 0.5px;
text-transform: uppercase;
}
.module table {
border-collapse: collapse;
}
/* MESSAGES & ERRORS */
ul.messagelist {
padding: 0;
margin: 0;
}
ul.messagelist li {
display: block;
font-weight: 400;
font-size: 13px;
padding: 10px 10px 10px 65px;
margin: 0 0 10px 0;
background: #dfd url(../img/icon-yes.svg) 40px 12px no-repeat;
background-size: 16px auto;
color: #333;
}
ul.messagelist li.warning {
background: #ffc url(../img/icon-alert.svg) 40px 14px no-repeat;
background-size: 14px auto;
}
ul.messagelist li.error {
background: #ffefef url(../img/icon-no.svg) 40px 12px no-repeat;
background-size: 16px auto;
}
.errornote {
font-size: 14px;
font-weight: 700;
display: block;
padding: 10px 12px;
margin: 0 0 10px 0;
color: #ba2121;
border: 1px solid #ba2121;
border-radius: 4px;
background-color: #fff;
background-position: 5px 12px;
}
ul.errorlist {
margin: 0 0 4px;
padding: 0;
color: #ba2121;
background: #fff;
}
ul.errorlist li {
font-size: 13px;
display: block;
margin-bottom: 4px;
}
ul.errorlist li:first-child {
margin-top: 0;
}
ul.errorlist li a {
color: inherit;
text-decoration: underline;
}
td ul.errorlist {
margin: 0;
padding: 0;
}
td ul.errorlist li {
margin: 0;
}
.form-row.errors {
margin: 0;
border: none;
border-bottom: 1px solid #eee;
background: none;
}
.form-row.errors ul.errorlist li {
padding-left: 0;
}
.errors input, .errors select, .errors textarea,
td ul.errorlist + input, td ul.errorlist + select, td ul.errorlist + textarea {
border: 1px solid #ba2121;
}
.description {
font-size: 12px;
padding: 5px 0 0 12px;
}
/* BREADCRUMBS */
div.breadcrumbs {
background: #79aec8;
padding: 10px 40px;
border: none;
font-size: 14px;
color: #c4dce8;
text-align: left;
}
div.breadcrumbs a {
color: #fff;
}
div.breadcrumbs a:focus, div.breadcrumbs a:hover {
color: #c4dce8;
}
/* ACTION ICONS */
.viewlink, .inlineviewlink {
padding-left: 16px;
background: url(../img/icon-viewlink.svg) 0 1px no-repeat;
}
.addlink {
padding-left: 16px;
background: url(../img/icon-addlink.svg) 0 1px no-repeat;
}
.changelink, .inlinechangelink {
padding-left: 16px;
background: url(../img/icon-changelink.svg) 0 1px no-repeat;
}
.deletelink {
padding-left: 16px;
background: url(../img/icon-deletelink.svg) 0 1px no-repeat;
}
a.deletelink:link, a.deletelink:visited {
color: #CC3434;
}
a.deletelink:focus, a.deletelink:hover {
color: #993333;
text-decoration: none;
}
/* OBJECT TOOLS */
.object-tools {
font-size: 10px;
font-weight: bold;
padding-left: 0;
float: right;
position: relative;
margin-top: -48px;
}
.form-row .object-tools {
margin-top: 5px;
margin-bottom: 5px;
float: none;
height: 2em;
padding-left: 3.5em;
}
.object-tools li {
display: block;
float: left;
margin-left: 5px;
height: 16px;
}
.object-tools a {
border-radius: 15px;
}
.object-tools a:link, .object-tools a:visited {
display: block;
float: left;
padding: 3px 12px;
background: #999;
font-weight: 400;
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.5px;
color: #fff;
}
.object-tools a:focus, .object-tools a:hover {
background-color: #417690;
}
.object-tools a:focus{
text-decoration: none;
}
.object-tools a.viewsitelink, .object-tools a.golink,.object-tools a.addlink {
background-repeat: no-repeat;
background-position: right 7px center;
padding-right: 26px;
}
.object-tools a.viewsitelink, .object-tools a.golink {
background-image: url(../img/tooltag-arrowright.svg);
}
.object-tools a.addlink {
background-image: url(../img/tooltag-add.svg);
}
/* OBJECT HISTORY */
table#change-history {
width: 100%;
}
table#change-history tbody th {
width: 16em;
}
/* PAGE STRUCTURE */
#container {
position: relative;
width: 100%;
min-width: 980px;
padding: 0;
display: flex;
flex-direction: column;
height: 100%;
}
#container > div {
flex-shrink: 0;
}
#container > .main {
display: flex;
flex: 1 0 auto;
}
.main > .content {
flex: 1 0;
max-width: 100%;
}
#content {
padding: 20px 40px;
}
.dashboard #content {
width: 600px;
}
#content-main {
float: left;
width: 100%;
}
#content-related {
float: right;
width: 260px;
position: relative;
margin-right: -300px;
}
#footer {
clear: both;
padding: 10px;
}
/* COLUMN TYPES */
.colMS {
margin-right: 300px;
}
.colSM {
margin-left: 300px;
}
.colSM #content-related {
float: left;
margin-right: 0;
margin-left: -300px;
}
.colSM #content-main {
float: right;
}
.popup .colM {
width: auto;
}
/* HEADER */
#header {
width: auto;
height: auto;
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 40px;
background: #417690;
color: #ffc;
overflow: hidden;
}
#header a:link, #header a:visited {
color: #fff;
}
#header a:focus , #header a:hover {
text-decoration: underline;
}
#branding {
float: left;
}
#branding h1 {
padding: 0;
margin: 0 20px 0 0;
font-weight: 300;
font-size: 24px;
color: #f5dd5d;
}
#branding h1, #branding h1 a:link, #branding h1 a:visited {
color: #f5dd5d;
}
#branding h2 {
padding: 0 10px;
font-size: 14px;
margin: -8px 0 8px 0;
font-weight: normal;
color: #ffc;
}
#branding a:hover {
text-decoration: none;
}
#user-tools {
float: right;
padding: 0;
margin: 0 0 0 20px;
font-weight: 300;
font-size: 11px;
letter-spacing: 0.5px;
text-transform: uppercase;
text-align: right;
}
#user-tools a {
border-bottom: 1px solid rgba(255, 255, 255, 0.25);
}
#user-tools a:focus, #user-tools a:hover {
text-decoration: none;
border-bottom-color: #79aec8;
color: #79aec8;
}
/* SIDEBAR */
#content-related {
background: #f8f8f8;
}
#content-related .module {
background: none;
}
#content-related h3 {
font-size: 14px;
color: #666;
padding: 0 16px;
margin: 0 0 16px;
}
#content-related h4 {
font-size: 13px;
}
#content-related p {
padding-left: 16px;
padding-right: 16px;
}
#content-related .actionlist {
padding: 0;
margin: 16px;
}
#content-related .actionlist li {
line-height: 1.2;
margin-bottom: 10px;
padding-left: 18px;
}
#content-related .module h2 {
background: none;
padding: 16px;
margin-bottom: 16px;
border-bottom: 1px solid #eaeaea;
font-size: 18px;
color: #333;
}
.delete-confirmation form input[type="submit"] {
background: #ba2121;
border-radius: 4px;
padding: 10px 15px;
color: #fff;
}
.delete-confirmation form input[type="submit"]:active,
.delete-confirmation form input[type="submit"]:focus,
.delete-confirmation form input[type="submit"]:hover {
background: #a41515;
}
.delete-confirmation form .cancel-link {
display: inline-block;
vertical-align: middle;
height: 15px;
line-height: 15px;
background: #ddd;
border-radius: 4px;
padding: 10px 15px;
color: #333;
margin: 0 0 0 10px;
}
.delete-confirmation form .cancel-link:active,
.delete-confirmation form .cancel-link:focus,
.delete-confirmation form .cancel-link:hover {
background: #ccc;
}
/* POPUP */
.popup #content {
padding: 20px;
}
.popup #container {
min-width: 0;
}
.popup #header {
padding: 10px 20px;
}

+ 354
- 0
master/static/admin/css/changelists.css View File

@ -0,0 +1,354 @@
/* CHANGELISTS */
#changelist {
display: flex;
align-items: flex-start;
justify-content: space-between;
}
#changelist .changelist-form-container {
flex: 1 1 auto;
min-width: 0;
}
#changelist table {
width: 100%;
}
.change-list .hiddenfields { display:none; }
.change-list .filtered table {
border-right: none;
}
.change-list .filtered {
min-height: 400px;
}
.change-list .filtered .results, .change-list .filtered .paginator,
.filtered #toolbar, .filtered div.xfull {
width: auto;
}
.change-list .filtered table tbody th {
padding-right: 1em;
}
#changelist-form .results {
overflow-x: auto;
width: 100%;
}
#changelist .toplinks {
border-bottom: 1px solid #ddd;
}
#changelist .paginator {
color: #666;
border-bottom: 1px solid #eee;
background: #fff;
overflow: hidden;
}
/* CHANGELIST TABLES */
#changelist table thead th {
padding: 0;
white-space: nowrap;
vertical-align: middle;
}
#changelist table thead th.action-checkbox-column {
width: 1.5em;
text-align: center;
}
#changelist table tbody td.action-checkbox {
text-align: center;
}
#changelist table tfoot {
color: #666;
}
/* TOOLBAR */
#toolbar {
padding: 8px 10px;
margin-bottom: 15px;
border-top: 1px solid #eee;
border-bottom: 1px solid #eee;
background: #f8f8f8;
color: #666;
}
#toolbar form input {
border-radius: 4px;
font-size: 14px;
padding: 5px;
color: #333;
}
#toolbar #searchbar {
height: 19px;
border: 1px solid #ccc;
padding: 2px 5px;
margin: 0;
vertical-align: top;
font-size: 13px;
max-width: 100%;
}
#toolbar #searchbar:focus {
border-color: #999;
}
#toolbar form input[type="submit"] {
border: 1px solid #ccc;
font-size: 13px;
padding: 4px 8px;
margin: 0;
vertical-align: middle;
background: #fff;
box-shadow: 0 -15px 20px -10px rgba(0, 0, 0, 0.15) inset;
cursor: pointer;
color: #333;
}
#toolbar form input[type="submit"]:focus,
#toolbar form input[type="submit"]:hover {
border-color: #999;
}
#changelist-search img {
vertical-align: middle;
margin-right: 4px;
}
/* FILTER COLUMN */
#changelist-filter {
order: 1;
width: 240px;
background: #f8f8f8;
border-left: none;
margin: 0 0 0 30px;
}
#changelist-filter h2 {
font-size: 14px;
text-transform: uppercase;
letter-spacing: 0.5px;
padding: 5px 15px;
margin-bottom: 12px;
border-bottom: none;
}
#changelist-filter h3 {
font-weight: 400;
font-size: 14px;
padding: 0 15px;
margin-bottom: 10px;
}
#changelist-filter ul {
margin: 5px 0;
padding: 0 15px 15px;
border-bottom: 1px solid #eaeaea;
}
#changelist-filter ul:last-child {
border-bottom: none;
}
#changelist-filter li {
list-style-type: none;
margin-left: 0;
padding-left: 0;
}
#changelist-filter a {
display: block;
color: #999;
text-overflow: ellipsis;
overflow-x: hidden;
}
#changelist-filter li.selected {
border-left: 5px solid #eaeaea;
padding-left: 10px;
margin-left: -15px;
}
#changelist-filter li.selected a {
color: #5b80b2;
}
#changelist-filter a:focus, #changelist-filter a:hover,
#changelist-filter li.selected a:focus,
#changelist-filter li.selected a:hover {
color: #036;
}
#changelist-filter #changelist-filter-clear a {
font-size: 13px;
padding-bottom: 10px;
border-bottom: 1px solid #eaeaea;
}
/* DATE DRILLDOWN */
.change-list ul.toplinks {
display: block;
float: left;
padding: 0;
margin: 0;
width: 100%;
}
.change-list ul.toplinks li {
padding: 3px 6px;
font-weight: bold;
list-style-type: none;
display: inline-block;
}
.change-list ul.toplinks .date-back a {
color: #999;
}
.change-list ul.toplinks .date-back a:focus,
.change-list ul.toplinks .date-back a:hover {
color: #036;
}
/* PAGINATOR */
.paginator {
font-size: 13px;
padding-top: 10px;
padding-bottom: 10px;
line-height: 22px;
margin: 0;
border-top: 1px solid #ddd;
width: 100%;
}
.paginator a:link, .paginator a:visited {
padding: 2px 6px;
background: #79aec8;
text-decoration: none;
color: #fff;
}
.paginator a.showall {
border: none;
background: none;
color: #5b80b2;
}
.paginator a.showall:focus, .paginator a.showall:hover {
background: none;
color: #036;
}
.paginator .end {
margin-right: 6px;
}
.paginator .this-page {
padding: 2px 6px;
font-weight: bold;
font-size: 13px;
vertical-align: top;
}
.paginator a:focus, .paginator a:hover {
color: white;
background: #036;
}
/* ACTIONS */
.filtered .actions {
border-right: none;
}
#changelist table input {
margin: 0;
vertical-align: baseline;
}
#changelist table tbody tr.selected {
background-color: #FFFFCC;
}
#changelist .actions {
padding: 10px;
background: #fff;
border-top: none;
border-bottom: none;
line-height: 24px;
color: #999;
width: 100%;
}
#changelist .actions.selected {
background: #fffccf;
border-top: 1px solid #fffee8;
border-bottom: 1px solid #edecd6;
}
#changelist .actions span.all,
#changelist .actions span.action-counter,
#changelist .actions span.clear,
#changelist .actions span.question {
font-size: 13px;
margin: 0 0.5em;
display: none;
}
#changelist .actions:last-child {
border-bottom: none;
}
#changelist .actions select {
vertical-align: top;
height: 24px;
background: none;
color: #000;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 14px;
padding: 0 0 0 4px;
margin: 0;
margin-left: 10px;
}
#changelist .actions select:focus {
border-color: #999;
}
#changelist .actions label {
display: inline-block;
vertical-align: middle;
font-size: 13px;
}
#changelist .actions .button {
font-size: 13px;
border: 1px solid #ccc;
border-radius: 4px;
background: #fff;
box-shadow: 0 -15px 20px -10px rgba(0, 0, 0, 0.15) inset;
cursor: pointer;
height: 24px;
line-height: 1;
padding: 4px 8px;
margin: 0;
color: #333;
}
#changelist .actions .button:focus, #changelist .actions .button:hover {
border-color: #999;
}

+ 26
- 0
master/static/admin/css/dashboard.css View File

@ -0,0 +1,26 @@
/* DASHBOARD */
.dashboard .module table th {
width: 100%;
}
.dashboard .module table td {
white-space: nowrap;
}
.dashboard .module table td a {
display: block;
padding-right: .6em;
}
/* RECENT ACTIONS MODULE */
.module ul.actionlist {
margin-left: 0;
}
ul.actionlist li {
list-style-type: none;
overflow: hidden;
text-overflow: ellipsis;
}

+ 20
- 0
master/static/admin/css/fonts.css View File

@ -0,0 +1,20 @@
@font-face {
font-family: 'Roboto';
src: url('../fonts/Roboto-Bold-webfont.woff');
font-weight: 700;
font-style: normal;
}
@font-face {
font-family: 'Roboto';
src: url('../fonts/Roboto-Regular-webfont.woff');
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'Roboto';
src: url('../fonts/Roboto-Light-webfont.woff');
font-weight: 300;
font-style: normal;
}

+ 527
- 0
master/static/admin/css/forms.css View File

@ -0,0 +1,527 @@
@import url('widgets.css');
/* FORM ROWS */
.form-row {
overflow: hidden;
padding: 10px;
font-size: 13px;
border-bottom: 1px solid #eee;
}
.form-row img, .form-row input {
vertical-align: middle;
}
.form-row label input[type="checkbox"] {
margin-top: 0;
vertical-align: 0;
}
form .form-row p {
padding-left: 0;
}
.hidden {
display: none;
}
/* FORM LABELS */
label {
font-weight: normal;
color: #666;
font-size: 13px;
}
.required label, label.required {
font-weight: bold;
color: #333;
}
/* RADIO BUTTONS */
form ul.radiolist li {
list-style-type: none;
}
form ul.radiolist label {
float: none;
display: inline;
}
form ul.radiolist input[type="radio"] {
margin: -2px 4px 0 0;
padding: 0;
}
form ul.inline {
margin-left: 0;
padding: 0;
}
form ul.inline li {
float: left;
padding-right: 7px;
}
/* ALIGNED FIELDSETS */
.aligned label {
display: block;
padding: 4px 10px 0 0;
float: left;
width: 160px;
word-wrap: break-word;
line-height: 1;
}
.aligned label:not(.vCheckboxLabel):after {
content: '';
display: inline-block;
vertical-align: middle;
height: 26px;
}
.aligned label + p, .aligned label + div.help, .aligned label + div.readonly {
padding: 6px 0;
margin-top: 0;
margin-bottom: 0;
margin-left: 170px;
}
.aligned ul label {
display: inline;
float: none;
width: auto;
}
.aligned .form-row input {
margin-bottom: 0;
}
.colMS .aligned .vLargeTextField, .colMS .aligned .vXMLLargeTextField {
width: 350px;
}
form .aligned ul {
margin-left: 160px;
padding-left: 10px;
}
form .aligned ul.radiolist {
display: inline-block;
margin: 0;
padding: 0;
}
form .aligned p.help,
form .aligned div.help {
clear: left;
margin-top: 0;
margin-left: 160px;
padding-left: 10px;
}
form .aligned label + p.help,
form .aligned label + div.help {
margin-left: 0;
padding-left: 0;
}
form .aligned p.help:last-child,
form .aligned div.help:last-child {
margin-bottom: 0;
padding-bottom: 0;
}
form .aligned input + p.help,
form .aligned textarea + p.help,
form .aligned select + p.help,
form .aligned input + div.help,
form .aligned textarea + div.help,
form .aligned select + div.help {
margin-left: 160px;
padding-left: 10px;
}
form .aligned ul li {
list-style: none;
}
form .aligned table p {
margin-left: 0;
padding-left: 0;
}
.aligned .vCheckboxLabel {
float: none;
width: auto;
display: inline-block;
vertical-align: -3px;
padding: 0 0 5px 5px;
}
.aligned .vCheckboxLabel + p.help,
.aligned .vCheckboxLabel + div.help {
margin-top: -4px;
}
.colM .aligned .vLargeTextField, .colM .aligned .vXMLLargeTextField {
width: 610px;
}
.checkbox-row p.help,
.checkbox-row div.help {
margin-left: 0;
padding-left: 0;
}
fieldset .fieldBox {
float: left;
margin-right: 20px;
}
/* WIDE FIELDSETS */
.wide label {
width: 200px;
}
form .wide p,
form .wide input + p.help,
form .wide input + div.help {
margin-left: 200px;
}
form .wide p.help,
form .wide div.help {
padding-left: 38px;
}
form div.help ul {
padding-left: 0;
margin-left: 0;
}
.colM fieldset.wide .vLargeTextField, .colM fieldset.wide .vXMLLargeTextField {
width: 450px;
}
/* COLLAPSED FIELDSETS */
fieldset.collapsed * {
display: none;
}
fieldset.collapsed h2, fieldset.collapsed {
display: block;
}
fieldset.collapsed {
border: 1px solid #eee;
border-radius: 4px;
overflow: hidden;
}
fieldset.collapsed h2 {
background: #f8f8f8;
color: #666;
}
fieldset .collapse-toggle {
color: #fff;
}
fieldset.collapsed .collapse-toggle {
background: transparent;
display: inline;
color: #447e9b;
}
/* MONOSPACE TEXTAREAS */
fieldset.monospace textarea {
font-family: "Bitstream Vera Sans Mono", Monaco, "Courier New", Courier, monospace;
}
/* SUBMIT ROW */
.submit-row {
padding: 12px 14px;
margin: 0 0 20px;
background: #f8f8f8;
border: 1px solid #eee;
border-radius: 4px;
text-align: right;
overflow: hidden;
}
body.popup .submit-row {
overflow: auto;
}
.submit-row input {
height: 35px;
line-height: 15px;
margin: 0 0 0 5px;
}
.submit-row input.default {
margin: 0 0 0 8px;
text-transform: uppercase;
}
.submit-row p {
margin: 0.3em;
}
.submit-row p.deletelink-box {
float: left;
margin: 0;
}
.submit-row a.deletelink {
display: block;
background: #ba2121;
border-radius: 4px;
padding: 10px 15px;
height: 15px;
line-height: 15px;
color: #fff;
}
.submit-row a.closelink {
display: inline-block;
background: #bbbbbb;
border-radius: 4px;
padding: 10px 15px;
height: 15px;
line-height: 15px;
margin: 0 0 0 5px;
color: #fff;
}
.submit-row a.deletelink:focus,
.submit-row a.deletelink:hover,
.submit-row a.deletelink:active {
background: #a41515;
}
.submit-row a.closelink:focus,
.submit-row a.closelink:hover,
.submit-row a.closelink:active {
background: #aaaaaa;
}
/* CUSTOM FORM FIELDS */
.vSelectMultipleField {
vertical-align: top;
}
.vCheckboxField {
border: none;
}
.vDateField, .vTimeField {
margin-right: 2px;
margin-bottom: 4px;
}
.vDateField {
min-width: 6.85em;
}
.vTimeField {
min-width: 4.7em;
}
.vURLField {
width: 30em;
}
.vLargeTextField, .vXMLLargeTextField {
width: 48em;
}
.flatpages-flatpage #id_content {
height: 40.2em;
}
.module table .vPositiveSmallIntegerField {
width: 2.2em;
}
.vTextField, .vUUIDField {
width: 20em;
}
.vIntegerField {
width: 5em;
}
.vBigIntegerField {
width: 10em;
}
.vForeignKeyRawIdAdminField {
width: 5em;
}
/* INLINES */
.inline-group {
padding: 0;
margin: 0 0 30px;
}
.inline-group thead th {
padding: 8px 10px;
}
.inline-group .aligned label {
width: 160px;
}
.inline-related {
position: relative;
}
.inline-related h3 {
margin: 0;
color: #666;
padding: 5px;
font-size: 13px;
background: #f8f8f8;
border-top: 1px solid #eee;
border-bottom: 1px solid #eee;
}
.inline-related h3 span.delete {
float: right;
}
.inline-related h3 span.delete label {
margin-left: 2px;
font-size: 11px;
}
.inline-related fieldset {
margin: 0;
background: #fff;
border: none;
width: 100%;
}
.inline-related fieldset.module h3 {
margin: 0;
padding: 2px 5px 3px 5px;
font-size: 11px;
text-align: left;
font-weight: bold;
background: #bcd;
color: #fff;
}
.inline-group .tabular fieldset.module {
border: none;
}
.inline-related.tabular fieldset.module table {
width: 100%;
overflow-x: scroll;
}
.last-related fieldset {
border: none;
}
.inline-group .tabular tr.has_original td {
padding-top: 2em;
}
.inline-group .tabular tr td.original {
padding: 2px 0 0 0;
width: 0;
_position: relative;
}
.inline-group .tabular th.original {
width: 0px;
padding: 0;
}
.inline-group .tabular td.original p {
position: absolute;
left: 0;
height: 1.1em;
padding: 2px 9px;
overflow: hidden;
font-size: 9px;
font-weight: bold;
color: #666;
_width: 700px;
}
.inline-group ul.tools {
padding: 0;
margin: 0;
list-style: none;
}
.inline-group ul.tools li {
display: inline;
padding: 0 5px;
}
.inline-group div.add-row,
.inline-group .tabular tr.add-row td {
color: #666;
background: #f8f8f8;
padding: 8px 10px;
border-bottom: 1px solid #eee;
}
.inline-group .tabular tr.add-row td {
padding: 8px 10px;
border-bottom: 1px solid #eee;
}
.inline-group ul.tools a.add,
.inline-group div.add-row a,
.inline-group .tabular tr.add-row td a {
background: url(../img/icon-addlink.svg) 0 1px no-repeat;
padding-left: 16px;
font-size: 12px;
}
.empty-form {
display: none;
}
/* RELATED FIELD ADD ONE / LOOKUP */
.related-lookup {
margin-left: 5px;
display: inline-block;
vertical-align: middle;
background-repeat: no-repeat;
background-size: 14px;
}
.related-lookup {
width: 16px;
height: 16px;
background-image: url(../img/search.svg);
}
form .related-widget-wrapper ul {
display: inline-block;
margin-left: 0;
padding-left: 0;
}
.clearable-file-input input {
margin-top: 0;
}

+ 79
- 0
master/static/admin/css/login.css View File

@ -0,0 +1,79 @@
/* LOGIN FORM */
.login {
background: #f8f8f8;
height: auto;
}
.login #header {
height: auto;
padding: 15px 16px;
justify-content: center;
}
.login #header h1 {
font-size: 18px;
}
.login #header h1 a {
color: #fff;
}
.login #content {
padding: 20px 20px 0;
}
.login #container {
background: #fff;
border: 1px solid #eaeaea;
border-radius: 4px;
overflow: hidden;
width: 28em;
min-width: 300px;
margin: 100px auto;
height: auto;
}
.login #content-main {
width: 100%;
}
.login .form-row {
padding: 4px 0;
float: left;
width: 100%;
border-bottom: none;
}
.login .form-row label {
padding-right: 0.5em;
line-height: 2em;
font-size: 1em;
clear: both;
color: #333;
}
.login .form-row #id_username, .login .form-row #id_password {
clear: both;
padding: 8px;
width: 100%;
box-sizing: border-box;
}
.login span.help {
font-size: 10px;
display: block;
}
.login .submit-row {
clear: both;
padding: 1em 0 0 9.4em;
margin: 0;
border: none;
background: none;
text-align: left;
}
.login .password-reset-link {
text-align: center;
}

+ 119
- 0
master/static/admin/css/nav_sidebar.css View File

@ -0,0 +1,119 @@
.sticky {
position: sticky;
top: 0;
max-height: 100vh;
}
.toggle-nav-sidebar {
z-index: 20;
left: 0;
display: flex;
align-items: center;
justify-content: center;
flex: 0 0 23px;
width: 23px;
border-right: 1px solid #eaeaea;
background-color: #ffffff;
cursor: pointer;
font-size: 20px;
color: #447e9b;
padding: 0;
}
[dir="rtl"] .toggle-nav-sidebar {
border-left: 1px solid #eaeaea;
border-right: 0;
}
.toggle-nav-sidebar:hover,
.toggle-nav-sidebar:focus {
background-color: #f6f6f6;
}
#nav-sidebar {
z-index: 15;
flex: 0 0 275px;
left: -276px;
margin-left: -276px;
border-top: 1px solid transparent;
border-right: 1px solid #eaeaea;
background-color: #ffffff;
overflow: auto;
}
[dir="rtl"] #nav-sidebar {
border-left: 1px solid #eaeaea;
border-right: 0;
left: 0;
margin-left: 0;
right: -276px;
margin-right: -276px;
}
.toggle-nav-sidebar::before {
content: '\00BB';
}
.main.shifted .toggle-nav-sidebar::before {
content: '\00AB';
}
.main.shifted > #nav-sidebar {
left: 24px;
margin-left: 0;
}
[dir="rtl"] .main.shifted > #nav-sidebar {
left: 0;
right: 24px;
margin-right: 0;
}
#nav-sidebar .module th {
width: 100%;
overflow-wrap: anywhere;
}
#nav-sidebar .module th,
#nav-sidebar .module caption {
padding-left: 16px;
}
#nav-sidebar .module td {
white-space: nowrap;
}
[dir="rtl"] #nav-sidebar .module th,
[dir="rtl"] #nav-sidebar .module caption {
padding-left: 8px;
padding-right: 16px;
}
#nav-sidebar .current-app .section:link,
#nav-sidebar .current-app .section:visited {
color: #ffc;
font-weight: bold;
}
#nav-sidebar .current-model {
background: #ffc;
}
.main > #nav-sidebar + .content {
max-width: calc(100% - 23px);
}
.main.shifted > #nav-sidebar + .content {
max-width: calc(100% - 299px);
}
@media (max-width: 767px) {
#nav-sidebar, #toggle-nav-sidebar {
display: none;
}
.main > #nav-sidebar + .content,
.main.shifted > #nav-sidebar + .content {
max-width: 100%;
}
}

+ 1004
- 0
master/static/admin/css/responsive.css
File diff suppressed because it is too large
View File


+ 80
- 0
master/static/admin/css/responsive_rtl.css View File

@ -0,0 +1,80 @@
/* TABLETS */
@media (max-width: 1024px) {
[dir="rtl"] .colMS {
margin-right: 0;
}
[dir="rtl"] #user-tools {
text-align: right;
}
[dir="rtl"] #changelist .actions label {
padding-left: 10px;
padding-right: 0;
}
[dir="rtl"] #changelist .actions select {
margin-left: 0;
margin-right: 15px;
}
[dir="rtl"] .change-list .filtered .results,
[dir="rtl"] .change-list .filtered .paginator,
[dir="rtl"] .filtered #toolbar,
[dir="rtl"] .filtered div.xfull,
[dir="rtl"] .filtered .actions,
[dir="rtl"] #changelist-filter {
margin-left: 0;
}
[dir="rtl"] .inline-group ul.tools a.add,
[dir="rtl"] .inline-group div.add-row a,
[dir="rtl"] .inline-group .tabular tr.add-row td a {
padding: 8px 26px 8px 10px;
background-position: calc(100% - 8px) 9px;
}
[dir="rtl"] .related-widget-wrapper-link + .selector {
margin-right: 0;
margin-left: 15px;
}
[dir="rtl"] .selector .selector-filter label {
margin-right: 0;
margin-left: 8px;
}
[dir="rtl"] .object-tools li {
float: right;
}
[dir="rtl"] .object-tools li + li {
margin-left: 0;
margin-right: 15px;
}
[dir="rtl"] .dashboard .module table td a {
padding-left: 0;
padding-right: 16px;
}
}
/* MOBILE */
@media (max-width: 767px) {
[dir="rtl"] .aligned .related-lookup,
[dir="rtl"] .aligned .datetimeshortcuts {
margin-left: 0;
margin-right: 15px;
}
[dir="rtl"] .aligned ul {
margin-right: 0;
}
[dir="rtl"] #changelist-filter {
margin-left: 0;
margin-right: 0;
}
}

+ 249
- 0
master/static/admin/css/rtl.css View File

@ -0,0 +1,249 @@
body {
direction: rtl;
}
/* LOGIN */
.login .form-row {
float: right;
}
.login .form-row label {
float: right;
padding-left: 0.5em;
padding-right: 0;
text-align: left;
}
.login .submit-row {
clear: both;
padding: 1em 9.4em 0 0;
}
/* GLOBAL */
th {
text-align: right;
}
.module h2, .module caption {
text-align: right;
}
.module ul, .module ol {
margin-left: 0;
margin-right: 1.5em;
}
.viewlink, .addlink, .changelink {
padding-left: 0;
padding-right: 16px;
background-position: 100% 1px;
}
.deletelink {
padding-left: 0;
padding-right: 16px;
background-position: 100% 1px;
}
.object-tools {
float: left;
}
thead th:first-child,
tfoot td:first-child {
border-left: none;
}
/* LAYOUT */
#user-tools {
right: auto;
left: 0;
text-align: left;
}
div.breadcrumbs {
text-align: right;
}
#content-main {
float: right;
}
#content-related {
float: left;
margin-left: -300px;
margin-right: auto;
}
.colMS {
margin-left: 300px;
margin-right: 0;
}
/* SORTABLE TABLES */
table thead th.sorted .sortoptions {
float: left;
}
thead th.sorted .text {
padding-right: 0;
padding-left: 42px;
}
/* dashboard styles */
.dashboard .module table td a {
padding-left: .6em;
padding-right: 16px;
}
/* changelists styles */
.change-list .filtered table {
border-left: none;
border-right: 0px none;
}
#changelist-filter {
border-left: none;
border-right: none;
margin-left: 0;
margin-right: 30px;
}
#changelist-filter li.selected {
border-left: none;
padding-left: 10px;
margin-left: 0;
border-right: 5px solid #eaeaea;
padding-right: 10px;
margin-right: -15px;
}
#changelist table tbody td:first-child, #changelist table tbody th:first-child {
border-right: none;
border-left: none;
}
/* FORMS */
.aligned label {
padding: 0 0 3px 1em;
float: right;
}
.submit-row {
text-align: left
}
.submit-row p.deletelink-box {
float: right;
}
.submit-row input.default {
margin-left: 0;
}
.vDateField, .vTimeField {
margin-left: 2px;
}
.aligned .form-row input {
margin-left: 5px;
}
form .aligned p.help, form .aligned div.help {
clear: right;
}
form .aligned ul {
margin-right: 163px;
margin-left: 0;
}
form ul.inline li {
float: right;
padding-right: 0;
padding-left: 7px;
}
input[type=submit].default, .submit-row input.default {
float: left;
}
fieldset .fieldBox {
float: right;
margin-left: 20px;
margin-right: 0;
}
.errorlist li {
background-position: 100% 12px;
padding: 0;
}
.errornote {
background-position: 100% 12px;
padding: 10px 12px;
}
/* WIDGETS */
.calendarnav-previous {
top: 0;
left: auto;
right: 10px;
}
.calendarnav-next {
top: 0;
right: auto;
left: 10px;
}
.calendar caption, .calendarbox h2 {
text-align: center;
}
.selector {
float: right;
}
.selector .selector-filter {
text-align: right;
}
.inline-deletelink {
float: left;
}
form .form-row p.datetime {
overflow: hidden;
}
.related-widget-wrapper {
float: right;
}
/* MISC */
.inline-related h2, .inline-group h2 {
text-align: right
}
.inline-related h3 span.delete {
padding-right: 20px;
padding-left: inherit;
left: 10px;
right: inherit;
float:left;
}
.inline-related h3 span.delete label {
margin-left: inherit;
margin-right: 2px;
}

+ 21
- 0
master/static/admin/css/vendor/select2/LICENSE-SELECT2.md View File

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

+ 481
- 0
master/static/admin/css/vendor/select2/select2.css View File

@ -0,0 +1,481 @@
.select2-container {
box-sizing: border-box;
display: inline-block;
margin: 0;
position: relative;
vertical-align: middle; }
.select2-container .select2-selection--single {
box-sizing: border-box;
cursor: pointer;
display: block;
height: 28px;
user-select: none;
-webkit-user-select: none; }
.select2-container .select2-selection--single .select2-selection__rendered {
display: block;
padding-left: 8px;
padding-right: 20px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap; }
.select2-container .select2-selection--single .select2-selection__clear {
position: relative; }
.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered {
padding-right: 8px;
padding-left: 20px; }
.select2-container .select2-selection--multiple {
box-sizing: border-box;
cursor: pointer;
display: block;
min-height: 32px;
user-select: none;
-webkit-user-select: none; }
.select2-container .select2-selection--multiple .select2-selection__rendered {
display: inline-block;
overflow: hidden;
padding-left: 8px;
text-overflow: ellipsis;
white-space: nowrap; }
.select2-container .select2-search--inline {
float: left; }
.select2-container .select2-search--inline .select2-search__field {
box-sizing: border-box;
border: none;
font-size: 100%;
margin-top: 5px;
padding: 0; }
.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button {
-webkit-appearance: none; }
.select2-dropdown {
background-color: white;
border: 1px solid #aaa;
border-radius: 4px;
box-sizing: border-box;
display: block;
position: absolute;
left: -100000px;
width: 100%;
z-index: 1051; }
.select2-results {
display: block; }
.select2-results__options {
list-style: none;
margin: 0;
padding: 0; }
.select2-results__option {
padding: 6px;
user-select: none;
-webkit-user-select: none; }
.select2-results__option[aria-selected] {
cursor: pointer; }
.select2-container--open .select2-dropdown {
left: 0; }
.select2-container--open .select2-dropdown--above {
border-bottom: none;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0; }
.select2-container--open .select2-dropdown--below {
border-top: none;
border-top-left-radius: 0;
border-top-right-radius: 0; }
.select2-search--dropdown {
display: block;
padding: 4px; }
.select2-search--dropdown .select2-search__field {
padding: 4px;
width: 100%;
box-sizing: border-box; }
.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button {
-webkit-appearance: none; }
.select2-search--dropdown.select2-search--hide {
display: none; }
.select2-close-mask {
border: 0;
margin: 0;
padding: 0;
display: block;
position: fixed;
left: 0;
top: 0;
min-height: 100%;
min-width: 100%;
height: auto;
width: auto;
opacity: 0;
z-index: 99;
background-color: #fff;
filter: alpha(opacity=0); }
.select2-hidden-accessible {
border: 0 !important;
clip: rect(0 0 0 0) !important;
-webkit-clip-path: inset(50%) !important;
clip-path: inset(50%) !important;
height: 1px !important;
overflow: hidden !important;
padding: 0 !important;
position: absolute !important;
width: 1px !important;
white-space: nowrap !important; }
.select2-container--default .select2-selection--single {
background-color: #fff;
border: 1px solid #aaa;
border-radius: 4px; }
.select2-container--default .select2-selection--single .select2-selection__rendered {
color: #444;
line-height: 28px; }
.select2-container--default .select2-selection--single .select2-selection__clear {
cursor: pointer;
float: right;
font-weight: bold; }
.select2-container--default .select2-selection--single .select2-selection__placeholder {
color: #999; }
.select2-container--default .select2-selection--single .select2-selection__arrow {
height: 26px;
position: absolute;
top: 1px;
right: 1px;
width: 20px; }
.select2-container--default .select2-selection--single .select2-selection__arrow b {
border-color: #888 transparent transparent transparent;
border-style: solid;
border-width: 5px 4px 0 4px;
height: 0;
left: 50%;
margin-left: -4px;
margin-top: -2px;
position: absolute;
top: 50%;
width: 0; }
.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear {
float: left; }
.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow {
left: 1px;
right: auto; }
.select2-container--default.select2-container--disabled .select2-selection--single {
background-color: #eee;
cursor: default; }
.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear {
display: none; }
.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b {
border-color: transparent transparent #888 transparent;
border-width: 0 4px 5px 4px; }
.select2-container--default .select2-selection--multiple {
background-color: white;
border: 1px solid #aaa;
border-radius: 4px;
cursor: text; }
.select2-container--default .select2-selection--multiple .select2-selection__rendered {
box-sizing: border-box;
list-style: none;
margin: 0;
padding: 0 5px;
width: 100%; }
.select2-container--default .select2-selection--multiple .select2-selection__rendered li {
list-style: none; }
.select2-container--default .select2-selection--multiple .select2-selection__clear {
cursor: pointer;
float: right;
font-weight: bold;
margin-top: 5px;
margin-right: 10px;
padding: 1px; }
.select2-container--default .select2-selection--multiple .select2-selection__choice {
background-color: #e4e4e4;
border: 1px solid #aaa;
border-radius: 4px;
cursor: default;
float: left;
margin-right: 5px;
margin-top: 5px;
padding: 0 5px; }
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove {
color: #999;
cursor: pointer;
display: inline-block;
font-weight: bold;
margin-right: 2px; }
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover {
color: #333; }
.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline {
float: right; }
.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
margin-left: 5px;
margin-right: auto; }
.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove {
margin-left: 2px;
margin-right: auto; }
.select2-container--default.select2-container--focus .select2-selection--multiple {
border: solid black 1px;
outline: 0; }
.select2-container--default.select2-container--disabled .select2-selection--multiple {
background-color: #eee;
cursor: default; }
.select2-container--default.select2-container--disabled .select2-selection__choice__remove {
display: none; }
.select2-container--default.select2-container--open.select2-container--above .select2-selection--single, .select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple {
border-top-left-radius: 0;
border-top-right-radius: 0; }
.select2-container--default.select2-container--open.select2-container--below .select2-selection--single, .select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0; }
.select2-container--default .select2-search--dropdown .select2-search__field {
border: 1px solid #aaa; }
.select2-container--default .select2-search--inline .select2-search__field {
background: transparent;
border: none;
outline: 0;
box-shadow: none;
-webkit-appearance: textfield; }
.select2-container--default .select2-results > .select2-results__options {
max-height: 200px;
overflow-y: auto; }
.select2-container--default .select2-results__option[role=group] {
padding: 0; }
.select2-container--default .select2-results__option[aria-disabled=true] {
color: #999; }
.select2-container--default .select2-results__option[aria-selected=true] {
background-color: #ddd; }
.select2-container--default .select2-results__option .select2-results__option {
padding-left: 1em; }
.select2-container--default .select2-results__option .select2-results__option .select2-results__group {
padding-left: 0; }
.select2-container--default .select2-results__option .select2-results__option .select2-results__option {
margin-left: -1em;
padding-left: 2em; }
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -2em;
padding-left: 3em; }
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -3em;
padding-left: 4em; }
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -4em;
padding-left: 5em; }
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -5em;
padding-left: 6em; }
.select2-container--default .select2-results__option--highlighted[aria-selected] {
background-color: #5897fb;
color: white; }
.select2-container--default .select2-results__group {
cursor: default;
display: block;
padding: 6px; }
.select2-container--classic .select2-selection--single {
background-color: #f7f7f7;
border: 1px solid #aaa;
border-radius: 4px;
outline: 0;
background-image: -webkit-linear-gradient(top, white 50%, #eeeeee 100%);
background-image: -o-linear-gradient(top, white 50%, #eeeeee 100%);
background-image: linear-gradient(to bottom, white 50%, #eeeeee 100%);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); }
.select2-container--classic .select2-selection--single:focus {
border: 1px solid #5897fb; }
.select2-container--classic .select2-selection--single .select2-selection__rendered {
color: #444;
line-height: 28px; }
.select2-container--classic .select2-selection--single .select2-selection__clear {
cursor: pointer;
float: right;
font-weight: bold;
margin-right: 10px; }
.select2-container--classic .select2-selection--single .select2-selection__placeholder {
color: #999; }
.select2-container--classic .select2-selection--single .select2-selection__arrow {
background-color: #ddd;
border: none;
border-left: 1px solid #aaa;
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
height: 26px;
position: absolute;
top: 1px;
right: 1px;
width: 20px;
background-image: -webkit-linear-gradient(top, #eeeeee 50%, #cccccc 100%);
background-image: -o-linear-gradient(top, #eeeeee 50%, #cccccc 100%);
background-image: linear-gradient(to bottom, #eeeeee 50%, #cccccc 100%);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0); }
.select2-container--classic .select2-selection--single .select2-selection__arrow b {
border-color: #888 transparent transparent transparent;
border-style: solid;
border-width: 5px 4px 0 4px;
height: 0;
left: 50%;
margin-left: -4px;
margin-top: -2px;
position: absolute;
top: 50%;
width: 0; }
.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear {
float: left; }
.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow {
border: none;
border-right: 1px solid #aaa;
border-radius: 0;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
left: 1px;
right: auto; }
.select2-container--classic.select2-container--open .select2-selection--single {
border: 1px solid #5897fb; }
.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow {
background: transparent;
border: none; }
.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b {
border-color: transparent transparent #888 transparent;
border-width: 0 4px 5px 4px; }
.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single {
border-top: none;
border-top-left-radius: 0;
border-top-right-radius: 0;
background-image: -webkit-linear-gradient(top, white 0%, #eeeeee 50%);
background-image: -o-linear-gradient(top, white 0%, #eeeeee 50%);
background-image: linear-gradient(to bottom, white 0%, #eeeeee 50%);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); }
.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single {
border-bottom: none;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
background-image: -webkit-linear-gradient(top, #eeeeee 50%, white 100%);
background-image: -o-linear-gradient(top, #eeeeee 50%, white 100%);
background-image: linear-gradient(to bottom, #eeeeee 50%, white 100%);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0); }
.select2-container--classic .select2-selection--multiple {
background-color: white;
border: 1px solid #aaa;
border-radius: 4px;
cursor: text;
outline: 0; }
.select2-container--classic .select2-selection--multiple:focus {
border: 1px solid #5897fb; }
.select2-container--classic .select2-selection--multiple .select2-selection__rendered {
list-style: none;
margin: 0;
padding: 0 5px; }
.select2-container--classic .select2-selection--multiple .select2-selection__clear {
display: none; }
.select2-container--classic .select2-selection--multiple .select2-selection__choice {
background-color: #e4e4e4;
border: 1px solid #aaa;
border-radius: 4px;
cursor: default;
float: left;
margin-right: 5px;
margin-top: 5px;
padding: 0 5px; }
.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove {
color: #888;
cursor: pointer;
display: inline-block;
font-weight: bold;
margin-right: 2px; }
.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover {
color: #555; }
.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
float: right;
margin-left: 5px;
margin-right: auto; }
.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove {
margin-left: 2px;
margin-right: auto; }
.select2-container--classic.select2-container--open .select2-selection--multiple {
border: 1px solid #5897fb; }
.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple {
border-top: none;
border-top-left-radius: 0;
border-top-right-radius: 0; }
.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple {
border-bottom: none;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0; }
.select2-container--classic .select2-search--dropdown .select2-search__field {
border: 1px solid #aaa;
outline: 0; }
.select2-container--classic .select2-search--inline .select2-search__field {
outline: 0;
box-shadow: none; }
.select2-container--classic .select2-dropdown {
background-color: white;
border: 1px solid transparent; }
.select2-container--classic .select2-dropdown--above {
border-bottom: none; }
.select2-container--classic .select2-dropdown--below {
border-top: none; }
.select2-container--classic .select2-results > .select2-results__options {
max-height: 200px;
overflow-y: auto; }
.select2-container--classic .select2-results__option[role=group] {
padding: 0; }
.select2-container--classic .select2-results__option[aria-disabled=true] {
color: grey; }
.select2-container--classic .select2-results__option--highlighted[aria-selected] {
background-color: #3875d7;
color: white; }
.select2-container--classic .select2-results__group {
cursor: default;
display: block;
padding: 6px; }
.select2-container--classic.select2-container--open .select2-dropdown {
border-color: #5897fb; }

+ 1
- 0
master/static/admin/css/vendor/select2/select2.min.css
File diff suppressed because it is too large
View File


+ 574
- 0
master/static/admin/css/widgets.css View File

@ -0,0 +1,574 @@
/* SELECTOR (FILTER INTERFACE) */
.selector {
width: 800px;
float: left;
}
.selector select {
width: 380px;
height: 17.2em;
}
.selector-available, .selector-chosen {
float: left;
width: 380px;
text-align: center;
margin-bottom: 5px;
}
.selector-chosen select {
border-top: none;
}
.selector-available h2, .selector-chosen h2 {
border: 1px solid #ccc;
border-radius: 4px 4px 0 0;
}
.selector-chosen h2 {
background: #79aec8;
color: #fff;
}
.selector .selector-available h2 {
background: #f8f8f8;
color: #666;
}
.selector .selector-filter {
background: white;
border: 1px solid #ccc;
border-width: 0 1px;
padding: 8px;
color: #999;
font-size: 10px;
margin: 0;
text-align: left;
}
.selector .selector-filter label,
.inline-group .aligned .selector .selector-filter label {
float: left;
margin: 7px 0 0;
width: 18px;
height: 18px;
padding: 0;
overflow: hidden;
line-height: 1;
}
.selector .selector-available input {
width: 320px;
margin-left: 8px;
}
.selector ul.selector-chooser {
float: left;
width: 22px;
background-color: #eee;
border-radius: 10px;
margin: 10em 5px 0 5px;
padding: 0;
}
.selector-chooser li {
margin: 0;
padding: 3px;
list-style-type: none;
}
.selector select {
padding: 0 10px;
margin: 0 0 10px;
border-radius: 0 0 4px 4px;
}
.selector-add, .selector-remove {
width: 16px;
height: 16px;
display: block;
text-indent: -3000px;
overflow: hidden;
cursor: default;
opacity: 0.3;
}
.active.selector-add, .active.selector-remove {
opacity: 1;
}
.active.selector-add:hover, .active.selector-remove:hover {
cursor: pointer;
}
.selector-add {
background: url(../img/selector-icons.svg) 0 -96px no-repeat;
}
.active.selector-add:focus, .active.selector-add:hover {
background-position: 0 -112px;
}
.selector-remove {
background: url(../img/selector-icons.svg) 0 -64px no-repeat;
}
.active.selector-remove:focus, .active.selector-remove:hover {
background-position: 0 -80px;
}
a.selector-chooseall, a.selector-clearall {
display: inline-block;
height: 16px;
text-align: left;
margin: 1px auto 3px;
overflow: hidden;
font-weight: bold;
line-height: 16px;
color: #666;
text-decoration: none;
opacity: 0.3;
}
a.active.selector-chooseall:focus, a.active.selector-clearall:focus,
a.active.selector-chooseall:hover, a.active.selector-clearall:hover {
color: #447e9b;
}
a.active.selector-chooseall, a.active.selector-clearall {
opacity: 1;
}
a.active.selector-chooseall:hover, a.active.selector-clearall:hover {
cursor: pointer;
}
a.selector-chooseall {
padding: 0 18px 0 0;
background: url(../img/selector-icons.svg) right -160px no-repeat;
cursor: default;
}
a.active.selector-chooseall:focus, a.active.selector-chooseall:hover {
background-position: 100% -176px;
}
a.selector-clearall {
padding: 0 0 0 18px;
background: url(../img/selector-icons.svg) 0 -128px no-repeat;
cursor: default;
}
a.active.selector-clearall:focus, a.active.selector-clearall:hover {
background-position: 0 -144px;
}
/* STACKED SELECTORS */
.stacked {
float: left;
width: 490px;
}
.stacked select {
width: 480px;
height: 10.1em;
}
.stacked .selector-available, .stacked .selector-chosen {
width: 480px;
}
.stacked .selector-available {
margin-bottom: 0;
}
.stacked .selector-available input {
width: 422px;
}
.stacked ul.selector-chooser {
height: 22px;
width: 50px;
margin: 0 0 10px 40%;
background-color: #eee;
border-radius: 10px;
}
.stacked .selector-chooser li {
float: left;
padding: 3px 3px 3px 5px;
}
.stacked .selector-chooseall, .stacked .selector-clearall {
display: none;
}
.stacked .selector-add {
background: url(../img/selector-icons.svg) 0 -32px no-repeat;
cursor: default;
}
.stacked .active.selector-add {
background-position: 0 -32px;
cursor: pointer;
}
.stacked .active.selector-add:focus, .stacked .active.selector-add:hover {
background-position: 0 -48px;
cursor: pointer;
}
.stacked .selector-remove {
background: url(../img/selector-icons.svg) 0 0 no-repeat;
cursor: default;
}
.stacked .active.selector-remove {
background-position: 0 0px;
cursor: pointer;
}
.stacked .active.selector-remove:focus, .stacked .active.selector-remove:hover {
background-position: 0 -16px;
cursor: pointer;
}
.selector .help-icon {
background: url(../img/icon-unknown.svg) 0 0 no-repeat;
display: inline-block;
vertical-align: middle;
margin: -2px 0 0 2px;
width: 13px;
height: 13px;
}
.selector .selector-chosen .help-icon {
background: url(../img/icon-unknown-alt.svg) 0 0 no-repeat;
}
.selector .search-label-icon {
background: url(../img/search.svg) 0 0 no-repeat;
display: inline-block;
height: 18px;
width: 18px;
}
/* DATE AND TIME */
p.datetime {
line-height: 20px;
margin: 0;
padding: 0;
color: #666;
font-weight: bold;
}
.datetime span {
white-space: nowrap;
font-weight: normal;
font-size: 11px;
color: #ccc;
}
.datetime input, .form-row .datetime input.vDateField, .form-row .datetime input.vTimeField {
margin-left: 5px;
margin-bottom: 4px;
}
table p.datetime {
font-size: 11px;
margin-left: 0;
padding-left: 0;
}
.datetimeshortcuts .clock-icon, .datetimeshortcuts .date-icon {
position: relative;
display: inline-block;
vertical-align: middle;
height: 16px;
width: 16px;
overflow: hidden;
}
.datetimeshortcuts .clock-icon {
background: url(../img/icon-clock.svg) 0 0 no-repeat;
}
.datetimeshortcuts a:focus .clock-icon,
.datetimeshortcuts a:hover .clock-icon {
background-position: 0 -16px;
}
.datetimeshortcuts .date-icon {
background: url(../img/icon-calendar.svg) 0 0 no-repeat;
top: -1px;
}
.datetimeshortcuts a:focus .date-icon,
.datetimeshortcuts a:hover .date-icon {
background-position: 0 -16px;
}
.timezonewarning {
font-size: 11px;
color: #999;
}
/* URL */
p.url {
line-height: 20px;
margin: 0;
padding: 0;
color: #666;
font-size: 11px;
font-weight: bold;
}
.url a {
font-weight: normal;
}
/* FILE UPLOADS */
p.file-upload {
line-height: 20px;
margin: 0;
padding: 0;
color: #666;
font-size: 11px;
font-weight: bold;
}
.aligned p.file-upload {
margin-left: 170px;
}
.file-upload a {
font-weight: normal;
}
.file-upload .deletelink {
margin-left: 5px;
}
span.clearable-file-input label {
color: #333;
font-size: 11px;
display: inline;
float: none;
}
/* CALENDARS & CLOCKS */
.calendarbox, .clockbox {
margin: 5px auto;
font-size: 12px;
width: 19em;
text-align: center;
background: white;
border: 1px solid #ddd;
border-radius: 4px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
overflow: hidden;
position: relative;
}
.clockbox {
width: auto;
}
.calendar {
margin: 0;
padding: 0;
}
.calendar table {
margin: 0;
padding: 0;
border-collapse: collapse;
background: white;
width: 100%;
}
.calendar caption, .calendarbox h2 {
margin: 0;
text-align: center;
border-top: none;
background: #f5dd5d;
font-weight: 700;
font-size: 12px;
color: #333;
}
.calendar th {
padding: 8px 5px;
background: #f8f8f8;
border-bottom: 1px solid #ddd;
font-weight: 400;
font-size: 12px;
text-align: center;
color: #666;
}
.calendar td {
font-weight: 400;
font-size: 12px;
text-align: center;
padding: 0;
border-top: 1px solid #eee;
border-bottom: none;
}
.calendar td.selected a {
background: #79aec8;
color: #fff;
}
.calendar td.nonday {
background: #f8f8f8;
}
.calendar td.today a {
font-weight: 700;
}
.calendar td a, .timelist a {
display: block;
font-weight: 400;
padding: 6px;
text-decoration: none;
color: #444;
}
.calendar td a:focus, .timelist a:focus,
.calendar td a:hover, .timelist a:hover {
background: #79aec8;
color: white;
}
.calendar td a:active, .timelist a:active {
background: #417690;
color: white;
}
.calendarnav {
font-size: 10px;
text-align: center;
color: #ccc;
margin: 0;
padding: 1px 3px;
}
.calendarnav a:link, #calendarnav a:visited,
#calendarnav a:focus, #calendarnav a:hover {
color: #999;
}
.calendar-shortcuts {
background: white;
font-size: 11px;
line-height: 11px;
border-top: 1px solid #eee;
padding: 8px 0;
color: #ccc;
}
.calendarbox .calendarnav-previous, .calendarbox .calendarnav-next {
display: block;
position: absolute;
top: 8px;
width: 15px;
height: 15px;
text-indent: -9999px;
padding: 0;
}
.calendarnav-previous {
left: 10px;
background: url(../img/calendar-icons.svg) 0 0 no-repeat;
}
.calendarbox .calendarnav-previous:focus,
.calendarbox .calendarnav-previous:hover {
background-position: 0 -15px;
}
.calendarnav-next {
right: 10px;
background: url(../img/calendar-icons.svg) 0 -30px no-repeat;
}
.calendarbox .calendarnav-next:focus,
.calendarbox .calendarnav-next:hover {
background-position: 0 -45px;
}
.calendar-cancel {
margin: 0;
padding: 4px 0;
font-size: 12px;
background: #eee;
border-top: 1px solid #ddd;
color: #333;
}
.calendar-cancel:focus, .calendar-cancel:hover {
background: #ddd;
}
.calendar-cancel a {
color: black;
display: block;
}
ul.timelist, .timelist li {
list-style-type: none;
margin: 0;
padding: 0;
}
.timelist a {
padding: 2px;
}
/* EDIT INLINE */
.inline-deletelink {
float: right;
text-indent: -9999px;
background: url(../img/inline-delete.svg) 0 0 no-repeat;
width: 16px;
height: 16px;
border: 0px none;
}
.inline-deletelink:focus, .inline-deletelink:hover {
cursor: pointer;
}
/* RELATED WIDGET WRAPPER */
.related-widget-wrapper {
float: left; /* display properly in form rows with multiple fields */
overflow: hidden; /* clear floated contents */
}
.related-widget-wrapper-link {
opacity: 0.3;
}
.related-widget-wrapper-link:link {
opacity: .8;
}
.related-widget-wrapper-link:link:focus,
.related-widget-wrapper-link:link:hover {
opacity: 1;
}
select + .related-widget-wrapper-link,
.related-widget-wrapper-link + .related-widget-wrapper-link {
margin-left: 7px;
}

+ 202
- 0
master/static/admin/fonts/LICENSE.txt View File

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

+ 3
- 0
master/static/admin/fonts/README.txt View File

@ -0,0 +1,3 @@
Roboto webfont source: https://www.google.com/fonts/specimen/Roboto
WOFF files extracted using https://github.com/majodev/google-webfonts-helper
Weights used in this project: Light (300), Regular (400), Bold (700)

BIN
master/static/admin/fonts/Roboto-Bold-webfont.woff View File


BIN
master/static/admin/fonts/Roboto-Light-webfont.woff View File


BIN
master/static/admin/fonts/Roboto-Regular-webfont.woff View File


+ 20
- 0
master/static/admin/img/LICENSE View File

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

+ 7
- 0
master/static/admin/img/README.txt View File

@ -0,0 +1,7 @@
All icons are taken from Font Awesome (http://fontawesome.io/) project.
The Font Awesome font is licensed under the SIL OFL 1.1:
- https://scripts.sil.org/OFL
SVG icons source: https://github.com/encharm/Font-Awesome-SVG-PNG
Font-Awesome-SVG-PNG is licensed under the MIT license (see file license
in current folder).

+ 14
- 0
master/static/admin/img/calendar-icons.svg View File

@ -0,0 +1,14 @@
<svg width="15" height="60" viewBox="0 0 1792 7168" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<g id="previous">
<path d="M1037 1395l102-102q19-19 19-45t-19-45l-307-307 307-307q19-19 19-45t-19-45l-102-102q-19-19-45-19t-45 19l-454 454q-19 19-19 45t19 45l454 454q19 19 45 19t45-19zm627-499q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/>
</g>
<g id="next">
<path d="M845 1395l454-454q19-19 19-45t-19-45l-454-454q-19-19-45-19t-45 19l-102 102q-19 19-19 45t19 45l307 307-307 307q-19 19-19 45t19 45l102 102q19 19 45 19t45-19zm819-499q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/>
</g>
</defs>
<use xlink:href="#previous" x="0" y="0" fill="#333333" />
<use xlink:href="#previous" x="0" y="1792" fill="#000000" />
<use xlink:href="#next" x="0" y="3584" fill="#333333" />
<use xlink:href="#next" x="0" y="5376" fill="#000000" />
</svg>

+ 1
- 0
master/static/admin/img/gis/move_vertex_off.svg View File

@ -0,0 +1 @@
<svg width="24" height="22" viewBox="0 0 847 779" xmlns="http://www.w3.org/2000/svg"><g><path fill="#EBECE6" d="M120 1h607c66 0 120 54 120 120v536c0 66-54 120-120 120h-607c-66 0-120-54-120-120v-536c0-66 54-120 120-120z"/><path fill="#9E9E93" d="M120 1h607c66 0 120 54 120 120v536c0 66-54 120-120 120h-607c-66 0-120-54-120-120v-536c0-66 54-120 120-120zm607 25h-607c-26 0-50 11-67 28-17 18-28 41-28 67v536c0 27 11 50 28 68 17 17 41 27 67 27h607c26 0 49-10 67-27 17-18 28-41 28-68v-536c0-26-11-49-28-67-18-17-41-28-67-28z"/><path stroke="#A9A8A4" stroke-width="20" d="M706 295l-68 281"/><path stroke="#E47474" stroke-width="20" d="M316 648l390-353M141 435l175 213"/><path stroke="#C9C9C9" stroke-width="20" d="M319 151l-178 284M706 295l-387-144"/><g fill="#040405"><path d="M319 111c22 0 40 18 40 40s-18 40-40 40-40-18-40-40 18-40 40-40zM141 395c22 0 40 18 40 40s-18 40-40 40c-23 0-41-18-41-40s18-40 41-40zM316 608c22 0 40 18 40 40 0 23-18 41-40 41s-40-18-40-41c0-22 18-40 40-40zM706 254c22 0 40 18 40 41 0 22-18 40-40 40s-40-18-40-40c0-23 18-41 40-41zM638 536c22 0 40 18 40 40s-18 40-40 40-40-18-40-40 18-40 40-40z"/></g></g></svg>

+ 1
- 0
master/static/admin/img/gis/move_vertex_on.svg View File

@ -0,0 +1 @@
<svg width="24" height="22" viewBox="0 0 847 779" xmlns="http://www.w3.org/2000/svg"><g><path fill="#F1C02A" d="M120 1h607c66 0 120 54 120 120v536c0 66-54 120-120 120h-607c-66 0-120-54-120-120v-536c0-66 54-120 120-120z"/><path fill="#9E9E93" d="M120 1h607c66 0 120 54 120 120v536c0 66-54 120-120 120h-607c-66 0-120-54-120-120v-536c0-66 54-120 120-120zm607 25h-607c-26 0-50 11-67 28-17 18-28 41-28 67v536c0 27 11 50 28 68 17 17 41 27 67 27h607c26 0 49-10 67-27 17-18 28-41 28-68v-536c0-26-11-49-28-67-18-17-41-28-67-28z"/><path stroke="#A9A8A4" stroke-width="20" d="M706 295l-68 281"/><path stroke="#E47474" stroke-width="20" d="M316 648l390-353M141 435l175 213"/><path stroke="#C9A741" stroke-width="20" d="M319 151l-178 284M706 295l-387-144"/><g fill="#040405"><path d="M319 111c22 0 40 18 40 40s-18 40-40 40-40-18-40-40 18-40 40-40zM141 395c22 0 40 18 40 40s-18 40-40 40c-23 0-41-18-41-40s18-40 41-40zM316 608c22 0 40 18 40 40 0 23-18 41-40 41s-40-18-40-41c0-22 18-40 40-40zM706 254c22 0 40 18 40 41 0 22-18 40-40 40s-40-18-40-40c0-23 18-41 40-41zM638 536c22 0 40 18 40 40s-18 40-40 40-40-18-40-40 18-40 40-40z"/></g></g></svg>

+ 3
- 0
master/static/admin/img/icon-addlink.svg View File

@ -0,0 +1,3 @@
<svg width="13" height="13" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg">
<path fill="#70bf2b" d="M1600 796v192q0 40-28 68t-68 28h-416v416q0 40-28 68t-68 28h-192q-40 0-68-28t-28-68v-416h-416q-40 0-68-28t-28-68v-192q0-40 28-68t68-28h416v-416q0-40 28-68t68-28h192q40 0 68 28t28 68v416h416q40 0 68 28t28 68z"/>
</svg>

+ 3
- 0
master/static/admin/img/icon-alert.svg View File

@ -0,0 +1,3 @@
<svg width="14" height="14" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg">
<path fill="#efb80b" d="M1024 1375v-190q0-14-9.5-23.5t-22.5-9.5h-192q-13 0-22.5 9.5t-9.5 23.5v190q0 14 9.5 23.5t22.5 9.5h192q13 0 22.5-9.5t9.5-23.5zm-2-374l18-459q0-12-10-19-13-11-24-11h-220q-11 0-24 11-10 7-10 21l17 457q0 10 10 16.5t24 6.5h185q14 0 23.5-6.5t10.5-16.5zm-14-934l768 1408q35 63-2 126-17 29-46.5 46t-63.5 17h-1536q-34 0-63.5-17t-46.5-46q-37-63-2-126l768-1408q17-31 47-49t65-18 65 18 47 49z"/>
</svg>

+ 9
- 0
master/static/admin/img/icon-calendar.svg View File

@ -0,0 +1,9 @@
<svg width="16" height="32" viewBox="0 0 1792 3584" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<g id="icon">
<path d="M192 1664h288v-288h-288v288zm352 0h320v-288h-320v288zm-352-352h288v-320h-288v320zm352 0h320v-320h-320v320zm-352-384h288v-288h-288v288zm736 736h320v-288h-320v288zm-384-736h320v-288h-320v288zm768 736h288v-288h-288v288zm-384-352h320v-320h-320v320zm-352-864v-288q0-13-9.5-22.5t-22.5-9.5h-64q-13 0-22.5 9.5t-9.5 22.5v288q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5-9.5t9.5-22.5zm736 864h288v-320h-288v320zm-384-384h320v-288h-320v288zm384 0h288v-288h-288v288zm32-480v-288q0-13-9.5-22.5t-22.5-9.5h-64q-13 0-22.5 9.5t-9.5 22.5v288q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5-9.5t9.5-22.5zm384-64v1280q0 52-38 90t-90 38h-1408q-52 0-90-38t-38-90v-1280q0-52 38-90t90-38h128v-96q0-66 47-113t113-47h64q66 0 113 47t47 113v96h384v-96q0-66 47-113t113-47h64q66 0 113 47t47 113v96h128q52 0 90 38t38 90z"/>
</g>
</defs>
<use xlink:href="#icon" x="0" y="0" fill="#447e9b" />
<use xlink:href="#icon" x="0" y="1792" fill="#003366" />
</svg>

+ 3
- 0
master/static/admin/img/icon-changelink.svg View File

@ -0,0 +1,3 @@
<svg width="13" height="13" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg">
<path fill="#efb80b" d="M491 1536l91-91-235-235-91 91v107h128v128h107zm523-928q0-22-22-22-10 0-17 7l-542 542q-7 7-7 17 0 22 22 22 10 0 17-7l542-542q7-7 7-17zm-54-192l416 416-832 832h-416v-416zm683 96q0 53-37 90l-166 166-416-416 166-165q36-38 90-38 53 0 91 38l235 234q37 39 37 91z"/>
</svg>

+ 9
- 0
master/static/admin/img/icon-clock.svg View File

@ -0,0 +1,9 @@
<svg width="16" height="32" viewBox="0 0 1792 3584" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<g id="icon">
<path d="M1024 544v448q0 14-9 23t-23 9h-320q-14 0-23-9t-9-23v-64q0-14 9-23t23-9h224v-352q0-14 9-23t23-9h64q14 0 23 9t9 23zm416 352q0-148-73-273t-198-198-273-73-273 73-198 198-73 273 73 273 198 198 273 73 273-73 198-198 73-273zm224 0q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/>
</g>
</defs>
<use xlink:href="#icon" x="0" y="0" fill="#447e9b" />
<use xlink:href="#icon" x="0" y="1792" fill="#003366" />
</svg>

+ 3
- 0
master/static/admin/img/icon-deletelink.svg View File

@ -0,0 +1,3 @@
<svg width="14" height="14" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg">
<path fill="#dd4646" d="M1490 1322q0 40-28 68l-136 136q-28 28-68 28t-68-28l-294-294-294 294q-28 28-68 28t-68-28l-136-136q-28-28-28-68t28-68l294-294-294-294q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 294 294-294q28-28 68-28t68 28l136 136q28 28 28 68t-28 68l-294 294 294 294q28 28 28 68z"/>
</svg>

+ 3
- 0
master/static/admin/img/icon-no.svg View File

@ -0,0 +1,3 @@
<svg width="13" height="13" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg">
<path fill="#dd4646" d="M1277 1122q0-26-19-45l-181-181 181-181q19-19 19-45 0-27-19-46l-90-90q-19-19-46-19-26 0-45 19l-181 181-181-181q-19-19-45-19-27 0-46 19l-90 90q-19 19-19 46 0 26 19 45l181 181-181 181q-19 19-19 45 0 27 19 46l90 90q19 19 46 19 26 0 45-19l181-181 181 181q19 19 45 19 27 0 46-19l90-90q19-19 19-46zm387-226q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/>
</svg>

+ 3
- 0
master/static/admin/img/icon-unknown-alt.svg View File

@ -0,0 +1,3 @@
<svg width="13" height="13" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg">
<path fill="#ffffff" d="M1024 1376v-192q0-14-9-23t-23-9h-192q-14 0-23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23-9t9-23zm256-672q0-88-55.5-163t-138.5-116-170-41q-243 0-371 213-15 24 8 42l132 100q7 6 19 6 16 0 25-12 53-68 86-92 34-24 86-24 48 0 85.5 26t37.5 59q0 38-20 61t-68 45q-63 28-115.5 86.5t-52.5 125.5v36q0 14 9 23t23 9h192q14 0 23-9t9-23q0-19 21.5-49.5t54.5-49.5q32-18 49-28.5t46-35 44.5-48 28-60.5 12.5-81zm384 192q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/>
</svg>

+ 3
- 0
master/static/admin/img/icon-unknown.svg View File

@ -0,0 +1,3 @@
<svg width="13" height="13" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg">
<path fill="#666666" d="M1024 1376v-192q0-14-9-23t-23-9h-192q-14 0-23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23-9t9-23zm256-672q0-88-55.5-163t-138.5-116-170-41q-243 0-371 213-15 24 8 42l132 100q7 6 19 6 16 0 25-12 53-68 86-92 34-24 86-24 48 0 85.5 26t37.5 59q0 38-20 61t-68 45q-63 28-115.5 86.5t-52.5 125.5v36q0 14 9 23t23 9h192q14 0 23-9t9-23q0-19 21.5-49.5t54.5-49.5q32-18 49-28.5t46-35 44.5-48 28-60.5 12.5-81zm384 192q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/>
</svg>

+ 3
- 0
master/static/admin/img/icon-viewlink.svg View File

@ -0,0 +1,3 @@
<svg width="13" height="13" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg">
<path fill="#2b70bf" d="M1664 960q-152-236-381-353 61 104 61 225 0 185-131.5 316.5t-316.5 131.5-316.5-131.5-131.5-316.5q0-121 61-225-229 117-381 353 133 205 333.5 326.5t434.5 121.5 434.5-121.5 333.5-326.5zm-720-384q0-20-14-34t-34-14q-125 0-214.5 89.5t-89.5 214.5q0 20 14 34t34 14 34-14 14-34q0-86 61-147t147-61q20 0 34-14t14-34zm848 384q0 34-20 69-140 230-376.5 368.5t-499.5 138.5-499.5-139-376.5-368q-20-35-20-69t20-69q140-229 376.5-368t499.5-139 499.5 139 376.5 368q20 35 20 69z"/>
</svg>

+ 3
- 0
master/static/admin/img/icon-yes.svg View File

@ -0,0 +1,3 @@
<svg width="13" height="13" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg">
<path fill="#70bf2b" d="M1412 734q0-28-18-46l-91-90q-19-19-45-19t-45 19l-408 407-226-226q-19-19-45-19t-45 19l-91 90q-18 18-18 46 0 27 18 45l362 362q19 19 45 19 27 0 46-19l543-543q18-18 18-45zm252 162q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/>
</svg>

+ 3
- 0
master/static/admin/img/inline-delete.svg View File

@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg">
<path fill="#999999" d="M1277 1122q0-26-19-45l-181-181 181-181q19-19 19-45 0-27-19-46l-90-90q-19-19-46-19-26 0-45 19l-181 181-181-181q-19-19-45-19-27 0-46 19l-90 90q-19 19-19 46 0 26 19 45l181 181-181 181q-19 19-19 45 0 27 19 46l90 90q19 19 46 19 26 0 45-19l181-181 181 181q19 19 45 19 27 0 46-19l90-90q19-19 19-46zm387-226q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/>
</svg>

+ 3
- 0
master/static/admin/img/search.svg View File

@ -0,0 +1,3 @@
<svg width="15" height="15" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg">
<path fill="#555555" d="M1216 832q0-185-131.5-316.5t-316.5-131.5-316.5 131.5-131.5 316.5 131.5 316.5 316.5 131.5 316.5-131.5 131.5-316.5zm512 832q0 52-38 90t-90 38q-54 0-90-38l-343-342q-179 124-399 124-143 0-273.5-55.5t-225-150-150-225-55.5-273.5 55.5-273.5 150-225 225-150 273.5-55.5 273.5 55.5 225 150 150 225 55.5 273.5q0 220-124 399l343 343q37 37 37 90z"/>
</svg>

+ 34
- 0
master/static/admin/img/selector-icons.svg View File

@ -0,0 +1,34 @@
<svg width="16" height="192" viewBox="0 0 1792 21504" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<g id="up">
<path d="M1412 895q0-27-18-45l-362-362-91-91q-18-18-45-18t-45 18l-91 91-362 362q-18 18-18 45t18 45l91 91q18 18 45 18t45-18l189-189v502q0 26 19 45t45 19h128q26 0 45-19t19-45v-502l189 189q19 19 45 19t45-19l91-91q18-18 18-45zm252 1q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/>
</g>
<g id="down">
<path d="M1412 897q0-27-18-45l-91-91q-18-18-45-18t-45 18l-189 189v-502q0-26-19-45t-45-19h-128q-26 0-45 19t-19 45v502l-189-189q-19-19-45-19t-45 19l-91 91q-18 18-18 45t18 45l362 362 91 91q18 18 45 18t45-18l91-91 362-362q18-18 18-45zm252-1q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/>
</g>
<g id="left">
<path d="M1408 960v-128q0-26-19-45t-45-19h-502l189-189q19-19 19-45t-19-45l-91-91q-18-18-45-18t-45 18l-362 362-91 91q-18 18-18 45t18 45l91 91 362 362q18 18 45 18t45-18l91-91q18-18 18-45t-18-45l-189-189h502q26 0 45-19t19-45zm256-64q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/>
</g>
<g id="right">
<path d="M1413 896q0-27-18-45l-91-91-362-362q-18-18-45-18t-45 18l-91 91q-18 18-18 45t18 45l189 189h-502q-26 0-45 19t-19 45v128q0 26 19 45t45 19h502l-189 189q-19 19-19 45t19 45l91 91q18 18 45 18t45-18l362-362 91-91q18-18 18-45zm251 0q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/>
</g>
<g id="clearall">
<path transform="translate(336, 336) scale(0.75)" d="M1037 1395l102-102q19-19 19-45t-19-45l-307-307 307-307q19-19 19-45t-19-45l-102-102q-19-19-45-19t-45 19l-454 454q-19 19-19 45t19 45l454 454q19 19 45 19t45-19zm627-499q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/>
</g>
<g id="chooseall">
<path transform="translate(336, 336) scale(0.75)" d="M845 1395l454-454q19-19 19-45t-19-45l-454-454q-19-19-45-19t-45 19l-102 102q-19 19-19 45t19 45l307 307-307 307q-19 19-19 45t19 45l102 102q19 19 45 19t45-19zm819-499q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/>
</g>
</defs>
<use xlink:href="#up" x="0" y="0" fill="#666666" />
<use xlink:href="#up" x="0" y="1792" fill="#447e9b" />
<use xlink:href="#down" x="0" y="3584" fill="#666666" />
<use xlink:href="#down" x="0" y="5376" fill="#447e9b" />
<use xlink:href="#left" x="0" y="7168" fill="#666666" />
<use xlink:href="#left" x="0" y="8960" fill="#447e9b" />
<use xlink:href="#right" x="0" y="10752" fill="#666666" />
<use xlink:href="#right" x="0" y="12544" fill="#447e9b" />
<use xlink:href="#clearall" x="0" y="14336" fill="#666666" />
<use xlink:href="#clearall" x="0" y="16128" fill="#447e9b" />
<use xlink:href="#chooseall" x="0" y="17920" fill="#666666" />
<use xlink:href="#chooseall" x="0" y="19712" fill="#447e9b" />
</svg>

+ 19
- 0
master/static/admin/img/sorting-icons.svg View File

@ -0,0 +1,19 @@
<svg width="14" height="84" viewBox="0 0 1792 10752" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<g id="sort">
<path d="M1408 1088q0 26-19 45l-448 448q-19 19-45 19t-45-19l-448-448q-19-19-19-45t19-45 45-19h896q26 0 45 19t19 45zm0-384q0 26-19 45t-45 19h-896q-26 0-45-19t-19-45 19-45l448-448q19-19 45-19t45 19l448 448q19 19 19 45z"/>
</g>
<g id="ascending">
<path d="M1408 1216q0 26-19 45t-45 19h-896q-26 0-45-19t-19-45 19-45l448-448q19-19 45-19t45 19l448 448q19 19 19 45z"/>
</g>
<g id="descending">
<path d="M1408 704q0 26-19 45l-448 448q-19 19-45 19t-45-19l-448-448q-19-19-19-45t19-45 45-19h896q26 0 45 19t19 45z"/>
</g>
</defs>
<use xlink:href="#sort" x="0" y="0" fill="#999999" />
<use xlink:href="#sort" x="0" y="1792" fill="#447e9b" />
<use xlink:href="#ascending" x="0" y="3584" fill="#999999" />
<use xlink:href="#ascending" x="0" y="5376" fill="#447e9b" />
<use xlink:href="#descending" x="0" y="7168" fill="#999999" />
<use xlink:href="#descending" x="0" y="8960" fill="#447e9b" />
</svg>

+ 3
- 0
master/static/admin/img/tooltag-add.svg View File

@ -0,0 +1,3 @@
<svg width="13" height="13" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg">
<path fill="#ffffff" d="M1600 736v192q0 40-28 68t-68 28h-416v416q0 40-28 68t-68 28h-192q-40 0-68-28t-28-68v-416h-416q-40 0-68-28t-28-68v-192q0-40 28-68t68-28h416v-416q0-40 28-68t68-28h192q40 0 68 28t28 68v416h416q40 0 68 28t28 68z"/>
</svg>

+ 3
- 0
master/static/admin/img/tooltag-arrowright.svg View File

@ -0,0 +1,3 @@
<svg width="13" height="13" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg">
<path fill="#ffffff" d="M1363 877l-742 742q-19 19-45 19t-45-19l-166-166q-19-19-19-45t19-45l531-531-531-531q-19-19-19-45t19-45l166-166q19-19 45-19t45 19l742 742q19 19 19 45t-19 45z"/>
</svg>

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

Loading…
Cancel
Save