system_settings 0.1.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +28 -0
- data/app/controllers/system_settings/application_controller.rb +11 -0
- data/app/controllers/system_settings/root_controller.rb +13 -0
- data/app/controllers/system_settings/settings_controller.rb +27 -0
- data/app/models/system_settings/application_record.rb +5 -0
- data/app/models/system_settings/configurator.rb +81 -0
- data/app/models/system_settings/integer_list_setting.rb +8 -0
- data/app/models/system_settings/integer_setting.rb +8 -0
- data/app/models/system_settings/list_of_integers_validator.rb +42 -0
- data/app/models/system_settings/setting.rb +8 -0
- data/app/models/system_settings/string_list_setting.rb +7 -0
- data/app/models/system_settings/string_setting.rb +7 -0
- data/app/models/system_settings/type/integer_list.rb +32 -0
- data/app/models/system_settings/type/string_list.rb +28 -0
- data/config/locales/system_settings.en.yml +32 -0
- data/config/routes.rb +7 -0
- data/db/migrate/20181007125347_create_system_settings_settings.rb +11 -0
- data/frontend/build/asset-manifest.json +11 -0
- data/frontend/build/favicon.ico +0 -0
- data/frontend/build/index.html +1 -0
- data/frontend/build/precache-manifest.130ca067521371497dba783c23aa7e16.js +22 -0
- data/frontend/build/service-worker.js +39 -0
- data/frontend/build/static/css/main.e262560e.chunk.css +1 -0
- data/frontend/build/static/js/2.83a5f4da.chunk.js +1 -0
- data/frontend/build/static/js/main.afaa2372.chunk.js +1 -0
- data/frontend/build/static/js/runtime~main.a09e9b82.js +1 -0
- data/lib/system_settings/engine.rb +17 -0
- data/lib/system_settings/version.rb +3 -0
- data/lib/system_settings.rb +7 -0
- data/lib/tasks/system_settings_tasks.rake +4 -0
- metadata +130 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 856385bd0d4333e0d4044a3afaca3dfad12db9cd3ade70940ab588cc8162ac0e
|
4
|
+
data.tar.gz: 2ccd7b81d43f94bc33e473eef401ae2cdaa0b6ae212e64e8b0d4826717be16c1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 31b69d9e2d3663a773cc6539211a2a53644f33a2aec0a40c1c8da1791a9dd81941dfb38d3e0615a4fcd0090e5b45b080f5ed2891303fc05fb8bae7ed0b804fd4
|
7
|
+
data.tar.gz: 415a9d5a5968a4ed30be94b6ba4812d803be1c5a2d5ebbe15fbb8d716beacd9caa378669e471b3284ca31bcb42ab7ac90226fd3cd4ad8a639ce4f5dcf2c2f9f0
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2018 Krists Ozols
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# SystemSettings
|
2
|
+
Short description and motivation.
|
3
|
+
|
4
|
+
## Usage
|
5
|
+
How to use my plugin.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem 'system_settings'
|
12
|
+
```
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
```bash
|
16
|
+
$ bundle
|
17
|
+
```
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
```bash
|
21
|
+
$ gem install system_settings
|
22
|
+
```
|
23
|
+
|
24
|
+
## Contributing
|
25
|
+
Contribution directions go here.
|
26
|
+
|
27
|
+
## License
|
28
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module SystemSettings
|
2
|
+
class ApplicationController < ActionController::Base
|
3
|
+
protect_from_forgery with: :exception
|
4
|
+
|
5
|
+
private
|
6
|
+
|
7
|
+
def add_authenticity_token
|
8
|
+
response.headers["Authenticity-Token"] = form_authenticity_token if protect_against_forgery?
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require_relative "./application_controller"
|
2
|
+
|
3
|
+
module SystemSettings
|
4
|
+
class RootController < ApplicationController
|
5
|
+
def index
|
6
|
+
if File.exists?(SystemSettings::Engine.frontend_build_index_html_path)
|
7
|
+
render file: SystemSettings::Engine.frontend_build_index_html_path
|
8
|
+
else
|
9
|
+
render plain: "Frontend application has not been compiled", status: :not_implemented
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require_relative "./application_controller"
|
2
|
+
|
3
|
+
module SystemSettings
|
4
|
+
class SettingsController < ApplicationController
|
5
|
+
RETURN_ATTRIBUTES = ["id", "name", "type", "value", "description"].freeze
|
6
|
+
|
7
|
+
def index
|
8
|
+
@settings = SystemSettings::Setting.order(:name)
|
9
|
+
render json: @settings.map { |s| s.as_json(only: RETURN_ATTRIBUTES) }
|
10
|
+
end
|
11
|
+
|
12
|
+
def show
|
13
|
+
@setting = SystemSettings::Setting.find(params[:id])
|
14
|
+
add_authenticity_token
|
15
|
+
render json: @setting.as_json(only: RETURN_ATTRIBUTES)
|
16
|
+
end
|
17
|
+
|
18
|
+
def update
|
19
|
+
@setting = SystemSettings::Setting.find(params[:id])
|
20
|
+
if @setting.update(value: params[:value])
|
21
|
+
render json: @setting.as_json(only: RETURN_ATTRIBUTES)
|
22
|
+
else
|
23
|
+
render json: {errors: @setting.errors.as_json}, status: :unprocessable_entity
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module SystemSettings
|
2
|
+
class Configurator
|
3
|
+
|
4
|
+
class << self
|
5
|
+
def from_file(path)
|
6
|
+
file_content = File.read(path)
|
7
|
+
new.tap do |obj|
|
8
|
+
obj.instance_eval(file_content, path, 1)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_reader :items
|
14
|
+
|
15
|
+
def initialize(&block)
|
16
|
+
@items = []
|
17
|
+
if block_given?
|
18
|
+
if block.arity == 1
|
19
|
+
yield self
|
20
|
+
else
|
21
|
+
instance_exec(&block)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def string(name, value: nil, description: nil, &blk)
|
27
|
+
add(name, SystemSettings::StringSetting, value: value, description: description, &blk)
|
28
|
+
end
|
29
|
+
|
30
|
+
def string_list(name, value: nil, description: nil, &blk)
|
31
|
+
add(name, SystemSettings::StringListSetting, value: value, description: description, &blk)
|
32
|
+
end
|
33
|
+
|
34
|
+
def integer(name, value: nil, description: nil, &blk)
|
35
|
+
add(name, SystemSettings::IntegerSetting, value: value, description: description, &blk)
|
36
|
+
end
|
37
|
+
|
38
|
+
def integer_list(name, value: nil, description: nil, &blk)
|
39
|
+
add(name, SystemSettings::IntegerListSetting, value: value, description: description, &blk)
|
40
|
+
end
|
41
|
+
|
42
|
+
def persist
|
43
|
+
if settings_table_exists?
|
44
|
+
SystemSettings::Setting.transaction do
|
45
|
+
@items.each do |entry|
|
46
|
+
persisted_record = entry[:class].find_by(name: entry[:name])
|
47
|
+
if persisted_record
|
48
|
+
persisted_record.update_attributes!(description: entry[:description])
|
49
|
+
else
|
50
|
+
entry[:class].create!(name: entry[:name], value: entry[:value], description: entry[:description])
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
else
|
55
|
+
$stderr.puts "SystemSettings: Settings table has not been created!"
|
56
|
+
false
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def purge
|
61
|
+
if settings_table_exists?
|
62
|
+
SystemSettings::Setting.delete_all
|
63
|
+
true
|
64
|
+
else
|
65
|
+
false
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def settings_table_exists?
|
72
|
+
SystemSettings::Setting.table_exists?
|
73
|
+
end
|
74
|
+
|
75
|
+
def add(name, class_const, value:, description:)
|
76
|
+
value = yield(value) if block_given?
|
77
|
+
value = value.call if value.is_a?(Proc)
|
78
|
+
@items.push(name: name, class: class_const, value: value, description: description)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module SystemSettings
|
2
|
+
class ListOfIntegersValidator < ActiveModel::EachValidator
|
3
|
+
LIST_REGEXP = /\A[+-]?\d+(?:; *[+-]?\d+)*\z/
|
4
|
+
SINGLE_REGEXP = /\A[+-]?\d+\z/
|
5
|
+
|
6
|
+
def validate_each(record, attr_name, value)
|
7
|
+
came_from_user = :"#{attr_name}_came_from_user?"
|
8
|
+
|
9
|
+
if record.respond_to?(came_from_user) && record.public_send(came_from_user)
|
10
|
+
raw_value = record.read_attribute_before_type_cast(attr_name)
|
11
|
+
end
|
12
|
+
raw_value ||= value
|
13
|
+
|
14
|
+
if record_attribute_changed_in_place?(record, attr_name)
|
15
|
+
raw_value = value
|
16
|
+
end
|
17
|
+
|
18
|
+
unless matches_list_of_integers_regexp?(raw_value)
|
19
|
+
record.errors.add(attr_name, :not_a_list_of_integers)
|
20
|
+
return
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def record_attribute_changed_in_place?(record, attr_name)
|
27
|
+
record.respond_to?(:attribute_changed_in_place?) &&
|
28
|
+
record.attribute_changed_in_place?(attr_name.to_s)
|
29
|
+
end
|
30
|
+
|
31
|
+
def matches_list_of_integers_regexp?(raw_value)
|
32
|
+
case raw_value
|
33
|
+
when String
|
34
|
+
LIST_REGEXP.match?(raw_value)
|
35
|
+
when Array
|
36
|
+
raw_value.all? { |v| SINGLE_REGEXP.match?(v.to_s) }
|
37
|
+
else
|
38
|
+
false
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module SystemSettings
|
2
|
+
module Type
|
3
|
+
class IntegerList < ActiveModel::Type::Value
|
4
|
+
SEPARATOR = ";".freeze
|
5
|
+
|
6
|
+
def type
|
7
|
+
:integer_list
|
8
|
+
end
|
9
|
+
|
10
|
+
def deserialize(value)
|
11
|
+
value.presence && JSON.parse(value)
|
12
|
+
end
|
13
|
+
|
14
|
+
def serialize(value)
|
15
|
+
JSON.dump(value) unless value.nil?
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def cast_value(value)
|
21
|
+
case value
|
22
|
+
when Array
|
23
|
+
value.map { |v| v.to_i rescue nil }
|
24
|
+
when String
|
25
|
+
value.split(SEPARATOR).map { |v| v.to_i rescue nil }
|
26
|
+
else
|
27
|
+
nil
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module SystemSettings
|
2
|
+
module Type
|
3
|
+
class StringList < ActiveModel::Type::Value
|
4
|
+
def type
|
5
|
+
:string_list
|
6
|
+
end
|
7
|
+
|
8
|
+
def deserialize(value)
|
9
|
+
value.presence && JSON.parse(value)
|
10
|
+
end
|
11
|
+
|
12
|
+
def serialize(value)
|
13
|
+
JSON.dump(value) unless value.nil?
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def cast_value(value)
|
19
|
+
case value
|
20
|
+
when Array
|
21
|
+
value.map { |v| String(v).strip }
|
22
|
+
when String
|
23
|
+
value.split(/(?<=[^\\]);/).map(&:strip)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
en:
|
2
|
+
activerecord:
|
3
|
+
models:
|
4
|
+
system_settings/setting:
|
5
|
+
one: "System Setting"
|
6
|
+
other: "System Settings"
|
7
|
+
system_settings/integer_list_setting:
|
8
|
+
one: "System Setting (Integer list)"
|
9
|
+
other: "System Settings (Integer list)"
|
10
|
+
system_settings/integer_setting:
|
11
|
+
one: "System Setting (Integer)"
|
12
|
+
other: "System Settings (Integer)"
|
13
|
+
system_settings/string_list_setting:
|
14
|
+
one: "System Setting (String list)"
|
15
|
+
other: "System Settings (String list)"
|
16
|
+
system_settings/string_setting:
|
17
|
+
one: "System Setting (String)"
|
18
|
+
other: "System Settings (String)"
|
19
|
+
attributes:
|
20
|
+
system_settings/setting:
|
21
|
+
id: "ID"
|
22
|
+
name: "Name"
|
23
|
+
type: "Type"
|
24
|
+
description: "Description"
|
25
|
+
created_at: "Created at"
|
26
|
+
uploaded_at: "Updated at"
|
27
|
+
errors:
|
28
|
+
models:
|
29
|
+
system_settings/setting:
|
30
|
+
attributes:
|
31
|
+
value:
|
32
|
+
not_a_list_of_integers: "not a list of integers"
|
data/config/routes.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
class CreateSystemSettingsSettings < ActiveRecord::Migration[5.2]
|
2
|
+
def change
|
3
|
+
create_table :system_settings_settings do |t|
|
4
|
+
t.string :name, null: false, index: { unique: true }
|
5
|
+
t.string :type, null: false, index: true
|
6
|
+
t.text :value
|
7
|
+
t.text :description
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
{
|
2
|
+
"files": {
|
3
|
+
"main.css": "/system_settings/static/css/main.e262560e.chunk.css",
|
4
|
+
"main.js": "/system_settings/static/js/main.afaa2372.chunk.js",
|
5
|
+
"runtime~main.js": "/system_settings/static/js/runtime~main.a09e9b82.js",
|
6
|
+
"static/js/2.83a5f4da.chunk.js": "/system_settings/static/js/2.83a5f4da.chunk.js",
|
7
|
+
"index.html": "/system_settings/index.html",
|
8
|
+
"precache-manifest.130ca067521371497dba783c23aa7e16.js": "/system_settings/precache-manifest.130ca067521371497dba783c23aa7e16.js",
|
9
|
+
"service-worker.js": "/system_settings/service-worker.js"
|
10
|
+
}
|
11
|
+
}
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
<!doctype html><html lang="en"><head><meta charset="utf-8"><link rel="shortcut icon" href="/system_settings/favicon.ico"><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name="theme-color" content="#000000"><title>System Settings</title><link href="/system_settings/static/css/main.e262560e.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script src="/system_settings/static/js/runtime~main.a09e9b82.js"></script><script src="/system_settings/static/js/2.83a5f4da.chunk.js"></script><script src="/system_settings/static/js/main.afaa2372.chunk.js"></script></body></html>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
self.__precacheManifest = (self.__precacheManifest || []).concat([
|
2
|
+
{
|
3
|
+
"revision": "e04ed1ed3403d21f675ed787109671dd",
|
4
|
+
"url": "/system_settings/index.html"
|
5
|
+
},
|
6
|
+
{
|
7
|
+
"revision": "b12967943154ae7a6202",
|
8
|
+
"url": "/system_settings/static/css/main.e262560e.chunk.css"
|
9
|
+
},
|
10
|
+
{
|
11
|
+
"revision": "fbb0a923d9fbb93afddb",
|
12
|
+
"url": "/system_settings/static/js/2.83a5f4da.chunk.js"
|
13
|
+
},
|
14
|
+
{
|
15
|
+
"revision": "b12967943154ae7a6202",
|
16
|
+
"url": "/system_settings/static/js/main.afaa2372.chunk.js"
|
17
|
+
},
|
18
|
+
{
|
19
|
+
"revision": "1b52e032205e59a9e84f",
|
20
|
+
"url": "/system_settings/static/js/runtime~main.a09e9b82.js"
|
21
|
+
}
|
22
|
+
]);
|
@@ -0,0 +1,39 @@
|
|
1
|
+
/**
|
2
|
+
* Welcome to your Workbox-powered service worker!
|
3
|
+
*
|
4
|
+
* You'll need to register this file in your web app and you should
|
5
|
+
* disable HTTP caching for this file too.
|
6
|
+
* See https://goo.gl/nhQhGp
|
7
|
+
*
|
8
|
+
* The rest of the code is auto-generated. Please don't update this file
|
9
|
+
* directly; instead, make changes to your Workbox build configuration
|
10
|
+
* and re-run your build process.
|
11
|
+
* See https://goo.gl/2aRDsh
|
12
|
+
*/
|
13
|
+
|
14
|
+
importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.0/workbox-sw.js");
|
15
|
+
|
16
|
+
importScripts(
|
17
|
+
"/system_settings/precache-manifest.130ca067521371497dba783c23aa7e16.js"
|
18
|
+
);
|
19
|
+
|
20
|
+
self.addEventListener('message', (event) => {
|
21
|
+
if (event.data && event.data.type === 'SKIP_WAITING') {
|
22
|
+
self.skipWaiting();
|
23
|
+
}
|
24
|
+
});
|
25
|
+
|
26
|
+
workbox.core.clientsClaim();
|
27
|
+
|
28
|
+
/**
|
29
|
+
* The workboxSW.precacheAndRoute() method efficiently caches and responds to
|
30
|
+
* requests for URLs in the manifest.
|
31
|
+
* See https://goo.gl/S9QRab
|
32
|
+
*/
|
33
|
+
self.__precacheManifest = [].concat(self.__precacheManifest || []);
|
34
|
+
workbox.precaching.precacheAndRoute(self.__precacheManifest, {});
|
35
|
+
|
36
|
+
workbox.routing.registerNavigationRoute(workbox.precaching.getCacheKeyForURL("/system_settings/index.html"), {
|
37
|
+
|
38
|
+
blacklist: [/^\/_/,/\/[^\/]+\.[^\/]+$/],
|
39
|
+
});
|
@@ -0,0 +1 @@
|
|
1
|
+
.App_container__BLGGc{min-height:100vh;display:flex;flex-direction:column;position:relative;z-index:auto}.App_header-wrap__3DnwX{position:fixed;width:100%;background:#fff;border-bottom:1px solid #e1e1e1;z-index:1}.App_header__1o2Y8{max-width:1020px;margin:0 auto;display:flex}.App_header-name__2XXxc{font-size:1.5rem;line-height:2rem;font-weight:700;padding:.5rem 0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-decoration:none}.App_header-name__2XXxc:active,.App_header-name__2XXxc:focus,.App_header-name__2XXxc:hover{text-decoration:none}.App_header-spacer__3F0KU{margin-top:calc(3rem + 1px);height:3rem}.App_content-wrap__1oPWs{flex-grow:5;box-sizing:border-box;display:flex}.App_content__3dh9P{max-width:1020px;min-width:0;margin:0 auto;display:flex;flex-grow:1;flex-direction:column}.NotFoundPage_container__35vs4{flex-grow:1;align-items:center;justify-content:center;display:flex}.ListPage_table__2qY_8{table-layout:fixed;white-space:nowrap;width:100%;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ListPage_table__2qY_8 td:empty:after{content:"-"}.ListPage_empty-tr__2VxYl{color:#a6a6a6}.ListPage_empty-tr__2VxYl td{text-align:center}.ListPage_name__1-Gs-{width:20%;overflow:hidden;text-overflow:ellipsis}.ListPage_table__2qY_8 tbody .ListPage_description__1Sci0,.ListPage_table__2qY_8 tbody .ListPage_name__1-Gs-,.ListPage_table__2qY_8 tbody .ListPage_value__3X3Vq{-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;user-select:text}.ListPage_description__1Sci0{width:50%}.ListPage_description__1Sci0,.ListPage_value__3X3Vq{overflow:hidden;text-overflow:ellipsis}.ListPage_actions__2iqTu{width:50px;text-align:right}.PageLoadError_wrap__mpF75{display:flex;align-items:flex-start;justify-content:center}.PageLoadError_container__kcD9o{display:flex;flex-direction:column;background:#ffe5e5;padding:.25rem .5rem;border-radius:4px;color:#b94343;text-align:center}.PageLoadError_error-small__14Fex{font-size:.85em}#nprogress{pointer-events:none}#nprogress .bar{background:#ffc25b;position:fixed;z-index:1031;top:0;left:0;width:100%;height:2px}#nprogress .peg{display:block;position:absolute;right:0;width:100px;height:100%;box-shadow:0 0 10px #ffc25b,0 0 5px #ffc25b;opacity:1;-webkit-transform:rotate(3deg) translateY(-4px);transform:rotate(3deg) translateY(-4px)}#nprogress .spinner{display:block;position:fixed;z-index:1031;top:.9rem;right:.9rem}#nprogress .spinner-icon{width:1.2rem;height:1.2rem;box-sizing:border-box;border-color:#ffc25b transparent transparent #ffc25b;border-style:solid;border-width:2px;border-radius:50%;-webkit-animation:nprogress-spinner .4s linear infinite;animation:nprogress-spinner .4s linear infinite}.nprogress-custom-parent{overflow:hidden;position:relative}.nprogress-custom-parent #nprogress .bar,.nprogress-custom-parent #nprogress .spinner{position:absolute}@-webkit-keyframes nprogress-spinner{0%{-webkit-transform:rotate(0deg)}to{-webkit-transform:rotate(1turn)}}@keyframes nprogress-spinner{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.Attribute_wrap__1Zy9J{display:flex;flex-direction:column;margin-bottom:1rem}.Attribute_name__3a-cD{font-size:.8em;color:#737373;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.Attribute_value__IxZCj:empty:after{content:"-"}.ButtonBar_container__21aEr{border-top:1px dotted #f2f2f2;padding-top:1rem;margin-bottom:1rem}.ButtonBar_container__21aEr>*{margin-right:.5rem}.LabeledInput_wrap__2KAyr{position:relative;margin-bottom:1em}.LabeledInput_label__1AyjZ{font-size:.8em;color:#737373;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:block}.LabeledInput_input-and-error-wrap__2iJKd{display:flex;align-items:baseline}.LabeledInput_error__2QBpW{flex-grow:0;display:block;color:#ff3656;margin-left:1rem;white-space:nowrap}.LabeledInput_hint__rAeG8{font-size:.8em;display:block}.SettingForm_error-wrap__3SdnI{display:flex;padding:.5rem 0}.SettingForm_error-message__uQK1Y{background:#ffe5e5;padding:.25rem .5rem;border-radius:4px;color:#b94343}.SettingForm_error-small__3owRp{font-size:.85em}.ClassicSpinner_wrap__1LF2_{display:block}html{box-sizing:border-box;overflow-y:scroll;font-size:14px}*,:after,:before{box-sizing:inherit}:root,body{background:#fff}body{color:#233656;font-family:Arial,Helvetica,sans-serif;font-weight:400;font-size:1rem;line-height:1.5rem;margin:0;padding:0;min-height:100vh;position:relative;display:flex;flex-direction:column}table{border-collapse:collapse;border-spacing:0}table td,table th{text-align:left}a{color:#233656;text-decoration:none}a:hover{text-decoration:underline}a.button,button,input[type=button],input[type=submit]{display:inline-block;cursor:pointer;border:none;border-radius:3px;padding:.375rem .75rem;font-size:1rem;line-height:1.5;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;white-space:nowrap}button,input[type=button],input[type=submit]{color:#4d4d4d;background-color:#d9d9d9;-webkit-transition:background-color .1s ease-in-out;transition:background-color .1s ease-in-out;outline:none}button:focus,button:hover,input[type=button]:focus,input[type=button]:hover,input[type=submit]:focus,input[type=submit]:hover{background-color:#b8b8b8}button:active,input[type=button]:active,input[type=submit]:active{background-color:#828282}a.button{color:#4d4d4d;background-color:initial;-webkit-transition:background-color .1s ease-in-out;transition:background-color .1s ease-in-out;outline:none;text-decoration:none}a.button:focus,a.button:hover{background-color:rgba(0,0,0,.15)}a.button:active{background-color:rgba(0,0,0,.4)}a.button.primary,button.primary,input[type=button].primary,input[type=submit].primary{color:#4d4d4d;background-color:#a6a6a6;-webkit-transition:background-color .1s ease-in-out;transition:background-color .1s ease-in-out;outline:none}a.button.primary:focus,a.button.primary:hover,button.primary:focus,button.primary:hover,input[type=button].primary:focus,input[type=button].primary:hover,input[type=submit].primary:focus,input[type=submit].primary:hover{background-color:#8d8d8d}a.button.primary:active,button.primary:active,input[type=button].primary:active,input[type=submit].primary:active{background-color:#646464}input[type=text]{border:none;border-radius:3px;padding:.5em;font-size:1rem;line-height:normal;color:#4d4d4d;background-color:#e6e6e6;-webkit-transition:background-color .1s ease-in-out;transition:background-color .1s ease-in-out;outline:none;box-sizing:initial;width:auto;min-width:12ch;max-width:calc(100% - 2em);will-change:width}input[type=text]:focus{background-color:#c4c4c4}input[type=text]:active{background-color:#bfbfbf}.button-wrap{display:flex;align-items:center}.svg-wrap{display:block}code{border-radius:2px;padding:0 .2rem}.sysname,code{background:#f2f2f2}.sysname{display:inline-block;border-radius:3px;padding:0 .5em;font-family:Courier New,Courier,monospace;font-size:.75em}#root{z-index:1;position:relative}
|