├── Master
├── requirements.txt
├── coloring-requirements.txt
├── assets
│ ├── img
│ │ └── favicon.png
│ ├── css
│ │ ├── styles.css
│ │ ├── Navigation-with-Search.css
│ │ └── Header-Dark.css
│ ├── js
│ │ ├── bs-init.js
│ │ ├── lists-control.js
│ │ ├── DataTable---Fully-BSS-Editable.js
│ │ └── jquery.min.js
│ └── bootstrap
│ │ └── js
│ │ └── bootstrap.min.js
├── threats.py
├── interface.py
└── templates
│ └── index.html
├── Screenshots
├── how.png
├── Main_part(1).png
├── Main_part(2).png
├── close_button_prompt.PNG
└── Details
│ ├── Threats table
│ ├── threats_table.PNG
│ ├── arp_threat_bubble.PNG
│ ├── ping_threat_bubble.PNG
│ └── Notifications
│ │ ├── threats_notification.PNG
│ │ └── threats_alternative_notification.PNG
│ ├── Monitoring table
│ ├── monitoring_table.PNG
│ ├── packet_details_(1).PNG
│ ├── packet_details_(2).PNG
│ └── Buttons
│ │ ├── Monitor_copy_button.PNG
│ │ ├── Monitor_export_button.PNG
│ │ ├── Monitor_print_button.PNG
│ │ ├── simple_search_example.PNG
│ │ └── detailed_search_example.PNG
│ └── Connected device table
│ ├── device_details_bubble.PNG
│ └── connected_devices_table.PNG
├── run.bat
├── LICENSE
├── .gitignore
├── README.md
└── Client
└── main.go
/Master/requirements.txt:
--------------------------------------------------------------------------------
1 | flask
2 | requests
3 |
--------------------------------------------------------------------------------
/Master/coloring-requirements.txt:
--------------------------------------------------------------------------------
1 | colorama
2 | win_unicode_console
3 |
--------------------------------------------------------------------------------
/Screenshots/how.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/D4Vinci/EagleEye/HEAD/Screenshots/how.png
--------------------------------------------------------------------------------
/Screenshots/Main_part(1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/D4Vinci/EagleEye/HEAD/Screenshots/Main_part(1).png
--------------------------------------------------------------------------------
/Screenshots/Main_part(2).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/D4Vinci/EagleEye/HEAD/Screenshots/Main_part(2).png
--------------------------------------------------------------------------------
/Master/assets/img/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/D4Vinci/EagleEye/HEAD/Master/assets/img/favicon.png
--------------------------------------------------------------------------------
/Screenshots/close_button_prompt.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/D4Vinci/EagleEye/HEAD/Screenshots/close_button_prompt.PNG
--------------------------------------------------------------------------------
/Screenshots/Details/Threats table/threats_table.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/D4Vinci/EagleEye/HEAD/Screenshots/Details/Threats table/threats_table.PNG
--------------------------------------------------------------------------------
/Screenshots/Details/Threats table/arp_threat_bubble.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/D4Vinci/EagleEye/HEAD/Screenshots/Details/Threats table/arp_threat_bubble.PNG
--------------------------------------------------------------------------------
/Screenshots/Details/Monitoring table/monitoring_table.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/D4Vinci/EagleEye/HEAD/Screenshots/Details/Monitoring table/monitoring_table.PNG
--------------------------------------------------------------------------------
/Screenshots/Details/Threats table/ping_threat_bubble.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/D4Vinci/EagleEye/HEAD/Screenshots/Details/Threats table/ping_threat_bubble.PNG
--------------------------------------------------------------------------------
/Screenshots/Details/Monitoring table/packet_details_(1).PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/D4Vinci/EagleEye/HEAD/Screenshots/Details/Monitoring table/packet_details_(1).PNG
--------------------------------------------------------------------------------
/Screenshots/Details/Monitoring table/packet_details_(2).PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/D4Vinci/EagleEye/HEAD/Screenshots/Details/Monitoring table/packet_details_(2).PNG
--------------------------------------------------------------------------------
/run.bat:
--------------------------------------------------------------------------------
1 | start cmd /k "cd Master && color a && prompt Master$g && python interface.py"
2 | start cmd /k "cd Client && color F0 && prompt Client$g && go run main.go"
3 |
--------------------------------------------------------------------------------
/Screenshots/Details/Connected device table/device_details_bubble.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/D4Vinci/EagleEye/HEAD/Screenshots/Details/Connected device table/device_details_bubble.PNG
--------------------------------------------------------------------------------
/Screenshots/Details/Monitoring table/Buttons/Monitor_copy_button.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/D4Vinci/EagleEye/HEAD/Screenshots/Details/Monitoring table/Buttons/Monitor_copy_button.PNG
--------------------------------------------------------------------------------
/Screenshots/Details/Connected device table/connected_devices_table.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/D4Vinci/EagleEye/HEAD/Screenshots/Details/Connected device table/connected_devices_table.PNG
--------------------------------------------------------------------------------
/Screenshots/Details/Monitoring table/Buttons/Monitor_export_button.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/D4Vinci/EagleEye/HEAD/Screenshots/Details/Monitoring table/Buttons/Monitor_export_button.PNG
--------------------------------------------------------------------------------
/Screenshots/Details/Monitoring table/Buttons/Monitor_print_button.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/D4Vinci/EagleEye/HEAD/Screenshots/Details/Monitoring table/Buttons/Monitor_print_button.PNG
--------------------------------------------------------------------------------
/Screenshots/Details/Monitoring table/Buttons/simple_search_example.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/D4Vinci/EagleEye/HEAD/Screenshots/Details/Monitoring table/Buttons/simple_search_example.PNG
--------------------------------------------------------------------------------
/Screenshots/Details/Monitoring table/Buttons/detailed_search_example.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/D4Vinci/EagleEye/HEAD/Screenshots/Details/Monitoring table/Buttons/detailed_search_example.PNG
--------------------------------------------------------------------------------
/Screenshots/Details/Threats table/Notifications/threats_notification.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/D4Vinci/EagleEye/HEAD/Screenshots/Details/Threats table/Notifications/threats_notification.PNG
--------------------------------------------------------------------------------
/Screenshots/Details/Threats table/Notifications/threats_alternative_notification.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/D4Vinci/EagleEye/HEAD/Screenshots/Details/Threats table/Notifications/threats_alternative_notification.PNG
--------------------------------------------------------------------------------
/Master/assets/css/styles.css:
--------------------------------------------------------------------------------
1 | td.details-control {
2 | text-align: center;
3 | color: forestgreen;
4 | cursor: pointer;
5 | }
6 |
7 | tr.shown td.details-control {
8 | text-align: center;
9 | color: red;
10 | }
11 |
12 | a.not-link {
13 | color: inherit;
14 | text-decoration: none;
15 | }
16 |
17 |
--------------------------------------------------------------------------------
/Master/assets/js/bs-init.js:
--------------------------------------------------------------------------------
1 |
2 | if (window.innerWidth < 768) {
3 | [].slice.call(document.querySelectorAll('[data-bss-disabled-mobile]')).forEach(function (elem) {
4 | elem.classList.remove('animated');
5 | elem.removeAttribute('data-bss-hover-animate');
6 | elem.removeAttribute('data-aos');
7 | });
8 | }
9 |
10 | document.addEventListener('DOMContentLoaded', function() {
11 |
12 | var hoverAnimationTriggerList = [].slice.call(document.querySelectorAll('[data-bss-hover-animate]'));
13 | var hoverAnimationList = hoverAnimationTriggerList.forEach(function (hoverAnimationEl) {
14 | hoverAnimationEl.addEventListener('mouseenter', function(e){ e.target.classList.add('animated', e.target.dataset.bssHoverAnimate) });
15 | hoverAnimationEl.addEventListener('mouseleave', function(e){ e.target.classList.remove('animated', e.target.dataset.bssHoverAnimate) });
16 | });
17 | }, false);
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Karim shoair
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | pip-wheel-metadata/
24 | share/python-wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 | MANIFEST
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .nox/
44 | .coverage
45 | .coverage.*
46 | .cache
47 | nosetests.xml
48 | coverage.xml
49 | *.cover
50 | *.py,cover
51 | .hypothesis/
52 | .pytest_cache/
53 |
54 | # Translations
55 | *.mo
56 | *.pot
57 |
58 | # Django stuff:
59 | *.log
60 | local_settings.py
61 | db.sqlite3
62 | db.sqlite3-journal
63 |
64 | # Flask stuff:
65 | instance/
66 | .webassets-cache
67 |
68 | # Scrapy stuff:
69 | .scrapy
70 |
71 | # Sphinx documentation
72 | docs/_build/
73 |
74 | # PyBuilder
75 | target/
76 |
77 | # Jupyter Notebook
78 | .ipynb_checkpoints
79 |
80 | # IPython
81 | profile_default/
82 | ipython_config.py
83 |
84 | # pyenv
85 | .python-version
86 |
87 | # pipenv
88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
91 | # install all needed dependencies.
92 | #Pipfile.lock
93 |
94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
95 | __pypackages__/
96 |
97 | # Celery stuff
98 | celerybeat-schedule
99 | celerybeat.pid
100 |
101 | # SageMath parsed files
102 | *.sage.py
103 |
104 | # Environments
105 | .env
106 | .venv
107 | env/
108 | venv/
109 | ENV/
110 | env.bak/
111 | venv.bak/
112 |
113 | # Spyder project settings
114 | .spyderproject
115 | .spyproject
116 |
117 | # Rope project settings
118 | .ropeproject
119 |
120 | # mkdocs documentation
121 | /site
122 |
123 | # mypy
124 | .mypy_cache/
125 | .dmypy.json
126 | dmypy.json
127 |
128 | # Pyre type checker
129 | .pyre/
130 |
--------------------------------------------------------------------------------
/Master/assets/js/lists-control.js:
--------------------------------------------------------------------------------
1 | $("#exit").click(function(){
2 | if (confirm("Are you sure to close EagleEye?")){
3 | $.get("/exit", function(data, status){});
4 | close();
5 | }
6 | });
7 |
8 | document.addEventListener('DOMContentLoaded', function() {
9 | if (!Notification) {
10 | alert('Desktop notifications not available in your browser. Try Chromium.');
11 | return;
12 | }
13 |
14 | if (Notification.permission !== 'granted')
15 | Notification.requestPermission();
16 | });
17 |
18 |
19 | function notify(text) {
20 | if (Notification.permission !== 'granted'){
21 | Notification.requestPermission();
22 | }
23 | var notification = new Notification('Security Alert!', {
24 | icon: '/assets/img/favicon.png',
25 | body: text,
26 | });
27 | notification.onclick = function() {
28 | window.open('#threats-list');
29 | };
30 | return true;
31 | }
32 |
33 | var ips = [];
34 | setInterval(function(){
35 | try{
36 | $.getJSON('/devices_list', function(data) {
37 | // console.log(data);
38 | for (var i in data) {
39 | if(ips.includes(data[i].device_ip)==false){
40 | ips.push(data[i].device_ip);
41 | $('#devices-list').append( "
"+ data[i].device_ip +" ");
42 | }
43 | }
44 | });
45 | } catch(e){
46 | console.log(e);
47 | }
48 | }
49 | ,5000);
50 |
51 | var threats = [];
52 | setInterval(function(){
53 | $.getJSON('/threats_list', function(data) {
54 | try {
55 | // console.log(data);
56 | for (var threat of Object.keys(data)) {
57 | if(threats.includes(threat)==false){
58 | threats.push(threat);
59 | if(!notify(data[threat].info.title)){
60 | // $('#alert-body').text(data[threat].info.title);
61 | // $('.alert').css('visibility', 'visible');
62 | }
63 | $('#threats-list').append( ""+ data[threat].info.title +" ");
64 | }
65 | }
66 | } catch(e){
67 | console.log(e);
68 | }
69 | });
70 | }
71 | ,5000);
72 |
--------------------------------------------------------------------------------
/Master/assets/css/Navigation-with-Search.css:
--------------------------------------------------------------------------------
1 | .navigation-clean-search {
2 | background: #fff;
3 | padding-top: .75rem;
4 | padding-bottom: .75rem;
5 | color: #333;
6 | border-radius: 0;
7 | box-shadow: none;
8 | border: none;
9 | margin-bottom: 0;
10 | }
11 |
12 | @media (min-width:768px) {
13 | .navigation-clean-search {
14 | padding-top: 1rem;
15 | padding-bottom: 1rem;
16 | }
17 | }
18 |
19 | .navigation-clean-search .navbar-brand {
20 | font-weight: bold;
21 | color: inherit;
22 | }
23 |
24 | .navigation-clean-search .navbar-brand:hover {
25 | color: #222;
26 | }
27 |
28 | .navigation-clean-search .navbar-toggler {
29 | border-color: #ddd;
30 | }
31 |
32 | .navigation-clean-search .navbar-toggler:hover, .navigation-clean-search .navbar-toggler:focus {
33 | background: none;
34 | }
35 |
36 | .navigation-clean-search .navbar-toggler {
37 | color: #888;
38 | }
39 |
40 | .navigation-clean-search .navbar-collapse, .navigation-clean-search .form-inline {
41 | border-top-color: #ddd;
42 | }
43 |
44 | .navigation-clean-search .navbar-nav a.active, .navigation-clean-search .navbar-nav > .show > a {
45 | background: none;
46 | box-shadow: none;
47 | }
48 |
49 | .navigation-clean-search.navbar-light .navbar-nav a.active, .navigation-clean-search.navbar-light .navbar-nav a.active:focus, .navigation-clean-search.navbar-light .navbar-nav a.active:hover {
50 | color: #8f8f8f;
51 | box-shadow: none;
52 | background: none;
53 | pointer-events: none;
54 | }
55 |
56 | .navigation-clean-search.navbar .navbar-nav .nav-link {
57 | padding-left: 18px;
58 | padding-right: 18px;
59 | }
60 |
61 | .navigation-clean-search.navbar-light .navbar-nav .nav-link {
62 | color: #465765;
63 | }
64 |
65 | .navigation-clean-search.navbar-light .navbar-nav .nav-link:focus, .navigation-clean-search.navbar-light .navbar-nav .nav-link:hover {
66 | color: #37434d !important;
67 | background-color: transparent;
68 | }
69 |
70 | .navigation-clean-search .action-button, .navigation-clean-button .action-button:active {
71 | background: #56c6c6;
72 | border-radius: 20px;
73 | font-size: inherit;
74 | color: #fff !important;
75 | box-shadow: none;
76 | border: none;
77 | text-shadow: none;
78 | padding: 8px 20px;
79 | transition: background-color 0.25s;
80 | }
81 |
82 | .navigation-clean-search .action-button:hover, .navigation-clean-search .action-button:focus {
83 | background: #66d7d7;
84 | }
85 |
86 | .navigation-clean-search .form-inline label {
87 | color: #ccc;
88 | }
89 |
90 | .navigation-clean-search .form-inline .search-field {
91 | background: none;
92 | border: none;
93 | border-bottom: 1px solid transparent;
94 | border-radius: 0;
95 | color: #ccc;
96 | box-shadow: none;
97 | color: inherit;
98 | transition: border-bottom-color 0.3s;
99 | }
100 |
101 | @media (max-width:767px) {
102 | .navigation-clean-search .form-inline .search-field {
103 | display: inline-block;
104 | width: 80%;
105 | }
106 | }
107 |
108 | .navigation-clean-search .form-inline .search-field:focus {
109 | border-bottom: 1px solid #ccc;
110 | }
111 |
112 |
--------------------------------------------------------------------------------
/Master/threats.py:
--------------------------------------------------------------------------------
1 | import requests, json, time, sys, os, random, traceback, socket, copy
2 | import concurrent.futures, threading
3 | from base64 import b64encode
4 | global current_input, valid_device
5 | current_input = False
6 |
7 | if os.name=="nt":
8 | try:
9 | import win_unicode_console , colorama
10 | win_unicode_console.enable()
11 | colorama.init()
12 | except:
13 | G = Y = B = R = W = M = C = end = Bold = underline = ''
14 |
15 | # Colors
16 | G, B, R, W, M, C, end, Bold, underline = '\033[32m', '\033[94m', '\033[31m', '\x1b[37m', '\x1b[35m', '\x1b[36m', '\033[0m', "\033[1m", "\033[4m"
17 |
18 |
19 | threats_classes = []
20 |
21 | class threats_checker:
22 | def __init__(self, packets):
23 | self.packets = packets
24 | self.results = {}
25 | self.settings = {
26 | "icmp_sweep":{
27 | "threshold":15
28 | },
29 | "arp_sweep":{
30 | "threshold":25
31 | }
32 | }
33 | self.info = {
34 | "icmp_sweep":{
35 | "title":"An attacker attempted to do a ping sweep attack on device(s) on the network!",
36 | "reference":"https://en.wikipedia.org/wiki/Ping_sweep",
37 | },
38 | "arp_sweep":{
39 | "title":"An attacker attempted to do a arp sweep attack on device(s) on the network!",
40 | "reference":"https://netscantools.blogspot.com/2009/06/arp-scan-versus-ping-sweep.html",
41 | }
42 | }
43 | self.checkers = [self.icmp_sweep, self.arp_sweep]
44 |
45 | def icmp_sweep(self):
46 | _name = "icmp_sweep"
47 | highest_repeat = lambda x:max(set(x), key = x.count)
48 | echo_packets = []
49 | for packet in self.packets:
50 | if "icmp" in packet["protocols"].lower():
51 | if int(packet.get("ICMPType",10)) in [0,8]: # Echo or echo reply type
52 | echo_packets.append(packet)
53 | list_of_src = [p["srcip"] for p in echo_packets]
54 | if list_of_src:
55 | highest_sender = highest_repeat(list_of_src) # The most famous one in the network lol
56 | if list_of_src.count(highest_sender)<=1:
57 | highest_sender = None
58 | if highest_sender:
59 | if len(echo_packets)>self.settings[_name]["threshold"]:
60 | return { _name:{ "source":highest_sender, "count":len(echo_packets), "info":self.info[_name] } }
61 | return None
62 |
63 | def arp_sweep(self):
64 | _name = "arp_sweep"
65 | highest_repeat = lambda x:max(set(x), key = x.count)
66 | arp_packets = []
67 | for packet in self.packets:
68 | if "arp" in packet["protocols"].lower():
69 | if packet["dstmac"].lower()=="ff:ff:ff:ff:ff:ff":
70 | arp_packets.append(packet)
71 | list_of_src = [p["srcmac"] for p in arp_packets]
72 | if list_of_src:
73 | highest_sender = highest_repeat(list_of_src) # The most famous one in the network lol
74 | if list_of_src.count(highest_sender)<=1:
75 | highest_sender = None
76 | if highest_sender:
77 | if len(arp_packets)>self.settings[_name]["threshold"]:
78 | return { _name:{ "source":highest_sender, "count":len(arp_packets), "info":self.info[_name] } }
79 | return None
80 |
81 | def helper(self, function):
82 | return function()
83 |
84 | def launch(self):
85 | with concurrent.futures.ThreadPoolExecutor(max_workers=1000) as executor:
86 | for result in executor.map(self.helper, self.checkers):
87 | if result:
88 | self.results.update(result)
89 | return self.results
90 |
--------------------------------------------------------------------------------
/Master/assets/css/Header-Dark.css:
--------------------------------------------------------------------------------
1 | .header-dark {
2 | background: url(mountain_bg.jpg) #444;
3 | background-size: cover;
4 | padding-bottom: 80px;
5 | }
6 |
7 | @media (min-width:768px) {
8 | .header-dark {
9 | padding-bottom: 120px;
10 | }
11 | }
12 |
13 | .header-dark .navbar {
14 | background: transparent;
15 | color: #fff;
16 | border-radius: 0;
17 | box-shadow: none;
18 | border: none;
19 | }
20 |
21 | @media (min-width:768px) {
22 | .header-dark .navbar {
23 | padding-top: .75rem;
24 | padding-bottom: .75rem;
25 | }
26 | }
27 |
28 | .header-dark .navbar .navbar-brand {
29 | font-weight: bold;
30 | color: inherit;
31 | }
32 |
33 | .header-dark .navbar .navbar-brand:hover {
34 | color: #f0f0f0;
35 | }
36 |
37 | .header-dark .navbar .navbar-collapse span {
38 | margin-top: 5px;
39 | }
40 |
41 | .header-dark .navbar .navbar-collapse span .login {
42 | color: #d9d9d9;
43 | margin-right: .5rem;
44 | text-decoration: none;
45 | }
46 |
47 | .header-dark .navbar .navbar-collapse span .login:hover {
48 | color: #fff;
49 | }
50 |
51 | .header-dark .navbar .navbar-toggler {
52 | border-color: #747474;
53 | }
54 |
55 | .header-dark .navbar .navbar-toggler:hover, .header-dark .navbar-toggler:focus {
56 | background: none;
57 | }
58 |
59 | .header-dark .navbar .navbar-toggler {
60 | color: #eee;
61 | }
62 |
63 | .header-dark .navbar .navbar-collapse, .header-dark .navbar .form-inline {
64 | border-color: #636363;
65 | }
66 |
67 | @media (min-width: 992px) {
68 | .header-dark .navbar.navbar .navbar-nav .nav-link {
69 | padding-left: 1.2rem;
70 | padding-right: 1.2rem;
71 | }
72 | }
73 |
74 | .header-dark .navbar.navbar-dark .navbar-nav .nav-link {
75 | color: #d9d9d9;
76 | }
77 |
78 | .header-dark .navbar.navbar-dark .navbar-nav .nav-link:focus, .header-dark .navbar.navbar-dark .navbar-nav .nav-link:hover {
79 | color: #fcfeff !important;
80 | background-color: transparent;
81 | }
82 |
83 | .header-dark .navbar .navbar-nav > li > .dropdown-menu {
84 | margin-top: -5px;
85 | box-shadow: 0 4px 8px rgba(0,0,0,.1);
86 | background-color: #fff;
87 | border-radius: 2px;
88 | }
89 |
90 | .header-dark .navbar .dropdown-menu .dropdown-item:focus, .header-dark .navbar .dropdown-menu .dropdown-item {
91 | line-height: 2;
92 | font-size: 14px;
93 | color: #37434d;
94 | }
95 |
96 | .header-dark .navbar .dropdown-menu .dropdown-item:focus, .header-dark .navbar .dropdown-menu .drodown-item:hover {
97 | background: #ebeff1;
98 | }
99 |
100 | .header-dark .navbar .action-button, .header-dark .navbar .action-button:active {
101 | background: #208f8f;
102 | border-radius: 20px;
103 | font-size: inherit;
104 | color: #fff;
105 | box-shadow: none;
106 | border: none;
107 | text-shadow: none;
108 | padding: .5rem .8rem;
109 | transition: background-color 0.25s;
110 | }
111 |
112 | .header-dark .navbar .action-button:hover {
113 | background: #269d9d;
114 | }
115 |
116 | .header-dark .navbar .form-inline label {
117 | color: #ccc;
118 | }
119 |
120 | .header-dark .navbar .form-inline .search-field {
121 | display: inline-block;
122 | width: 80%;
123 | background: none;
124 | border: none;
125 | border-bottom: 1px solid transparent;
126 | border-radius: 0;
127 | color: #ccc;
128 | box-shadow: none;
129 | color: inherit;
130 | transition: border-bottom-color 0.3s;
131 | }
132 |
133 | .header-dark .navbar .form-inline .search-field:focus {
134 | border-bottom: 1px solid #ccc;
135 | }
136 |
137 | .header-dark .hero {
138 | margin-top: 60px;
139 | }
140 |
141 | @media (min-width:768px) {
142 | .header-dark .hero {
143 | margin-top: 20px;
144 | }
145 | }
146 |
147 | .header-dark .hero h1 {
148 | color: #fff;
149 | font-family: 'Bitter', serif;
150 | font-size: 40px;
151 | margin-top: 20px;
152 | margin-bottom: 80px;
153 | }
154 |
155 | @media (min-width:768px) {
156 | .header-dark .hero h1 {
157 | margin-bottom: 50px;
158 | line-height: 1.5;
159 | }
160 | }
161 |
162 | .header-dark .hero .embed-responsive iframe {
163 | background-color: #666;
164 | }
165 |
166 |
--------------------------------------------------------------------------------
/Master/assets/js/DataTable---Fully-BSS-Editable.js:
--------------------------------------------------------------------------------
1 | function format ( d ) {
2 | let details = ""
3 | details += 'Device IP: '+d.ip+' '
4 | details += 'Packet received at: '+d.time+' '
5 | if (d.dns_query != null)
6 | details +='DNS query: '+d.dns_query+' '
7 |
8 | details +=" "
9 | if (d.srcmac != null && d.srcmac !='-'){
10 | details += 'Ethernet '
11 | details += 'Source MAC: '+d.srcmac+' '
12 | details += 'Destination MAC: '+d.dstmac+' '
13 | details += 'Type: '+d.ethernet_type+' '
14 | details += ' '
15 | }
16 | if (d.srcip != null && d.srcip !='-'){
17 | details += 'IPv4 '
18 | details += 'Source IP: '+d.srcip+' '
19 | details += 'Destination IP: '+d.dstip+' '
20 | details += 'Protocol: '+d.ip_proto+' '
21 | details += ' '
22 | }
23 | if (d.tcp_srcport != null){
24 | details += 'TCP '
25 | details += 'Source port: '+d.tcp_srcport+' '
26 | details += 'Destination port: '+d.tcp_dstport+' '
27 | details += 'Sequence: '+d.tcp_seq+' '
28 | details += ' '
29 | }
30 | if (d.udp_srcport != null){
31 | details += 'UDP '
32 | details += 'Source port: '+d.udp_srcport+' '
33 | details += 'Destination port: '+d.udp_dstport+' '
34 | details += 'Length: '+d.udp_length+' '
35 | details += ' '
36 | }
37 | if (d.ICMPType != null){
38 | details += 'ICMPv4 '
39 | details += 'Type: '+d.ICMPType+' '
40 | details += 'Sequence: '+d.ICMPSeq+' '
41 | details += 'Checksum: '+d.ICMPChecksum+' '
42 | details += ' '
43 | }
44 | if (d.payload != null){
45 | details += 'Application layer payload '
46 | details += ''+d.payload+'
';
47 | details += ' '
48 | }
49 | return details;
50 | }
51 |
52 | $(document).ready(function() {
53 | var table = $('.mydatatable').DataTable({
54 | dom: 'Bfrti',
55 | ajax:"/results_table",
56 | "columns": [
57 | {
58 | "className": 'details-control',
59 | "orderable": false,
60 | "data": null,
61 | "defaultContent": '',
62 | "render": function () {
63 | return ' ';
64 | },
65 | width:"15px"
66 | },
67 | { "data": "ip" },
68 | { "data": "time" },
69 | { "data": "protocols" },
70 | { "data": "app_layer" },
71 | { "data": "srcmac" },
72 | { "data": "dstmac" },
73 | { "data": "srcip" },
74 | { "data": "dstip" }
75 | ],
76 | columnDefs: [
77 | {
78 | targets: 4,
79 | className: 'text-center'
80 | }
81 | ],
82 | buttons: [
83 | {
84 | extend: 'collection',
85 | text: 'Export data as',
86 | buttons: [ 'csv', 'excel', 'pdf' ]
87 | },
88 | 'copy', 'print'
89 | ],
90 | responsive: true,
91 | scrollY: 400,
92 | scrollX: true,
93 | autoWidth: true,
94 | scrollCollapse: true,
95 | paging: true,
96 | info: false,
97 | ordering: false,
98 | pagingType: "simple_numbers"
99 | });
100 | setInterval( function () { table.ajax.reload(); }, 60000 );
101 | $('.mydatatable tbody').on('click', 'td.details-control', function () {
102 | var tr = $(this).closest('tr');
103 | var tdi = tr.find("i.fa");
104 | var row = table.row( tr );
105 |
106 | if ( row.child.isShown() ) {
107 | // This row is already open - close it
108 | row.child.hide();
109 | tr.removeClass('shown');
110 | tdi.first().removeClass('fa-minus-square');
111 | tdi.first().addClass('fa-plus-square');
112 | }
113 | else {
114 | // Open this row
115 | row.child( format(row.data()) ).show();
116 | tr.addClass('shown');
117 | tdi.first().removeClass('fa-plus-square');
118 | tdi.first().addClass('fa-minus-square');
119 | }
120 | } );
121 | });
122 |
--------------------------------------------------------------------------------
/Master/interface.py:
--------------------------------------------------------------------------------
1 | import webbrowser, logging
2 | from threats import *
3 | from flask import Flask, render_template, request, jsonify
4 | # from flask_ngrok import run_with_ngrok
5 | from functools import wraps
6 | from datetime import datetime
7 |
8 | global rows, row_id, devices
9 | app = Flask(__name__, static_url_path=None, static_folder="assets")
10 | # run_with_ngrok(app)
11 | row_id = 0
12 | rows = {
13 | "data":[]
14 | }
15 | devices = {
16 | "ips":[],
17 | "details":[],
18 | }
19 | log = logging.getLogger('werkzeug')
20 | log.setLevel(logging.ERROR)
21 | host_port = 8000
22 | current_host = "127.0.0.1"
23 | serve_localhost = True
24 | view_browser = True
25 |
26 | if not serve_localhost:
27 | sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
28 | sock.connect(("8.8.8.8", 80))
29 | current_host = sock.getsockname()[0]
30 | sock.close()
31 |
32 | def savePacket(user_ip, json_data):
33 | global rows, row_id, devices
34 | for d in devices["details"]:
35 | if d["device_ip"]==user_ip:
36 | d["Status"] = "Active"
37 | break
38 | row = {
39 | "id": row_id,
40 | "ip":user_ip,
41 | "time":json_data.get("createdAt","0"),
42 | "srcmac":json_data.get("ethernetSrcMac",""),
43 | "dstmac":json_data.get("ethernetDstMac",""),
44 | "ethernet_type":json_data.get("ethernetType",""),
45 | "dns_query":json_data.get("dnsQuery",""),
46 | "srcip":json_data.get("IPv4SrcIP","-"),
47 | "dstip":json_data.get("IPv4DstIP","-"),
48 | "ip_proto":json_data.get("IPv4Protocol",""),
49 | "tcp_srcport":json_data.get("TCPSrcPort",""),
50 | "tcp_dstport":json_data.get("TCPDstPort",""),
51 | "tcp_seq":json_data.get("TCPSeq",""),
52 | "udp_srcport":json_data.get("UDPSrcPort",""),
53 | "udp_dstport":json_data.get("UDPDstPort",""),
54 | "udp_length":json_data.get("UDPLength",""),
55 | "ICMPType":json_data.get("ICMPType",""),
56 | "ICMPSeq":json_data.get("ICMPSeq",""),
57 | "ICMPChecksum":json_data.get("ICMPChecksum",""),
58 | "payload":json_data.get("Payload","").strip(),
59 | "app_layer": 'NO '
60 | }
61 | row = {k: v for k, v in row.items() if v!=""}
62 | protocols = json_data.get("PacketLayers",[""])
63 | if "Payload" in protocols:
64 | row["app_layer"] = 'YES '
65 | protocols.remove("Payload")
66 | row["protocols"] = ", ".join(protocols)
67 | # row["payload"] = row["payload"].encode()
68 | row_id +=1
69 | rows["data"].append(row)
70 |
71 | def addUser(user_ip, json_data):
72 | global devices
73 | if user_ip not in devices["ips"]:
74 | devices["ips"].append(user_ip)
75 | devices["details"].append({
76 | "Status": "Active",
77 | "device_ip":user_ip,
78 | "Devices_name":json_data["DeviceName"],
79 | "User_name":json_data["Username"],
80 | "OS":json_data["OS"]
81 | })
82 | else:
83 | for d in devices["details"]:
84 | if d["device_ip"]==user_ip:
85 | d["Status"] = "Active"
86 | break
87 |
88 | def log_this_one():
89 | def hooker(func): # Yes hooker :"D from hook
90 | @wraps(func)
91 | def func_returner(*args, **kwargs):
92 | proto = request.environ.get('SERVER_PROTOCOL')
93 | method = request.method
94 | current_endpoint = str(request.url_rule)
95 | current_time = datetime.utcnow()
96 | if request.environ.get('HTTP_X_FORWARDED_FOR') is None:
97 | user_ip = request.environ['REMOTE_ADDR']
98 | else:
99 | user_ip = request.environ['HTTP_X_FORWARDED_FOR']
100 | print(f'{user_ip} {R}- -{end} [{current_time}] "{method} {current_endpoint} {proto}" ')
101 | if request.is_json:
102 | json_data = request.get_json()
103 | # print(json.dumps(json_data, sort_keys=True, indent=2))
104 | if json_data["RequestType"]=="packet":
105 | savePacket(json_data["Deviceip"], json_data["Data"])
106 | else:
107 | # print(json.dumps(json_data, sort_keys=True, indent=2))
108 | addUser(json_data["Deviceip"], json_data)
109 | return func(*args, **kwargs)
110 | return func_returner
111 | return hooker
112 |
113 | @app.route('/results_table', methods=["GET"])
114 | def get_table():
115 | # print(rows)
116 | # return rows
117 | return jsonify({ "data":sorted(rows["data"], key = lambda i: i['time'], reverse=True) })
118 |
119 | @app.route('/devices_list', methods=["GET"])
120 | def get_devices():
121 | # print(rows)
122 | return jsonify(devices["details"])
123 |
124 | @app.route('/threats_list', methods=["GET"])
125 | def get_threats():
126 | check = threats_checker(rows["data"])
127 | result = check.launch()
128 | if result:
129 | return jsonify(result)
130 | else:
131 | return jsonify([])
132 |
133 | @app.route('/', methods=["GET", "POST"])
134 | @log_this_one()
135 | def hello():
136 | return render_template("index.html")
137 | # return "Running in console :)"
138 |
139 | @app.route('/exit', methods=["GET"])
140 | def goodbye():
141 | os._exit(0)
142 | return "Bye!"
143 |
144 | @app.after_request
145 | def add_header(r):
146 | """
147 | Add headers to both force latest IE rendering engine or Chrome Frame,
148 | and also to cache the rendered page for 10 minutes.
149 | """
150 | r.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
151 | r.headers["Pragma"] = "no-cache"
152 | r.headers["Expires"] = "0"
153 | r.headers['Cache-Control'] = 'public, max-age=0'
154 | #if r.headers["Content-Type"] !="application/json" and r.status_code!=304:
155 | # print(str(r.status_code)+" -",end="")
156 | return r
157 |
158 | def open_browser():
159 | time.sleep(2)
160 | # browser = webbrowser.get()
161 | webbrowser.open(f'http://{current_host}:{host_port}/',new=0)
162 |
163 | if __name__ == '__main__':
164 | if view_browser:
165 | threading.Thread(target=open_browser,daemon=True).start()
166 | print(f'Serving on url http://{current_host}:{host_port}/')
167 | while True:
168 | try:
169 | app.run(host=current_host, port=host_port, threaded=True, debug=True, use_reloader=False)
170 | # app.run()
171 | break
172 | except OSError:
173 | sys.stdout.write(f"[!] Port {host_port} is in use! Trying the following port")
174 | sys.stdout.flush()
175 | host_port +=1
176 | continue
177 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # EagleEye - host-based IDS and network monitoring system
2 | > This is project needs a lot of work to be ready to use as it's my graduation project so it's not user-friendly, only for experienced users, beta version, and I published/made it only for educational purposes!
3 |
4 | 
5 |
6 | - EagleEye consists of two parts:
7 | - **Client** *(Written in Golang)*
8 | + **Purpose:** Capture every packet on device and extract important details in famous protocols then finally send all the collected data to the master if online!
9 | + **Usage:** It should be installed on each device you want to monitor (ex: employee devices for companies).
10 | - **Master**: *(Written in Python and Bootstrap)*
11 | + **Purpose:** Receive every packet sent from the clients, display it organized in the GUI monitoring table, display connected devices information like current system user/system info, compare the captured data to the threats models already written before, and then finally alert the master user for possible security threats in the network as what a typical IDS system would do!
12 | + **Usage:** It should be running on a server on the same network as the clients (ex: a server managed by the IT department or blue hacking team for the company maybe).
13 |
14 | > For more info, you will need to read about (I)ntrusion (D)etection (S)ystems and its types. I recommend [the NIST guide](https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-94.pdf).
15 |
16 | ## Screenshots
17 |
18 | ### Main GUI
19 |
20 |
21 | ---
22 | ### Monitoring table
23 |
24 |
25 |
26 |
27 | > Notice the buttons in the table gives you the ability to export table as (CSV, Excel, PDF), copy table data to clipboard, and print the table data if you want.
28 |
29 | ### Monitoring table search
30 | #### Simple search
31 |
32 |
33 | #### Detailed search
34 |
35 |
36 | > As you can see the search here gives you the ability to search for any thing represented in the table.
37 | ---
38 | ### Connected devices table
39 | #### When a new client connected to the client
40 |
41 |
42 | #### Information about each client
43 |
44 |
45 | > Notice table refreshed automatically every 5s or on page refresh!
46 | ---
47 | ### Threats table
48 | #### When a threats detected
49 |
50 |
51 | #### Details about any possible threats detected + reference on click
52 |
53 |
54 | #### Desktop notification for threats
55 |
56 |
57 | > Notice table refreshed automatically every 5s or on page refresh!
58 | ---
59 | ## Installation instructions
60 | ### The Client
61 | #### Requirements
62 | - Supports Windows system only currently (Because of the data grabbed from the registry, need to change that).
63 | - The following instructions
64 |
65 | #### Installation instructions
66 | 1. Make sure you have Golang installed.
67 | 2. Install gopacket library by using this command:
68 | `go get github.com/google/gopacket`
69 | 3. Download and install npcap from [here](https://nmap.org/npcap/).
70 | 4. Change the following variables in the code according to your needs:
71 | + *Line57:* Change variable **url** to your current Master url
72 | + *Line59:* Change variable **device** to the network interface you would listen to, for windows you will need [this article](https://haydz.github.io/2020/07/06/Go-Windows-NIC.html)!
73 | + *Line66:* Change variable **filter** to the filter you want in capturing network packets or leave it empty as it is (if you want to capture all packets). The filter syntax is bpf which is the same used in Wireshark search, you can learn it from [this guide](https://docs.extrahop.com/8.3/bpf-syntax/). I left some examples in the comments too, if anyone wants to use it.
74 | 5. In CMD navigate to the client directory, of course.
75 | 6. Now you can run the client as a script with this command: `go run main.go`
76 | 7. To compile/build it, you can use the following command: `go build -o client.exe main.go`, maybe you could need [this guide](https://golang.org/cmd/go/#Compile_packages_and_dependencies).
77 | 8. If you did all of these, go have a life dude :laughing: (Joking)
78 | ---
79 | ### The Master
80 | #### Requirements
81 | - Any OS.
82 | - The following instructions, it's a lot easier than the client don't worry LOL!
83 |
84 | #### Installation instructions
85 | 1. Make sure you have Python 3 installed (Version 3.5 and above) and pip.
86 | 2. In CMD navigate to the master folder then install the requirements by using this command: `pip install -r requirements.txt` or `python -m pip install -r requirements.txt`
87 | 3. If you are on windows and colored print in CMD matters to you, run this command: `pip install -r coloring-requirements.txt` or `python -m pip install -r coloring-requirements.txt`
88 | 4. Now a few variables to change according to your needs :laughing:
89 | + *Line21:* Change variable **host_port** to the port you want to serve on (Default:8000)
90 | + *Line23:* Change variable **serve_localhost** change to True if you want to run master on local host only (Default:True)
91 | + *Line24:* Change variable **view_browser** change to True if you want the master to open the serving url on the browser automatically (Default:True)
92 | 5. Now you can run the master by `python interface.py`
93 | 6. Have fun :)
94 |
95 | # TODO list
96 | - [ ] Expanding the GUI (user login, settings...)
97 | - [ ] Add in-mail and SMS notifications.
98 | - [ ] Optimize the network usage
99 | - [ ] Add more threat models specially the more complicated ones like ARP-spoofing based attacks.
100 | - [ ] Add detailed reports for security threats table.
101 | - [ ] Add the ability to check the status of each client and change it if the device is not active and not online for, say, 1 hour.
102 | - [ ] Make the client work on more platforms.
103 | - [ ] Make a setup GUI for the client (More user friendly)
104 | - [ ] TBD
105 |
--------------------------------------------------------------------------------
/Master/templates/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | EagleEye
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
31 |
32 |
33 |
34 |
35 |
Alert! text
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
47 |
48 |
49 |
50 |
51 |
52 | #
53 | Device
54 | Time
55 | Protocols
56 | App layer
57 | Source MAC
58 | Destination MAC
59 | Source IP
60 | Destination IP
61 |
62 |
63 |
64 |
65 |
66 | -
67 | -
68 | -
69 | -
70 | -
71 | -
72 | -
73 | -
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
Possible security threats
87 |
88 |
89 |
Connected Devices
90 |
91 |
92 |
106 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
--------------------------------------------------------------------------------
/Client/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | // Before start do: go get github.com/google/gopacket
4 | // Then install npcap https://nmap.org/npcap/
5 | import (
6 | "fmt"
7 | "log"
8 | "github.com/google/gopacket"
9 | "github.com/google/gopacket/layers"
10 | "github.com/google/gopacket/pcap"
11 | "time"
12 | "strings"
13 | "net/http"
14 | "bytes"
15 | "net"
16 | "encoding/json"
17 | "os"
18 | "os/user"
19 | "golang.org/x/sys/windows/registry"
20 | )
21 |
22 | type Packet_data struct {
23 | PacketLayers []string `json:"PacketLayers"`
24 | CreatedAt string `json:"createdAt"`
25 | EthernetSrcMac string `json:"ethernetSrcMac,omitempty"`
26 | EthernetDstMac string `json:"ethernetDstMac,omitempty"`
27 | EthernetType string `json:"ethernetType,omitempty"`
28 | DnsQuery string `json:"dnsQuery,omitempty"`
29 | IPv4SrcIP string `json:"IPv4SrcIP,omitempty"`
30 | IPv4DstIP string `json:"IPv4DstIP,omitempty"`
31 | IPv4Protocol string `json:"IPv4Protocol,omitempty"`
32 | TCPSrcPort string `json:"TCPSrcPort,omitempty"`
33 | TCPDstPort string `json:"TCPDstPort,omitempty"`
34 | TCPSeq string `json:"TCPSeq,omitempty"`
35 | UDPSrcPort string `json:"UDPSrcPort,omitempty"`
36 | UDPDstPort string `json:"UDPDstPort,omitempty"`
37 | UDPLength string `json:"UDPLength,omitempty"`
38 | ICMPType string `json:"ICMPType,omitempty"`
39 | ICMPSeq string `json:"ICMPSeq,omitempty"`
40 | ICMPChecksum string `json:"ICMPChecksum,omitempty"`
41 | Payload string `json:"Payload,omitempty"`}
42 |
43 | type Packet_request struct {
44 | RequestType string `json:RequestType`
45 | Deviceip string `json:Deviceip`
46 | Data Packet_data `json:data`}
47 |
48 | type Info_request struct{
49 | RequestType string `json:RequestType`
50 | Deviceip string `json:Deviceip`
51 | DeviceName string `json:deviceName`
52 | Username string `json:username`
53 | OS string `json:os`}
54 |
55 | var (
56 | url string = "http://127.0.0.1:8000/"
57 | // for windows the device name should always start with \\Device\\NPF_
58 | // If it starts with \\Device\\Tcpip_ or anything just replace it
59 | device string = "\\Device\\NPF_{394B19E7-D72C-47A2-8915-62201EF9901B}"
60 | snapshot_len int32 = 102400
61 | promiscuous bool = false
62 | err error
63 | // timeout time.Duration = 30 * time.Second
64 | handle *pcap.Handle
65 | // Packets filter in bpf syntax (https://docs.extrahop.com/8.3/bpf-syntax/)
66 | filter string = " "
67 | // dns only "udp and port 53"
68 | // http only "tcp and dst port 80" or "tcp and port 80" for more the whole packets
69 | // http get requests only "tcp and tcp[20:4] = 0x47455420"
70 | // http and https "tcp and (dst port 80 or dst port 8080 or dst port 443)"
71 | // for range of ports "portrange 0-10000"
72 | )
73 |
74 | func GetOutboundIP() string {
75 | conn, err := net.Dial("udp", "8.8.8.8:80")
76 | if err != nil {
77 | log.Fatal(err)
78 | }
79 | defer conn.Close()
80 | localAddr := conn.LocalAddr().(*net.UDPAddr)
81 | return localAddr.IP.String()
82 | }
83 |
84 | func main() {
85 | // Sending device info to master
86 | fmt.Printf("Device ip %v\n", GetOutboundIP())
87 | hostname, err := os.Hostname()
88 | u, err := user.Current()
89 | username:= u.Username
90 | key, _ := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE)
91 | defer key.Close()
92 | winver, _, _ := key.GetStringValue("ProductName")
93 | info := &Info_request{
94 | RequestType:"info",
95 | Deviceip:GetOutboundIP(),
96 | DeviceName:hostname,
97 | Username:username,
98 | OS:winver,
99 | }
100 | jsonStr, _ := json.Marshal(info)
101 | req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
102 | req.Header.Set("Content-Type", "application/json")
103 | for{
104 | client := &http.Client{}
105 | resp, err := client.Do(req)
106 | if err == nil {
107 | // panic(err)
108 | defer resp.Body.Close()
109 | break
110 | } else{
111 | fmt.Printf(".")
112 | // defer resp.Body.Close()
113 | }
114 | }
115 | //-------------------------------------
116 | handle, err = pcap.OpenLive(device, snapshot_len, promiscuous, pcap.BlockForever)
117 | if err != nil {
118 | log.Fatal(err)
119 | }
120 | defer handle.Close()
121 | err = handle.SetBPFFilter(filter)
122 | if err != nil {
123 | log.Fatal(err)
124 | }
125 | fmt.Printf("\n\tCapturing/Listening for packets, filter='%v'\n\n", filter)
126 | packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
127 | for packet := range packetSource.Packets() {
128 | // Process packet here
129 | processPacket(packet)
130 | }
131 |
132 | }
133 |
134 | func processPacket(packet gopacket.Packet) {
135 | fmt.Println("---------------------")
136 | layers_names := []string{}
137 | for _, layer := range packet.Layers() {
138 | layers_names = append(layers_names, fmt.Sprintf("%v", layer.LayerType()))
139 | }
140 | fmt.Println("Packet layers: " + strings.Join(layers_names, ", "))
141 | dt := time.Now()
142 | Request := &Packet_request{
143 | RequestType:"packet",
144 | Deviceip:GetOutboundIP(),
145 | Data:Packet_data{
146 | PacketLayers:layers_names,
147 | CreatedAt: dt.Format("01-02-2006 15:04:05.0"),
148 | },
149 | }
150 | netLayer := packet.NetworkLayer()
151 | if netLayer != nil {
152 | netFlow := netLayer.NetworkFlow()
153 | src, dst := netFlow.Endpoints()
154 | fmt.Printf(" Src: %v, Dst: %v \n", src, dst)
155 | } else {
156 | fmt.Println()
157 | }
158 | ethernetLayer := packet.Layer(layers.LayerTypeEthernet)
159 | tcpLayer := packet.Layer(layers.LayerTypeTCP) //packet.NetworkLayer()
160 | udpLayer := packet.Layer(layers.LayerTypeUDP)
161 | ipLayer := packet.Layer(layers.LayerTypeIPv4)
162 | dnsLayer := packet.Layer(layers.LayerTypeDNS)
163 | icmpLayer := packet.Layer(layers.LayerTypeICMPv4)
164 | applicationLayer := packet.ApplicationLayer()
165 | // if ipLayer != nil && tcpLayer != nil && applicationLayer != nil {
166 | if ethernetLayer != nil {
167 | // Ethernet type is typically IPv4 but could be ARP or other
168 | ethernetPacket, _ := ethernetLayer.(*layers.Ethernet)
169 | fmt.Printf("[Ethernet] Source MAC: %v, Destination MAC: %v and Ethernet type: %v \n", ethernetPacket.SrcMAC, ethernetPacket.DstMAC, ethernetPacket.EthernetType)
170 | Request.Data.EthernetSrcMac = fmt.Sprintf("%v",ethernetPacket.SrcMAC)
171 | Request.Data.EthernetDstMac = fmt.Sprintf("%v",ethernetPacket.DstMAC)
172 | Request.Data.EthernetType = fmt.Sprintf("%v",ethernetPacket.EthernetType)
173 | }
174 | // if strings.Contains(string(applicationLayer.Payload()), "HTTP") {
175 |
176 | if dnsLayer != nil {
177 | dns, _ := dnsLayer.(*layers.DNS)
178 | fmt.Printf("[DNS Query] %s\n", dns.Questions)
179 | Request.Data.DnsQuery = fmt.Sprintf("%v",dns.Questions)
180 | }
181 | if ipLayer != nil {
182 | ip, _ := ipLayer.(*layers.IPv4)
183 | // IP layer variables:
184 | // TOS, Length, Id, Flags, FragOffset, TTL, Protocol (TCP?),
185 | // Checksum, SrcIP, DstIP
186 | fmt.Printf("[IPv4] From %s -> %s (Protocol: %s)\n", ip.SrcIP, ip.DstIP, ip.Protocol)
187 | Request.Data.IPv4SrcIP = fmt.Sprintf("%v",ip.SrcIP)
188 | Request.Data.IPv4DstIP = fmt.Sprintf("%v",ip.DstIP)
189 | Request.Data.IPv4Protocol = fmt.Sprintf("%v",ip.Protocol)
190 | }
191 |
192 | if tcpLayer != nil {
193 | // TCP layer variables:
194 | // SrcPort, DstPort, Seq, Ack, DataOffset, Window, Checksum, Urgent
195 | // Bool flags: FIN, SYN, RST, PSH, ACK, URG, ECE, CWR, NS
196 | tcp, _ := tcpLayer.(*layers.TCP)
197 | fmt.Printf("[TCP] Ports from %d -> %d (Sequence: %d)\n", tcp.SrcPort, tcp.DstPort, tcp.Seq)
198 | Request.Data.TCPSrcPort = fmt.Sprintf("%v",tcp.SrcPort)
199 | Request.Data.TCPDstPort = fmt.Sprintf("%v",tcp.DstPort)
200 | Request.Data.TCPSeq = fmt.Sprintf("%v",tcp.Seq)
201 | }
202 |
203 | if udpLayer != nil {
204 | // UDP layer variables: SrcPort, DstPort, Length, Checksum
205 | udp, _ := udpLayer.(*layers.UDP)
206 | fmt.Printf("[UDP] Ports from %d -> %d (Length: %d)\n", udp.SrcPort, udp.DstPort, udp.Length)
207 | Request.Data.UDPSrcPort = fmt.Sprintf("%v",udp.SrcPort)
208 | Request.Data.UDPDstPort = fmt.Sprintf("%v",udp.DstPort)
209 | Request.Data.UDPLength = fmt.Sprintf("%v",udp.Length)
210 | }
211 |
212 | if icmpLayer != nil {
213 | // ICMP layer variables: TypeCode, Checksum, Id, Seq
214 | icmp, _ := icmpLayer.(*layers.ICMPv4)
215 | fmt.Printf("[ICMP] ICMP packet type %d Sequence %d (Checksum: %d)\n", int8(icmp.TypeCode), int8(icmp.Seq), uint8(icmp.Checksum))
216 | Request.Data.ICMPType = fmt.Sprintf("%v",int8(icmp.TypeCode))
217 | Request.Data.ICMPSeq = fmt.Sprintf("%v",int8(icmp.Seq))
218 | Request.Data.ICMPChecksum = fmt.Sprintf("%v",uint8(icmp.Checksum))
219 | }
220 |
221 | if applicationLayer != nil {
222 | // fmt.Printf("[Payload] %s\n", applicationLayer.Payload())
223 | Request.Data.Payload = fmt.Sprintf("%s",applicationLayer.Payload())
224 | }
225 |
226 | fmt.Println("---------------------\n ")
227 | jsonStr, _ := json.Marshal(Request)
228 | req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
229 | req.Header.Set("Content-Type", "application/json")
230 | client := &http.Client{}
231 | resp, err := client.Do(req)
232 | if err != nil {
233 | // panic(err)
234 | }
235 | if resp !=nil{
236 | defer resp.Body.Close()
237 | }
238 | // fmt.Println("response Status:", resp.Status)
239 | // fmt.Println("response Headers:", resp.Header)
240 | // body, _ := ioutil.ReadAll(resp.Body)
241 | // fmt.Println("response Body:", string(body))
242 | // Check for errors
243 | if err := packet.ErrorLayer(); err != nil {
244 | fmt.Println("Error decoding some part of the packet:", err)
245 | }
246 | }
247 |
--------------------------------------------------------------------------------
/Master/assets/bootstrap/js/bootstrap.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Bootstrap v5.0.1 (https://getbootstrap.com/)
3 | * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
5 | */
6 | !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap=e()}(this,(function(){"use strict";const t={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter(t=>t.matches(e)),parents(t,e){const i=[];let n=t.parentNode;for(;n&&n.nodeType===Node.ELEMENT_NODE&&3!==n.nodeType;)n.matches(e)&&i.push(n),n=n.parentNode;return i},prev(t,e){let i=t.previousElementSibling;for(;i;){if(i.matches(e))return[i];i=i.previousElementSibling}return[]},next(t,e){let i=t.nextElementSibling;for(;i;){if(i.matches(e))return[i];i=i.nextElementSibling}return[]}},e=t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t},i=t=>{let e=t.getAttribute("data-bs-target");if(!e||"#"===e){let i=t.getAttribute("href");if(!i||!i.includes("#")&&!i.startsWith("."))return null;i.includes("#")&&!i.startsWith("#")&&(i="#"+i.split("#")[1]),e=i&&"#"!==i?i.trim():null}return e},n=t=>{const e=i(t);return e&&document.querySelector(e)?e:null},s=t=>{const e=i(t);return e?document.querySelector(e):null},o=t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:i}=window.getComputedStyle(t);const n=Number.parseFloat(e),s=Number.parseFloat(i);return n||s?(e=e.split(",")[0],i=i.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(i))):0},r=t=>{t.dispatchEvent(new Event("transitionend"))},a=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),l=e=>a(e)?e.jquery?e[0]:e:"string"==typeof e&&e.length>0?t.findOne(e):null,c=(t,e)=>{let i=!1;const n=e+5;t.addEventListener("transitionend",(function e(){i=!0,t.removeEventListener("transitionend",e)})),setTimeout(()=>{i||r(t)},n)},d=(t,e,i)=>{Object.keys(i).forEach(n=>{const s=i[n],o=e[n],r=o&&a(o)?"element":null==(l=o)?""+l:{}.toString.call(l).match(/\s([a-z]+)/i)[1].toLowerCase();var l;if(!new RegExp(s).test(r))throw new TypeError(`${t.toUpperCase()}: Option "${n}" provided type "${r}" but expected type "${s}".`)})},h=t=>{if(!t)return!1;if(t.style&&t.parentNode&&t.parentNode.style){const e=getComputedStyle(t),i=getComputedStyle(t.parentNode);return"none"!==e.display&&"none"!==i.display&&"hidden"!==e.visibility}return!1},u=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),f=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?f(t.parentNode):null},p=()=>{},m=t=>t.offsetHeight,g=()=>{const{jQuery:t}=window;return t&&!document.body.hasAttribute("data-bs-no-jquery")?t:null},_=()=>"rtl"===document.documentElement.dir,b=t=>{var e;e=()=>{const e=g();if(e){const i=t.NAME,n=e.fn[i];e.fn[i]=t.jQueryInterface,e.fn[i].Constructor=t,e.fn[i].noConflict=()=>(e.fn[i]=n,t.jQueryInterface)}},"loading"===document.readyState?document.addEventListener("DOMContentLoaded",e):e()},v=t=>{"function"==typeof t&&t()},y=new Map;var w={set(t,e,i){y.has(t)||y.set(t,new Map);const n=y.get(t);n.has(e)||0===n.size?n.set(e,i):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(n.keys())[0]}.`)},get:(t,e)=>y.has(t)&&y.get(t).get(e)||null,remove(t,e){if(!y.has(t))return;const i=y.get(t);i.delete(e),0===i.size&&y.delete(t)}};const E=/[^.]*(?=\..*)\.|.*/,T=/\..*/,A=/::\d+$/,L={};let O=1;const k={mouseenter:"mouseover",mouseleave:"mouseout"},C=/^(mouseenter|mouseleave)/i,x=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function D(t,e){return e&&`${e}::${O++}`||t.uidEvent||O++}function N(t){const e=D(t);return t.uidEvent=e,L[e]=L[e]||{},L[e]}function S(t,e,i=null){const n=Object.keys(t);for(let s=0,o=n.length;sfunction(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};n?n=t(n):i=t(i)}const[o,r,a]=I(e,i,n),l=N(t),c=l[a]||(l[a]={}),d=S(c,r,o?i:null);if(d)return void(d.oneOff=d.oneOff&&s);const h=D(r,e.replace(E,"")),u=o?function(t,e,i){return function n(s){const o=t.querySelectorAll(e);for(let{target:r}=s;r&&r!==this;r=r.parentNode)for(let a=o.length;a--;)if(o[a]===r)return s.delegateTarget=r,n.oneOff&&H.off(t,s.type,e,i),i.apply(r,[s]);return null}}(t,i,n):function(t,e){return function i(n){return n.delegateTarget=t,i.oneOff&&H.off(t,n.type,e),e.apply(t,[n])}}(t,i);u.delegationSelector=o?i:null,u.originalHandler=r,u.oneOff=s,u.uidEvent=h,c[h]=u,t.addEventListener(a,u,o)}function P(t,e,i,n,s){const o=S(e[i],n,s);o&&(t.removeEventListener(i,o,Boolean(s)),delete e[i][o.uidEvent])}function M(t){return t=t.replace(T,""),k[t]||t}const H={on(t,e,i,n){j(t,e,i,n,!1)},one(t,e,i,n){j(t,e,i,n,!0)},off(t,e,i,n){if("string"!=typeof e||!t)return;const[s,o,r]=I(e,i,n),a=r!==e,l=N(t),c=e.startsWith(".");if(void 0!==o){if(!l||!l[r])return;return void P(t,l,r,o,s?i:null)}c&&Object.keys(l).forEach(i=>{!function(t,e,i,n){const s=e[i]||{};Object.keys(s).forEach(o=>{if(o.includes(n)){const n=s[o];P(t,e,i,n.originalHandler,n.delegationSelector)}})}(t,l,i,e.slice(1))});const d=l[r]||{};Object.keys(d).forEach(i=>{const n=i.replace(A,"");if(!a||e.includes(n)){const e=d[i];P(t,l,r,e.originalHandler,e.delegationSelector)}})},trigger(t,e,i){if("string"!=typeof e||!t)return null;const n=g(),s=M(e),o=e!==s,r=x.has(s);let a,l=!0,c=!0,d=!1,h=null;return o&&n&&(a=n.Event(e,i),n(t).trigger(a),l=!a.isPropagationStopped(),c=!a.isImmediatePropagationStopped(),d=a.isDefaultPrevented()),r?(h=document.createEvent("HTMLEvents"),h.initEvent(s,l,!0)):h=new CustomEvent(e,{bubbles:l,cancelable:!0}),void 0!==i&&Object.keys(i).forEach(t=>{Object.defineProperty(h,t,{get:()=>i[t]})}),d&&h.preventDefault(),c&&t.dispatchEvent(h),h.defaultPrevented&&void 0!==a&&a.preventDefault(),h}};class R{constructor(t){(t=l(t))&&(this._element=t,w.set(this._element,this.constructor.DATA_KEY,this))}dispose(){w.remove(this._element,this.constructor.DATA_KEY),H.off(this._element,this.constructor.EVENT_KEY),Object.getOwnPropertyNames(this).forEach(t=>{this[t]=null})}_queueCallback(t,e,i=!0){if(!i)return void v(t);const n=o(e);H.one(e,"transitionend",()=>v(t)),c(e,n)}static getInstance(t){return w.get(t,this.DATA_KEY)}static get VERSION(){return"5.0.1"}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}static get DATA_KEY(){return"bs."+this.NAME}static get EVENT_KEY(){return"."+this.DATA_KEY}}class B extends R{static get NAME(){return"alert"}close(t){const e=t?this._getRootElement(t):this._element,i=this._triggerCloseEvent(e);null===i||i.defaultPrevented||this._removeElement(e)}_getRootElement(t){return s(t)||t.closest(".alert")}_triggerCloseEvent(t){return H.trigger(t,"close.bs.alert")}_removeElement(t){t.classList.remove("show");const e=t.classList.contains("fade");this._queueCallback(()=>this._destroyElement(t),t,e)}_destroyElement(t){t.parentNode&&t.parentNode.removeChild(t),H.trigger(t,"closed.bs.alert")}static jQueryInterface(t){return this.each((function(){let e=w.get(this,"bs.alert");e||(e=new B(this)),"close"===t&&e[t](this)}))}static handleDismiss(t){return function(e){e&&e.preventDefault(),t.close(this)}}}H.on(document,"click.bs.alert.data-api",'[data-bs-dismiss="alert"]',B.handleDismiss(new B)),b(B);class W extends R{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){let e=w.get(this,"bs.button");e||(e=new W(this)),"toggle"===t&&e[t]()}))}}function q(t){return"true"===t||"false"!==t&&(t===Number(t).toString()?Number(t):""===t||"null"===t?null:t)}function z(t){return t.replace(/[A-Z]/g,t=>"-"+t.toLowerCase())}H.on(document,"click.bs.button.data-api",'[data-bs-toggle="button"]',t=>{t.preventDefault();const e=t.target.closest('[data-bs-toggle="button"]');let i=w.get(e,"bs.button");i||(i=new W(e)),i.toggle()}),b(W);const U={setDataAttribute(t,e,i){t.setAttribute("data-bs-"+z(e),i)},removeDataAttribute(t,e){t.removeAttribute("data-bs-"+z(e))},getDataAttributes(t){if(!t)return{};const e={};return Object.keys(t.dataset).filter(t=>t.startsWith("bs")).forEach(i=>{let n=i.replace(/^bs/,"");n=n.charAt(0).toLowerCase()+n.slice(1,n.length),e[n]=q(t.dataset[i])}),e},getDataAttribute:(t,e)=>q(t.getAttribute("data-bs-"+z(e))),offset(t){const e=t.getBoundingClientRect();return{top:e.top+document.body.scrollTop,left:e.left+document.body.scrollLeft}},position:t=>({top:t.offsetTop,left:t.offsetLeft})},$={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0,touch:!0},F={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean",touch:"boolean"},V="next",K="prev",X="left",Y="right";class Q extends R{constructor(e,i){super(e),this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this.touchStartX=0,this.touchDeltaX=0,this._config=this._getConfig(i),this._indicatorsElement=t.findOne(".carousel-indicators",this._element),this._touchSupported="ontouchstart"in document.documentElement||navigator.maxTouchPoints>0,this._pointerEvent=Boolean(window.PointerEvent),this._addEventListeners()}static get Default(){return $}static get NAME(){return"carousel"}next(){this._isSliding||this._slide(V)}nextWhenVisible(){!document.hidden&&h(this._element)&&this.next()}prev(){this._isSliding||this._slide(K)}pause(e){e||(this._isPaused=!0),t.findOne(".carousel-item-next, .carousel-item-prev",this._element)&&(r(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null}cycle(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config&&this._config.interval&&!this._isPaused&&(this._updateInterval(),this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))}to(e){this._activeElement=t.findOne(".active.carousel-item",this._element);const i=this._getItemIndex(this._activeElement);if(e>this._items.length-1||e<0)return;if(this._isSliding)return void H.one(this._element,"slid.bs.carousel",()=>this.to(e));if(i===e)return this.pause(),void this.cycle();const n=e>i?V:K;this._slide(n,this._items[e])}_getConfig(t){return t={...$,...t},d("carousel",t,F),t}_handleSwipe(){const t=Math.abs(this.touchDeltaX);if(t<=40)return;const e=t/this.touchDeltaX;this.touchDeltaX=0,e&&this._slide(e>0?Y:X)}_addEventListeners(){this._config.keyboard&&H.on(this._element,"keydown.bs.carousel",t=>this._keydown(t)),"hover"===this._config.pause&&(H.on(this._element,"mouseenter.bs.carousel",t=>this.pause(t)),H.on(this._element,"mouseleave.bs.carousel",t=>this.cycle(t))),this._config.touch&&this._touchSupported&&this._addTouchEventListeners()}_addTouchEventListeners(){const e=t=>{!this._pointerEvent||"pen"!==t.pointerType&&"touch"!==t.pointerType?this._pointerEvent||(this.touchStartX=t.touches[0].clientX):this.touchStartX=t.clientX},i=t=>{this.touchDeltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this.touchStartX},n=t=>{!this._pointerEvent||"pen"!==t.pointerType&&"touch"!==t.pointerType||(this.touchDeltaX=t.clientX-this.touchStartX),this._handleSwipe(),"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout(t=>this.cycle(t),500+this._config.interval))};t.find(".carousel-item img",this._element).forEach(t=>{H.on(t,"dragstart.bs.carousel",t=>t.preventDefault())}),this._pointerEvent?(H.on(this._element,"pointerdown.bs.carousel",t=>e(t)),H.on(this._element,"pointerup.bs.carousel",t=>n(t)),this._element.classList.add("pointer-event")):(H.on(this._element,"touchstart.bs.carousel",t=>e(t)),H.on(this._element,"touchmove.bs.carousel",t=>i(t)),H.on(this._element,"touchend.bs.carousel",t=>n(t)))}_keydown(t){/input|textarea/i.test(t.target.tagName)||("ArrowLeft"===t.key?(t.preventDefault(),this._slide(Y)):"ArrowRight"===t.key&&(t.preventDefault(),this._slide(X)))}_getItemIndex(e){return this._items=e&&e.parentNode?t.find(".carousel-item",e.parentNode):[],this._items.indexOf(e)}_getItemByOrder(t,e){const i=t===V,n=t===K,s=this._getItemIndex(e),o=this._items.length-1;if((n&&0===s||i&&s===o)&&!this._config.wrap)return e;const r=(s+(n?-1:1))%this._items.length;return-1===r?this._items[this._items.length-1]:this._items[r]}_triggerSlideEvent(e,i){const n=this._getItemIndex(e),s=this._getItemIndex(t.findOne(".active.carousel-item",this._element));return H.trigger(this._element,"slide.bs.carousel",{relatedTarget:e,direction:i,from:s,to:n})}_setActiveIndicatorElement(e){if(this._indicatorsElement){const i=t.findOne(".active",this._indicatorsElement);i.classList.remove("active"),i.removeAttribute("aria-current");const n=t.find("[data-bs-target]",this._indicatorsElement);for(let t=0;t{H.trigger(this._element,"slid.bs.carousel",{relatedTarget:r,direction:u,from:o,to:a})};if(this._element.classList.contains("slide")){r.classList.add(h),m(r),s.classList.add(d),r.classList.add(d);const t=()=>{r.classList.remove(d,h),r.classList.add("active"),s.classList.remove("active",h,d),this._isSliding=!1,setTimeout(f,0)};this._queueCallback(t,s,!0)}else s.classList.remove("active"),r.classList.add("active"),this._isSliding=!1,f();l&&this.cycle()}_directionToOrder(t){return[Y,X].includes(t)?_()?t===X?K:V:t===X?V:K:t}_orderToDirection(t){return[V,K].includes(t)?_()?t===K?X:Y:t===K?Y:X:t}static carouselInterface(t,e){let i=w.get(t,"bs.carousel"),n={...$,...U.getDataAttributes(t)};"object"==typeof e&&(n={...n,...e});const s="string"==typeof e?e:n.slide;if(i||(i=new Q(t,n)),"number"==typeof e)i.to(e);else if("string"==typeof s){if(void 0===i[s])throw new TypeError(`No method named "${s}"`);i[s]()}else n.interval&&n.ride&&(i.pause(),i.cycle())}static jQueryInterface(t){return this.each((function(){Q.carouselInterface(this,t)}))}static dataApiClickHandler(t){const e=s(this);if(!e||!e.classList.contains("carousel"))return;const i={...U.getDataAttributes(e),...U.getDataAttributes(this)},n=this.getAttribute("data-bs-slide-to");n&&(i.interval=!1),Q.carouselInterface(e,i),n&&w.get(e,"bs.carousel").to(n),t.preventDefault()}}H.on(document,"click.bs.carousel.data-api","[data-bs-slide], [data-bs-slide-to]",Q.dataApiClickHandler),H.on(window,"load.bs.carousel.data-api",()=>{const e=t.find('[data-bs-ride="carousel"]');for(let t=0,i=e.length;tt===this._element);null!==o&&r.length&&(this._selector=o,this._triggerArray.push(i))}this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle()}static get Default(){return G}static get NAME(){return"collapse"}toggle(){this._element.classList.contains("show")?this.hide():this.show()}show(){if(this._isTransitioning||this._element.classList.contains("show"))return;let e,i;this._parent&&(e=t.find(".show, .collapsing",this._parent).filter(t=>"string"==typeof this._config.parent?t.getAttribute("data-bs-parent")===this._config.parent:t.classList.contains("collapse")),0===e.length&&(e=null));const n=t.findOne(this._selector);if(e){const t=e.find(t=>n!==t);if(i=t?w.get(t,"bs.collapse"):null,i&&i._isTransitioning)return}if(H.trigger(this._element,"show.bs.collapse").defaultPrevented)return;e&&e.forEach(t=>{n!==t&&J.collapseInterface(t,"hide"),i||w.set(t,"bs.collapse",null)});const s=this._getDimension();this._element.classList.remove("collapse"),this._element.classList.add("collapsing"),this._element.style[s]=0,this._triggerArray.length&&this._triggerArray.forEach(t=>{t.classList.remove("collapsed"),t.setAttribute("aria-expanded",!0)}),this.setTransitioning(!0);const o="scroll"+(s[0].toUpperCase()+s.slice(1));this._queueCallback(()=>{this._element.classList.remove("collapsing"),this._element.classList.add("collapse","show"),this._element.style[s]="",this.setTransitioning(!1),H.trigger(this._element,"shown.bs.collapse")},this._element,!0),this._element.style[s]=this._element[o]+"px"}hide(){if(this._isTransitioning||!this._element.classList.contains("show"))return;if(H.trigger(this._element,"hide.bs.collapse").defaultPrevented)return;const t=this._getDimension();this._element.style[t]=this._element.getBoundingClientRect()[t]+"px",m(this._element),this._element.classList.add("collapsing"),this._element.classList.remove("collapse","show");const e=this._triggerArray.length;if(e>0)for(let t=0;t{this.setTransitioning(!1),this._element.classList.remove("collapsing"),this._element.classList.add("collapse"),H.trigger(this._element,"hidden.bs.collapse")},this._element,!0)}setTransitioning(t){this._isTransitioning=t}_getConfig(t){return(t={...G,...t}).toggle=Boolean(t.toggle),d("collapse",t,Z),t}_getDimension(){return this._element.classList.contains("width")?"width":"height"}_getParent(){let{parent:e}=this._config;e=l(e);const i=`[data-bs-toggle="collapse"][data-bs-parent="${e}"]`;return t.find(i,e).forEach(t=>{const e=s(t);this._addAriaAndCollapsedClass(e,[t])}),e}_addAriaAndCollapsedClass(t,e){if(!t||!e.length)return;const i=t.classList.contains("show");e.forEach(t=>{i?t.classList.remove("collapsed"):t.classList.add("collapsed"),t.setAttribute("aria-expanded",i)})}static collapseInterface(t,e){let i=w.get(t,"bs.collapse");const n={...G,...U.getDataAttributes(t),..."object"==typeof e&&e?e:{}};if(!i&&n.toggle&&"string"==typeof e&&/show|hide/.test(e)&&(n.toggle=!1),i||(i=new J(t,n)),"string"==typeof e){if(void 0===i[e])throw new TypeError(`No method named "${e}"`);i[e]()}}static jQueryInterface(t){return this.each((function(){J.collapseInterface(this,t)}))}}H.on(document,"click.bs.collapse.data-api",'[data-bs-toggle="collapse"]',(function(e){("A"===e.target.tagName||e.delegateTarget&&"A"===e.delegateTarget.tagName)&&e.preventDefault();const i=U.getDataAttributes(this),s=n(this);t.find(s).forEach(t=>{const e=w.get(t,"bs.collapse");let n;e?(null===e._parent&&"string"==typeof i.parent&&(e._config.parent=i.parent,e._parent=e._getParent()),n="toggle"):n=i,J.collapseInterface(t,n)})})),b(J);var tt="top",et="bottom",it="right",nt="left",st=[tt,et,it,nt],ot=st.reduce((function(t,e){return t.concat([e+"-start",e+"-end"])}),[]),rt=[].concat(st,["auto"]).reduce((function(t,e){return t.concat([e,e+"-start",e+"-end"])}),[]),at=["beforeRead","read","afterRead","beforeMain","main","afterMain","beforeWrite","write","afterWrite"];function lt(t){return t?(t.nodeName||"").toLowerCase():null}function ct(t){if(null==t)return window;if("[object Window]"!==t.toString()){var e=t.ownerDocument;return e&&e.defaultView||window}return t}function dt(t){return t instanceof ct(t).Element||t instanceof Element}function ht(t){return t instanceof ct(t).HTMLElement||t instanceof HTMLElement}function ut(t){return"undefined"!=typeof ShadowRoot&&(t instanceof ct(t).ShadowRoot||t instanceof ShadowRoot)}var ft={name:"applyStyles",enabled:!0,phase:"write",fn:function(t){var e=t.state;Object.keys(e.elements).forEach((function(t){var i=e.styles[t]||{},n=e.attributes[t]||{},s=e.elements[t];ht(s)&<(s)&&(Object.assign(s.style,i),Object.keys(n).forEach((function(t){var e=n[t];!1===e?s.removeAttribute(t):s.setAttribute(t,!0===e?"":e)})))}))},effect:function(t){var e=t.state,i={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(e.elements.popper.style,i.popper),e.styles=i,e.elements.arrow&&Object.assign(e.elements.arrow.style,i.arrow),function(){Object.keys(e.elements).forEach((function(t){var n=e.elements[t],s=e.attributes[t]||{},o=Object.keys(e.styles.hasOwnProperty(t)?e.styles[t]:i[t]).reduce((function(t,e){return t[e]="",t}),{});ht(n)&<(n)&&(Object.assign(n.style,o),Object.keys(s).forEach((function(t){n.removeAttribute(t)})))}))}},requires:["computeStyles"]};function pt(t){return t.split("-")[0]}function mt(t){var e=t.getBoundingClientRect();return{width:e.width,height:e.height,top:e.top,right:e.right,bottom:e.bottom,left:e.left,x:e.left,y:e.top}}function gt(t){var e=mt(t),i=t.offsetWidth,n=t.offsetHeight;return Math.abs(e.width-i)<=1&&(i=e.width),Math.abs(e.height-n)<=1&&(n=e.height),{x:t.offsetLeft,y:t.offsetTop,width:i,height:n}}function _t(t,e){var i=e.getRootNode&&e.getRootNode();if(t.contains(e))return!0;if(i&&ut(i)){var n=e;do{if(n&&t.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function bt(t){return ct(t).getComputedStyle(t)}function vt(t){return["table","td","th"].indexOf(lt(t))>=0}function yt(t){return((dt(t)?t.ownerDocument:t.document)||window.document).documentElement}function wt(t){return"html"===lt(t)?t:t.assignedSlot||t.parentNode||(ut(t)?t.host:null)||yt(t)}function Et(t){return ht(t)&&"fixed"!==bt(t).position?t.offsetParent:null}function Tt(t){for(var e=ct(t),i=Et(t);i&&vt(i)&&"static"===bt(i).position;)i=Et(i);return i&&("html"===lt(i)||"body"===lt(i)&&"static"===bt(i).position)?e:i||function(t){var e=-1!==navigator.userAgent.toLowerCase().indexOf("firefox");if(-1!==navigator.userAgent.indexOf("Trident")&&ht(t)&&"fixed"===bt(t).position)return null;for(var i=wt(t);ht(i)&&["html","body"].indexOf(lt(i))<0;){var n=bt(i);if("none"!==n.transform||"none"!==n.perspective||"paint"===n.contain||-1!==["transform","perspective"].indexOf(n.willChange)||e&&"filter"===n.willChange||e&&n.filter&&"none"!==n.filter)return i;i=i.parentNode}return null}(t)||e}function At(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}var Lt=Math.max,Ot=Math.min,kt=Math.round;function Ct(t,e,i){return Lt(t,Ot(e,i))}function xt(t){return Object.assign({},{top:0,right:0,bottom:0,left:0},t)}function Dt(t,e){return e.reduce((function(e,i){return e[i]=t,e}),{})}var Nt={name:"arrow",enabled:!0,phase:"main",fn:function(t){var e,i=t.state,n=t.name,s=t.options,o=i.elements.arrow,r=i.modifiersData.popperOffsets,a=pt(i.placement),l=At(a),c=[nt,it].indexOf(a)>=0?"height":"width";if(o&&r){var d=function(t,e){return xt("number"!=typeof(t="function"==typeof t?t(Object.assign({},e.rects,{placement:e.placement})):t)?t:Dt(t,st))}(s.padding,i),h=gt(o),u="y"===l?tt:nt,f="y"===l?et:it,p=i.rects.reference[c]+i.rects.reference[l]-r[l]-i.rects.popper[c],m=r[l]-i.rects.reference[l],g=Tt(o),_=g?"y"===l?g.clientHeight||0:g.clientWidth||0:0,b=p/2-m/2,v=d[u],y=_-h[c]-d[f],w=_/2-h[c]/2+b,E=Ct(v,w,y),T=l;i.modifiersData[n]=((e={})[T]=E,e.centerOffset=E-w,e)}},effect:function(t){var e=t.state,i=t.options.element,n=void 0===i?"[data-popper-arrow]":i;null!=n&&("string"!=typeof n||(n=e.elements.popper.querySelector(n)))&&_t(e.elements.popper,n)&&(e.elements.arrow=n)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]},St={top:"auto",right:"auto",bottom:"auto",left:"auto"};function It(t){var e,i=t.popper,n=t.popperRect,s=t.placement,o=t.offsets,r=t.position,a=t.gpuAcceleration,l=t.adaptive,c=t.roundOffsets,d=!0===c?function(t){var e=t.x,i=t.y,n=window.devicePixelRatio||1;return{x:kt(kt(e*n)/n)||0,y:kt(kt(i*n)/n)||0}}(o):"function"==typeof c?c(o):o,h=d.x,u=void 0===h?0:h,f=d.y,p=void 0===f?0:f,m=o.hasOwnProperty("x"),g=o.hasOwnProperty("y"),_=nt,b=tt,v=window;if(l){var y=Tt(i),w="clientHeight",E="clientWidth";y===ct(i)&&"static"!==bt(y=yt(i)).position&&(w="scrollHeight",E="scrollWidth"),y=y,s===tt&&(b=et,p-=y[w]-n.height,p*=a?1:-1),s===nt&&(_=it,u-=y[E]-n.width,u*=a?1:-1)}var T,A=Object.assign({position:r},l&&St);return a?Object.assign({},A,((T={})[b]=g?"0":"",T[_]=m?"0":"",T.transform=(v.devicePixelRatio||1)<2?"translate("+u+"px, "+p+"px)":"translate3d("+u+"px, "+p+"px, 0)",T)):Object.assign({},A,((e={})[b]=g?p+"px":"",e[_]=m?u+"px":"",e.transform="",e))}var jt={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(t){var e=t.state,i=t.options,n=i.gpuAcceleration,s=void 0===n||n,o=i.adaptive,r=void 0===o||o,a=i.roundOffsets,l=void 0===a||a,c={placement:pt(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:s};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign({},e.styles.popper,It(Object.assign({},c,{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:r,roundOffsets:l})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign({},e.styles.arrow,It(Object.assign({},c,{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-placement":e.placement})},data:{}},Pt={passive:!0},Mt={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(t){var e=t.state,i=t.instance,n=t.options,s=n.scroll,o=void 0===s||s,r=n.resize,a=void 0===r||r,l=ct(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return o&&c.forEach((function(t){t.addEventListener("scroll",i.update,Pt)})),a&&l.addEventListener("resize",i.update,Pt),function(){o&&c.forEach((function(t){t.removeEventListener("scroll",i.update,Pt)})),a&&l.removeEventListener("resize",i.update,Pt)}},data:{}},Ht={left:"right",right:"left",bottom:"top",top:"bottom"};function Rt(t){return t.replace(/left|right|bottom|top/g,(function(t){return Ht[t]}))}var Bt={start:"end",end:"start"};function Wt(t){return t.replace(/start|end/g,(function(t){return Bt[t]}))}function qt(t){var e=ct(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function zt(t){return mt(yt(t)).left+qt(t).scrollLeft}function Ut(t){var e=bt(t),i=e.overflow,n=e.overflowX,s=e.overflowY;return/auto|scroll|overlay|hidden/.test(i+s+n)}function $t(t,e){var i;void 0===e&&(e=[]);var n=function t(e){return["html","body","#document"].indexOf(lt(e))>=0?e.ownerDocument.body:ht(e)&&Ut(e)?e:t(wt(e))}(t),s=n===(null==(i=t.ownerDocument)?void 0:i.body),o=ct(n),r=s?[o].concat(o.visualViewport||[],Ut(n)?n:[]):n,a=e.concat(r);return s?a:a.concat($t(wt(r)))}function Ft(t){return Object.assign({},t,{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function Vt(t,e){return"viewport"===e?Ft(function(t){var e=ct(t),i=yt(t),n=e.visualViewport,s=i.clientWidth,o=i.clientHeight,r=0,a=0;return n&&(s=n.width,o=n.height,/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||(r=n.offsetLeft,a=n.offsetTop)),{width:s,height:o,x:r+zt(t),y:a}}(t)):ht(e)?function(t){var e=mt(t);return e.top=e.top+t.clientTop,e.left=e.left+t.clientLeft,e.bottom=e.top+t.clientHeight,e.right=e.left+t.clientWidth,e.width=t.clientWidth,e.height=t.clientHeight,e.x=e.left,e.y=e.top,e}(e):Ft(function(t){var e,i=yt(t),n=qt(t),s=null==(e=t.ownerDocument)?void 0:e.body,o=Lt(i.scrollWidth,i.clientWidth,s?s.scrollWidth:0,s?s.clientWidth:0),r=Lt(i.scrollHeight,i.clientHeight,s?s.scrollHeight:0,s?s.clientHeight:0),a=-n.scrollLeft+zt(t),l=-n.scrollTop;return"rtl"===bt(s||i).direction&&(a+=Lt(i.clientWidth,s?s.clientWidth:0)-o),{width:o,height:r,x:a,y:l}}(yt(t)))}function Kt(t){return t.split("-")[1]}function Xt(t){var e,i=t.reference,n=t.element,s=t.placement,o=s?pt(s):null,r=s?Kt(s):null,a=i.x+i.width/2-n.width/2,l=i.y+i.height/2-n.height/2;switch(o){case tt:e={x:a,y:i.y-n.height};break;case et:e={x:a,y:i.y+i.height};break;case it:e={x:i.x+i.width,y:l};break;case nt:e={x:i.x-n.width,y:l};break;default:e={x:i.x,y:i.y}}var c=o?At(o):null;if(null!=c){var d="y"===c?"height":"width";switch(r){case"start":e[c]=e[c]-(i[d]/2-n[d]/2);break;case"end":e[c]=e[c]+(i[d]/2-n[d]/2)}}return e}function Yt(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=void 0===n?t.placement:n,o=i.boundary,r=void 0===o?"clippingParents":o,a=i.rootBoundary,l=void 0===a?"viewport":a,c=i.elementContext,d=void 0===c?"popper":c,h=i.altBoundary,u=void 0!==h&&h,f=i.padding,p=void 0===f?0:f,m=xt("number"!=typeof p?p:Dt(p,st)),g="popper"===d?"reference":"popper",_=t.elements.reference,b=t.rects.popper,v=t.elements[u?g:d],y=function(t,e,i){var n="clippingParents"===e?function(t){var e=$t(wt(t)),i=["absolute","fixed"].indexOf(bt(t).position)>=0&&ht(t)?Tt(t):t;return dt(i)?e.filter((function(t){return dt(t)&&_t(t,i)&&"body"!==lt(t)})):[]}(t):[].concat(e),s=[].concat(n,[i]),o=s[0],r=s.reduce((function(e,i){var n=Vt(t,i);return e.top=Lt(n.top,e.top),e.right=Ot(n.right,e.right),e.bottom=Ot(n.bottom,e.bottom),e.left=Lt(n.left,e.left),e}),Vt(t,o));return r.width=r.right-r.left,r.height=r.bottom-r.top,r.x=r.left,r.y=r.top,r}(dt(v)?v:v.contextElement||yt(t.elements.popper),r,l),w=mt(_),E=Xt({reference:w,element:b,strategy:"absolute",placement:s}),T=Ft(Object.assign({},b,E)),A="popper"===d?T:w,L={top:y.top-A.top+m.top,bottom:A.bottom-y.bottom+m.bottom,left:y.left-A.left+m.left,right:A.right-y.right+m.right},O=t.modifiersData.offset;if("popper"===d&&O){var k=O[s];Object.keys(L).forEach((function(t){var e=[it,et].indexOf(t)>=0?1:-1,i=[tt,et].indexOf(t)>=0?"y":"x";L[t]+=k[i]*e}))}return L}function Qt(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=i.boundary,o=i.rootBoundary,r=i.padding,a=i.flipVariations,l=i.allowedAutoPlacements,c=void 0===l?rt:l,d=Kt(n),h=d?a?ot:ot.filter((function(t){return Kt(t)===d})):st,u=h.filter((function(t){return c.indexOf(t)>=0}));0===u.length&&(u=h);var f=u.reduce((function(e,i){return e[i]=Yt(t,{placement:i,boundary:s,rootBoundary:o,padding:r})[pt(i)],e}),{});return Object.keys(f).sort((function(t,e){return f[t]-f[e]}))}var Gt={name:"flip",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name;if(!e.modifiersData[n]._skip){for(var s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0===r||r,l=i.fallbackPlacements,c=i.padding,d=i.boundary,h=i.rootBoundary,u=i.altBoundary,f=i.flipVariations,p=void 0===f||f,m=i.allowedAutoPlacements,g=e.options.placement,_=pt(g),b=l||(_!==g&&p?function(t){if("auto"===pt(t))return[];var e=Rt(t);return[Wt(t),e,Wt(e)]}(g):[Rt(g)]),v=[g].concat(b).reduce((function(t,i){return t.concat("auto"===pt(i)?Qt(e,{placement:i,boundary:d,rootBoundary:h,padding:c,flipVariations:p,allowedAutoPlacements:m}):i)}),[]),y=e.rects.reference,w=e.rects.popper,E=new Map,T=!0,A=v[0],L=0;L=0,D=x?"width":"height",N=Yt(e,{placement:O,boundary:d,rootBoundary:h,altBoundary:u,padding:c}),S=x?C?it:nt:C?et:tt;y[D]>w[D]&&(S=Rt(S));var I=Rt(S),j=[];if(o&&j.push(N[k]<=0),a&&j.push(N[S]<=0,N[I]<=0),j.every((function(t){return t}))){A=O,T=!1;break}E.set(O,j)}if(T)for(var P=function(t){var e=v.find((function(e){var i=E.get(e);if(i)return i.slice(0,t).every((function(t){return t}))}));if(e)return A=e,"break"},M=p?3:1;M>0&&"break"!==P(M);M--);e.placement!==A&&(e.modifiersData[n]._skip=!0,e.placement=A,e.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function Zt(t,e,i){return void 0===i&&(i={x:0,y:0}),{top:t.top-e.height-i.y,right:t.right-e.width+i.x,bottom:t.bottom-e.height+i.y,left:t.left-e.width-i.x}}function Jt(t){return[tt,it,et,nt].some((function(e){return t[e]>=0}))}var te={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(t){var e=t.state,i=t.name,n=e.rects.reference,s=e.rects.popper,o=e.modifiersData.preventOverflow,r=Yt(e,{elementContext:"reference"}),a=Yt(e,{altBoundary:!0}),l=Zt(r,n),c=Zt(a,s,o),d=Jt(l),h=Jt(c);e.modifiersData[i]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:d,hasPopperEscaped:h},e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-reference-hidden":d,"data-popper-escaped":h})}},ee={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.offset,o=void 0===s?[0,0]:s,r=rt.reduce((function(t,i){return t[i]=function(t,e,i){var n=pt(t),s=[nt,tt].indexOf(n)>=0?-1:1,o="function"==typeof i?i(Object.assign({},e,{placement:t})):i,r=o[0],a=o[1];return r=r||0,a=(a||0)*s,[nt,it].indexOf(n)>=0?{x:a,y:r}:{x:r,y:a}}(i,e.rects,o),t}),{}),a=r[e.placement],l=a.x,c=a.y;null!=e.modifiersData.popperOffsets&&(e.modifiersData.popperOffsets.x+=l,e.modifiersData.popperOffsets.y+=c),e.modifiersData[n]=r}},ie={name:"popperOffsets",enabled:!0,phase:"read",fn:function(t){var e=t.state,i=t.name;e.modifiersData[i]=Xt({reference:e.rects.reference,element:e.rects.popper,strategy:"absolute",placement:e.placement})},data:{}},ne={name:"preventOverflow",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0!==r&&r,l=i.boundary,c=i.rootBoundary,d=i.altBoundary,h=i.padding,u=i.tether,f=void 0===u||u,p=i.tetherOffset,m=void 0===p?0:p,g=Yt(e,{boundary:l,rootBoundary:c,padding:h,altBoundary:d}),_=pt(e.placement),b=Kt(e.placement),v=!b,y=At(_),w="x"===y?"y":"x",E=e.modifiersData.popperOffsets,T=e.rects.reference,A=e.rects.popper,L="function"==typeof m?m(Object.assign({},e.rects,{placement:e.placement})):m,O={x:0,y:0};if(E){if(o||a){var k="y"===y?tt:nt,C="y"===y?et:it,x="y"===y?"height":"width",D=E[y],N=E[y]+g[k],S=E[y]-g[C],I=f?-A[x]/2:0,j="start"===b?T[x]:A[x],P="start"===b?-A[x]:-T[x],M=e.elements.arrow,H=f&&M?gt(M):{width:0,height:0},R=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},B=R[k],W=R[C],q=Ct(0,T[x],H[x]),z=v?T[x]/2-I-q-B-L:j-q-B-L,U=v?-T[x]/2+I+q+W+L:P+q+W+L,$=e.elements.arrow&&Tt(e.elements.arrow),F=$?"y"===y?$.clientTop||0:$.clientLeft||0:0,V=e.modifiersData.offset?e.modifiersData.offset[e.placement][y]:0,K=E[y]+z-V-F,X=E[y]+U-V;if(o){var Y=Ct(f?Ot(N,K):N,D,f?Lt(S,X):S);E[y]=Y,O[y]=Y-D}if(a){var Q="x"===y?tt:nt,G="x"===y?et:it,Z=E[w],J=Z+g[Q],st=Z-g[G],ot=Ct(f?Ot(J,K):J,Z,f?Lt(st,X):st);E[w]=ot,O[w]=ot-Z}}e.modifiersData[n]=O}},requiresIfExists:["offset"]};function se(t,e,i){void 0===i&&(i=!1);var n,s,o=yt(e),r=mt(t),a=ht(e),l={scrollLeft:0,scrollTop:0},c={x:0,y:0};return(a||!a&&!i)&&(("body"!==lt(e)||Ut(o))&&(l=(n=e)!==ct(n)&&ht(n)?{scrollLeft:(s=n).scrollLeft,scrollTop:s.scrollTop}:qt(n)),ht(e)?((c=mt(e)).x+=e.clientLeft,c.y+=e.clientTop):o&&(c.x=zt(o))),{x:r.left+l.scrollLeft-c.x,y:r.top+l.scrollTop-c.y,width:r.width,height:r.height}}var oe={placement:"bottom",modifiers:[],strategy:"absolute"};function re(){for(var t=arguments.length,e=new Array(t),i=0;i"applyStyles"===t.name&&!1===t.enabled);this._popper=de(e,this._menu,i),n&&U.setDataAttribute(this._menu,"popper","static")}"ontouchstart"in document.documentElement&&!t.closest(".navbar-nav")&&[].concat(...document.body.children).forEach(t=>H.on(t,"mouseover",p)),this._element.focus(),this._element.setAttribute("aria-expanded",!0),this._menu.classList.toggle("show"),this._element.classList.toggle("show"),H.trigger(this._element,"shown.bs.dropdown",e)}}hide(){if(u(this._element)||!this._menu.classList.contains("show"))return;const t={relatedTarget:this._element};this._completeHide(t)}dispose(){this._popper&&this._popper.destroy(),super.dispose()}update(){this._inNavbar=this._detectNavbar(),this._popper&&this._popper.update()}_addEventListeners(){H.on(this._element,"click.bs.dropdown",t=>{t.preventDefault(),this.toggle()})}_completeHide(t){H.trigger(this._element,"hide.bs.dropdown",t).defaultPrevented||("ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach(t=>H.off(t,"mouseover",p)),this._popper&&this._popper.destroy(),this._menu.classList.remove("show"),this._element.classList.remove("show"),this._element.setAttribute("aria-expanded","false"),U.removeDataAttribute(this._menu,"popper"),H.trigger(this._element,"hidden.bs.dropdown",t))}_getConfig(t){if(t={...this.constructor.Default,...U.getDataAttributes(this._element),...t},d("dropdown",t,this.constructor.DefaultType),"object"==typeof t.reference&&!a(t.reference)&&"function"!=typeof t.reference.getBoundingClientRect)throw new TypeError("dropdown".toUpperCase()+': Option "reference" provided type "object" without a required "getBoundingClientRect" method.');return t}_getMenuElement(){return t.next(this._element,".dropdown-menu")[0]}_getPlacement(){const t=this._element.parentNode;if(t.classList.contains("dropend"))return _e;if(t.classList.contains("dropstart"))return be;const e="end"===getComputedStyle(this._menu).getPropertyValue("--bs-position").trim();return t.classList.contains("dropup")?e?pe:fe:e?ge:me}_detectNavbar(){return null!==this._element.closest(".navbar")}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map(t=>Number.parseInt(t,10)):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return"static"===this._config.display&&(t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,..."function"==typeof this._config.popperConfig?this._config.popperConfig(t):this._config.popperConfig}}_selectMenuItem(e){const i=t.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter(h);if(!i.length)return;let n=i.indexOf(e.target);"ArrowUp"===e.key&&n>0&&n--,"ArrowDown"===e.key&&nthis.matches('[data-bs-toggle="dropdown"]')?this:t.prev(this,'[data-bs-toggle="dropdown"]')[0];if("Escape"===e.key)return n().focus(),void we.clearMenus();i||"ArrowUp"!==e.key&&"ArrowDown"!==e.key?i&&"Space"!==e.key?we.getInstance(n())._selectMenuItem(e):we.clearMenus():n().click()}}H.on(document,"keydown.bs.dropdown.data-api",'[data-bs-toggle="dropdown"]',we.dataApiKeydownHandler),H.on(document,"keydown.bs.dropdown.data-api",".dropdown-menu",we.dataApiKeydownHandler),H.on(document,"click.bs.dropdown.data-api",we.clearMenus),H.on(document,"keyup.bs.dropdown.data-api",we.clearMenus),H.on(document,"click.bs.dropdown.data-api",'[data-bs-toggle="dropdown"]',(function(t){t.preventDefault(),we.dropdownInterface(this)})),b(we);const Ee=()=>{const t=document.documentElement.clientWidth;return Math.abs(window.innerWidth-t)},Te=(t=Ee())=>{Ae(),Le("body","paddingRight",e=>e+t),Le(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top","paddingRight",e=>e+t),Le(".sticky-top","marginRight",e=>e-t)},Ae=()=>{const t=document.body.style.overflow;t&&U.setDataAttribute(document.body,"overflow",t),document.body.style.overflow="hidden"},Le=(e,i,n)=>{const s=Ee();t.find(e).forEach(t=>{if(t!==document.body&&window.innerWidth>t.clientWidth+s)return;const e=t.style[i],o=window.getComputedStyle(t)[i];U.setDataAttribute(t,i,e),t.style[i]=n(Number.parseFloat(o))+"px"})},Oe=()=>{ke("body","overflow"),ke("body","paddingRight"),ke(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top","paddingRight"),ke(".sticky-top","marginRight")},ke=(e,i)=>{t.find(e).forEach(t=>{const e=U.getDataAttribute(t,i);void 0===e?t.style.removeProperty(i):(U.removeDataAttribute(t,i),t.style[i]=e)})},Ce={isVisible:!0,isAnimated:!1,rootElement:document.body,clickCallback:null},xe={isVisible:"boolean",isAnimated:"boolean",rootElement:"element",clickCallback:"(function|null)"};class De{constructor(t){this._config=this._getConfig(t),this._isAppended=!1,this._element=null}show(t){this._config.isVisible?(this._append(),this._config.isAnimated&&m(this._getElement()),this._getElement().classList.add("show"),this._emulateAnimation(()=>{v(t)})):v(t)}hide(t){this._config.isVisible?(this._getElement().classList.remove("show"),this._emulateAnimation(()=>{this.dispose(),v(t)})):v(t)}_getElement(){if(!this._element){const t=document.createElement("div");t.className="modal-backdrop",this._config.isAnimated&&t.classList.add("fade"),this._element=t}return this._element}_getConfig(t){return(t={...Ce,..."object"==typeof t?t:{}}).rootElement=t.rootElement||document.body,d("backdrop",t,xe),t}_append(){this._isAppended||(this._config.rootElement.appendChild(this._getElement()),H.on(this._getElement(),"mousedown.bs.backdrop",()=>{v(this._config.clickCallback)}),this._isAppended=!0)}dispose(){this._isAppended&&(H.off(this._element,"mousedown.bs.backdrop"),this._getElement().parentNode.removeChild(this._element),this._isAppended=!1)}_emulateAnimation(t){if(!this._config.isAnimated)return void v(t);const e=o(this._getElement());H.one(this._getElement(),"transitionend",()=>v(t)),c(this._getElement(),e)}}const Ne={backdrop:!0,keyboard:!0,focus:!0},Se={backdrop:"(boolean|string)",keyboard:"boolean",focus:"boolean"};class Ie extends R{constructor(e,i){super(e),this._config=this._getConfig(i),this._dialog=t.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._isShown=!1,this._ignoreBackdropClick=!1,this._isTransitioning=!1}static get Default(){return Ne}static get NAME(){return"modal"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){if(this._isShown||this._isTransitioning)return;this._isAnimated()&&(this._isTransitioning=!0);const e=H.trigger(this._element,"show.bs.modal",{relatedTarget:t});this._isShown||e.defaultPrevented||(this._isShown=!0,Te(),document.body.classList.add("modal-open"),this._adjustDialog(),this._setEscapeEvent(),this._setResizeEvent(),H.on(this._element,"click.dismiss.bs.modal",'[data-bs-dismiss="modal"]',t=>this.hide(t)),H.on(this._dialog,"mousedown.dismiss.bs.modal",()=>{H.one(this._element,"mouseup.dismiss.bs.modal",t=>{t.target===this._element&&(this._ignoreBackdropClick=!0)})}),this._showBackdrop(()=>this._showElement(t)))}hide(t){if(t&&t.preventDefault(),!this._isShown||this._isTransitioning)return;if(H.trigger(this._element,"hide.bs.modal").defaultPrevented)return;this._isShown=!1;const e=this._isAnimated();e&&(this._isTransitioning=!0),this._setEscapeEvent(),this._setResizeEvent(),H.off(document,"focusin.bs.modal"),this._element.classList.remove("show"),H.off(this._element,"click.dismiss.bs.modal"),H.off(this._dialog,"mousedown.dismiss.bs.modal"),this._queueCallback(()=>this._hideModal(),this._element,e)}dispose(){[window,this._dialog].forEach(t=>H.off(t,".bs.modal")),this._backdrop.dispose(),super.dispose(),H.off(document,"focusin.bs.modal")}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new De({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_getConfig(t){return t={...Ne,...U.getDataAttributes(this._element),...t},d("modal",t,Se),t}_showElement(e){const i=this._isAnimated(),n=t.findOne(".modal-body",this._dialog);this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.appendChild(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0,n&&(n.scrollTop=0),i&&m(this._element),this._element.classList.add("show"),this._config.focus&&this._enforceFocus(),this._queueCallback(()=>{this._config.focus&&this._element.focus(),this._isTransitioning=!1,H.trigger(this._element,"shown.bs.modal",{relatedTarget:e})},this._dialog,i)}_enforceFocus(){H.off(document,"focusin.bs.modal"),H.on(document,"focusin.bs.modal",t=>{document===t.target||this._element===t.target||this._element.contains(t.target)||this._element.focus()})}_setEscapeEvent(){this._isShown?H.on(this._element,"keydown.dismiss.bs.modal",t=>{this._config.keyboard&&"Escape"===t.key?(t.preventDefault(),this.hide()):this._config.keyboard||"Escape"!==t.key||this._triggerBackdropTransition()}):H.off(this._element,"keydown.dismiss.bs.modal")}_setResizeEvent(){this._isShown?H.on(window,"resize.bs.modal",()=>this._adjustDialog()):H.off(window,"resize.bs.modal")}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide(()=>{document.body.classList.remove("modal-open"),this._resetAdjustments(),Oe(),H.trigger(this._element,"hidden.bs.modal")})}_showBackdrop(t){H.on(this._element,"click.dismiss.bs.modal",t=>{this._ignoreBackdropClick?this._ignoreBackdropClick=!1:t.target===t.currentTarget&&(!0===this._config.backdrop?this.hide():"static"===this._config.backdrop&&this._triggerBackdropTransition())}),this._backdrop.show(t)}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(H.trigger(this._element,"hidePrevented.bs.modal").defaultPrevented)return;const t=this._element.scrollHeight>document.documentElement.clientHeight;t||(this._element.style.overflowY="hidden"),this._element.classList.add("modal-static");const e=o(this._dialog);H.off(this._element,"transitionend"),H.one(this._element,"transitionend",()=>{this._element.classList.remove("modal-static"),t||(H.one(this._element,"transitionend",()=>{this._element.style.overflowY=""}),c(this._element,e))}),c(this._element,e),this._element.focus()}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=Ee(),i=e>0;(!i&&t&&!_()||i&&!t&&_())&&(this._element.style.paddingLeft=e+"px"),(i&&!t&&!_()||!i&&t&&_())&&(this._element.style.paddingRight=e+"px")}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const i=Ie.getInstance(this)||new Ie(this,"object"==typeof t?t:{});if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t](e)}}))}}H.on(document,"click.bs.modal.data-api",'[data-bs-toggle="modal"]',(function(t){const e=s(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),H.one(e,"show.bs.modal",t=>{t.defaultPrevented||H.one(e,"hidden.bs.modal",()=>{h(this)&&this.focus()})}),(Ie.getInstance(e)||new Ie(e)).toggle(this)})),b(Ie);const je={backdrop:!0,keyboard:!0,scroll:!1},Pe={backdrop:"boolean",keyboard:"boolean",scroll:"boolean"};class Me extends R{constructor(t,e){super(t),this._config=this._getConfig(e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._addEventListeners()}static get NAME(){return"offcanvas"}static get Default(){return je}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||H.trigger(this._element,"show.bs.offcanvas",{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._element.style.visibility="visible",this._backdrop.show(),this._config.scroll||(Te(),this._enforceFocusOnElement(this._element)),this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add("show"),this._queueCallback(()=>{H.trigger(this._element,"shown.bs.offcanvas",{relatedTarget:t})},this._element,!0))}hide(){this._isShown&&(H.trigger(this._element,"hide.bs.offcanvas").defaultPrevented||(H.off(document,"focusin.bs.offcanvas"),this._element.blur(),this._isShown=!1,this._element.classList.remove("show"),this._backdrop.hide(),this._queueCallback(()=>{this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._element.style.visibility="hidden",this._config.scroll||Oe(),H.trigger(this._element,"hidden.bs.offcanvas")},this._element,!0)))}dispose(){this._backdrop.dispose(),super.dispose(),H.off(document,"focusin.bs.offcanvas")}_getConfig(t){return t={...je,...U.getDataAttributes(this._element),..."object"==typeof t?t:{}},d("offcanvas",t,Pe),t}_initializeBackDrop(){return new De({isVisible:this._config.backdrop,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:()=>this.hide()})}_enforceFocusOnElement(t){H.off(document,"focusin.bs.offcanvas"),H.on(document,"focusin.bs.offcanvas",e=>{document===e.target||t===e.target||t.contains(e.target)||t.focus()}),t.focus()}_addEventListeners(){H.on(this._element,"click.dismiss.bs.offcanvas",'[data-bs-dismiss="offcanvas"]',()=>this.hide()),H.on(this._element,"keydown.dismiss.bs.offcanvas",t=>{this._config.keyboard&&"Escape"===t.key&&this.hide()})}static jQueryInterface(t){return this.each((function(){const e=w.get(this,"bs.offcanvas")||new Me(this,"object"==typeof t?t:{});if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}H.on(document,"click.bs.offcanvas.data-api",'[data-bs-toggle="offcanvas"]',(function(e){const i=s(this);if(["A","AREA"].includes(this.tagName)&&e.preventDefault(),u(this))return;H.one(i,"hidden.bs.offcanvas",()=>{h(this)&&this.focus()});const n=t.findOne(".offcanvas.show");n&&n!==i&&Me.getInstance(n).hide(),(w.get(i,"bs.offcanvas")||new Me(i)).toggle(this)})),H.on(window,"load.bs.offcanvas.data-api",()=>{t.find(".offcanvas.show").forEach(t=>(w.get(t,"bs.offcanvas")||new Me(t)).show())}),b(Me);const He=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),Re=/^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/i,Be=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i,We=(t,e)=>{const i=t.nodeName.toLowerCase();if(e.includes(i))return!He.has(i)||Boolean(Re.test(t.nodeValue)||Be.test(t.nodeValue));const n=e.filter(t=>t instanceof RegExp);for(let t=0,e=n.length;t{We(t,a)||i.removeAttribute(t.nodeName)})}return n.body.innerHTML}const ze=new RegExp("(^|\\s)bs-tooltip\\S+","g"),Ue=new Set(["sanitize","allowList","sanitizeFn"]),$e={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(array|string|function)",container:"(string|element|boolean)",fallbackPlacements:"array",boundary:"(string|element)",customClass:"(string|function)",sanitize:"boolean",sanitizeFn:"(null|function)",allowList:"object",popperConfig:"(null|object|function)"},Fe={AUTO:"auto",TOP:"top",RIGHT:_()?"left":"right",BOTTOM:"bottom",LEFT:_()?"right":"left"},Ve={animation:!0,template:'',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:[0,0],container:!1,fallbackPlacements:["top","right","bottom","left"],boundary:"clippingParents",customClass:"",sanitize:!0,sanitizeFn:null,allowList:{"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},popperConfig:null},Ke={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"};class Xe extends R{constructor(t,e){if(void 0===he)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(t),this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this._config=this._getConfig(e),this.tip=null,this._setListeners()}static get Default(){return Ve}static get NAME(){return"tooltip"}static get Event(){return Ke}static get DefaultType(){return $e}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(t){if(this._isEnabled)if(t){const e=this._initializeOnDelegatedTarget(t);e._activeTrigger.click=!e._activeTrigger.click,e._isWithActiveTrigger()?e._enter(null,e):e._leave(null,e)}else{if(this.getTipElement().classList.contains("show"))return void this._leave(null,this);this._enter(null,this)}}dispose(){clearTimeout(this._timeout),H.off(this._element.closest(".modal"),"hide.bs.modal",this._hideModalHandler),this.tip&&this.tip.parentNode&&this.tip.parentNode.removeChild(this.tip),this._popper&&this._popper.destroy(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this.isWithContent()||!this._isEnabled)return;const t=H.trigger(this._element,this.constructor.Event.SHOW),i=f(this._element),n=null===i?this._element.ownerDocument.documentElement.contains(this._element):i.contains(this._element);if(t.defaultPrevented||!n)return;const s=this.getTipElement(),o=e(this.constructor.NAME);s.setAttribute("id",o),this._element.setAttribute("aria-describedby",o),this.setContent(),this._config.animation&&s.classList.add("fade");const r="function"==typeof this._config.placement?this._config.placement.call(this,s,this._element):this._config.placement,a=this._getAttachment(r);this._addAttachmentClass(a);const{container:l}=this._config;w.set(s,this.constructor.DATA_KEY,this),this._element.ownerDocument.documentElement.contains(this.tip)||(l.appendChild(s),H.trigger(this._element,this.constructor.Event.INSERTED)),this._popper?this._popper.update():this._popper=de(this._element,s,this._getPopperConfig(a)),s.classList.add("show");const c="function"==typeof this._config.customClass?this._config.customClass():this._config.customClass;c&&s.classList.add(...c.split(" ")),"ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach(t=>{H.on(t,"mouseover",p)});const d=this.tip.classList.contains("fade");this._queueCallback(()=>{const t=this._hoverState;this._hoverState=null,H.trigger(this._element,this.constructor.Event.SHOWN),"out"===t&&this._leave(null,this)},this.tip,d)}hide(){if(!this._popper)return;const t=this.getTipElement();if(H.trigger(this._element,this.constructor.Event.HIDE).defaultPrevented)return;t.classList.remove("show"),"ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach(t=>H.off(t,"mouseover",p)),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1;const e=this.tip.classList.contains("fade");this._queueCallback(()=>{this._isWithActiveTrigger()||("show"!==this._hoverState&&t.parentNode&&t.parentNode.removeChild(t),this._cleanTipClass(),this._element.removeAttribute("aria-describedby"),H.trigger(this._element,this.constructor.Event.HIDDEN),this._popper&&(this._popper.destroy(),this._popper=null))},this.tip,e),this._hoverState=""}update(){null!==this._popper&&this._popper.update()}isWithContent(){return Boolean(this.getTitle())}getTipElement(){if(this.tip)return this.tip;const t=document.createElement("div");return t.innerHTML=this._config.template,this.tip=t.children[0],this.tip}setContent(){const e=this.getTipElement();this.setElementContent(t.findOne(".tooltip-inner",e),this.getTitle()),e.classList.remove("fade","show")}setElementContent(t,e){if(null!==t)return a(e)?(e=l(e),void(this._config.html?e.parentNode!==t&&(t.innerHTML="",t.appendChild(e)):t.textContent=e.textContent)):void(this._config.html?(this._config.sanitize&&(e=qe(e,this._config.allowList,this._config.sanitizeFn)),t.innerHTML=e):t.textContent=e)}getTitle(){let t=this._element.getAttribute("data-bs-original-title");return t||(t="function"==typeof this._config.title?this._config.title.call(this._element):this._config.title),t}updateAttachment(t){return"right"===t?"end":"left"===t?"start":t}_initializeOnDelegatedTarget(t,e){const i=this.constructor.DATA_KEY;return(e=e||w.get(t.delegateTarget,i))||(e=new this.constructor(t.delegateTarget,this._getDelegateConfig()),w.set(t.delegateTarget,i,e)),e}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map(t=>Number.parseInt(t,10)):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"onChange",enabled:!0,phase:"afterWrite",fn:t=>this._handlePopperPlacementChange(t)}],onFirstUpdate:t=>{t.options.placement!==t.placement&&this._handlePopperPlacementChange(t)}};return{...e,..."function"==typeof this._config.popperConfig?this._config.popperConfig(e):this._config.popperConfig}}_addAttachmentClass(t){this.getTipElement().classList.add("bs-tooltip-"+this.updateAttachment(t))}_getAttachment(t){return Fe[t.toUpperCase()]}_setListeners(){this._config.trigger.split(" ").forEach(t=>{if("click"===t)H.on(this._element,this.constructor.Event.CLICK,this._config.selector,t=>this.toggle(t));else if("manual"!==t){const e="hover"===t?this.constructor.Event.MOUSEENTER:this.constructor.Event.FOCUSIN,i="hover"===t?this.constructor.Event.MOUSELEAVE:this.constructor.Event.FOCUSOUT;H.on(this._element,e,this._config.selector,t=>this._enter(t)),H.on(this._element,i,this._config.selector,t=>this._leave(t))}}),this._hideModalHandler=()=>{this._element&&this.hide()},H.on(this._element.closest(".modal"),"hide.bs.modal",this._hideModalHandler),this._config.selector?this._config={...this._config,trigger:"manual",selector:""}:this._fixTitle()}_fixTitle(){const t=this._element.getAttribute("title"),e=typeof this._element.getAttribute("data-bs-original-title");(t||"string"!==e)&&(this._element.setAttribute("data-bs-original-title",t||""),!t||this._element.getAttribute("aria-label")||this._element.textContent||this._element.setAttribute("aria-label",t),this._element.setAttribute("title",""))}_enter(t,e){e=this._initializeOnDelegatedTarget(t,e),t&&(e._activeTrigger["focusin"===t.type?"focus":"hover"]=!0),e.getTipElement().classList.contains("show")||"show"===e._hoverState?e._hoverState="show":(clearTimeout(e._timeout),e._hoverState="show",e._config.delay&&e._config.delay.show?e._timeout=setTimeout(()=>{"show"===e._hoverState&&e.show()},e._config.delay.show):e.show())}_leave(t,e){e=this._initializeOnDelegatedTarget(t,e),t&&(e._activeTrigger["focusout"===t.type?"focus":"hover"]=e._element.contains(t.relatedTarget)),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState="out",e._config.delay&&e._config.delay.hide?e._timeout=setTimeout(()=>{"out"===e._hoverState&&e.hide()},e._config.delay.hide):e.hide())}_isWithActiveTrigger(){for(const t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1}_getConfig(t){const e=U.getDataAttributes(this._element);return Object.keys(e).forEach(t=>{Ue.has(t)&&delete e[t]}),(t={...this.constructor.Default,...e,..."object"==typeof t&&t?t:{}}).container=!1===t.container?document.body:l(t.container),"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),d("tooltip",t,this.constructor.DefaultType),t.sanitize&&(t.template=qe(t.template,t.allowList,t.sanitizeFn)),t}_getDelegateConfig(){const t={};if(this._config)for(const e in this._config)this.constructor.Default[e]!==this._config[e]&&(t[e]=this._config[e]);return t}_cleanTipClass(){const t=this.getTipElement(),e=t.getAttribute("class").match(ze);null!==e&&e.length>0&&e.map(t=>t.trim()).forEach(e=>t.classList.remove(e))}_handlePopperPlacementChange(t){const{state:e}=t;e&&(this.tip=e.elements.popper,this._cleanTipClass(),this._addAttachmentClass(this._getAttachment(e.placement)))}static jQueryInterface(t){return this.each((function(){let e=w.get(this,"bs.tooltip");const i="object"==typeof t&&t;if((e||!/dispose|hide/.test(t))&&(e||(e=new Xe(this,i)),"string"==typeof t)){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}b(Xe);const Ye=new RegExp("(^|\\s)bs-popover\\S+","g"),Qe={...Xe.Default,placement:"right",offset:[0,8],trigger:"click",content:"",template:''},Ge={...Xe.DefaultType,content:"(string|element|function)"},Ze={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"};class Je extends Xe{static get Default(){return Qe}static get NAME(){return"popover"}static get Event(){return Ze}static get DefaultType(){return Ge}isWithContent(){return this.getTitle()||this._getContent()}setContent(){const e=this.getTipElement();this.setElementContent(t.findOne(".popover-header",e),this.getTitle());let i=this._getContent();"function"==typeof i&&(i=i.call(this._element)),this.setElementContent(t.findOne(".popover-body",e),i),e.classList.remove("fade","show")}_addAttachmentClass(t){this.getTipElement().classList.add("bs-popover-"+this.updateAttachment(t))}_getContent(){return this._element.getAttribute("data-bs-content")||this._config.content}_cleanTipClass(){const t=this.getTipElement(),e=t.getAttribute("class").match(Ye);null!==e&&e.length>0&&e.map(t=>t.trim()).forEach(e=>t.classList.remove(e))}static jQueryInterface(t){return this.each((function(){let e=w.get(this,"bs.popover");const i="object"==typeof t?t:null;if((e||!/dispose|hide/.test(t))&&(e||(e=new Je(this,i),w.set(this,"bs.popover",e)),"string"==typeof t)){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}b(Je);const ti={offset:10,method:"auto",target:""},ei={offset:"number",method:"string",target:"(string|element)"};class ii extends R{constructor(t,e){super(t),this._scrollElement="BODY"===this._element.tagName?window:this._element,this._config=this._getConfig(e),this._selector=`${this._config.target} .nav-link, ${this._config.target} .list-group-item, ${this._config.target} .dropdown-item`,this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,H.on(this._scrollElement,"scroll.bs.scrollspy",()=>this._process()),this.refresh(),this._process()}static get Default(){return ti}static get NAME(){return"scrollspy"}refresh(){const e=this._scrollElement===this._scrollElement.window?"offset":"position",i="auto"===this._config.method?e:this._config.method,s="position"===i?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),t.find(this._selector).map(e=>{const o=n(e),r=o?t.findOne(o):null;if(r){const t=r.getBoundingClientRect();if(t.width||t.height)return[U[i](r).top+s,o]}return null}).filter(t=>t).sort((t,e)=>t[0]-e[0]).forEach(t=>{this._offsets.push(t[0]),this._targets.push(t[1])})}dispose(){H.off(this._scrollElement,".bs.scrollspy"),super.dispose()}_getConfig(t){if("string"!=typeof(t={...ti,...U.getDataAttributes(this._element),..."object"==typeof t&&t?t:{}}).target&&a(t.target)){let{id:i}=t.target;i||(i=e("scrollspy"),t.target.id=i),t.target="#"+i}return d("scrollspy",t,ei),t}_getScrollTop(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop}_getScrollHeight(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)}_getOffsetHeight(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height}_process(){const t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),i=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=i){const t=this._targets[this._targets.length-1];this._activeTarget!==t&&this._activate(t)}else{if(this._activeTarget&&t0)return this._activeTarget=null,void this._clear();for(let e=this._offsets.length;e--;)this._activeTarget!==this._targets[e]&&t>=this._offsets[e]&&(void 0===this._offsets[e+1]||t`${t}[data-bs-target="${e}"],${t}[href="${e}"]`),n=t.findOne(i.join(","));n.classList.contains("dropdown-item")?(t.findOne(".dropdown-toggle",n.closest(".dropdown")).classList.add("active"),n.classList.add("active")):(n.classList.add("active"),t.parents(n,".nav, .list-group").forEach(e=>{t.prev(e,".nav-link, .list-group-item").forEach(t=>t.classList.add("active")),t.prev(e,".nav-item").forEach(e=>{t.children(e,".nav-link").forEach(t=>t.classList.add("active"))})})),H.trigger(this._scrollElement,"activate.bs.scrollspy",{relatedTarget:e})}_clear(){t.find(this._selector).filter(t=>t.classList.contains("active")).forEach(t=>t.classList.remove("active"))}static jQueryInterface(t){return this.each((function(){const e=ii.getInstance(this)||new ii(this,"object"==typeof t?t:{});if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}H.on(window,"load.bs.scrollspy.data-api",()=>{t.find('[data-bs-spy="scroll"]').forEach(t=>new ii(t))}),b(ii);class ni extends R{static get NAME(){return"tab"}show(){if(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&this._element.classList.contains("active"))return;let e;const i=s(this._element),n=this._element.closest(".nav, .list-group");if(n){const i="UL"===n.nodeName||"OL"===n.nodeName?":scope > li > .active":".active";e=t.find(i,n),e=e[e.length-1]}const o=e?H.trigger(e,"hide.bs.tab",{relatedTarget:this._element}):null;if(H.trigger(this._element,"show.bs.tab",{relatedTarget:e}).defaultPrevented||null!==o&&o.defaultPrevented)return;this._activate(this._element,n);const r=()=>{H.trigger(e,"hidden.bs.tab",{relatedTarget:this._element}),H.trigger(this._element,"shown.bs.tab",{relatedTarget:e})};i?this._activate(i,i.parentNode,r):r()}_activate(e,i,n){const s=(!i||"UL"!==i.nodeName&&"OL"!==i.nodeName?t.children(i,".active"):t.find(":scope > li > .active",i))[0],o=n&&s&&s.classList.contains("fade"),r=()=>this._transitionComplete(e,s,n);s&&o?(s.classList.remove("show"),this._queueCallback(r,e,!0)):r()}_transitionComplete(e,i,n){if(i){i.classList.remove("active");const e=t.findOne(":scope > .dropdown-menu .active",i.parentNode);e&&e.classList.remove("active"),"tab"===i.getAttribute("role")&&i.setAttribute("aria-selected",!1)}e.classList.add("active"),"tab"===e.getAttribute("role")&&e.setAttribute("aria-selected",!0),m(e),e.classList.contains("fade")&&e.classList.add("show");let s=e.parentNode;if(s&&"LI"===s.nodeName&&(s=s.parentNode),s&&s.classList.contains("dropdown-menu")){const i=e.closest(".dropdown");i&&t.find(".dropdown-toggle",i).forEach(t=>t.classList.add("active")),e.setAttribute("aria-expanded",!0)}n&&n()}static jQueryInterface(t){return this.each((function(){const e=w.get(this,"bs.tab")||new ni(this);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}H.on(document,"click.bs.tab.data-api",'[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),u(this)||(w.get(this,"bs.tab")||new ni(this)).show()})),b(ni);const si={animation:"boolean",autohide:"boolean",delay:"number"},oi={animation:!0,autohide:!0,delay:5e3};class ri extends R{constructor(t,e){super(t),this._config=this._getConfig(e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get DefaultType(){return si}static get Default(){return oi}static get NAME(){return"toast"}show(){H.trigger(this._element,"show.bs.toast").defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add("fade"),this._element.classList.remove("hide"),m(this._element),this._element.classList.add("showing"),this._queueCallback(()=>{this._element.classList.remove("showing"),this._element.classList.add("show"),H.trigger(this._element,"shown.bs.toast"),this._maybeScheduleHide()},this._element,this._config.animation))}hide(){this._element.classList.contains("show")&&(H.trigger(this._element,"hide.bs.toast").defaultPrevented||(this._element.classList.remove("show"),this._queueCallback(()=>{this._element.classList.add("hide"),H.trigger(this._element,"hidden.bs.toast")},this._element,this._config.animation)))}dispose(){this._clearTimeout(),this._element.classList.contains("show")&&this._element.classList.remove("show"),super.dispose()}_getConfig(t){return t={...oi,...U.getDataAttributes(this._element),..."object"==typeof t&&t?t:{}},d("toast",t,this.constructor.DefaultType),t}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout(()=>{this.hide()},this._config.delay)))}_onInteraction(t,e){switch(t.type){case"mouseover":case"mouseout":this._hasMouseInteraction=e;break;case"focusin":case"focusout":this._hasKeyboardInteraction=e}if(e)return void this._clearTimeout();const i=t.relatedTarget;this._element===i||this._element.contains(i)||this._maybeScheduleHide()}_setListeners(){H.on(this._element,"click.dismiss.bs.toast",'[data-bs-dismiss="toast"]',()=>this.hide()),H.on(this._element,"mouseover.bs.toast",t=>this._onInteraction(t,!0)),H.on(this._element,"mouseout.bs.toast",t=>this._onInteraction(t,!1)),H.on(this._element,"focusin.bs.toast",t=>this._onInteraction(t,!0)),H.on(this._element,"focusout.bs.toast",t=>this._onInteraction(t,!1))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){let e=w.get(this,"bs.toast");if(e||(e=new ri(this,"object"==typeof t&&t)),"string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}return b(ri),{Alert:B,Button:W,Carousel:Q,Collapse:J,Dropdown:we,Modal:Ie,Offcanvas:Me,Popover:Je,ScrollSpy:ii,Tab:ni,Toast:ri,Tooltip:Xe}}));
7 | //# sourceMappingURL=bootstrap.bundle.min.js.map
--------------------------------------------------------------------------------
/Master/assets/js/jquery.min.js:
--------------------------------------------------------------------------------
1 | /*! jQuery v3.5.1 | (c) JS Foundation and other contributors | jquery.org/license */
2 | !function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.5.1",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML=" ",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML=" ";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function D(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||j,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,j=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML=" ",y.option=!!ce.lastChild;var ge={thead:[1,""],col:[2,""],tr:[2,""],td:[3,""],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function qe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function Le(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function He(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Oe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):("number"==typeof f.top&&(f.top+="px"),"number"==typeof f.left&&(f.left+="px"),c.css(f))}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=$e(y.pixelPosition,function(e,t){if(t)return t=Be(e,n),Me.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0