AItool commited on
Commit
a235263
·
verified ·
1 Parent(s): 6889f7c

Upload 15 files

Browse files
README.en.md ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ # Scope of project
2
+ 1. Enable multiple languages translate based on helsinki models.✅
3
+ 2. Enable auto detect langauge ✅
4
+ 3. Show error message instead of gradio error ✅
5
+ 4. Add examples ✅
6
+ 5. Auto detect on text change ✅
__init__.py ADDED
File without changes
adibideak.py ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ adibide_esaldiak = [
2
+ "Zer da benetakoa? galdetu zion Untxiak egun batean.",
3
+ "¿Qué es real? preguntó el Conejo un día.",
4
+ "Что реально? спросил кролик однажды.",
5
+ "Was ist real? fragte das Kaninchen eines Tages.",
6
+ "What is real? asked the Rabbit one day."
7
+ ]
app.py ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ @author: idoia lerchundi
3
+ """
4
+ import streamlit as st
5
+ from language_directions import *
6
+ from transformers import pipeline
7
+ from adibideak import adibide_esaldiak
8
+ from PIL import Image
9
+
10
+
11
+ def local_css(file_name):
12
+ with open(file_name) as f:
13
+ st.markdown(f"<style>{f.read()}</style>", unsafe_allow_html=True)
14
+
15
+ st.set_page_config(
16
+ page_title="Streamlit iCodeIdoia",
17
+ )
18
+
19
+ st.image("images/banner.jpg")
20
+
21
+ # ---- LOAD
22
+ local_css("styles/style.css")
23
+
24
+ source_lang_dict = get_all_source_languages()
25
+ target_lang_dict = {}
26
+ source_languages = source_lang_dict.keys()
27
+
28
+ def get_auto_detect_source_dropdown(input_text):
29
+ source, _ = auto_detect_language_code(input_text)
30
+ language_name = get_name_from_iso_code(source)
31
+ source_dropdown_text = "Detected - " + language_name
32
+ update_source_languages_dict(source_lang_dict, source_dropdown_text)
33
+ source_language_dropdown = st.selectbox(choices=source_languages,
34
+ value=source_dropdown_text,
35
+ label="Input Language")
36
+
37
+ ########################
38
+ return source_language_dropdown, language_name
39
+
40
+ def get_target_dropdown(source_language_name, input_text):
41
+ global target_lang_dict
42
+ target_lang_dict, source_language = get_target_languages(source_lang_dict[source_language_name], input_text)
43
+ target_languages = list(target_lang_dict.keys())
44
+ default_target_value = None
45
+ if "English" in target_languages or "english" in target_languages:
46
+ default_target_value = "English"
47
+ else:
48
+ default_target_value = target_languages[0]
49
+ target_dropdown = st.selectbox(choices=target_languages,
50
+ value=default_target_value,
51
+ label="Output Language")
52
+ return target_dropdown
53
+
54
+ def get_dropdown_value(dropdown):
55
+ if isinstance(dropdown, st.selectbox):
56
+ dropdown_value = dropdown.constructor_args.get('value')
57
+ elif isinstance(dropdown, str):
58
+ dropdown_value = dropdown
59
+ return dropdown_value
60
+
61
+ def get_dropdowns(source_dropdown, input_text):
62
+ source_language_name = get_dropdown_value(source_dropdown)
63
+ if input_text and source_language_name == "Detect" or source_language_name.startswith("Detected"):
64
+ source_dropdown, source_language_name = get_auto_detect_source_dropdown(input_text)
65
+ target_dropdown = get_target_dropdown(source_language_name=source_language_name,
66
+ input_text=input_text)
67
+ return source_dropdown, target_dropdown
68
+
69
+ def input_changed(source_language_dropdown, input_text=""):
70
+ return get_dropdowns(source_dropdown=source_language_dropdown,
71
+ input_text=input_text)
72
+
73
+ def translate(input_text, source, target):
74
+ source_readable = source
75
+ if source == "Detect" or source.startswith("Detected"):
76
+ source, _ = auto_detect_language_code(input_text)
77
+ if source in source_lang_dict.keys():
78
+ source = source_lang_dict[source]
79
+ target_lang_dict, _ = get_target_languages(source)
80
+ try:
81
+ target = target_lang_dict[target]
82
+ model = f"Helsinki-NLP/opus-mt-{source}-{target}"
83
+ pipe = pipeline("translation", model=model)
84
+ translation = pipe(input_text)
85
+ return translation[0]['translation_text']
86
+ except KeyError:
87
+ return f"Error: Translation from {source_readable} to {target} is not supported by Translation Models"
88
+
89
+ with st.container():
90
+ st.header("Euskera-EU Basque translator - itzultzailea")
91
+ st.caption("This is a trained AI translator - Hau AI itzultzaile bat da.")
92
+ coffee = """
93
+ <div style="margin: 0.75em 0;"><a href="https://www.buymeacoffee.com/Artgen" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Buy Me A Coffee" height="41" width="174"></a></div>
94
+ """
95
+ col1, col2 = st.columns([1,1], gap="small")
96
+
97
+ with col1:
98
+ #source_language_dropdown.change
99
+ slang = ("Detect", "Basque") # Example list of languages
100
+ source_language_dropdown = st.selectbox("Language - Hizkuntza", slang, key='source_languages')
101
+
102
+ # Create a text area widget
103
+ input_textbox = st.text_area("Enter text - Idatzi textua", value="", key='input_text')
104
+
105
+ with col2:
106
+ tlang=("","English","German","Russian","Spanish")
107
+ target_language_dropdown = st.selectbox("Translation - Itzulpena", tlang, key='target_languages')
108
+ #translated_textbox = st.text_area("Translation - Itzulpena", value="", disabled=False)
109
+
110
+ if st.button('Translate - Itzuli') and len(input_textbox)> 0:
111
+ translated_output = translate(input_textbox,source_language_dropdown,target_language_dropdown)
112
+ st.text_area("Translation - Itzulpena", value=translated_output, disabled=True)
113
+
114
+ @st.cache_data
115
+ def load_data(inputt,inputl,targetl):
116
+ data = translate(inputt,inputl,targetl)
117
+ return data
118
+
119
+ if len(target_language_dropdown)>1 and len(source_language_dropdown)>0 and target_language_dropdown!= "" and source_language_dropdown!="Detect" and len(input_textbox)>0:
120
+ data_load_state = st.text("Translating - Itzultzen..")
121
+ #data = load_data(input_textbox,source_language_dropdown,target_language_dropdown)
122
+ data_load_state.text("Translation...completed - Itzulpena amaituta.")
123
+ st.markdown(coffee, unsafe_allow_html=True)
gr_app.py ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from language_directions import get_all_source_languages,update_source_languages_dict,get_target_languages,auto_detect_language_code
3
+ from transformers import pipeline
4
+ from adibideak import adibide_esaldiak
5
+ from iso639_wrapper import get_name_from_iso_code
6
+
7
+ source_lang_dict = get_all_source_languages()
8
+ target_lang_dict = {}
9
+ source_languages = source_lang_dict.keys()
10
+
11
+ def get_auto_detect_source_dropdown(input_text):
12
+ source, _ = auto_detect_language_code(input_text)
13
+ language_name = get_name_from_iso_code(source)
14
+ source_dropdown_text = "Detected - " + language_name
15
+ update_source_languages_dict(source_lang_dict, source_dropdown_text)
16
+ source_language_dropdown = gr.Dropdown(choices=source_languages,
17
+ value=source_dropdown_text,
18
+ label="Input Language")
19
+ return source_language_dropdown, language_name
20
+
21
+ def get_target_dropdown(source_language_name, input_text):
22
+ global target_lang_dict
23
+ target_lang_dict, source_language = get_target_languages(source_lang_dict[source_language_name], input_text)
24
+ target_languages = list(target_lang_dict.keys())
25
+ default_target_value = None
26
+ if "English" in target_languages or "english" in target_languages:
27
+ default_target_value = "English"
28
+ else:
29
+ default_target_value = target_languages[0]
30
+ target_dropdown = gr.Dropdown(choices=target_languages,
31
+ value=default_target_value,
32
+ label="Output Language")
33
+ return target_dropdown
34
+
35
+ def get_dropdown_value(dropdown):
36
+ if isinstance(dropdown, gr.Dropdown):
37
+ dropdown_value = dropdown.constructor_args.get('value')
38
+ elif isinstance(dropdown, str):
39
+ dropdown_value = dropdown
40
+ return dropdown_value
41
+
42
+ def get_dropdowns(source_dropdown, input_text):
43
+ source_language_name = get_dropdown_value(source_dropdown)
44
+ if input_text and source_language_name == "Detect" or source_language_name.startswith("Detected"):
45
+ source_dropdown, source_language_name = get_auto_detect_source_dropdown(input_text)
46
+ target_dropdown = get_target_dropdown(source_language_name=source_language_name,
47
+ input_text=input_text)
48
+ return source_dropdown, target_dropdown
49
+
50
+ def input_changed(source_language_dropdown, input_text=""):
51
+ return get_dropdowns(source_dropdown=source_language_dropdown,
52
+ input_text=input_text)
53
+
54
+ def translate(input_text, source, target):
55
+ source_readable = source
56
+ if source == "Detect" or source.startswith("Detected"):
57
+ source, _ = auto_detect_language_code(input_text)
58
+ if source in source_lang_dict.keys():
59
+ source = source_lang_dict[source]
60
+ target_lang_dict, _ = get_target_languages(source)
61
+ try:
62
+ target = target_lang_dict[target]
63
+ model = f"Helsinki-NLP/opus-mt-{source}-{target}"
64
+ pipe = pipeline("translation", model=model)
65
+ translation = pipe(input_text)
66
+ return translation[0]['translation_text'], ""
67
+ except KeyError:
68
+ return "", f"Error: Translation from {source_readable} to {target} is not supported by Translation Models"
69
+
70
+
71
+ with gr.Blocks() as demo:
72
+ gr.HTML("""<html>
73
+ <head>
74
+ <style>
75
+ h2 {
76
+ text-align: center;
77
+ }
78
+ </style>
79
+ </head>
80
+ <body>
81
+ <h2>Euskera-EU Basque translator - itzultzailea</h2>
82
+ </body>
83
+ </html>""")
84
+ with gr.Row():
85
+ with gr.Column():
86
+ source_language_dropdown = gr.Dropdown(choices=source_languages,
87
+ value="Detect",
88
+ label="Input Language - Input Hizkuntza")
89
+ input_textbox = gr.Textbox(lines=5, placeholder="Enter text to translate", label="Input Text")
90
+ with gr.Column():
91
+ target_language_dropdown = gr.Dropdown(choices=["Basque", "English", "French", "Spanish"],
92
+ value="Basque",
93
+ label="Output Language - Output Hizkuntza")
94
+ translated_textbox = gr.Textbox(lines=5, placeholder="", label="Translated Text")
95
+ info_label = gr.HTML("")
96
+ btn = gr.Button("Translate - Itzuli")
97
+ source_language_dropdown.change(input_changed, inputs=[source_language_dropdown, input_textbox], outputs=[source_language_dropdown, target_language_dropdown])
98
+ input_textbox.change(input_changed, inputs=[source_language_dropdown, input_textbox], outputs=[source_language_dropdown, target_language_dropdown])
99
+ btn.click(translate, inputs=[input_textbox,
100
+ source_language_dropdown,
101
+ target_language_dropdown],
102
+ outputs=[translated_textbox, info_label])
103
+ gr.Examples(adibide_esaldiak, inputs=[input_textbox])
104
+
105
+ if __name__ == "__main__":
106
+ demo.launch()
gr_requirements.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ -i https://pypi.python.org/simple
2
+ gradio==3.*
3
+ iso639-lang
4
+ pycld2 # In future, maybe use lingua-language-detector
5
+ torch
6
+ transformers
7
+ sentencepiece
8
+ langdetect
9
+ sacremoses
helsinki_models.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ helsinki_models = [
2
+ "Helsinki-NLP/opus-mt-tc-big-itc-eu",
3
+ "Helsinki-NLP/opus-mt-tc-big-eu-itc",
4
+ "Helsinki-NLP/opus-mt-euq-en",
5
+ "Helsinki-NLP/opus-mt-eu-ru",
6
+ "Helsinki-NLP/opus-mt-eu-es",
7
+ "Helsinki-NLP/opus-mt-eu-en",
8
+ "Helsinki-NLP/opus-mt-eu-de",
9
+ "Helsinki-NLP/opus-mt-en-euq",
10
+ "Helsinki-NLP/opus-mt-en-euq",
11
+ "Helsinki-NLP/opus-mt-en-eu",
12
+ "Helsinki-NLP/opus-mt-de-eu",
13
+ "Helsinki-NLP/opus-mt-ru-eu",
14
+ "Helsinki-NLP/opus-mt-es-eu",
15
+ ]
16
+
17
+ def get_clearly_formatted_language_directions():
18
+ # Clearly formatted language directions only
19
+ # Helsinki-NLP/opus-mt-tc-base-bat-zle is ignored
20
+ # Helsinki-NLP/opus-mt-tc-fr-en is accepted due to clarity of source language being fr and target language being en
21
+ language_directions = [model.split("Helsinki-NLP/opus-mt-")[1] for model in helsinki_models
22
+ if (len(model.split("-"))<6 and
23
+ "opus-mt" in model and
24
+ len(model.split("_")) == 1)
25
+ and len(model) < len("Helsinki-NLP/opus-mt-src-trg")]
26
+ return language_directions
images/banner.jpg ADDED
iso639_wrapper.py ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #from iso639 import Lang, iter_langs
2
+ from iso639 import iter_langs
3
+ from regex import R
4
+
5
+ langs = [lang for lang in iter_langs()]
6
+
7
+ # iso 1
8
+ iso1_code_to_name = {lg.pt1: lg.name for lg in langs}
9
+ iso1_name_to_code = {lg.name: lg.pt1 for lg in langs}
10
+
11
+ # iso 2
12
+ iso2b_code_to_name = {lg.pt2b: lg.name for lg in langs}
13
+ iso2b_name_to_code = {lg.name: lg.pt2b for lg in langs}
14
+ iso2t_code_to_name = {lg.pt2t: lg.name for lg in langs}
15
+ iso2t_name_to_code = {lg.name: lg.pt2t for lg in langs}
16
+
17
+ # iso 3
18
+ iso3_code_to_name = {lg.pt3: lg.name for lg in langs}
19
+ iso3_name_to_code = {lg.name: lg.pt3 for lg in langs}
20
+
21
+ # iso 5
22
+ iso5_code_to_name = {lg.pt5: lg.name for lg in langs}
23
+ iso5_name_to_code = {lg.name: lg.pt5 for lg in langs}
24
+
25
+ # https://github.com/Helsinki-NLP/Tatoeba-Challenge/blob/master/README.md#in-more-detail
26
+ helsinki_precendence = ["iso3", "iso5", "iso1", "iso2t", "iso2b"]
27
+
28
+ rename_dict = {"Panjabi": "Punjabi"}
29
+
30
+ def rename_languages(language):
31
+ if language in rename_dict:
32
+ return rename_dict[language]
33
+ return language
34
+
35
+ def rename_return_value(func):
36
+ def wrapper(*args, **kwargs):
37
+ result = func(*args, **kwargs)
38
+ if isinstance(result, str):
39
+ return rename_languages(result)
40
+ elif isinstance(result, list):
41
+ return [rename_languages(item) for item in result]
42
+ elif isinstance(result, dict):
43
+ return {key: rename_languages(value) for key, value in result.items()}
44
+ else:
45
+ return result
46
+ return wrapper
47
+
48
+ @rename_return_value
49
+ def get_name_from_iso_code(iso_code, precedence=helsinki_precendence):
50
+ for code_type in precedence:
51
+ if code_type == "iso1" and iso_code in iso1_code_to_name.keys():
52
+ return iso1_code_to_name[iso_code]
53
+ elif code_type == "iso2b" and iso_code in iso2b_code_to_name.keys():
54
+ return iso2b_code_to_name[iso_code]
55
+ elif code_type == "iso2t" and iso_code in iso2t_code_to_name.keys():
56
+ return iso2t_code_to_name[iso_code]
57
+ elif code_type == "iso3" and iso_code in iso3_code_to_name.keys():
58
+ return iso3_code_to_name[iso_code]
59
+ elif code_type == "iso5" and iso_code in iso5_code_to_name.keys():
60
+ return iso5_code_to_name[iso_code]
language_detection.py ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pycld2 as cld2
2
+ from langdetect import detect
3
+
4
+ def detect_language(input_text):
5
+ if not input_text:
6
+ return "unknown"
7
+ _, _, details = cld2.detect(input_text)
8
+ detected_language = details[0][0].lower()
9
+ if detected_language == "unknown":
10
+ language_code = detect(input_text)
11
+ return language_code
12
+ else:
13
+ return detected_language
language_directions.py ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from helsinki_models import helsinki_models, get_clearly_formatted_language_directions
2
+ from iso639_wrapper import get_name_from_iso_code
3
+ from language_detection import detect_language
4
+ from collections import OrderedDict
5
+ from utils import convert_keys_to_lowercase, match_in_keys, match_in_values
6
+
7
+ def get_all_source_languages():
8
+ """
9
+ Returns a human-readable `dict source_languages_names:codes`
10
+ based on the available models.
11
+ """
12
+ source_languages = {}
13
+ language_directions = get_clearly_formatted_language_directions()
14
+
15
+ for direction in language_directions:
16
+ source_lang_code = direction.split('-')[0]
17
+ source_language_name = get_name_from_iso_code(source_lang_code)
18
+ if source_language_name:
19
+ source_languages[source_language_name] = source_lang_code
20
+ source_languages = OrderedDict(sorted(source_languages.items()))
21
+ all_source_langs_including_auto_detect = \
22
+ { **{'Detect' : 'Detect'}, **source_languages}
23
+ return all_source_langs_including_auto_detect
24
+
25
+ def update_source_languages_dict(source_languages_dict, auto_detected_language):
26
+ source_languages_dict[auto_detected_language] = "Detect"
27
+
28
+ def get_target_languages(source_language_code, input_text=None):
29
+ """
30
+ Returns a human-readable `dict of target languages names to codes`
31
+ based on the available models and the source language passed.
32
+ """
33
+ include_all_languages = False
34
+ if source_language_code == "Detect":
35
+ source_language_code, include_all_languages = auto_detect_language_code(input_text)
36
+
37
+ target_languages = {}
38
+ language_directions = get_clearly_formatted_language_directions()
39
+ for direction in language_directions:
40
+ if direction.startswith(f"{source_language_code}-") or include_all_languages:
41
+ target_language = direction.split('-')[1] # Extracting the last part as the target language
42
+ target_language_name = get_name_from_iso_code(target_language)
43
+ if target_language_name:
44
+ target_languages[target_language_name] = target_language
45
+ return OrderedDict(sorted(target_languages.items())), source_language_code
46
+
47
+ def auto_detect_language_code(input_text):
48
+ DEFAULT_SOURCE_LANGUAGE = "eu"
49
+ detected_language_string = DEFAULT_SOURCE_LANGUAGE
50
+ if not input_text:
51
+ return DEFAULT_SOURCE_LANGUAGE, True
52
+ language_or_code = detect_language(input_text)
53
+ if language_or_code == "unknown":
54
+ return DEFAULT_SOURCE_LANGUAGE, True
55
+ else:
56
+ detected_language_string = match_in_keys(get_all_source_languages(), language_or_code)
57
+ if not detected_language_string:
58
+ detected_language_string = match_in_values(get_all_source_languages(), language_or_code)
59
+ if detected_language_string:
60
+ return detected_language_string, False
61
+ else:
62
+ return DEFAULT_SOURCE_LANGUAGE, True
63
+
64
+
65
+ # Example usage:
66
+ # all_source_languages = get_all_source_languages()
67
+ # print("All Source Languages:", all_source_languages)
68
+
69
+ # source_language_code = "pa" # Replace with your desired source language
70
+ # target_languages = get_target_languages(source_language_code)
71
+ # print(f"Target Languages for {source_language_code}:", target_languages)
requirements.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ -i https://pypi.python.org/simple
2
+ streamlit
3
+ iso639-lang
4
+ pycld2 # In future, maybe use lingua-language-detector
5
+ torch
6
+ transformers
7
+ sentencepiece
8
+ langdetect
9
+ sacremoses
styles/style.css ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ @author: idoia lerchundi
3
+ */
4
+ input[type=message], input[type=email], input[type=text], textarea {
5
+ width: 100%;
6
+ padding: 12px;
7
+ border: 1px solid #ccc;
8
+ border-radius: 4px;
9
+ box-sizing: border-box;
10
+ margin-top: 6px;
11
+ margin-bottom: 16px;
12
+ resize: vertical;
13
+ }
14
+ button[type=submit] {
15
+ background-color: #04AA6D;
16
+ color: white;
17
+ padding: 12px 20px;
18
+ border: none;
19
+ border-radius: 4px;
20
+ cursor: pointer;
21
+ }
22
+ button[type=submit]:hover {
23
+ background-color: #45a049;
24
+ }
25
+ /* Hide Streamlit Branding */
26
+ #MainMenu {visibility: hidden;}
27
+ footer {visibility: hidden;}
28
+ header {visibility: hidden;}
29
+
30
+ .block-container{padding:0 20px 20px 20px}
styles/w3.css ADDED
@@ -0,0 +1,250 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ html{box-sizing:border-box}*,*:before,*:after{box-sizing:inherit}
2
+ html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}
3
+ .w3-menubar{
4
+ width:100%;
5
+ overflow:auto;
6
+ position:absolute;
7
+ top:10px;
8
+ color:rgba(0, 0, 0, 1);
9
+ font-family:Hind;
10
+ text-align:left;
11
+ font-size:16px;
12
+ letter-spacing:0;
13
+ }
14
+ .w3-center .w3-menubar{display:inline-block;width:auto}
15
+ .w3-menubar .w3-menubar-item{padding:10px auto 10px auto;float:left;width:auto;border:none;display:block;outline:0;}
16
+ .w3-menubar .w3-dropdown-hover,.w3-bar .w3-dropdown-click{position:static;float:left}
17
+ .w3-menubar .w3-button{white-space:normal}
18
+ .w3-menubar-block .w3-menubar-item{width:100%;display:block;padding:8px 16px;text-align:left;border:none;white-space:normal;float:none;outline:0}
19
+ .w3-menubar-block.w3-center .w3-menubar-item{text-align:center}.w3-block{display:block;width:100%}
20
+ .w3-top,.w3-bottom{position:relative;width:100%;z-index:1}.w3-top{left:330px;top:0px;}.w3-bottom{bottom:0}
21
+ article,aside,details,figcaption,figure,footer,header,main,menu,nav,section{display:block}summary{display:list-item}
22
+ audio,canvas,progress,video{display:inline-block}progress{vertical-align:baseline}
23
+ audio:not([controls]){display:none;height:0}[hidden],template{display:none}
24
+ a{background-color:transparent}a:active,a:hover{outline-width:0}
25
+ abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}
26
+ b,strong{font-weight:bolder}dfn{font-style:italic}mark{background:#ff0;color:#000}
27
+ small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
28
+ sub{bottom:-0.25em}sup{top:-0.5em}figure{margin:1em 40px}img{border-style:none}
29
+ code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}hr{box-sizing:content-box;height:0;overflow:visible}
30
+ button,input,select,textarea,optgroup{font:inherit;margin:0}optgroup{font-weight:bold}
31
+ button,input{overflow:visible}button,select{text-transform:none}
32
+ button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}
33
+ button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0}
34
+ button:-moz-focusring,[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted ButtonText}
35
+ fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:.35em .625em .75em}
36
+ legend{color:inherit;display:table;max-width:100%;padding:0;white-space:normal}textarea{overflow:auto}
37
+ [type=checkbox],[type=radio]{padding:0}
38
+ [type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}
39
+ [type=search]{-webkit-appearance:textfield;outline-offset:-2px}
40
+ [type=search]::-webkit-search-decoration{-webkit-appearance:none}
41
+ ::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}
42
+ html,body{font-family:Verdana,sans-serif;font-size:15px;line-height:1.5}html{overflow-x:hidden}
43
+ h1{font-size:36px}h2{font-size:30px}h3{font-size:24px}h4{font-size:20px}h5{font-size:18px}h6{font-size:16px}
44
+ .w3-serif{font-family:serif}.w3-sans-serif{font-family:sans-serif}.w3-cursive{font-family:cursive}.w3-monospace{font-family:monospace}
45
+ h1,h2,h3,h4,h5,h6{font-family:"Segoe UI",Arial,sans-serif;font-weight:400;margin:10px 0}.w3-wide{letter-spacing:4px}
46
+ hr{border:0;border-top:1px solid #eee;margin:20px 0}
47
+ .w3-image{max-width:100%;height:auto}img{vertical-align:middle}a{color:inherit}
48
+ .w3-table,.w3-table-all{border-collapse:collapse;border-spacing:0;width:100%;display:table}.w3-table-all{border:1px solid #ccc}
49
+ .w3-bordered tr,.w3-table-all tr{border-bottom:1px solid #ddd}.w3-striped tbody tr:nth-child(even){background-color:#f1f1f1}
50
+ .w3-table-all tr:nth-child(odd){background-color:#fff}.w3-table-all tr:nth-child(even){background-color:#f1f1f1}
51
+ .w3-hoverable tbody tr:hover,.w3-ul.w3-hoverable li:hover{background-color:#ccc}.w3-centered tr th,.w3-centered tr td{text-align:center}
52
+ .w3-table td,.w3-table th,.w3-table-all td,.w3-table-all th{padding:8px 8px;display:table-cell;text-align:left;vertical-align:top}
53
+ .w3-table th:first-child,.w3-table td:first-child,.w3-table-all th:first-child,.w3-table-all td:first-child{padding-left:16px}
54
+ .w3-btn,.w3-button{border:none;display:inline-block;padding:8px 16px;vertical-align:middle;overflow:hidden;text-decoration:none;color:inherit;background-color:inherit;text-align:center;cursor:pointer;white-space:nowrap}
55
+ .w3-btn:hover{box-shadow:0 8px 16px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19)}
56
+ .w3-btn,.w3-button{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
57
+ .w3-disabled,.w3-btn:disabled,.w3-button:disabled{cursor:not-allowed;opacity:0.3}.w3-disabled *,:disabled *{pointer-events:none}
58
+ .w3-btn.w3-disabled:hover,.w3-btn:disabled:hover{box-shadow:none}
59
+ .w3-badge,.w3-tag{background-color:#000;color:#fff;display:inline-block;padding-left:8px;padding-right:8px;text-align:center}.w3-badge{border-radius:50%}
60
+ .w3-ul{list-style-type:none;padding:0;margin:0}.w3-ul li{padding:8px 16px;border-bottom:1px solid #ddd}.w3-ul li:last-child{border-bottom:none}
61
+ .w3-tooltip,.w3-display-container{position:relative}.w3-tooltip .w3-text{display:none}.w3-tooltip:hover .w3-text{display:inline-block}
62
+ .w3-ripple:active{opacity:0.5}.w3-ripple{transition:opacity 0s}
63
+ .w3-input{padding:8px;display:block;border:none;border-bottom:1px solid #ccc;width:100%}
64
+ .w3-select{padding:9px 0;width:100%;border:none;border-bottom:1px solid #ccc}
65
+ .w3-dropdown-click,.w3-dropdown-hover{position:relative;display:inline-block;cursor:pointer}
66
+ .w3-dropdown-hover:hover .w3-dropdown-content{display:block}
67
+ .w3-dropdown-hover:first-child,.w3-dropdown-click:hover{background-color:#ccc;color:#000}
68
+ .w3-dropdown-hover:hover > .w3-button:first-child,.w3-dropdown-click:hover > .w3-button:first-child{background-color:#ccc;color:#000}
69
+ .w3-dropdown-content{cursor:auto;color:#000;background-color:#fff;display:none;position:absolute;min-width:160px;margin:0;padding:0;z-index:1}
70
+ .w3-check,.w3-radio{width:24px;height:24px;position:relative;top:6px}
71
+ .w3-sidebar{height:100%;width:200px;background-color:#fff;position:fixed!important;z-index:1;overflow:auto}
72
+ .w3-bar-block .w3-dropdown-hover,.w3-bar-block .w3-dropdown-click{width:100%}
73
+ .w3-bar-block .w3-dropdown-hover .w3-dropdown-content,.w3-bar-block .w3-dropdown-click .w3-dropdown-content{min-width:100%}
74
+ .w3-bar-block .w3-dropdown-hover .w3-button,.w3-bar-block .w3-dropdown-click .w3-button{width:100%;text-align:left;padding:8px 16px}
75
+ .w3-main,#main{transition:margin-left .4s}
76
+ .w3-modal{z-index:3;display:none;padding-top:100px;position:fixed;left:0;top:0;width:100%;height:100%;overflow:auto;background-color:rgb(0,0,0);background-color:rgba(0,0,0,0.4)}
77
+ .w3-modal-content{margin:auto;background-color:#fff;position:relative;padding:0;outline:0;width:600px}
78
+ .w3-bar{width:100%;overflow:hidden}.w3-center .w3-bar{display:inline-block;width:auto}
79
+ .w3-bar .w3-bar-item{padding:8px 8px 8px 8px;float:right;width:auto;border:none;display:block;outline:0;}
80
+ .w3-bar .w3-dropdown-hover,.w3-bar .w3-dropdown-click{position:static;float:left}
81
+ .w3-bar .w3-button{white-space:normal}
82
+ .w3-bar-block .w3-bar-item{width:100%;display:block;padding:8px 16px;text-align:left;border:none;white-space:normal;float:none;outline:0}
83
+ .w3-bar-block.w3-center .w3-bar-item{text-align:center}.w3-block{display:block;width:100%}
84
+ .w3-responsive{display:block;overflow-x:auto}
85
+ .w3-container:after,.w3-container:before,.w3-panel:after,.w3-panel:before,.w3-row:after,.w3-row:before,.w3-row-padding:after,.w3-row-padding:before,
86
+ .w3-cell-row:before,.w3-cell-row:after,.w3-clear:after,.w3-clear:before,.w3-bar:before,.w3-bar:after{content:"";display:table;clear:both}
87
+ .w3-col,.w3-half,.w3-third,.w3-twothird,.w3-threequarter,.w3-quarter{float:left;width:100%}
88
+ .w3-col.s1{width:8.33333%}.w3-col.s2{width:16.66666%}.w3-col.s3{width:24.99999%}.w3-col.s4{width:33.33333%}
89
+ .w3-col.s5{width:41.66666%}.w3-col.s6{width:49.99999%}.w3-col.s7{width:58.33333%}.w3-col.s8{width:66.66666%}
90
+ .w3-col.s9{width:74.99999%}.w3-col.s10{width:83.33333%}.w3-col.s11{width:91.66666%}.w3-col.s12{width:99.99999%}
91
+ @media (min-width:601px){.w3-col.m1{width:8.33333%}.w3-col.m2{width:16.66666%}.w3-col.m3,.w3-quarter{width:24.99999%}.w3-col.m4,.w3-third{width:33.33333%}
92
+ .w3-col.m5{width:41.66666%}.w3-col.m6,.w3-half{width:49.99999%}.w3-col.m7{width:58.33333%}.w3-col.m8,.w3-twothird{width:66.66666%}
93
+ .w3-col.m9,.w3-threequarter{width:74.99999%}.w3-col.m10{width:83.33333%}.w3-col.m11{width:91.66666%}.w3-col.m12{width:99.99999%}}
94
+ @media (min-width:993px){.w3-col.l1{width:8.33333%}.w3-col.l2{width:16.66666%}.w3-col.l3{width:24.99999%}.w3-col.l4{width:33.33333%}
95
+ .w3-col.l5{width:41.66666%}.w3-col.l6{width:49.99999%}.w3-col.l7{width:58.33333%}.w3-col.l8{width:66.66666%}
96
+ .w3-col.l9{width:74.99999%}.w3-col.l10{width:83.33333%}.w3-col.l11{width:91.66666%}.w3-col.l12{width:99.99999%}}
97
+ .w3-rest{overflow:hidden}.w3-stretch{margin-left:-16px;margin-right:-16px}
98
+ .w3-content,.w3-auto{margin-left:auto;margin-right:auto}.w3-content{max-width:980px}.w3-auto{max-width:1140px}
99
+ .w3-cell-row{display:table;width:100%}.w3-cell{display:table-cell}
100
+ .w3-cell-top{vertical-align:top}.w3-cell-middle{vertical-align:middle}.w3-cell-bottom{vertical-align:bottom}
101
+ .w3-hide{display:none!important}.w3-show-block,.w3-show{display:block!important}.w3-show-inline-block{display:inline-block!important}
102
+ @media (max-width:1205px){.w3-auto{max-width:95%}}
103
+ @media (max-width:600px){.w3-modal-content{margin:0 10px;width:auto!important}.w3-modal{padding-top:30px}
104
+ .w3-dropdown-hover.w3-mobile .w3-dropdown-content,.w3-dropdown-click.w3-mobile .w3-dropdown-content{position:relative}
105
+ .w3-hide-small{display:none!important}.w3-mobile{display:block;width:100%!important}.w3-bar-item.w3-mobile,.w3-dropdown-hover.w3-mobile,.w3-dropdown-click.w3-mobile{text-align:center}
106
+ .w3-dropdown-hover.w3-mobile,.w3-dropdown-hover.w3-mobile .w3-btn,.w3-dropdown-hover.w3-mobile .w3-button,.w3-dropdown-click.w3-mobile,.w3-dropdown-click.w3-mobile .w3-btn,.w3-dropdown-click.w3-mobile .w3-button{width:100%}}
107
+ @media (max-width:768px){.w3-modal-content{width:500px}.w3-modal{padding-top:50px}}
108
+ @media (min-width:993px){.w3-modal-content{width:900px}.w3-hide-large{display:none!important}.w3-sidebar.w3-collapse{display:block!important}}
109
+ @media (max-width:992px) and (min-width:601px){.w3-hide-medium{display:none!important}}
110
+ @media (max-width:992px){.w3-sidebar.w3-collapse{display:none}.w3-main{margin-left:0!important;margin-right:0!important}.w3-auto{max-width:100%}}
111
+ /*w3-top was here */
112
+ .w3-overlay{position:fixed;display:none;width:100%;height:100%;top:0;left:0;right:0;bottom:0;background-color:rgba(0,0,0,0.5);z-index:2}
113
+ .w3-display-topleft{position:absolute;left:0;top:0}.w3-display-topright{position:absolute;right:0;top:0}
114
+ .w3-display-bottomleft{position:absolute;left:0;bottom:0}.w3-display-bottomright{position:absolute;right:0;bottom:0}
115
+ .w3-display-middle{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%)}
116
+ .w3-display-left{position:absolute;top:50%;left:0%;transform:translate(0%,-50%);-ms-transform:translate(-0%,-50%)}
117
+ .w3-display-right{position:absolute;top:50%;right:0%;transform:translate(0%,-50%);-ms-transform:translate(0%,-50%)}
118
+ .w3-display-topmiddle{position:absolute;left:50%;top:0;transform:translate(-50%,0%);-ms-transform:translate(-50%,0%)}
119
+ .w3-display-bottommiddle{position:absolute;left:50%;bottom:0;transform:translate(-50%,0%);-ms-transform:translate(-50%,0%)}
120
+ .w3-display-container:hover .w3-display-hover{display:block}.w3-display-container:hover span.w3-display-hover{display:inline-block}.w3-display-hover{display:none}
121
+ .w3-display-position{position:absolute}
122
+ .w3-circle{border-radius:50%}
123
+ .w3-round-small{border-radius:2px}.w3-round,.w3-round-medium{border-radius:4px}.w3-round-large{border-radius:8px}.w3-round-xlarge{border-radius:16px}.w3-round-xxlarge{border-radius:32px}
124
+ .w3-row-padding,.w3-row-padding>.w3-half,.w3-row-padding>.w3-third,.w3-row-padding>.w3-twothird,.w3-row-padding>.w3-threequarter,.w3-row-padding>.w3-quarter,.w3-row-padding>.w3-col{padding:0 8px}
125
+ .w3-container,.w3-panel{padding:0.0em 0px}.w3-panel{margin-top:16px;margin-bottom:16px}
126
+ .w3-code,.w3-codespan{font-family:Consolas,"courier new";font-size:16px}
127
+ .w3-code{width:auto;background-color:#fff;padding:8px 12px;border-left:4px solid #4CAF50;word-wrap:break-word}
128
+ .w3-codespan{color:crimson;background-color:#f1f1f1;padding-left:4px;padding-right:4px;font-size:110%}
129
+ .w3-card,.w3-card-2{box-shadow:0 2px 5px 0 rgba(0,0,0,0.16),0 2px 10px 0 rgba(0,0,0,0.12)}
130
+ .w3-card-4,.w3-hover-shadow:hover{box-shadow:0 4px 10px 0 rgba(0,0,0,0.2),0 4px 20px 0 rgba(0,0,0,0.19)}
131
+ .w3-spin{animation:w3-spin 2s infinite linear}@keyframes w3-spin{0%{transform:rotate(0deg)}100%{transform:rotate(359deg)}}
132
+ .w3-animate-fading{animation:fading 10s infinite}@keyframes fading{0%{opacity:0}50%{opacity:1}100%{opacity:0}}
133
+ .w3-animate-opacity{animation:opac 0.8s}@keyframes opac{from{opacity:0} to{opacity:1}}
134
+ .w3-animate-top{position:relative;animation:animatetop 0.4s}@keyframes animatetop{from{top:-300px;opacity:0} to{top:0;opacity:1}}
135
+ .w3-animate-left{position:relative;animation:animateleft 0.4s}@keyframes animateleft{from{left:-300px;opacity:0} to{left:0;opacity:1}}
136
+ .w3-animate-right{position:relative;animation:animateright 0.4s}@keyframes animateright{from{right:-300px;opacity:0} to{right:0;opacity:1}}
137
+ .w3-animate-bottom{position:relative;animation:animatebottom 0.4s}@keyframes animatebottom{from{bottom:-300px;opacity:0} to{bottom:0;opacity:1}}
138
+ .w3-animate-zoom {animation:animatezoom 0.6s}@keyframes animatezoom{from{transform:scale(0)} to{transform:scale(1)}}
139
+ .w3-animate-input{transition:width 0.4s ease-in-out}.w3-animate-input:focus{width:100%!important}
140
+ .w3-opacity,.w3-hover-opacity:hover{opacity:0.60}.w3-opacity-off,.w3-hover-opacity-off:hover{opacity:1}
141
+ .w3-opacity-max{opacity:0.25}.w3-opacity-min{opacity:0.75}
142
+ .w3-greyscale-max,.w3-grayscale-max,.w3-hover-greyscale:hover,.w3-hover-grayscale:hover{filter:grayscale(100%)}
143
+ .w3-greyscale,.w3-grayscale{filter:grayscale(75%)}.w3-greyscale-min,.w3-grayscale-min{filter:grayscale(50%)}
144
+ .w3-sepia{filter:sepia(75%)}.w3-sepia-max,.w3-hover-sepia:hover{filter:sepia(100%)}.w3-sepia-min{filter:sepia(50%)}
145
+ .w3-tiny{font-size:10px!important}.w3-small{font-size:12px!important}.w3-medium{font-size:15px!important}.w3-large{font-size:18px!important}
146
+ .w3-xlarge{font-size:24px!important}.w3-xxlarge{font-size:36px!important}.w3-xxxlarge{font-size:48px!important}.w3-jumbo{font-size:64px!important}
147
+ .w3-left-align{text-align:left!important}.w3-right-align{text-align:right!important}.w3-justify{text-align:justify!important}.w3-center{text-align:center!important}
148
+ .w3-border-0{border:0!important}.w3-border{border:1px solid #ccc!important}
149
+ .w3-border-top{border-top:1px solid #ccc!important}.w3-border-bottom{border-bottom:1px solid #ccc!important}
150
+ .w3-border-left{border-left:1px solid #ccc!important}.w3-border-right{border-right:1px solid #ccc!important}
151
+ .w3-topbar{border-top:6px solid #ccc!important}.w3-bottombar{border-bottom:6px solid #ccc!important}
152
+ .w3-leftbar{border-left:6px solid #ccc!important}.w3-rightbar{border-right:6px solid #ccc!important}
153
+ .w3-section,.w3-code{margin-top:16px!important;margin-bottom:16px!important}
154
+ .w3-margin{margin:16px!important}.w3-margin-top{margin-top:16px!important}.w3-margin-bottom{margin-bottom:16px!important}
155
+ .w3-margin-left{margin-left:16px!important}.w3-margin-right{margin-right:16px!important}
156
+ .w3-padding-small{padding:4px 8px!important}.w3-padding{padding:8px 16px!important}.w3-padding-large{padding:12px 24px!important}
157
+ .w3-padding-16{padding-top:16px!important;padding-bottom:16px!important}.w3-padding-24{padding-top:24px!important;padding-bottom:24px!important}
158
+ .w3-padding-32{padding-top:32px!important;padding-bottom:32px!important}.w3-padding-48{padding-top:48px!important;padding-bottom:48px!important}
159
+ .w3-padding-64{padding-top:64px!important;padding-bottom:64px!important}
160
+ .w3-padding-top-64{padding-top:64px!important}.w3-padding-top-48{padding-top:48px!important}
161
+ .w3-padding-top-32{padding-top:32px!important}.w3-padding-top-24{padding-top:24px!important}
162
+ .w3-left{float:left!important}.w3-right{float:right!important}
163
+ .w3-button:hover{color:#000!important;background-color:#ccc!important}
164
+ .w3-transparent,.w3-hover-none:hover{background-color:transparent!important}
165
+ .w3-hover-none:hover{box-shadow:none!important}
166
+ /* Colors */
167
+ .w3-amber,.w3-hover-amber:hover{color:#000!important;background-color:#ffc107!important}
168
+ .w3-aqua,.w3-hover-aqua:hover{color:#000!important;background-color:#00ffff!important}
169
+ .w3-blue,.w3-hover-blue:hover{color:#fff!important;background-color:#2196F3!important}
170
+ .w3-light-blue,.w3-hover-light-blue:hover{color:#000!important;background-color:#87CEEB!important}
171
+ .w3-brown,.w3-hover-brown:hover{color:#fff!important;background-color:#795548!important}
172
+ .w3-cyan,.w3-hover-cyan:hover{color:#000!important;background-color:#00bcd4!important}
173
+ .w3-blue-grey,.w3-hover-blue-grey:hover,.w3-blue-gray,.w3-hover-blue-gray:hover{color:#fff!important;background-color:#607d8b!important}
174
+ .w3-green,.w3-hover-green:hover{color:#fff!important;background-color:#4CAF50!important}
175
+ .w3-light-green,.w3-hover-light-green:hover{color:#000!important;background-color:#8bc34a!important}
176
+ .w3-indigo,.w3-hover-indigo:hover{color:#fff!important;background-color:#3f51b5!important}
177
+ .w3-khaki,.w3-hover-khaki:hover{color:#000!important;background-color:#f0e68c!important}
178
+ .w3-lime,.w3-hover-lime:hover{color:#000!important;background-color:#cddc39!important}
179
+ .w3-orange,.w3-hover-orange:hover{color:#000!important;background-color:#ff9800!important}
180
+ .w3-deep-orange,.w3-hover-deep-orange:hover{color:#fff!important;background-color:#ff5722!important}
181
+ .w3-pink,.w3-hover-pink:hover{color:#fff!important;background-color:#e91e63!important}
182
+ .w3-purple,.w3-hover-purple:hover{color:#fff!important;background-color:#9c27b0!important}
183
+ .w3-deep-purple,.w3-hover-deep-purple:hover{color:#fff!important;background-color:#673ab7!important}
184
+ .w3-red,.w3-hover-red:hover{color:#fff!important;background-color:#f44336!important}
185
+ .w3-sand,.w3-hover-sand:hover{color:#000!important;background-color:#fdf5e6!important}
186
+ .w3-teal,.w3-hover-teal:hover{color:#fff!important;background-color:#009688!important}
187
+ .w3-yellow,.w3-hover-yellow:hover{color:#000!important;background-color:#ffeb3b!important}
188
+ .w3-white,.w3-hover-white:hover{color:#000!important;background-color:#fff!important}
189
+ .w3-black,.w3-hover-black:hover{color:#fff!important;background-color:#000!important}
190
+ .w3-grey,.w3-hover-grey:hover,.w3-gray,.w3-hover-gray:hover{color:#000!important;background-color:#9e9e9e!important}
191
+ .w3-light-grey,.w3-hover-light-grey:hover,.w3-light-gray,.w3-hover-light-gray:hover{color:#000!important;background-color:#f1f1f1!important}
192
+ .w3-dark-grey,.w3-hover-dark-grey:hover,.w3-dark-gray,.w3-hover-dark-gray:hover{color:#fff!important;background-color:#616161!important}
193
+ .w3-pale-red,.w3-hover-pale-red:hover{color:#000!important;background-color:#ffdddd!important}
194
+ .w3-pale-green,.w3-hover-pale-green:hover{color:#000!important;background-color:#ddffdd!important}
195
+ .w3-pale-yellow,.w3-hover-pale-yellow:hover{color:#000!important;background-color:#ffffcc!important}
196
+ .w3-pale-blue,.w3-hover-pale-blue:hover{color:#000!important;background-color:#ddffff!important}
197
+ .w3-text-amber,.w3-hover-text-amber:hover{color:#ffc107!important}
198
+ .w3-text-aqua,.w3-hover-text-aqua:hover{color:#00ffff!important}
199
+ .w3-text-blue,.w3-hover-text-blue:hover{color:#2196F3!important}
200
+ .w3-text-light-blue,.w3-hover-text-light-blue:hover{color:#87CEEB!important}
201
+ .w3-text-brown,.w3-hover-text-brown:hover{color:#795548!important}
202
+ .w3-text-cyan,.w3-hover-text-cyan:hover{color:#00bcd4!important}
203
+ .w3-text-blue-grey,.w3-hover-text-blue-grey:hover,.w3-text-blue-gray,.w3-hover-text-blue-gray:hover{color:#607d8b!important}
204
+ .w3-text-green,.w3-hover-text-green:hover{color:#4CAF50!important}
205
+ .w3-text-light-green,.w3-hover-text-light-green:hover{color:#8bc34a!important}
206
+ .w3-text-indigo,.w3-hover-text-indigo:hover{color:#3f51b5!important}
207
+ .w3-text-khaki,.w3-hover-text-khaki:hover{color:#b4aa50!important}
208
+ .w3-text-lime,.w3-hover-text-lime:hover{color:#cddc39!important}
209
+ .w3-text-orange,.w3-hover-text-orange:hover{color:#ff9800!important}
210
+ .w3-text-deep-orange,.w3-hover-text-deep-orange:hover{color:#ff5722!important}
211
+ .w3-text-pink,.w3-hover-text-pink:hover{color:#e91e63!important}
212
+ .w3-text-purple,.w3-hover-text-purple:hover{color:#9c27b0!important}
213
+ .w3-text-deep-purple,.w3-hover-text-deep-purple:hover{color:#673ab7!important}
214
+ .w3-text-red,.w3-hover-text-red:hover{color:#f44336!important}
215
+ .w3-text-sand,.w3-hover-text-sand:hover{color:#fdf5e6!important}
216
+ .w3-text-teal,.w3-hover-text-teal:hover{color:#009688!important}
217
+ .w3-text-yellow,.w3-hover-text-yellow:hover{color:#d2be0e!important}
218
+ .w3-text-white,.w3-hover-text-white:hover{color:#fff!important}
219
+ .w3-text-black,.w3-hover-text-black:hover{color:#000!important}
220
+ .w3-text-grey,.w3-hover-text-grey:hover,.w3-text-gray,.w3-hover-text-gray:hover{color:#757575!important}
221
+ .w3-text-light-grey,.w3-hover-text-light-grey:hover,.w3-text-light-gray,.w3-hover-text-light-gray:hover{color:#f1f1f1!important}
222
+ .w3-text-dark-grey,.w3-hover-text-dark-grey:hover,.w3-text-dark-gray,.w3-hover-text-dark-gray:hover{color:#3a3a3a!important}
223
+ .w3-border-amber,.w3-hover-border-amber:hover{border-color:#ffc107!important}
224
+ .w3-border-aqua,.w3-hover-border-aqua:hover{border-color:#00ffff!important}
225
+ .w3-border-blue,.w3-hover-border-blue:hover{border-color:#2196F3!important}
226
+ .w3-border-light-blue,.w3-hover-border-light-blue:hover{border-color:#87CEEB!important}
227
+ .w3-border-brown,.w3-hover-border-brown:hover{border-color:#795548!important}
228
+ .w3-border-cyan,.w3-hover-border-cyan:hover{border-color:#00bcd4!important}
229
+ .w3-border-blue-grey,.w3-hover-border-blue-grey:hover,.w3-border-blue-gray,.w3-hover-border-blue-gray:hover{border-color:#607d8b!important}
230
+ .w3-border-green,.w3-hover-border-green:hover{border-color:#4CAF50!important}
231
+ .w3-border-light-green,.w3-hover-border-light-green:hover{border-color:#8bc34a!important}
232
+ .w3-border-indigo,.w3-hover-border-indigo:hover{border-color:#3f51b5!important}
233
+ .w3-border-khaki,.w3-hover-border-khaki:hover{border-color:#f0e68c!important}
234
+ .w3-border-lime,.w3-hover-border-lime:hover{border-color:#cddc39!important}
235
+ .w3-border-orange,.w3-hover-border-orange:hover{border-color:#ff9800!important}
236
+ .w3-border-deep-orange,.w3-hover-border-deep-orange:hover{border-color:#ff5722!important}
237
+ .w3-border-pink,.w3-hover-border-pink:hover{border-color:#e91e63!important}
238
+ .w3-border-purple,.w3-hover-border-purple:hover{border-color:#9c27b0!important}
239
+ .w3-border-deep-purple,.w3-hover-border-deep-purple:hover{border-color:#673ab7!important}
240
+ .w3-border-red,.w3-hover-border-red:hover{border-color:#f44336!important}
241
+ .w3-border-sand,.w3-hover-border-sand:hover{border-color:#fdf5e6!important}
242
+ .w3-border-teal,.w3-hover-border-teal:hover{border-color:#009688!important}
243
+ .w3-border-yellow,.w3-hover-border-yellow:hover{border-color:#ffeb3b!important}
244
+ .w3-border-white,.w3-hover-border-white:hover{border-color:#fff!important}
245
+ .w3-border-black,.w3-hover-border-black:hover{border-color:#000!important}
246
+ .w3-border-grey,.w3-hover-border-grey:hover,.w3-border-gray,.w3-hover-border-gray:hover{border-color:#9e9e9e!important}
247
+ .w3-border-light-grey,.w3-hover-border-light-grey:hover,.w3-border-light-gray,.w3-hover-border-light-gray:hover{border-color:#f1f1f1!important}
248
+ .w3-border-dark-grey,.w3-hover-border-dark-grey:hover,.w3-border-dark-gray,.w3-hover-border-dark-gray:hover{border-color:#616161!important}
249
+ .w3-border-pale-red,.w3-hover-border-pale-red:hover{border-color:#ffe7e7!important}.w3-border-pale-green,.w3-hover-border-pale-green:hover{border-color:#e7ffe7!important}
250
+ .w3-border-pale-yellow,.w3-hover-border-pale-yellow:hover{border-color:#ffffcc!important}.w3-border-pale-blue,.w3-hover-border-pale-blue:hover{border-color:#e7ffff!important}
utils.py ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from functools import cache
2
+
3
+
4
+ def convert_keys_to_lowercase(input_dict):
5
+ return {key.lower(): value for key, value in input_dict.items()}
6
+
7
+ def match_in_keys(dictionary, search_string):
8
+ lowercase_dict = convert_keys_to_lowercase(dictionary)
9
+ if search_string.lower() in list(lowercase_dict.keys()):
10
+ return lowercase_dict.get(search_string.lower())
11
+ for l_key in lowercase_dict.keys():
12
+ if l_key.startswith(search_string.lower()):
13
+ return lowercase_dict.get(l_key)
14
+
15
+ def match_in_values(dictionary, search_string):
16
+ lowercase_dict = convert_keys_to_lowercase(dictionary)
17
+ if search_string.lower() in list(lowercase_dict.values()):
18
+ return search_string