refactor: move Bootstrap modules and templates to dedicated repo

See https://github.com/HugoBlox/hugo-blox-bootstrap
This commit is contained in:
George Cushen committed 2025-08-25 21:16:45 +01:00
1 parent b8a8431ac3
commit 507f03411f
677 files changed
+324 -40588

No files matched your search

+29
View File
@@ -0,0 +1,29 @@
version: 2
updates:
# Update GitHub Actions
- package-ecosystem: 'github-actions'
directory: '/'
schedule:
interval: 'weekly'
open-pull-requests-limit: 10
labels:
- 'dependencies'
- 'github-actions'
commit-message:
prefix: 'ci'
include: 'scope'
# Update GitHub Actions in main starter template (academic-cv)
# Other starters can be manually updated from this template
- package-ecosystem: 'github-actions'
directory: '/starters/academic-cv'
schedule:
interval: 'weekly'
open-pull-requests-limit: 3
labels:
- 'dependencies'
- 'starters'
- 'template'
commit-message:
prefix: 'ci'
include: 'scope'
+10 -11
View File
@@ -15,18 +15,18 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest]
# node-version: [18.x]
# node-version: [18.x]
steps:
- uses: actions/checkout@v4
with:
submodules: true # Fetch any Git submodules (true OR recursive)
fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod
submodules: true # Fetch any Git submodules (true OR recursive)
fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod
# - name: Use Node.js ${{ matrix.node-version }}
# uses: actions/setup-node@v3
# with:
# node-version: ${{ matrix.node-version }}
# - name: Use Node.js ${{ matrix.node-version }}
# uses: actions/setup-node@v3
# with:
# node-version: ${{ matrix.node-version }}
- uses: pnpm/action-setup@v4
with:
@@ -41,18 +41,17 @@ jobs:
cd ..
- name: Check for linting errors
run: pnpm run lint:js # TODO: also lint styles again once new rule errors resolved
run: pnpm run lint:js # TODO: also lint styles again once new rule errors resolved
- name: Setup Hugo
uses: peaceiris/actions-hugo@v2
uses: peaceiris/actions-hugo@v3
with:
hugo-version: '0.148.2'
extended: true
- name: Build
run: hugo --minify
run: hugo --minify --templateMetrics --templateMetricsHints
working-directory: test
# format:
# runs-on: ubuntu-latest
#
+5 -15
View File
@@ -21,31 +21,21 @@ jobs:
split_repository: 'theme-academic-cv'
- local_path: 'starters/resume'
split_repository: 'theme-resume'
- local_path: 'starters-bootstrap/markdown-slides'
split_repository: 'theme-markdown-slides'
- local_path: 'starters/blog'
split_repository: 'theme-blog'
- local_path: 'starters/documentation'
split_repository: 'theme-documentation'
- local_path: 'starters-bootstrap/portfolio'
split_repository: 'theme-portfolio'
- local_path: 'starters-bootstrap/course'
split_repository: 'theme-online-course'
- local_path: 'starters/link-in-bio'
split_repository: 'theme-link-in-bio'
- local_path: 'starters-bootstrap/research-group'
split_repository: 'theme-research-group'
- local_path: 'starters-bootstrap/second-brain'
split_repository: 'theme-second-brain'
- local_path: 'starters/landing-page'
split_repository: 'theme-landing-page'
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
# step if no tag is pushed
- if: "!startsWith(github.ref, 'refs/tags/')"
uses: "symplify/monorepo-split-github-action@v2.3.0"
- if: ${{ !startsWith(github.ref, 'refs/tags/') }}
uses: 'symplify/monorepo-split-github-action@v2.3.0'
with:
# ↓ split "packages/<package-name><package-name>" directory
package_directory: '${{ matrix.package.local_path }}'
@@ -55,5 +45,5 @@ jobs:
repository_name: '${{ matrix.package.split_repository }}'
# ↓ the user signed under the split commit
user_name: "Splitter Bot"
user_email: "no.reply@hugoblox.com"
user_name: 'Splitter Bot'
user_email: 'no.reply@hugoblox.com'
-5
View File
@@ -1,5 +0,0 @@
# Hide Bootstrap module and starters from ripgrep/VS Code search
modules/blox-bootstrap/**
starters-bootstrap/**
+195 -65
View File
@@ -1,9 +1,60 @@
# Contributing to Hugo Blox Builder
# Contributing to Hugo Blox 🚀
Thanks for being interested in contributing! We’re so glad you want to help!
> **Welcome, researchers and academics!** Whether you're a professor sharing your publications, a PhD student building your first portfolio, or an AI researcher showcasing your work — this guide will help you contribute to the tool that powers 100,000s of researcher and lab websites worldwide.
[![All Access](https://img.shields.io/badge/Support-All%20Access-2ea44f?logo=heart)](https://hugoblox.com/all-access)
[![GitHub Sponsors](https://img.shields.io/badge/Sponsor-GitHub%20Sponsors-ea4aaa?logo=github)](https://github.com/sponsors/gcushen)
[![Star us](https://img.shields.io/github/stars/HugoBlox/hugo-blox-builder?style=social)](https://github.com/HugoBlox/hugo-blox-builder)
[![Discord](https://img.shields.io/discord/722225264733716590?logo=discord)](https://discord.gg/z8wNYzb)
## ❤️ Love Hugo Blox? Help keep it thriving.
> If Hugo Blox has saved you hours, taught you something, or helped you share your work, please take 2 minutes to give back. Most people won't — but if a small part of the community pitches in today, we can ship faster, fix more bugs, and keep the project healthy for everyone.
We want contributing to Hugo Blox to be fun, enjoyable, and educational for anyone and everyone. All contributions are welcome, including new plugins (such as new widgets, shortcodes, theme packs, and language packs), templates, features, documentation as well as updates and tweaks, blog posts, YouTube tutorials, live streaming customizations, meetups, and more.
## 🎯 Why Contribute?
### For Your Career
- **📝 Add to your CV**: Open source contributions demonstrate technical skills and collaboration
- **🌍 Build your reputation**: Your contributions are publicly visible and credited
- **🤝 Network with peers**: Connect with researchers and developers worldwide
- **📚 Learn modern web tech**: Gain experience with Hugo, Tailwind CSS, and modern web development
### For the Community
- **🔬 Shape the tool you use**: Directly influence features that matter to academics
- **⚡ Get fixes faster**: Contributing means your needs get addressed sooner
- **🌱 Support open research**: Keep academic tools free and accessible to all
- **🏆 Join 9k+ stars**: Be part of a thriving academic community
## 🚀 Quick Wins (Pick One!)
### ⏱️ 30 Seconds
- **⭐ Star the repository**: [github.com/HugoBlox/hugo-blox-builder](https://github.com/HugoBlox/hugo-blox-builder)
- **👍 Vote on issues**: Shape the roadmap by [upvoting features](https://github.com/HugoBlox/hugo-blox-builder/issues) you need
- **💡 Suggest an enhancement**: Have an idea? [Create a GitHub Issue](https://github.com/HugoBlox/hugo-blox-builder/issues) for the community to vote on
- **📢 Share your site**: Post your Hugo Blox site on X/LinkedIn/Reddit with #HugoBlox
### 🕐 5-10 Minutes
- **📸 Share a screenshot**: Show your beautiful site in [Discussions](https://github.com/HugoBlox/hugo-blox-builder/discussions)
- **🐛 Report issues clearly**: Found a bug? Help us fix it with clear steps to reproduce
- **💬 Help in Discord**: Answer a question in our [Discord community](https://discord.gg/z8wNYzb)
- **✏️ Fix documentation typos**: Spot an error? Fix it directly on GitHub (no setup needed!)
### 🕓 ~1 Hour
- **🔧 Implement a small issue**: See [help-wanted issues](https://github.com/HugoBlox/hugo-blox-builder/labels/help%20wanted)
- **📚 Write documentation**: Help keep the documentation complete and up-to-date
### 🕘 A Few Hours
- **🧩 Take a larger issue**: Contribute a significant feature or improvement
- **🎥 Create tutorials**: Record a YouTube video or write a detailed blog post
## Where to Start
Join the **Contributing** channel on the **[community Discord](https://discord.gg/z8wNYzb)**.
@@ -24,17 +75,85 @@ Whether or not you're a developer, there are plenty of non-technical ways that y
### For technical contributions
Repository structure:
## 🛠️ Development Setup
- modules
- The components and layouts which form the Hugo Blox page building framework that the templates depend on
- scripts
- A collection of scripts for helping maintain the repository
- starters
- The collection of starter templates (aka Hugo themes)
- To contribute an improvement to a starter template, make your changes to the relevant template within this folder. **Do not submit PRs to the dedicated template repositories as they are read-only.**
- test
- a minimal site that is built by the CI on every commit to help test PRs
> **No Go experience needed!** Most contributions only require basic HTML/CSS knowledge.
### Prerequisites
1. **Install Node.js** (for Tailwind CSS v4)
```bash
# macOS/Linux (using Homebrew)
brew install node
# Windows (download from nodejs.org)
# Or use WSL2 for a Linux environment
```
2. **Install pnpm** (our package manager)
```bash
npm install -g pnpm
```
3. **Install Hugo Extended** (latest version)
```bash
# macOS
brew install hugo
# Windows (using Chocolatey)
choco install hugo-extended
# Linux
snap install hugo --channel=extended
```
### Getting Started
1. **Fork & Clone**
```bash
# Fork on GitHub first, then:
git clone https://github.com/YOUR-USERNAME/hugo-blox-builder.git
cd hugo-blox-builder
```
2. **Install Dependencies**
```bash
pnpm install
```
3. **View a Starter Site**
```bash
# View the academic-cv starter (most popular)
./scripts/view-starter-dev.sh academic-cv
# Site opens at http://localhost:8081
```
That's it! You're ready to contribute. 🎉
### Repository structure
```
hugo-blox-builder/
├── modules/
│ └── blox-tailwind/ # Main theme module
│ ├── layouts/ # HTML templates (easy to edit!)
│ ├── assets/css/ # Tailwind CSS v4 styles
│ └── i18n/ # Translations (help translate!)
├── starters/
│ ├── academic-cv/ # CV/Resume template
│ ├── blog/ # Blog template
│ └── documentation/ # Docs template
└── scripts/ # Helper scripts
```
**Note**: To contribute an improvement to a starter template, make your changes to the relevant template within the `starters/` folder. **Do not submit PRs to the dedicated template repositories as they are read-only (changes are automatically propagated there from this mono-repository).**
#### What are some good issues to contribute to?
@@ -48,54 +167,6 @@ If you have an idea for a new feature, please start by [searching the issues](ht
Please be mindful of the project [scope](#scope).
#### How can I contribute an improvement?
Learn [how to contribute code on Github](https://codeburst.io/a-step-by-step-guide-to-making-your-first-github-contribution-5302260a2940).
**⚡️ To make quick and easy contributions, you can browse the repository on GitHub and edit your changes in GitHub's online editor. GitHub will then open a Pull Request (PR) for your changes to be reviewed by the community. ⚡️**
Otherwise, for larger changes, you can edit locally on your computer in your favorite editor, such as VSCode:
**Download the repo**
Fork (copy) the repo on GitHub and then clone (download) your fork to your computer:
```sh
git clone https://github.com/<YOUR_USERNAME>/hugo-blox-builder.git
```
**View a template**
[Install pnpm](https://pnpm.io/), the project's package manager.
Then choose the starter template you wish to view, such as _minimal_:
```sh
pnpm view:local academic-cv
```
Note that Hugo Server can occasionally stop working after changes are made (sometimes showing unrelated errors). If this happens, stop Hugo (Control-C) and restart it with the `pnpm view:local ...` command above.
**Implement your improvements**
Implement you changes and then check for any linting or formatting issues.
Code linting and formatting form part of the Continuous Integration process to help catch bugs and code issues in contributions.
Contributors can also run the flow on their fork of the "Hugo Blox Builder" repo when making contributions (you'll need Node and pnpm to run):
```sh
pnpm install
pnpm run lint
pnpm run format
```
**Open a Pull Request with your changes**
Use git to push (upload) your changes to GitHub and then open a Pull Request (PR) at https://github.com/HugoBlox/hugo-blox-builder/pulls
Please be mindful of the project [scope](#scope).
### Contribute Blox
[Create and publish your own blox](https://github.com/HugoBlox/create-blox)
@@ -106,7 +177,7 @@ Please be mindful of the project [scope](#scope).
### Contribute a language pack
To contribute a **new language pack** or an improvement to a language pack, refer to the [language pack guide](https://docs.hugoblox.com/reference/language/#create-or-modify-a-language-pack). Once created, [fork Hugo Blox Builder](https://github.com/HugoBlox/hugo-blox-builder), place your language pack in `blox-tailwind/i18n/`, add the name of the language to `blox-tailwind/data/i18n/language.yaml`, and open a Pull Request on Github with these two files.
To contribute a **new language pack** or an improvement to a language pack, refer to the [language pack guide](https://docs.hugoblox.com/reference/language/#create-or-modify-a-language-pack). Once created, [fork Hugo Blox Builder](https://github.com/HugoBlox/hugo-blox-builder), place your language pack in `modules/blox-tailwind/i18n/`, add the language metadata to `modules/blox-tailwind/data/languages.yaml`, and open a Pull Request on Github with these two files.
### Contribute a theme pack
@@ -120,12 +191,47 @@ Consider duplicating a bare-bones template, such as the [Link In Bio](https://gi
To contribute to **Hugo Academic CLI**, the automatic publication and blog post importer, refer to [its dedicated Github repository](https://github.com/GetRD/academic-file-converter) and Issue queue.
## Become a backer
## 🤝 Getting Help
To help us develop this free software sustainably under the open source license, we ask all individuals and businesses that use it to help support its ongoing maintenance and development via sponsorship:
### Where to Ask Questions
- ☕️ [**Donate a coffee**](https://github.com/sponsors/gcushen?frequency=one-time)
- ❤️ [**Become a sponsor and unlock awesome rewards**](https://hugoblox.com/sponsor/)
- **🗣️ Discord**: Real-time chat in [#contributing channel](https://discord.gg/z8wNYzb)
- **💬 Discussions**: Async help in [GitHub Discussions](https://github.com/HugoBlox/hugo-blox-builder/discussions)
- **🐛 Issues**: Bug reports and feature requests
### Tips for Getting Quick Help
1. **Share your environment**: Hugo version, HugoBlox version in `go.mod`, OS, browser
2. **Provide minimal reproduction**: Smallest example showing the issue
3. **Check existing issues**: Your question might be answered
4. **Be specific**: "Publications not showing" → "BibTeX import fails with DOI links"
## 🏆 Recognition & Rewards
### How We Thank Contributors
- **🎖️ Credits**: Named in release notes
- **🏷️ Contributor badge**: On your GitHub profile
- **📣 Social shoutouts**: Featured on our social media
- **🎯 Direct impact**: Your needs prioritized
- **🤝 Network access**: Connect with core team
### Hall of Fame
Check our [Contributors page](https://github.com/HugoBlox/hugo-blox-builder/graphs/contributors) to see everyone who's helped!
## 💚 Can't Contribute Code? Support the Project!
### Other Ways to Help
- **💰 Sponsor**:
- [All Access](https://hugoblox.com/all-access) - One-time payment for exclusive Pro templates and blocks
- [GitHub Sponsors](https://github.com/sponsors/gcushen) - Monthly donation to support open source development
- ☕️ [Donate a coffee](https://github.com/sponsors/gcushen?frequency=one-time)
- **📢 Spread the Word**: Share your Hugo Blox site and experience
- **📝 Write Tutorials**: Blog about your Hugo Blox setup
- **🎥 Create Videos**: YouTube tutorials help many researchers
- **🌍 Translate**: Help make Hugo Blox accessible globally
## Best practices
@@ -139,6 +245,8 @@ For example:
- new feature: `feat: add the X parameter`
- bug fix: `fix: typo in implementation of X parameter`
- performance: `perf: speed up init by pre-warming only pages`
- refactor: `refactor: simplify citation logic`
- docs: `docs: document the X parameter`
- style: `style: change font color from black to blue`
- build-related: `chore: rebuild JS assets`
@@ -162,3 +270,25 @@ The more regular active volunteers (rather than one-off contributors) we have su
The project's scope also has to be constrained so that it doesn't get too complex and unwieldy, from an architectural perspective, a testing perspective, and from a usability perspective.
Plugins (widgets, shortcodes, theme packs, language packs, and third-party JavaScript integrations) as well as templates allow the community to add major features without needing to contribute to Hugo Blox itself.
## 📋 Contribution Checklist
Before submitting a PR:
- [ ] **Test locally**: Run `./scripts/view-starter-dev.sh academic-cv`
- [ ] **Check formatting**: Run `pnpm run lint:js` (if you edited JS)
- [ ] **Update docs**: If adding features, document them in the code and in the PR
- [ ] **Add examples**: Show how to use new features
- [ ] **Write clear commit messages**: Help future contributors understand changes
## 🙏 Thank You!
Every contribution matters — whether it's fixing a typo, adding a translation, or building a new feature. You're helping thousands of researchers share their work with the world.
**Welcome to the Hugo Blox community!** 🎉
---
_Questions? Join our [Discord](https://discord.gg/z8wNYzb) or start a [Discussion](https://github.com/HugoBlox/hugo-blox-builder/discussions)._
_This project follows the [Contributor Covenant Code of Conduct](CODE_OF_CONDUCT.md)._
+62 -66
View File
@@ -1,74 +1,70 @@
{
"folders": [
{
"path": "."
}
],
"settings": {
"files.exclude": {
"**/modules/blox-bootstrap/**": true,
"**/starters-bootstrap/**": true,
"**/node_modules/**": true,
"**/public/**": true,
"**/resources/**": true,
"**/pagefind/**": true
},
"search.exclude": {
"**/modules/blox-bootstrap/**": true,
"**/starters-bootstrap/**": true,
"**/node_modules/**": true,
"**/public/**": true,
"**/resources/**": true,
"**/pagefind/**": true
},
"files.watcherExclude": {
"**/node_modules/**": true,
"**/public/**": true,
"**/resources/**": true,
"**/pagefind/**": true
},
"explorer.excludeGitIgnore": true,
"folders": [
{
"path": "."
}
],
"settings": {
"files.exclude": {
"**/node_modules/**": true,
"**/public/**": true,
"**/resources/**": true,
"**/pagefind/**": true
},
"search.exclude": {
"**/node_modules/**": true,
"**/public/**": true,
"**/resources/**": true,
"**/pagefind/**": true
},
"files.watcherExclude": {
"**/node_modules/**": true,
"**/public/**": true,
"**/resources/**": true,
"**/pagefind/**": true
},
"explorer.excludeGitIgnore": true,
"npm.packageManager": "pnpm",
"npm.packageManager": "pnpm",
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit",
"source.fixAll.stylelint": "explicit"
},
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit",
"source.fixAll.stylelint": "explicit"
},
"[javascript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
"[typescript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
"[json]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
"[css]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
"[html]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
"[markdown]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
"[javascript]": {"editor.defaultFormatter": "esbenp.prettier-vscode"},
"[typescript]": {"editor.defaultFormatter": "esbenp.prettier-vscode"},
"[json]": {"editor.defaultFormatter": "esbenp.prettier-vscode"},
"[css]": {"editor.defaultFormatter": "esbenp.prettier-vscode"},
"[html]": {"editor.defaultFormatter": "esbenp.prettier-vscode"},
"[markdown]": {"editor.defaultFormatter": "esbenp.prettier-vscode"},
"eslint.workingDirectories": [{ "mode": "auto" }],
"eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact"],
"eslint.workingDirectories": [{"mode": "auto"}],
"eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact"],
"stylelint.validate": ["css"],
"stylelint.validate": ["css"],
"tailwindCSS.emmetCompletions": true,
"tailwindCSS.emmetCompletions": true,
"yaml.validate": true
},
"extensions": {
"recommendations": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"stylelint.vscode-stylelint",
"bradlc.vscode-tailwindcss",
"redhat.vscode-yaml",
"tamasfe.even-better-toml",
"DavidAnson.vscode-markdownlint",
"ms-python.python",
"charliermarsh.ruff",
"streetsidesoftware.code-spell-checker",
"mikestead.dotenv",
"eamodio.gitlens",
"bierner.markdown-mermaid"
]
}
}
"yaml.validate": true
},
"extensions": {
"recommendations": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"stylelint.vscode-stylelint",
"bradlc.vscode-tailwindcss",
"redhat.vscode-yaml",
"tamasfe.even-better-toml",
"DavidAnson.vscode-markdownlint",
"ms-python.python",
"charliermarsh.ruff",
"streetsidesoftware.code-spell-checker",
"mikestead.dotenv",
"eamodio.gitlens",
"bierner.markdown-mermaid"
]
}
}
@@ -1,71 +0,0 @@
---
# Display name
title: "{{ replace .Name "-" " " | title }}"
# Username (this should match the folder name and the name on publications)
authors:
- "{{ urlize .Name }}"
# Is this the primary user of the site?
superuser: false
# Role/position (e.g., Professor of Artificial Intelligence)
role:
# Organizations/Affiliations
organizations:
- name:
url: ""
# Short bio (displayed in user profile at end of posts)
bio:
# List each interest with a dash
interests:
- Interest 1
- Interest 2
education:
courses:
- course: Title course 1
institution: Name of Institution
year: 2012
- course: Title course 1
institution: Name of Institution
year: 2012
# Social/Academic Networking
# For available icons, see: https://docs.hugoblox.com/getting-started/page-builder/#icons
# For an email link, use "fas" icon pack, "envelope" icon, and a link in the
# form "mailto:your-email@example.com" or "#contact" for contact widget.
social:
- icon: envelope
icon_pack: fas
link: '#contact' # For a direct email link, use "mailto:test@example.org".
- icon: twitter
icon_pack: fab
link: https://twitter.com/USERNAME
- icon: google-scholar
icon_pack: ai
link: https://scholar.google.com/citations?user=PERSON-ID
- icon: github
icon_pack: fab
link: https://github.com/USERNAME
# Link to a PDF of your resume/CV from the About widget.
# To enable, copy your resume/CV to `static/files/cv.pdf` and uncomment the lines below.
# - icon: cv
# icon_pack: ai
# link: files/cv.pdf
# Enter email to display Gravatar (if Gravatar enabled in Config)
email: ""
# Highlight the author in author lists? (true/false)
highlight_name: false
# Organizational groups that you belong to (for People widget)
# Set this to `[]` or comment out if you are not using People widget.
user_groups:
- Group 1
- Group 2
---
Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

@@ -1,9 +0,0 @@
---
# Documentation: https://docs.hugoblox.com/managing-content/
title: "{{ replace .Name "-" " " | title }}"
linktitle: "{{ replace .Name "-" " " | title }}"
date: {{ .Date }}
type: book
summary: ""
---
@@ -1,29 +0,0 @@
---
# Documentation: https://docs.hugoblox.com/managing-content/
title: "{{ replace .Name "-" " " | title }}"
subtitle: ""
summary: ""
authors: []
tags: []
categories: []
date: {{ .Date }}
lastmod: {{ .Date }}
featured: false
draft: false
# Featured image
# To use, add an image named `featured.jpg/png` to your page's folder.
# Focal points: Smart, Center, TopLeft, Top, TopRight, Left, Right, BottomLeft, Bottom, BottomRight.
image:
caption: ""
focal_point: ""
preview_only: false
# Projects (optional).
# Associate this post with one or more of your projects.
# Simply enter your project's folder or file name without extension.
# E.g. `projects = ["internal-project"]` references `content/project/deep-learning/index.md`.
# Otherwise, set `projects = []`.
projects: []
---
@@ -1,68 +0,0 @@
---
# Documentation: https://docs.hugoblox.com/managing-content/
title: "{{ replace .Name "-" " " | title }}"
event:
event_url:
location:
address:
street:
city:
region:
postcode:
country:
summary:
abstract:
# Talk start and end times.
# End time can optionally be hidden by prefixing the line with `#`.
date: {{ .Date }}
date_end: {{ .Date }}
all_day: false
# Schedule page publish date (NOT event date).
publishDate: {{ .Date }}
authors: []
tags: []
# Is this a featured event? (true/false)
featured: false
# Featured image
# To use, add an image named `featured.jpg/png` to your page's folder.
# Focal points: Smart, Center, TopLeft, Top, TopRight, Left, Right, BottomLeft, Bottom, BottomRight.
image:
caption: ""
focal_point: ""
preview_only: false
# Custom links (optional).
# Uncomment and edit lines below to show custom links.
# links:
# - name: Follow
# url: https://twitter.com
# icon_pack: fab
# icon: twitter
# Optional filename of your slides within your event's folder or a URL.
url_slides:
url_code:
url_pdf:
url_video:
# Markdown Slides (optional).
# Associate this event with Markdown slides.
# Simply enter your slide deck's filename without extension.
# E.g. `slides = "example-slides"` references `content/slides/example-slides.md`.
# Otherwise, set `slides = ""`.
slides: ""
# Projects (optional).
# Associate this post with one or more of your projects.
# Simply enter your project's folder or file name without extension.
# E.g. `projects = ["internal-project"]` references `content/project/deep-learning/index.md`.
# Otherwise, set `projects = []`.
projects: []
---
-48
View File
@@ -1,48 +0,0 @@
+++
# A section created with the Blank widget.
widget = "blank" # See https://docs.hugoblox.com/page-builder/
headless = true # This file represents a page section.
active = true # Activate this widget? true/false
weight = 1 # Order that this section will appear.
# Note: a full width section format can be enabled by commenting out the `title` and `subtitle` with a `#`.
title = "{{ replace .Name "-" " " | title }}"
subtitle = ""
[design]
# Choose how many columns the section has. Valid values: 1 or 2.
columns = "1"
[design.background]
# Apply a background color, gradient, or image.
# Uncomment (by removing `#`) an option to apply it.
# Choose a light or dark text color by setting `text_color_light`.
# Any HTML color name or Hex value is valid.
# Background color.
# color = "navy"
# Background gradient.
# gradient_start = "DeepSkyBlue"
# gradient_end = "SkyBlue"
# Background image.
# image = "image.jpg" # Name of image in `static/media/`.
# image_darken = 0.6 # Darken the image? Range 0-1 where 0 is transparent and 1 is opaque.
# Text color (true=light or false=dark).
# text_color_light = true
[design.spacing]
# Customize the section spacing. Order is top, right, bottom, left.
# padding = ["0px", "0px", "0px", "0px"]
[advanced]
# Custom CSS.
css_style = ""
# CSS class.
css_class = ""
+++
[**Add some elements here**](https://docs.hugoblox.com/writing-markdown-latex/)
@@ -1,29 +0,0 @@
---
# Documentation: https://docs.hugoblox.com/managing-content/
title: "{{ replace .Name "-" " " | title }}"
subtitle: ""
summary: ""
authors: []
tags: []
categories: []
date: {{ .Date }}
lastmod: {{ .Date }}
featured: false
draft: false
# Featured image
# To use, add an image named `featured.jpg/png` to your page's folder.
# Focal points: Smart, Center, TopLeft, Top, TopRight, Left, Right, BottomLeft, Bottom, BottomRight.
image:
caption: ""
focal_point: ""
preview_only: false
# Projects (optional).
# Associate this post with one or more of your projects.
# Simply enter your project's folder or file name without extension.
# E.g. `projects = ["internal-project"]` references `content/project/deep-learning/index.md`.
# Otherwise, set `projects = []`.
projects: []
---
@@ -1,41 +0,0 @@
---
# Documentation: https://docs.hugoblox.com/managing-content/
title: "{{ replace .Name "-" " " | title }}"
summary: ""
authors: []
tags: []
categories: []
date: {{ .Date }}
# Optional external URL for project (replaces project detail page).
external_link: ""
# Featured image
# To use, add an image named `featured.jpg/png` to your page's folder.
# Focal points: Smart, Center, TopLeft, Top, TopRight, Left, Right, BottomLeft, Bottom, BottomRight.
image:
caption: ""
focal_point: ""
preview_only: false
# Custom links (optional).
# Uncomment and edit lines below to show custom links.
# links:
# - name: Follow
# url: https://twitter.com
# icon_pack: fab
# icon: twitter
url_code: ""
url_pdf: ""
url_slides: ""
url_video: ""
# Slides (optional).
# Associate this project with Markdown slides.
# Simply enter your slide deck's filename without extension.
# E.g. `slides = "example-slides"` references `content/slides/example-slides.md`.
# Otherwise, set `slides = ""`.
slides: ""
---
@@ -1,69 +0,0 @@
---
# Documentation: https://docs.hugoblox.com/managing-content/
title: "{{ replace .Name "-" " " | title }}"
authors: []
date: {{ .Date }}
doi: ""
# Schedule page publish date (NOT publication's date).
publishDate: {{ .Date }}
# Publication type.
# Legend: 0 = Uncategorized; 1 = Conference paper; 2 = Journal article;
# 3 = Preprint / Working Paper; 4 = Report; 5 = Book; 6 = Book section;
# 7 = Thesis; 8 = Patent
publication_types: ["0"]
# Publication name and optional abbreviated publication name.
publication: ""
publication_short: ""
abstract: ""
# Summary. An optional shortened abstract.
summary: ""
tags: []
categories: []
featured: false
# Custom links (optional).
# Uncomment and edit lines below to show custom links.
# links:
# - name: Follow
# url: https://twitter.com
# icon_pack: fab
# icon: twitter
url_pdf:
url_code:
url_dataset:
url_poster:
url_project:
url_slides:
url_source:
url_video:
# Featured image
# To use, add an image named `featured.jpg/png` to your page's folder.
# Focal points: Smart, Center, TopLeft, Top, TopRight, Left, Right, BottomLeft, Bottom, BottomRight.
image:
caption: ""
focal_point: ""
preview_only: false
# Associated Projects (optional).
# Associate this publication with one or more of your projects.
# Simply enter your project's folder or file name without extension.
# E.g. `internal-project` references `content/project/internal-project/index.md`.
# Otherwise, set `projects: []`.
projects: []
# Slides (optional).
# Associate this publication with Markdown slides.
# Simply enter your slide deck's filename without extension.
# E.g. `slides: "example"` references `content/slides/example/index.md`.
# Otherwise, set `slides: ""`.
slides: ""
---
@@ -1,49 +0,0 @@
---
# Documentation: https://docs.hugoblox.com/managing-content/
title: "{{ replace .Name "-" " " | title }}"
summary: ""
authors: []
tags: []
categories: []
date: {{ .Date }}
slides:
# Choose a theme from https://github.com/hakimel/reveal.js#theming
theme: black
# Choose a code highlighting style (if highlighting enabled in `params.toml`)
# Light style: github. Dark style: dracula (default).
# Available highlight themes listed in: https://highlightjs.org/static/demo/
# Use lower case names and replace space with hyphen '-'
highlight_style: dracula
diagram: true
diagram_options:
# Mermaid diagram themes include: default,base,dark,neutral,forest
theme: base
# RevealJS slide options.
# Options are named using the snake case equivalent of those in the RevealJS docs.
reveal_options:
controls: true
progress: true
slide_number: c/t # true | false | h.v | h/v | c | c/t
center: true
rtl: false
mouse_wheel: true
transition: fade # none/fade/slide/convex/concave/zoom
transitionSpeed: default # default/fast/slow
background_transition: slide # none/fade/slide/convex/concave/zoom
touch: true
loop: false
menu_enabled: true
---
# Title
Author Name
---
## Slide 2
...
@@ -1,85 +0,0 @@
/* Background */ .bg { color: #f8f8f2; background-color: #282a36 }
/* PreWrapper */ .chroma { color: #f8f8f2; background-color: #282a36; }
/* Other */ .chroma .x { }
/* Error */ .chroma .err { }
/* CodeLine */ .chroma .cl { }
/* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; }
/* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; }
/* LineHighlight */ .chroma .hl { background-color: #ffc }
/* LineNumbersTable */ .chroma .lnt { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f }
/* LineNumbers */ .chroma .ln { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f }
/* Line */ .chroma .line { display: flex; }
/* Keyword */ .chroma .k { color: #ff79c6 }
/* KeywordConstant */ .chroma .kc { color: #ff79c6 }
/* KeywordDeclaration */ .chroma .kd { color: #8be9fd; font-style: italic }
/* KeywordNamespace */ .chroma .kn { color: #ff79c6 }
/* KeywordPseudo */ .chroma .kp { color: #ff79c6 }
/* KeywordReserved */ .chroma .kr { color: #ff79c6 }
/* KeywordType */ .chroma .kt { color: #8be9fd }
/* Name */ .chroma .n { }
/* NameAttribute */ .chroma .na { color: #50fa7b }
/* NameBuiltin */ .chroma .nb { color: #8be9fd; font-style: italic }
/* NameBuiltinPseudo */ .chroma .bp { }
/* NameClass */ .chroma .nc { color: #50fa7b }
/* NameConstant */ .chroma .no { }
/* NameDecorator */ .chroma .nd { }
/* NameEntity */ .chroma .ni { }
/* NameException */ .chroma .ne { }
/* NameFunction */ .chroma .nf { color: #50fa7b }
/* NameFunctionMagic */ .chroma .fm { }
/* NameLabel */ .chroma .nl { color: #8be9fd; font-style: italic }
/* NameNamespace */ .chroma .nn { }
/* NameOther */ .chroma .nx { }
/* NameProperty */ .chroma .py { }
/* NameTag */ .chroma .nt { color: #ff79c6 }
/* NameVariable */ .chroma .nv { color: #8be9fd; font-style: italic }
/* NameVariableClass */ .chroma .vc { color: #8be9fd; font-style: italic }
/* NameVariableGlobal */ .chroma .vg { color: #8be9fd; font-style: italic }
/* NameVariableInstance */ .chroma .vi { color: #8be9fd; font-style: italic }
/* NameVariableMagic */ .chroma .vm { }
/* Literal */ .chroma .l { }
/* LiteralDate */ .chroma .ld { }
/* LiteralString */ .chroma .s { color: #f1fa8c }
/* LiteralStringAffix */ .chroma .sa { color: #f1fa8c }
/* LiteralStringBacktick */ .chroma .sb { color: #f1fa8c }
/* LiteralStringChar */ .chroma .sc { color: #f1fa8c }
/* LiteralStringDelimiter */ .chroma .dl { color: #f1fa8c }
/* LiteralStringDoc */ .chroma .sd { color: #f1fa8c }
/* LiteralStringDouble */ .chroma .s2 { color: #f1fa8c }
/* LiteralStringEscape */ .chroma .se { color: #f1fa8c }
/* LiteralStringHeredoc */ .chroma .sh { color: #f1fa8c }
/* LiteralStringInterpol */ .chroma .si { color: #f1fa8c }
/* LiteralStringOther */ .chroma .sx { color: #f1fa8c }
/* LiteralStringRegex */ .chroma .sr { color: #f1fa8c }
/* LiteralStringSingle */ .chroma .s1 { color: #f1fa8c }
/* LiteralStringSymbol */ .chroma .ss { color: #f1fa8c }
/* LiteralNumber */ .chroma .m { color: #bd93f9 }
/* LiteralNumberBin */ .chroma .mb { color: #bd93f9 }
/* LiteralNumberFloat */ .chroma .mf { color: #bd93f9 }
/* LiteralNumberHex */ .chroma .mh { color: #bd93f9 }
/* LiteralNumberInteger */ .chroma .mi { color: #bd93f9 }
/* LiteralNumberIntegerLong */ .chroma .il { color: #bd93f9 }
/* LiteralNumberOct */ .chroma .mo { color: #bd93f9 }
/* Operator */ .chroma .o { color: #ff79c6 }
/* OperatorWord */ .chroma .ow { color: #ff79c6 }
/* Punctuation */ .chroma .p { }
/* Comment */ .chroma .c { color: #6272a4 }
/* CommentHashbang */ .chroma .ch { color: #6272a4 }
/* CommentMultiline */ .chroma .cm { color: #6272a4 }
/* CommentSingle */ .chroma .c1 { color: #6272a4 }
/* CommentSpecial */ .chroma .cs { color: #6272a4 }
/* CommentPreproc */ .chroma .cp { color: #ff79c6 }
/* CommentPreprocFile */ .chroma .cpf { color: #ff79c6 }
/* Generic */ .chroma .g { }
/* GenericDeleted */ .chroma .gd { color: #f55 }
/* GenericEmph */ .chroma .ge { text-decoration: underline }
/* GenericError */ .chroma .gr { }
/* GenericHeading */ .chroma .gh { font-weight: bold }
/* GenericInserted */ .chroma .gi { color: #50fa7b; font-weight: bold }
/* GenericOutput */ .chroma .go { color: #44475a }
/* GenericPrompt */ .chroma .gp { }
/* GenericStrong */ .chroma .gs { }
/* GenericSubheading */ .chroma .gu { font-weight: bold }
/* GenericTraceback */ .chroma .gt { }
/* GenericUnderline */ .chroma .gl { text-decoration: underline }
/* TextWhitespace */ .chroma .w { }
@@ -1,271 +0,0 @@
.chroma {
background-color: #0d1117;
color: #fff;
}
.chroma .nn {
color: #fff;
}
.chroma .err {
color: #f85149;
}
.chroma .p {
color: #c9d1d9;
}
.chroma .lntd {
border: 0;
margin: 0;
padding: 0;
vertical-align: top;
}
.chroma .lntable {
width: auto;
border: 0;
margin: 0;
display: block;
padding: 0;
overflow: auto;
border-spacing: 0;
}
.chroma .hl {
width: 100%;
display: block;
background-color: rgba(110,118,129,0.1);
}
.chroma .lnt {
color: #8b949e;
padding: 0 0.4em 0 0.4em;
font-size: 0.875rem;
margin-right: 0.4em;
}
.chroma .ln {
color: #8b949e;
padding: 0 0.4em 0 0.4em;
margin-right: 0.4em;
}
.chroma .k {
color: #ff7b72;
}
.chroma .kc {
color: #ff7b72;
font-weight: bold;
}
.chroma .kd {
color: #ff7b72;
font-weight: bold;
}
.chroma .kn {
color: #ff7b72;
font-weight: bold;
}
.chroma .kp {
color: #ff7b72;
font-weight: bold;
}
.chroma .kr {
color: #ff7b72;
font-weight: bold;
}
.chroma .kt {
color: #ff7b72;
font-weight: bold;
}
.chroma .na {
color: #c9d1d9;
}
.chroma .nb {
color: #c9d1d9;
}
.chroma .bp {
color: #c9d1d9;
}
.chroma .nc {
color: #7ee787;
font-weight: bold;
}
.chroma .no {
color: #79c0ff;
font-weight: bold;
}
.chroma .nd {
color: #bc8cff;
font-weight: bold;
}
.chroma .ni {
color: #ffa657;
}
.chroma .ne {
color: #ffa657;
font-weight: bold;
}
.chroma .nf {
color: #d2a8ff;
font-weight: bold;
}
.chroma .nl {
color: #79c0ff;
font-weight: bold;
}
.chroma .nm {
color: #ff7b72;
}
.chroma .nx {
color: #79c0ff;
}
.chroma .py {
color: #79c0ff;
}
.chroma .nt {
color: #7ee787;
}
.chroma .nv {
color: #79c0ff;
}
.chroma .vc {
color: #79c0ff;
}
.chroma .vg {
color: #79c0ff;
}
.chroma .vi {
color: #79c0ff;
}
.chroma .l {
color: #79c0ff;
}
.chroma .ld {
color: #79c0ff;
}
.chroma .s {
color: #79c0ff;
}
.chroma .sa {
color: #79c0ff;
}
.chroma .sb {
color: #79c0ff;
}
.chroma .sc {
color: #79c0ff;
}
.chroma .dl {
color: #79c0ff;
}
.chroma .sd {
color: #79c0ff;
}
.chroma .s2 {
color: #79c0ff;
}
.chroma .se {
color: #79c0ff;
}
.chroma .sh {
color: #79c0ff;
}
.chroma .si {
color: #79c0ff;
}
.chroma .sx {
color: #79c0ff;
}
.chroma .sr {
color: #79c0ff;
}
.chroma .s1 {
color: #79c0ff;
}
.chroma .ss {
color: #79c0ff;
}
.chroma .m {
color: #79c0ff;
}
.chroma .mb {
color: #79c0ff;
}
.chroma .mf {
color: #79c0ff;
}
.chroma .mh {
color: #79c0ff;
}
.chroma .mi {
color: #79c0ff;
}
.chroma .il {
color: #79c0ff;
}
.chroma .mo {
color: #79c0ff;
}
.chroma .o {
color: #a5d6ff;
font-weight: bold;
}
.chroma .ow {
color: #a5d6ff;
font-weight: bold;
}
.chroma .c {
color: #8b949e;
font-style: italic;
}
.chroma .ch {
color: #8b949e;
font-style: italic;
}
.chroma .cm {
color: #8b949e;
font-style: italic;
}
.chroma .c1 {
color: #8b949e;
font-style: italic;
}
.chroma .cs {
color: #8b949e;
font-style: italic;
}
.chroma .cpf {
color: #8b949e;
font-style: italic;
}
.chroma .gd {
color: #ffa198;
background-color: #490202;
}
.chroma .ge {
color: #c9d1d9;
font-style: italic;
}
.chroma .gr {
color: #ffa198;
}
.chroma .gh {
color: #79c0ff;
}
.chroma .gi {
color: #7ee787;
background-color: #56d364;
}
.chroma .go {
color: #8b949e;
}
.chroma .gp {
color: #8b949e;
}
.chroma .gs {
font-weight: bold;
}
.chroma .gu {
color: #79c0ff;
}
.chroma .gt {
color: #ffa198;
}
.chroma .gl {
text-decoration: underline;
}
.chroma .w {
color: #484f58;
}
@@ -1,85 +0,0 @@
/* Background */ .bg { background-color: #fff }
/* PreWrapper */ .chroma { background-color: #fff; }
/* Other */ .chroma .x { }
/* Error */ .chroma .err { color: #a61717; background-color: #e3d2d2 }
/* CodeLine */ .chroma .cl { }
/* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; }
/* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; }
/* LineHighlight */ .chroma .hl { background-color: #ffc }
/* LineNumbersTable */ .chroma .lnt { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em;color: #7f7f7f }
/* LineNumbers */ .chroma .ln { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em;color: #7f7f7f }
/* Line */ .chroma .line { display: flex; }
/* Keyword */ .chroma .k { color: #000; font-weight: bold }
/* KeywordConstant */ .chroma .kc { color: #000; font-weight: bold }
/* KeywordDeclaration */ .chroma .kd { color: #000; font-weight: bold }
/* KeywordNamespace */ .chroma .kn { color: #000; font-weight: bold }
/* KeywordPseudo */ .chroma .kp { color: #000; font-weight: bold }
/* KeywordReserved */ .chroma .kr { color: #000; font-weight: bold }
/* KeywordType */ .chroma .kt { color: #458; font-weight: bold }
/* Name */ .chroma .n { }
/* NameAttribute */ .chroma .na { color: #008080 }
/* NameBuiltin */ .chroma .nb { color: #0086b3 }
/* NameBuiltinPseudo */ .chroma .bp { color: #999 }
/* NameClass */ .chroma .nc { color: #458; font-weight: bold }
/* NameConstant */ .chroma .no { color: #008080 }
/* NameDecorator */ .chroma .nd { color: #3c5d5d; font-weight: bold }
/* NameEntity */ .chroma .ni { color: #800080 }
/* NameException */ .chroma .ne { color: #900; font-weight: bold }
/* NameFunction */ .chroma .nf { color: #900; font-weight: bold }
/* NameFunctionMagic */ .chroma .fm { }
/* NameLabel */ .chroma .nl { color: #900; font-weight: bold }
/* NameNamespace */ .chroma .nn { color: #555 }
/* NameOther */ .chroma .nx { }
/* NameProperty */ .chroma .py { }
/* NameTag */ .chroma .nt { color: #000080 }
/* NameVariable */ .chroma .nv { color: #008080 }
/* NameVariableClass */ .chroma .vc { color: #008080 }
/* NameVariableGlobal */ .chroma .vg { color: #008080 }
/* NameVariableInstance */ .chroma .vi { color: #008080 }
/* NameVariableMagic */ .chroma .vm { }
/* Literal */ .chroma .l { }
/* LiteralDate */ .chroma .ld { }
/* LiteralString */ .chroma .s { color: #d14 }
/* LiteralStringAffix */ .chroma .sa { color: #d14 }
/* LiteralStringBacktick */ .chroma .sb { color: #d14 }
/* LiteralStringChar */ .chroma .sc { color: #d14 }
/* LiteralStringDelimiter */ .chroma .dl { color: #d14 }
/* LiteralStringDoc */ .chroma .sd { color: #d14 }
/* LiteralStringDouble */ .chroma .s2 { color: #d14 }
/* LiteralStringEscape */ .chroma .se { color: #d14 }
/* LiteralStringHeredoc */ .chroma .sh { color: #d14 }
/* LiteralStringInterpol */ .chroma .si { color: #d14 }
/* LiteralStringOther */ .chroma .sx { color: #d14 }
/* LiteralStringRegex */ .chroma .sr { color: #009926 }
/* LiteralStringSingle */ .chroma .s1 { color: #d14 }
/* LiteralStringSymbol */ .chroma .ss { color: #990073 }
/* LiteralNumber */ .chroma .m { color: #099 }
/* LiteralNumberBin */ .chroma .mb { color: #099 }
/* LiteralNumberFloat */ .chroma .mf { color: #099 }
/* LiteralNumberHex */ .chroma .mh { color: #099 }
/* LiteralNumberInteger */ .chroma .mi { color: #099 }
/* LiteralNumberIntegerLong */ .chroma .il { color: #099 }
/* LiteralNumberOct */ .chroma .mo { color: #099 }
/* Operator */ .chroma .o { color: #000; font-weight: bold }
/* OperatorWord */ .chroma .ow { color: #000; font-weight: bold }
/* Punctuation */ .chroma .p { }
/* Comment */ .chroma .c { color: #998; font-style: italic }
/* CommentHashbang */ .chroma .ch { color: #998; font-style: italic }
/* CommentMultiline */ .chroma .cm { color: #998; font-style: italic }
/* CommentSingle */ .chroma .c1 { color: #998; font-style: italic }
/* CommentSpecial */ .chroma .cs { color: #999; font-weight: bold; font-style: italic }
/* CommentPreproc */ .chroma .cp { color: #999; font-weight: bold; font-style: italic }
/* CommentPreprocFile */ .chroma .cpf { color: #999; font-weight: bold; font-style: italic }
/* Generic */ .chroma .g { }
/* GenericDeleted */ .chroma .gd { color: #000; background-color: #fdd }
/* GenericEmph */ .chroma .ge { color: #000; font-style: italic }
/* GenericError */ .chroma .gr { color: #a00 }
/* GenericHeading */ .chroma .gh { color: #999 }
/* GenericInserted */ .chroma .gi { color: #000; background-color: #dfd }
/* GenericOutput */ .chroma .go { color: #888 }
/* GenericPrompt */ .chroma .gp { color: #555 }
/* GenericStrong */ .chroma .gs { font-weight: bold }
/* GenericSubheading */ .chroma .gu { color: #aaa }
/* GenericTraceback */ .chroma .gt { color: #a00 }
/* GenericUnderline */ .chroma .gl { text-decoration: underline }
/* TextWhitespace */ .chroma .w { color: #bbb }
@@ -1,9 +0,0 @@
/*!
* Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
* Copyright 2024 Fonticons, Inc.
*/
.fa{font-family:var(--fa-style-family,"Font Awesome 6 Free");font-weight:var(--fa-style,900)}.fa,.fa-brands,.fa-classic,.fa-regular,.fa-sharp-solid,.fa-solid,.fab,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:var(--fa-display,inline-block);font-style:normal;font-variant:normal;line-height:1;text-rendering:auto}.fa-classic,.fa-regular,.fa-solid,.far,.fas{font-family:"Font Awesome 6 Free"}.fa-brands,.fab{font-family:"Font Awesome 6 Brands"}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-2xs{font-size:.625em;line-height:.1em;vertical-align:.225em}.fa-xs{font-size:.75em;line-height:.08333em;vertical-align:.125em}.fa-sm{font-size:.875em;line-height:.07143em;vertical-align:.05357em}.fa-lg{font-size:1.25em;line-height:.05em;vertical-align:-.075em}.fa-xl{font-size:1.5em;line-height:.04167em;vertical-align:-.125em}.fa-2xl{font-size:2em;line-height:.03125em;vertical-align:-.1875em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:var(--fa-li-margin,2.5em);padding-left:0}.fa-ul>li{position:relative}.fa-li{left:calc(var(--fa-li-width, 2em)*-1);position:absolute;text-align:center;width:var(--fa-li-width,2em);line-height:inherit}.fa-border{border-radius:var(--fa-border-radius,.1em);border:var(--fa-border-width,.08em) var(--fa-border-style,solid) var(--fa-border-color,#eee);padding:var(--fa-border-padding,.2em .25em .15em)}.fa-pull-left{float:left;margin-right:var(--fa-pull-margin,.3em)}.fa-pull-right{float:right;margin-left:var(--fa-pull-margin,.3em)}.fa-beat{animation-name:fa-beat;animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,ease-in-out)}.fa-bounce{animation-name:fa-bounce;animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,cubic-bezier(.28,.84,.42,1))}.fa-fade{animation-name:fa-fade;animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1))}.fa-beat-fade,.fa-fade{animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s)}.fa-beat-fade{animation-name:fa-beat-fade;animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1))}.fa-flip{animation-name:fa-flip;animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,ease-in-out)}.fa-shake{animation-name:fa-shake;animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,linear)}.fa-shake,.fa-spin{animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal)}.fa-spin{animation-name:fa-spin;animation-duration:var(--fa-animation-duration,2s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,linear)}.fa-spin-reverse{--fa-animation-direction:reverse}.fa-pulse,.fa-spin-pulse{animation-name:fa-spin;animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,steps(8))}@media (prefers-reduced-motion:reduce){.fa-beat,.fa-beat-fade,.fa-bounce,.fa-fade,.fa-flip,.fa-pulse,.fa-shake,.fa-spin,.fa-spin-pulse{animation-delay:-1ms;animation-duration:1ms;animation-iteration-count:1;transition-delay:0s;transition-duration:0s}}@keyframes fa-beat{0%,90%{transform:scale(1)}45%{transform:scale(var(--fa-beat-scale,1.25))}}@keyframes fa-bounce{0%{transform:scale(1) translateY(0)}10%{transform:scale(var(--fa-bounce-start-scale-x,1.1),var(--fa-bounce-start-scale-y,.9)) translateY(0)}30%{transform:scale(var(--fa-bounce-jump-scale-x,.9),var(--fa-bounce-jump-scale-y,1.1)) translateY(var(--fa-bounce-height,-.5em))}50%{transform:scale(var(--fa-bounce-land-scale-x,1.05),var(--fa-bounce-land-scale-y,.95)) translateY(0)}57%{transform:scale(1) translateY(var(--fa-bounce-rebound,-.125em))}64%{transform:scale(1) translateY(0)}to{transform:scale(1) translateY(0)}}@Line truncated
.fa-0:before{content:"\30"}.fa-1:before{content:"\31"}.fa-2:before{content:"\32"}.fa-3:before{content:"\33"}.fa-4:before{content:"\34"}.fa-5:before{content:"\35"}.fa-6:before{content:"\36"}.fa-7:before{content:"\37"}.fa-8:before{content:"\38"}.fa-9:before{content:"\39"}.fa-fill-drip:before{content:"\f576"}.fa-arrows-to-circle:before{content:"\e4bd"}.fa-chevron-circle-right:before,.fa-circle-chevron-right:before{content:"\f138"}.fa-at:before{content:"\40"}.fa-trash-alt:before,.fa-trash-can:before{content:"\f2ed"}.fa-text-height:before{content:"\f034"}.fa-user-times:before,.fa-user-xmark:before{content:"\f235"}.fa-stethoscope:before{content:"\f0f1"}.fa-comment-alt:before,.fa-message:before{content:"\f27a"}.fa-info:before{content:"\f129"}.fa-compress-alt:before,.fa-down-left-and-up-right-to-center:before{content:"\f422"}.fa-explosion:before{content:"\e4e9"}.fa-file-alt:before,.fa-file-lines:before,.fa-file-text:before{content:"\f15c"}.fa-wave-square:before{content:"\f83e"}.fa-ring:before{content:"\f70b"}.fa-building-un:before{content:"\e4d9"}.fa-dice-three:before{content:"\f527"}.fa-calendar-alt:before,.fa-calendar-days:before{content:"\f073"}.fa-anchor-circle-check:before{content:"\e4aa"}.fa-building-circle-arrow-right:before{content:"\e4d1"}.fa-volleyball-ball:before,.fa-volleyball:before{content:"\f45f"}.fa-arrows-up-to-line:before{content:"\e4c2"}.fa-sort-desc:before,.fa-sort-down:before{content:"\f0dd"}.fa-circle-minus:before,.fa-minus-circle:before{content:"\f056"}.fa-door-open:before{content:"\f52b"}.fa-right-from-bracket:before,.fa-sign-out-alt:before{content:"\f2f5"}.fa-atom:before{content:"\f5d2"}.fa-soap:before{content:"\e06e"}.fa-heart-music-camera-bolt:before,.fa-icons:before{content:"\f86d"}.fa-microphone-alt-slash:before,.fa-microphone-lines-slash:before{content:"\f539"}.fa-bridge-circle-check:before{content:"\e4c9"}.fa-pump-medical:before{content:"\e06a"}.fa-fingerprint:before{content:"\f577"}.fa-hand-point-right:before{content:"\f0a4"}.fa-magnifying-glass-location:before,.fa-search-location:before{content:"\f689"}.fa-forward-step:before,.fa-step-forward:before{content:"\f051"}.fa-face-smile-beam:before,.fa-smile-beam:before{content:"\f5b8"}.fa-flag-checkered:before{content:"\f11e"}.fa-football-ball:before,.fa-football:before{content:"\f44e"}.fa-school-circle-exclamation:before{content:"\e56c"}.fa-crop:before{content:"\f125"}.fa-angle-double-down:before,.fa-angles-down:before{content:"\f103"}.fa-users-rectangle:before{content:"\e594"}.fa-people-roof:before{content:"\e537"}.fa-people-line:before{content:"\e534"}.fa-beer-mug-empty:before,.fa-beer:before{content:"\f0fc"}.fa-diagram-predecessor:before{content:"\e477"}.fa-arrow-up-long:before,.fa-long-arrow-up:before{content:"\f176"}.fa-burn:before,.fa-fire-flame-simple:before{content:"\f46a"}.fa-male:before,.fa-person:before{content:"\f183"}.fa-laptop:before{content:"\f109"}.fa-file-csv:before{content:"\f6dd"}.fa-menorah:before{content:"\f676"}.fa-truck-plane:before{content:"\e58f"}.fa-record-vinyl:before{content:"\f8d9"}.fa-face-grin-stars:before,.fa-grin-stars:before{content:"\f587"}.fa-bong:before{content:"\f55c"}.fa-pastafarianism:before,.fa-spaghetti-monster-flying:before{content:"\f67b"}.fa-arrow-down-up-across-line:before{content:"\e4af"}.fa-spoon:before,.fa-utensil-spoon:before{content:"\f2e5"}.fa-jar-wheat:before{content:"\e517"}.fa-envelopes-bulk:before,.fa-mail-bulk:before{content:"\f674"}.fa-file-circle-exclamation:before{content:"\e4eb"}.fa-circle-h:before,.fa-hospital-symbol:before{content:"\f47e"}.fa-pager:before{content:"\f815"}.fa-address-book:before,.fa-contact-book:before{content:"\f2b9"}.fa-strikethrough:before{content:"\f0cc"}.fa-k:before{content:"\4b"}.fa-landmark-flag:before{content:"\e51c"}.fa-pencil-alt:before,.fa-pencil:before{content:"\f303"}.fa-backward:before{content:"\f04a"}.fa-caret-right:before{content:"\f0da"}.fa-comments:before{content:"\f086"}.fa-file-clipboard:before,.fa-paste:before{content:"\f0ea"}.fa-code-pull-request:before{content:"\e13c"}.fa-clipboard-list:before{content:"\f46d"}.fa-truck-loading:before,.fa-truck-ramp-box:before{content:"\f4de"}.fa-user-check:before{content:"\f4fc"}.fa-vial-virus:before{content:"\e597"}.fa-sheet-plastic:before{content:"\e571"}.fa-blog:before{content:"\f781"}.fa-user-ninja:before{content:"\f504"}.fa-person-arrow-up-from-line:before{content:"\e539"}.fa-scroll-torah:before,.fa-torah:before{content:"\f6a0"}.fa-broom-ball:before,.fa-quidditch-broom-ball:before,.fa-quidditch:before{content:"\f458"}.fa-toggle-off:before{content:"\f204"}.fa-archive:before,.fa-box-archive:before{content:"\f187"}.fa-person-drowning:before{content:"\e545"}.fa-arrow-down-9-1:before,.fa-sort-numeric-desc:before,.fa-sort-numeric-down-alt:before{content:"\f886"}.fa-face-grin-tongue-squint:before,.fa-grin-tongue-squint:before{content:"\f58a"}.fa-spray-can:before{content:"\f5bd"}.fa-truck-monster:before{content:"\f63b"}.fa-w:before{content:"\57"}.fa-earth-africa:before,.fa-globe-africa:before{content:"\f57Line truncated
.fa-sr-only,.fa-sr-only-focusable:not(:focus),.sr-only,.sr-only-focusable:not(:focus){position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}:host,:root{--fa-style-family-brands:"Font Awesome 6 Brands";--fa-font-brands:normal 400 1em/1 "Font Awesome 6 Brands"}@font-face{font-family:"Font Awesome 6 Brands";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.ttf) format("truetype")}.fa-brands,.fab{font-weight:400}.fa-monero:before{content:"\f3d0"}.fa-hooli:before{content:"\f427"}.fa-yelp:before{content:"\f1e9"}.fa-cc-visa:before{content:"\f1f0"}.fa-lastfm:before{content:"\f202"}.fa-shopware:before{content:"\f5b5"}.fa-creative-commons-nc:before{content:"\f4e8"}.fa-aws:before{content:"\f375"}.fa-redhat:before{content:"\f7bc"}.fa-yoast:before{content:"\f2b1"}.fa-cloudflare:before{content:"\e07d"}.fa-ups:before{content:"\f7e0"}.fa-pixiv:before{content:"\e640"}.fa-wpexplorer:before{content:"\f2de"}.fa-dyalog:before{content:"\f399"}.fa-bity:before{content:"\f37a"}.fa-stackpath:before{content:"\f842"}.fa-buysellads:before{content:"\f20d"}.fa-first-order:before{content:"\f2b0"}.fa-modx:before{content:"\f285"}.fa-guilded:before{content:"\e07e"}.fa-vnv:before{content:"\f40b"}.fa-js-square:before,.fa-square-js:before{content:"\f3b9"}.fa-microsoft:before{content:"\f3ca"}.fa-qq:before{content:"\f1d6"}.fa-orcid:before{content:"\f8d2"}.fa-java:before{content:"\f4e4"}.fa-invision:before{content:"\f7b0"}.fa-creative-commons-pd-alt:before{content:"\f4ed"}.fa-centercode:before{content:"\f380"}.fa-glide-g:before{content:"\f2a6"}.fa-drupal:before{content:"\f1a9"}.fa-jxl:before{content:"\e67b"}.fa-dart-lang:before{content:"\e693"}.fa-hire-a-helper:before{content:"\f3b0"}.fa-creative-commons-by:before{content:"\f4e7"}.fa-unity:before{content:"\e049"}.fa-whmcs:before{content:"\f40d"}.fa-rocketchat:before{content:"\f3e8"}.fa-vk:before{content:"\f189"}.fa-untappd:before{content:"\f405"}.fa-mailchimp:before{content:"\f59e"}.fa-css3-alt:before{content:"\f38b"}.fa-reddit-square:before,.fa-square-reddit:before{content:"\f1a2"}.fa-vimeo-v:before{content:"\f27d"}.fa-contao:before{content:"\f26d"}.fa-square-font-awesome:before{content:"\e5ad"}.fa-deskpro:before{content:"\f38f"}.fa-brave:before{content:"\e63c"}.fa-sistrix:before{content:"\f3ee"}.fa-instagram-square:before,.fa-square-instagram:before{content:"\e055"}.fa-battle-net:before{content:"\f835"}.fa-the-red-yeti:before{content:"\f69d"}.fa-hacker-news-square:before,.fa-square-hacker-news:before{content:"\f3af"}.fa-edge:before{content:"\f282"}.fa-threads:before{content:"\e618"}.fa-napster:before{content:"\f3d2"}.fa-snapchat-square:before,.fa-square-snapchat:before{content:"\f2ad"}.fa-google-plus-g:before{content:"\f0d5"}.fa-artstation:before{content:"\f77a"}.fa-markdown:before{content:"\f60f"}.fa-sourcetree:before{content:"\f7d3"}.fa-google-plus:before{content:"\f2b3"}.fa-diaspora:before{content:"\f791"}.fa-foursquare:before{content:"\f180"}.fa-stack-overflow:before{content:"\f16c"}.fa-github-alt:before{content:"\f113"}.fa-phoenix-squadron:before{content:"\f511"}.fa-pagelines:before{content:"\f18c"}.fa-algolia:before{content:"\f36c"}.fa-red-river:before{content:"\f3e3"}.fa-creative-commons-sa:before{content:"\f4ef"}.fa-safari:before{content:"\f267"}.fa-google:before{content:"\f1a0"}.fa-font-awesome-alt:before,.fa-square-font-awesome-stroke:before{content:"\f35c"}.fa-atlassian:before{content:"\f77b"}.fa-linkedin-in:before{content:"\f0e1"}.fa-digital-ocean:before{content:"\f391"}.fa-nimblr:before{content:"\f5a8"}.fa-chromecast:before{content:"\f838"}.fa-evernote:before{content:"\f839"}.fa-hacker-news:before{content:"\f1d4"}.fa-creative-commons-sampling:before{content:"\f4f0"}.fa-adversal:before{content:"\f36a"}.fa-creative-commons:before{content:"\f25e"}.fa-watchman-monitoring:before{content:"\e087"}.fa-fonticons:before{content:"\f280"}.fa-weixin:before{content:"\f1d7"}.fa-shirtsinbulk:before{content:"\f214"}.fa-codepen:before{content:"\f1cb"}.fa-git-alt:before{content:"\f841"}.fa-lyft:before{content:"\f3c3"}.fa-rev:before{content:"\f5b2"}.fa-windows:before{content:"\f17a"}.fa-wizards-of-the-coast:before{content:"\f730"}.fa-square-viadeo:before,.fa-viadeo-square:before{content:"\f2aa"}.fa-meetup:before{content:"\f2e0"}.fa-centos:before{content:"\f789"}.fa-adn:before{content:"\f170"}.fa-cloudsmith:before{content:"\f384"}.fa-opensuse:before{content:"\e62b"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-dribbble-square:before,.fa-square-dribbble:before{content:"\f397"}.fa-codiepie:before{content:"\f284"}.fa-node:before{content:"\f419"}.fa-mix:before{content:"\f3cb"}.fa-steam:before{content:"\f1b6"}.fa-cc-apple-pay:before{content:"\f416"}.fa-scribd:before{content:"\f28a"}.fa-debian:before{content:"\e60b"}.fa-openid:before{content:"\f19b"}.fa-instalod:before{content:"\e081"}.fa-expeditedssl:before{content:"\f23e"}.fa-sellcast:before{cLine truncated
@@ -1,7 +0,0 @@
/*!
* Bootstrap v4.6.2 (https://getbootstrap.com/)
* Copyright 2011-2022 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("jquery")):"function"==typeof define&&define.amd?define(["exports","jquery"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap={},t.jQuery)}(this,(function(t,e){"use strict";function n(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var i=n(e);function o(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function r(t,e,n){return e&&o(t.prototype,e),n&&o(t,n),Object.defineProperty(t,"prototype",{writable:!1}),t}function a(){return a=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])}return t},a.apply(this,arguments)}function s(t,e){return s=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,e){return t.__proto__=e,t},s(t,e)}var l="transitionend";var u={TRANSITION_END:"bsTransitionEnd",getUID:function(t){do{t+=~~(1e6*Math.random())}while(document.getElementById(t));return t},getSelectorFromElement:function(t){var e=t.getAttribute("data-target");if(!e||"#"===e){var n=t.getAttribute("href");e=n&&"#"!==n?n.trim():""}try{return document.querySelector(e)?e:null}catch(t){return null}},getTransitionDurationFromElement:function(t){if(!t)return 0;var e=i.default(t).css("transition-duration"),n=i.default(t).css("transition-delay"),o=parseFloat(e),r=parseFloat(n);return o||r?(e=e.split(",")[0],n=n.split(",")[0],1e3*(parseFloat(e)+parseFloat(n))):0},reflow:function(t){return t.offsetHeight},triggerTransitionEnd:function(t){i.default(t).trigger(l)},supportsTransitionEnd:function(){return Boolean(l)},isElement:function(t){return(t[0]||t).nodeType},typeCheckConfig:function(t,e,n){for(var i in n)if(Object.prototype.hasOwnProperty.call(n,i)){var o=n[i],r=e[i],a=r&&u.isElement(r)?"element":null===(s=r)||"undefined"==typeof s?""+s:{}.toString.call(s).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(o).test(a))throw new Error(t.toUpperCase()+': Option "'+i+'" provided type "'+a+'" but expected type "'+o+'".')}var s},findShadowRoot:function(t){if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){var e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?u.findShadowRoot(t.parentNode):null},jQueryDetection:function(){if("undefined"==typeof i.default)throw new TypeError("Bootstrap's JavaScript requires jQuery. jQuery must be included before Bootstrap's JavaScript.");var t=i.default.fn.jquery.split(" ")[0].split(".");if(t[0]<2&&t[1]<9||1===t[0]&&9===t[1]&&t[2]<1||t[0]>=4)throw new Error("Bootstrap's JavaScript requires at least jQuery v1.9.1 but less than v4.0.0")}};u.jQueryDetection(),i.default.fn.emulateTransitionEnd=function(t){var e=this,n=!1;return i.default(this).one(u.TRANSITION_END,(function(){n=!0})),setTimeout((function(){n||u.triggerTransitionEnd(e)}),t),this},i.default.event.special[u.TRANSITION_END]={bindType:l,delegateType:l,handle:function(t){if(i.default(t.target).is(this))return t.handleObj.handler.apply(this,arguments)}};var f="bs.alert",d=i.default.fn.alert,c=function(){function t(t){this._element=t}var e=t.prototype;return e.close=function(t){var e=this._element;t&&(e=this._getRootElement(t)),this._triggerCloseEvent(e).isDefaultPrevented()||this._removeElement(e)},e.dispose=function(){i.default.removeData(this._element,f),this._element=null},e._getRootElement=function(t){var e=u.getSelectorFromElement(t),n=!1;return e&&(n=document.querySelector(e)),n||(n=i.default(t).closest(".alert")[0]),n},e._triggerCloseEvent=function(t){var e=i.default.Event("close.bs.alert");return i.default(t).trigger(e),e},e._removeElement=function(t){var e=this;if(i.default(t).removeClass("show"),i.default(t).hasClass("fade")){var n=u.getTransitionDurationFromElement(t);i.default(t).one(u.TRANSITION_END,(function(n){return e._destroyElement(t,n)})).emulateTransitionEnd(n)}else this._destroyElement(t)},e._destroyElement=function(t){i.default(t).detach().trigger("closed.bs.alert").remove()},t._jQueryInterface=function(e){return this.each((function(){var n=i.default(this),o=n.data(f);o||(o=new t(this),n.data(f,o)),"close"===e&&o[e](this)}))},t._handleDismiss=function(t){return function(e){e&&e.preventDefault(),t.close(this)}},r(t,null,[{key:"VERSION",get:function(){return"4.6.2"}}]),t}();i.default(document).on("click.bs.alert.data-api",'[data-dismiss="alert"]',c._handleDismiss(new c)),i.default.fn.alert=c._jQueryInterface,i.default.fn.alert.Constructor=c,i.default.fn.alert.noConflict=function(){return i.default.fn.alert=d,c._jQueryInterface};var h="bs.button",p=i.default.fn.button,m="active",g='[data-toggle^="button"]',_='input:not([type="hidden"])',v=".btn",b=function(){function t(t){this._element=t,this.shouldAvoidTriggerChange=!1}var e=t.prototype;return e.toggle=function(){var t=!0,e=!0,n=i.default(thiLine truncated
//# sourceMappingURL=bootstrap.bundle.min.js.map
@@ -1,7 +0,0 @@
/*!
* headroom.js v0.12.0 - Give your page some headroom. Hide your header until you need it
* Copyright (c) 2020 Nick Williams - http://wicky.nillia.ms/headroom.js
* License: MIT
*/
!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(t=t||self).Headroom=n()}(this,function(){"use strict";function t(){return"undefined"!=typeof window}function d(t){return function(t){return t&&t.document&&function(t){return 9===t.nodeType}(t.document)}(t)?function(t){var n=t.document,o=n.body,s=n.documentElement;return{scrollHeight:function(){return Math.max(o.scrollHeight,s.scrollHeight,o.offsetHeight,s.offsetHeight,o.clientHeight,s.clientHeight)},height:function(){return t.innerHeight||s.clientHeight||o.clientHeight},scrollY:function(){return void 0!==t.pageYOffset?t.pageYOffset:(s||o.parentNode||o).scrollTop}}}(t):function(t){return{scrollHeight:function(){return Math.max(t.scrollHeight,t.offsetHeight,t.clientHeight)},height:function(){return Math.max(t.offsetHeight,t.clientHeight)},scrollY:function(){return t.scrollTop}}}(t)}function n(t,s,e){var n,o=function(){var n=!1;try{var t={get passive(){n=!0}};window.addEventListener("test",t,t),window.removeEventListener("test",t,t)}catch(t){n=!1}return n}(),i=!1,r=d(t),l=r.scrollY(),a={};function c(){var t=Math.round(r.scrollY()),n=r.height(),o=r.scrollHeight();a.scrollY=t,a.lastScrollY=l,a.direction=l<t?"down":"up",a.distance=Math.abs(t-l),a.isOutOfBounds=t<0||o<t+n,a.top=t<=s.offset[a.direction],a.bottom=o<=t+n,a.toleranceExceeded=a.distance>s.tolerance[a.direction],e(a),l=t,i=!1}function h(){i||(i=!0,n=requestAnimationFrame(c))}var u=!!o&&{passive:!0,capture:!1};return t.addEventListener("scroll",h,u),c(),{destroy:function(){cancelAnimationFrame(n),t.removeEventListener("scroll",h,u)}}}function o(t){return t===Object(t)?t:{down:t,up:t}}function s(t,n){n=n||{},Object.assign(this,s.options,n),this.classes=Object.assign({},s.options.classes,n.classes),this.elem=t,this.tolerance=o(this.tolerance),this.offset=o(this.offset),this.initialised=!1,this.frozen=!1}return s.prototype={constructor:s,init:function(){return s.cutsTheMustard&&!this.initialised&&(this.addClass("initial"),this.initialised=!0,setTimeout(function(t){t.scrollTracker=n(t.scroller,{offset:t.offset,tolerance:t.tolerance},t.update.bind(t))},100,this)),this},destroy:function(){this.initialised=!1,Object.keys(this.classes).forEach(this.removeClass,this),this.scrollTracker.destroy()},unpin:function(){!this.hasClass("pinned")&&this.hasClass("unpinned")||(this.addClass("unpinned"),this.removeClass("pinned"),this.onUnpin&&this.onUnpin.call(this))},pin:function(){this.hasClass("unpinned")&&(this.addClass("pinned"),this.removeClass("unpinned"),this.onPin&&this.onPin.call(this))},freeze:function(){this.frozen=!0,this.addClass("frozen")},unfreeze:function(){this.frozen=!1,this.removeClass("frozen")},top:function(){this.hasClass("top")||(this.addClass("top"),this.removeClass("notTop"),this.onTop&&this.onTop.call(this))},notTop:function(){this.hasClass("notTop")||(this.addClass("notTop"),this.removeClass("top"),this.onNotTop&&this.onNotTop.call(this))},bottom:function(){this.hasClass("bottom")||(this.addClass("bottom"),this.removeClass("notBottom"),this.onBottom&&this.onBottom.call(this))},notBottom:function(){this.hasClass("notBottom")||(this.addClass("notBottom"),this.removeClass("bottom"),this.onNotBottom&&this.onNotBottom.call(this))},shouldUnpin:function(t){return"down"===t.direction&&!t.top&&t.toleranceExceeded},shouldPin:function(t){return"up"===t.direction&&t.toleranceExceeded||t.top},addClass:function(t){this.elem.classList.add.apply(this.elem.classList,this.classes[t].split(" "))},removeClass:function(t){this.elem.classList.remove.apply(this.elem.classList,this.classes[t].split(" "))},hasClass:function(t){return this.classes[t].split(" ").every(function(t){return this.classList.contains(t)},this.elem)},update:function(t){t.isOutOfBounds||!0!==this.frozen&&(t.top?this.top():this.notTop(),t.bottom?this.bottom():this.notBottom(),this.shouldUnpin(t)?this.unpin():this.shouldPin(t)&&this.pin())}},s.options={tolerance:{up:0,down:0},offset:0,scroller:t()?window:null,classes:{frozen:"headroom--frozen",pinned:"headroom--pinned",unpinned:"headroom--unpinned",top:"headroom--top",notTop:"headroom--not-top",bottom:"headroom--bottom",notBottom:"headroom--not-bottom",initial:"headroom"}},s.cutsTheMustard=!!(t()&&function(){}.bind&&"classList"in document.documentElement&&Object.assign&&Object.keys&&requestAnimationFrame),s});
@@ -1,330 +0,0 @@
/*! instant.page v5.2.0 - (C) 2019-2023 Alexandre Dieulot - https://instant.page/license */
let _chromiumMajorVersionInUserAgent = null
, _allowQueryString
, _allowExternalLinks
, _useWhitelist
, _delayOnHover = 65
, _lastTouchTimestamp
, _mouseoverTimer
, _preloadedList = new Set()
const DELAY_TO_NOT_BE_CONSIDERED_A_TOUCH_INITIATED_ACTION = 1111
init()
function init() {
const isSupported = document.createElement('link').relList.supports('prefetch')
// instant.page is meant to be loaded with <script type=module>
// (though sometimes webmasters load it as a regular script).
// So it’s normally executed (and must not cause JavaScript errors) in:
// - Chromium 61+
// - Gecko in Firefox 60+
// - WebKit in Safari 10.1+ (iOS 10.3+, macOS 10.10+)
//
// The check above used to check for IntersectionObserverEntry.isIntersecting
// but module scripts support implies this compatibility — except in Safari
// 10.1–12.0, but this prefetch check takes care of it.
if (!isSupported) {
return
}
const handleVaryAcceptHeader = 'instantVaryAccept' in document.body.dataset || 'Shopify' in window
// The `Vary: Accept` header when received in Chromium 79–109 makes prefetches
// unusable, as Chromium used to send a different `Accept` header.
// It’s applied on all Shopify sites by default, as Shopify is very popular
// and is the main source of this problem.
// `window.Shopify` only exists on “classic” Shopify sites. Those using
// Hydrogen (Remix SPA) aren’t concerned.
const chromiumUserAgentIndex = navigator.userAgent.indexOf('Chrome/')
if (chromiumUserAgentIndex > -1) {
_chromiumMajorVersionInUserAgent = parseInt(navigator.userAgent.substring(chromiumUserAgentIndex + 'Chrome/'.length))
}
// The user agent client hints API is a theoretically more reliable way to
// get Chromium’s version… but it’s not available in Samsung Internet 20.
// It also requires a secure context, which would make debugging harder,
// and is only available in recent Chromium versions.
// In practice, Chromium browsers never shy from announcing "Chrome" in
// their regular user agent string, as that maximizes their compatibility.
if (handleVaryAcceptHeader && _chromiumMajorVersionInUserAgent && _chromiumMajorVersionInUserAgent < 110) {
return
}
const mousedownShortcut = 'instantMousedownShortcut' in document.body.dataset
_allowQueryString = 'instantAllowQueryString' in document.body.dataset
_allowExternalLinks = 'instantAllowExternalLinks' in document.body.dataset
_useWhitelist = 'instantWhitelist' in document.body.dataset
const eventListenersOptions = {
capture: true,
passive: true,
}
let useMousedown = false
let useMousedownOnly = false
let useViewport = false
if ('instantIntensity' in document.body.dataset) {
const intensity = document.body.dataset.instantIntensity
if (intensity.startsWith('mousedown')) {
useMousedown = true
if (intensity == 'mousedown-only') {
useMousedownOnly = true
}
}
else if (intensity.startsWith('viewport')) {
const isNavigatorConnectionSaveDataEnabled = navigator.connection && navigator.connection.saveData
const isNavigatorConnectionLike2g = navigator.connection && navigator.connection.effectiveType && navigator.connection.effectiveType.includes('2g')
if (!isNavigatorConnectionSaveDataEnabled && !isNavigatorConnectionLike2g) {
if (intensity == "viewport") {
if (document.documentElement.clientWidth * document.documentElement.clientHeight < 450000) {
useViewport = true
// Smartphones are the most likely to have a slow connection, and
// their small screen size limits the number of links (and thus
// server load).
//
// Foldable phones (being expensive as of 2023), tablets and PCs
// generally have a decent connection, and a big screen displaying
// more links that would put more load on the server.
//
// iPhone 14 Pro Max (want): 430×932 = 400 760
// Samsung Galaxy S22 Ultra with display size set to 80% (want):
// 450×965 = 434 250
// Small tablet (don’t want): 600×960 = 576 000
// Those number are virtual screen size, the viewport (used for
// the check above) will be smaller with the browser’s interface.
}
}
else if (intensity == "viewport-all") {
useViewport = true
}
}
}
else {
const milliseconds = parseInt(intensity)
if (!isNaN(milliseconds)) {
_delayOnHover = milliseconds
}
}
}
if (!useMousedownOnly) {
document.addEventListener('touchstart', touchstartListener, eventListenersOptions)
}
if (!useMousedown) {
document.addEventListener('mouseover', mouseoverListener, eventListenersOptions)
}
else if (!mousedownShortcut) {
document.addEventListener('mousedown', mousedownListener, eventListenersOptions)
}
if (mousedownShortcut) {
document.addEventListener('mousedown', mousedownShortcutListener, eventListenersOptions)
}
if (useViewport) {
let requestIdleCallbackOrFallback = window.requestIdleCallback
// Safari has no support as of 16.3: https://webkit.org/b/164193
if (!requestIdleCallbackOrFallback) {
requestIdleCallbackOrFallback = (callback) => {
callback()
// A smarter fallback like setTimeout is not used because devices that
// may eventually be eligible to a Safari version supporting prefetch
// will be very powerful.
// The weakest devices that could be eligible are the 2017 iPad and
// the 2016 MacBook.
}
}
requestIdleCallbackOrFallback(function observeIntersection() {
const intersectionObserver = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const anchorElement = entry.target
intersectionObserver.unobserve(anchorElement)
preload(anchorElement.href)
}
})
})
document.querySelectorAll('a').forEach((anchorElement) => {
if (isPreloadable(anchorElement)) {
intersectionObserver.observe(anchorElement)
}
})
}, {
timeout: 1500,
})
}
}
function touchstartListener(event) {
_lastTouchTimestamp = performance.now()
// Chrome on Android triggers mouseover before touchcancel, so
// `_lastTouchTimestamp` must be assigned on touchstart to be measured
// on mouseover.
const anchorElement = event.target.closest('a')
if (!isPreloadable(anchorElement)) {
return
}
preload(anchorElement.href, 'high')
}
function mouseoverListener(event) {
if (performance.now() - _lastTouchTimestamp < DELAY_TO_NOT_BE_CONSIDERED_A_TOUCH_INITIATED_ACTION) {
return
}
if (!('closest' in event.target)) {
return
// Without this check sometimes an error “event.target.closest is not a function” is thrown, for unknown reasons
// That error denotes that `event.target` isn’t undefined. My best guess is that it’s the Document.
//
// Details could be gleaned from throwing such an error:
//throw new TypeError(`instant.page non-element event target: timeStamp=${~~event.timeStamp}, type=${event.type}, typeof=${typeof event.target}, nodeType=${event.target.nodeType}, nodeName=${event.target.nodeName}, viewport=${innerWidth}x${innerHeight}, coords=${event.clientX}x${event.clientY}, scroll=${scrollX}x${scrollY}`)
}
const anchorElement = event.target.closest('a')
if (!isPreloadable(anchorElement)) {
return
}
anchorElement.addEventListener('mouseout', mouseoutListener, {passive: true})
_mouseoverTimer = setTimeout(() => {
preload(anchorElement.href, 'high')
_mouseoverTimer = undefined
}, _delayOnHover)
}
function mousedownListener(event) {
const anchorElement = event.target.closest('a')
if (!isPreloadable(anchorElement)) {
return
}
preload(anchorElement.href, 'high')
}
function mouseoutListener(event) {
if (event.relatedTarget && event.target.closest('a') == event.relatedTarget.closest('a')) {
return
}
if (_mouseoverTimer) {
clearTimeout(_mouseoverTimer)
_mouseoverTimer = undefined
}
}
function mousedownShortcutListener(event) {
if (performance.now() - _lastTouchTimestamp < DELAY_TO_NOT_BE_CONSIDERED_A_TOUCH_INITIATED_ACTION) {
return
}
const anchorElement = event.target.closest('a')
if (event.which > 1 || event.metaKey || event.ctrlKey) {
return
}
if (!anchorElement) {
return
}
anchorElement.addEventListener('click', function (event) {
if (event.detail == 1337) {
return
}
event.preventDefault()
}, {capture: true, passive: false, once: true})
const customEvent = new MouseEvent('click', {view: window, bubbles: true, cancelable: false, detail: 1337})
anchorElement.dispatchEvent(customEvent)
}
function isPreloadable(anchorElement) {
if (!anchorElement || !anchorElement.href) {
return
}
if (_useWhitelist && !('instant' in anchorElement.dataset)) {
return
}
if (anchorElement.origin != location.origin) {
let allowed = _allowExternalLinks || 'instant' in anchorElement.dataset
if (!allowed || !_chromiumMajorVersionInUserAgent) {
// Chromium-only: see comment on “restrictive prefetch”
return
}
}
if (!['http:', 'https:'].includes(anchorElement.protocol)) {
return
}
if (anchorElement.protocol == 'http:' && location.protocol == 'https:') {
return
}
if (!_allowQueryString && anchorElement.search && !('instant' in anchorElement.dataset)) {
return
}
if (anchorElement.hash && anchorElement.pathname + anchorElement.search == location.pathname + location.search) {
return
}
if ('noInstant' in anchorElement.dataset) {
return
}
return true
}
function preload(url, fetchPriority = 'auto') {
if (_preloadedList.has(url)) {
return
}
const linkElement = document.createElement('link')
linkElement.rel = 'prefetch'
linkElement.href = url
linkElement.fetchPriority = fetchPriority
// By default, a prefetch is loaded with a low priority.
// When there’s a fair chance that this prefetch is going to be used in the
// near term (= after a touch/mouse event), giving it a high priority helps
// make the page load faster in case there are other resources loading.
// Prioritizing it implicitly means deprioritizing every other resource
// that’s loading on the page. Due to HTML documents usually being much
// smaller than other resources (notably images and JavaScript), and
// prefetches happening once the initial page is sufficiently loaded,
// this theft of bandwidth should rarely be detrimental.
linkElement.as = 'document'
// as=document is Chromium-only and allows cross-origin prefetches to be
// usable for navigation. They call it “restrictive prefetch” and intend
// to remove it: https://crbug.com/1352371
//
// This document from the Chrome team dated 2022-08-10
// https://docs.google.com/document/d/1x232KJUIwIf-k08vpNfV85sVCRHkAxldfuIA5KOqi6M
// claims (I haven’t tested) that data- and battery-saver modes as well as
// the setting to disable preloading do not disable restrictive prefetch,
// unlike regular prefetch. That’s good for prefetching on a touch/mouse
// event, but might be bad when prefetching every link in the viewport.
document.head.appendChild(linkElement)
_preloadedList.add(url)
}
@@ -1,2 +0,0 @@
/*! jQuery v3.6.4 | (c) OpenJS Foundation and other contributors | jquery.org/license */
!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,y=n.hasOwnProperty,a=y.toString,l=a.call(Object),v={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.4",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0<t&&t-1 in e)}S.fn=S.prototype={jquery:f,constructor:S,length:0,toArray:function(){return s.call(this)},get:function(e){return null==e?s.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=S.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return S.each(this,e)},map:function(n){return this.pushStack(S.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(s.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(S.grep(this,function(e,t){return(t+1)%2}))},odd:function(){return this.pushStack(S.grep(this,function(e,t){return t%2}))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:u,sort:t.sort,splice:t.splice},S.extend=S.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||m(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)r=e[t],"__proto__"!==t&&a!==r&&(l&&r&&(S.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||S.isPlainObject(n)?n:{},i=!1,a[t]=S.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},S.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==o.call(e))&&(!(t=r(e))||"function"==typeof(n=y.call(t,"constructor")&&t.constructor)&&a.call(n)===l)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e,t,n){b(e,{nonce:t&&t.nonce},n)},each:function(e,t){var n,r=0;if(p(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},makeArray:function(e,t){var n=t||[];return null!=e&&(p(Object(e))?S.merge(n,"string"==typeof e?[e]:e):u.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:i.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(p(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return g(a)},guid:1,support:v}),"function"==typeof Symbol&&(S.fn[Symbol.iterator]=t[Symbol.iterator]),S.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){n["[object "+t+"]"]=t.toLowerCase()});var d=function(n){var e,d,b,o,i,h,f,g,w,u,l,T,C,a,E,y,s,c,v,S="sizzle"+1*new Date,p=n.document,k=0,r=0,m=ue(),x=ue(),A=ue(),N=ue(),j=function(e,t){return e===t&&(l=!0),0},D={}.hasOwnProperty,t=[],q=t.pop,L=t.push,H=t.push,O=t.slice,P=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},R="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",I="(?:\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",W="\\["+M+"*("+I+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+I+"))|)"+M+"*\\]",F=":("+I+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+W+")*)|.*)\\)|)",$=new RegExp(M+"+","g"),B=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),_=new RegExp("^"+M+"*,"+M+"*"),z=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^Line truncated
@@ -1,631 +0,0 @@
/*! medium-zoom 1.0.8 | MIT License | https://github.com/francoischalifour/medium-zoom */
var _extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
var isSupported = function isSupported(node) {
return node.tagName === 'IMG';
};
/* eslint-disable-next-line no-prototype-builtins */
var isNodeList = function isNodeList(selector) {
return NodeList.prototype.isPrototypeOf(selector);
};
var isNode = function isNode(selector) {
return selector && selector.nodeType === 1;
};
var isSvg = function isSvg(image) {
var source = image.currentSrc || image.src;
return source.substr(-4).toLowerCase() === '.svg';
};
var getImagesFromSelector = function getImagesFromSelector(selector) {
try {
if (Array.isArray(selector)) {
return selector.filter(isSupported);
}
if (isNodeList(selector)) {
// Do not use spread operator or Array.from() for IE support
return [].slice.call(selector).filter(isSupported);
}
if (isNode(selector)) {
return [selector].filter(isSupported);
}
if (typeof selector === 'string') {
// Do not use spread operator or Array.from() for IE support
return [].slice.call(document.querySelectorAll(selector)).filter(isSupported);
}
return [];
} catch (err) {
throw new TypeError('The provided selector is invalid.\n' + 'Expects a CSS selector, a Node element, a NodeList or an array.\n' + 'See: https://github.com/francoischalifour/medium-zoom');
}
};
var createOverlay = function createOverlay(background) {
var overlay = document.createElement('div');
overlay.classList.add('medium-zoom-overlay');
overlay.style.background = background;
return overlay;
};
var cloneTarget = function cloneTarget(template) {
var _template$getBounding = template.getBoundingClientRect(),
top = _template$getBounding.top,
left = _template$getBounding.left,
width = _template$getBounding.width,
height = _template$getBounding.height;
var clone = template.cloneNode();
var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0;
clone.removeAttribute('id');
clone.style.position = 'absolute';
clone.style.top = top + scrollTop + 'px';
clone.style.left = left + scrollLeft + 'px';
clone.style.width = width + 'px';
clone.style.height = height + 'px';
clone.style.transform = '';
return clone;
};
var createCustomEvent = function createCustomEvent(type, params) {
var eventParams = _extends({
bubbles: false,
cancelable: false,
detail: undefined
}, params);
if (typeof window.CustomEvent === 'function') {
return new CustomEvent(type, eventParams);
}
var customEvent = document.createEvent('CustomEvent');
customEvent.initCustomEvent(type, eventParams.bubbles, eventParams.cancelable, eventParams.detail);
return customEvent;
};
var mediumZoom = function mediumZoom(selector) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
/**
* Ensure the compatibility with IE11 if no Promise polyfill are used.
*/
var Promise = window.Promise || function Promise(fn) {
function noop() {}
fn(noop, noop);
};
var _handleClick = function _handleClick(event) {
var target = event.target;
if (target === overlay) {
close();
return;
}
if (images.indexOf(target) === -1) {
return;
}
toggle({ target: target });
};
var _handleScroll = function _handleScroll() {
if (isAnimating || !active.original) {
return;
}
var currentScroll = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
if (Math.abs(scrollTop - currentScroll) > zoomOptions.scrollOffset) {
setTimeout(close, 150);
}
};
var _handleKeyUp = function _handleKeyUp(event) {
var key = event.key || event.keyCode;
// Close if escape key is pressed
if (key === 'Escape' || key === 'Esc' || key === 27) {
close();
}
};
var update = function update() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var newOptions = options;
if (options.background) {
overlay.style.background = options.background;
}
if (options.container && options.container instanceof Object) {
newOptions.container = _extends({}, zoomOptions.container, options.container);
}
if (options.template) {
var template = isNode(options.template) ? options.template : document.querySelector(options.template);
newOptions.template = template;
}
zoomOptions = _extends({}, zoomOptions, newOptions);
images.forEach(function (image) {
image.dispatchEvent(createCustomEvent('medium-zoom:update', {
detail: { zoom: zoom }
}));
});
return zoom;
};
var clone = function clone() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
return mediumZoom(_extends({}, zoomOptions, options));
};
var attach = function attach() {
for (var _len = arguments.length, selectors = Array(_len), _key = 0; _key < _len; _key++) {
selectors[_key] = arguments[_key];
}
var newImages = selectors.reduce(function (imagesAccumulator, currentSelector) {
return [].concat(imagesAccumulator, getImagesFromSelector(currentSelector));
}, []);
newImages.filter(function (newImage) {
return images.indexOf(newImage) === -1;
}).forEach(function (newImage) {
images.push(newImage);
newImage.classList.add('medium-zoom-image');
});
eventListeners.forEach(function (_ref) {
var type = _ref.type,
listener = _ref.listener,
options = _ref.options;
newImages.forEach(function (image) {
image.addEventListener(type, listener, options);
});
});
return zoom;
};
var detach = function detach() {
for (var _len2 = arguments.length, selectors = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
selectors[_key2] = arguments[_key2];
}
if (active.zoomed) {
close();
}
var imagesToDetach = selectors.length > 0 ? selectors.reduce(function (imagesAccumulator, currentSelector) {
return [].concat(imagesAccumulator, getImagesFromSelector(currentSelector));
}, []) : images;
imagesToDetach.forEach(function (image) {
image.classList.remove('medium-zoom-image');
image.dispatchEvent(createCustomEvent('medium-zoom:detach', {
detail: { zoom: zoom }
}));
});
images = images.filter(function (image) {
return imagesToDetach.indexOf(image) === -1;
});
return zoom;
};
var on = function on(type, listener) {
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
images.forEach(function (image) {
image.addEventListener('medium-zoom:' + type, listener, options);
});
eventListeners.push({ type: 'medium-zoom:' + type, listener: listener, options: options });
return zoom;
};
var off = function off(type, listener) {
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
images.forEach(function (image) {
image.removeEventListener('medium-zoom:' + type, listener, options);
});
eventListeners = eventListeners.filter(function (eventListener) {
return !(eventListener.type === 'medium-zoom:' + type && eventListener.listener.toString() === listener.toString());
});
return zoom;
};
var open = function open() {
var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
target = _ref2.target;
var _animate = function _animate() {
var container = {
width: document.documentElement.clientWidth,
height: document.documentElement.clientHeight,
left: 0,
top: 0,
right: 0,
bottom: 0
};
var viewportWidth = void 0;
var viewportHeight = void 0;
if (zoomOptions.container) {
if (zoomOptions.container instanceof Object) {
// The container is given as an object with properties like width, height, left, top
container = _extends({}, container, zoomOptions.container);
// We need to adjust custom options like container.right or container.bottom
viewportWidth = container.width - container.left - container.right - zoomOptions.margin * 2;
viewportHeight = container.height - container.top - container.bottom - zoomOptions.margin * 2;
} else {
// The container is given as an element
var zoomContainer = isNode(zoomOptions.container) ? zoomOptions.container : document.querySelector(zoomOptions.container);
var _zoomContainer$getBou = zoomContainer.getBoundingClientRect(),
_width = _zoomContainer$getBou.width,
_height = _zoomContainer$getBou.height,
_left = _zoomContainer$getBou.left,
_top = _zoomContainer$getBou.top;
container = _extends({}, container, {
width: _width,
height: _height,
left: _left,
top: _top
});
}
}
viewportWidth = viewportWidth || container.width - zoomOptions.margin * 2;
viewportHeight = viewportHeight || container.height - zoomOptions.margin * 2;
var zoomTarget = active.zoomedHd || active.original;
var naturalWidth = isSvg(zoomTarget) ? viewportWidth : zoomTarget.naturalWidth || viewportWidth;
var naturalHeight = isSvg(zoomTarget) ? viewportHeight : zoomTarget.naturalHeight || viewportHeight;
var _zoomTarget$getBoundi = zoomTarget.getBoundingClientRect(),
top = _zoomTarget$getBoundi.top,
left = _zoomTarget$getBoundi.left,
width = _zoomTarget$getBoundi.width,
height = _zoomTarget$getBoundi.height;
var scaleX = Math.min(Math.max(width, naturalWidth), viewportWidth) / width;
var scaleY = Math.min(Math.max(height, naturalHeight), viewportHeight) / height;
var scale = Math.min(scaleX, scaleY);
var translateX = (-left + (viewportWidth - width) / 2 + zoomOptions.margin + container.left) / scale;
var translateY = (-top + (viewportHeight - height) / 2 + zoomOptions.margin + container.top) / scale;
var transform = 'scale(' + scale + ') translate3d(' + translateX + 'px, ' + translateY + 'px, 0)';
active.zoomed.style.transform = transform;
if (active.zoomedHd) {
active.zoomedHd.style.transform = transform;
}
};
return new Promise(function (resolve) {
if (target && images.indexOf(target) === -1) {
resolve(zoom);
return;
}
var _handleOpenEnd = function _handleOpenEnd() {
isAnimating = false;
active.zoomed.removeEventListener('transitionend', _handleOpenEnd);
active.original.dispatchEvent(createCustomEvent('medium-zoom:opened', {
detail: { zoom: zoom }
}));
resolve(zoom);
};
if (active.zoomed) {
resolve(zoom);
return;
}
if (target) {
// The zoom was triggered manually via a click
active.original = target;
} else if (images.length > 0) {
var _images = images;
active.original = _images[0];
} else {
resolve(zoom);
return;
}
active.original.dispatchEvent(createCustomEvent('medium-zoom:open', {
detail: { zoom: zoom }
}));
scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
isAnimating = true;
active.zoomed = cloneTarget(active.original);
document.body.appendChild(overlay);
if (zoomOptions.template) {
var template = isNode(zoomOptions.template) ? zoomOptions.template : document.querySelector(zoomOptions.template);
active.template = document.createElement('div');
active.template.appendChild(template.content.cloneNode(true));
document.body.appendChild(active.template);
}
// If the selected <img> tag is inside a <picture> tag, set the
// currently-applied source as the cloned `src=` attribute.
// (as these might differ, or src= might be unset in some cases)
if (active.original.parentElement && active.original.parentElement.tagName === 'PICTURE' && active.original.currentSrc) {
active.zoomed.src = active.original.currentSrc;
}
document.body.appendChild(active.zoomed);
window.requestAnimationFrame(function () {
document.body.classList.add('medium-zoom--opened');
});
active.original.classList.add('medium-zoom-image--hidden');
active.zoomed.classList.add('medium-zoom-image--opened');
active.zoomed.addEventListener('click', close);
active.zoomed.addEventListener('transitionend', _handleOpenEnd);
if (active.original.getAttribute('data-zoom-src')) {
active.zoomedHd = active.zoomed.cloneNode();
// Reset the `scrset` property or the HD image won't load.
active.zoomedHd.removeAttribute('srcset');
active.zoomedHd.removeAttribute('sizes');
// Remove loading attribute so the browser can load the image normally
active.zoomedHd.removeAttribute('loading');
active.zoomedHd.src = active.zoomed.getAttribute('data-zoom-src');
active.zoomedHd.onerror = function () {
clearInterval(getZoomTargetSize);
console.warn('Unable to reach the zoom image target ' + active.zoomedHd.src);
active.zoomedHd = null;
_animate();
};
// We need to access the natural size of the full HD
// target as fast as possible to compute the animation.
var getZoomTargetSize = setInterval(function () {
if ( active.zoomedHd.complete) {
clearInterval(getZoomTargetSize);
active.zoomedHd.classList.add('medium-zoom-image--opened');
active.zoomedHd.addEventListener('click', close);
document.body.appendChild(active.zoomedHd);
_animate();
}
}, 10);
} else if (active.original.hasAttribute('srcset')) {
// If an image has a `srcset` attribuet, we don't know the dimensions of the
// zoomed (HD) image (like when `data-zoom-src` is specified).
// Therefore the approach is quite similar.
active.zoomedHd = active.zoomed.cloneNode();
// Resetting the sizes attribute tells the browser to load the
// image best fitting the current viewport size, respecting the `srcset`.
active.zoomedHd.removeAttribute('sizes');
// In Firefox, the `loading` attribute needs to be set to `eager` (default
// value) for the load event to be fired.
active.zoomedHd.removeAttribute('loading');
// Wait for the load event of the hd image. This will fire if the image
// is already cached.
var loadEventListener = active.zoomedHd.addEventListener('load', function () {
active.zoomedHd.removeEventListener('load', loadEventListener);
active.zoomedHd.classList.add('medium-zoom-image--opened');
active.zoomedHd.addEventListener('click', close);
document.body.appendChild(active.zoomedHd);
_animate();
});
} else {
_animate();
}
});
};
var close = function close() {
return new Promise(function (resolve) {
if (isAnimating || !active.original) {
resolve(zoom);
return;
}
var _handleCloseEnd = function _handleCloseEnd() {
active.original.classList.remove('medium-zoom-image--hidden');
document.body.removeChild(active.zoomed);
if (active.zoomedHd) {
document.body.removeChild(active.zoomedHd);
}
document.body.removeChild(overlay);
active.zoomed.classList.remove('medium-zoom-image--opened');
if (active.template) {
document.body.removeChild(active.template);
}
isAnimating = false;
active.zoomed.removeEventListener('transitionend', _handleCloseEnd);
active.original.dispatchEvent(createCustomEvent('medium-zoom:closed', {
detail: { zoom: zoom }
}));
active.original = null;
active.zoomed = null;
active.zoomedHd = null;
active.template = null;
resolve(zoom);
};
isAnimating = true;
document.body.classList.remove('medium-zoom--opened');
active.zoomed.style.transform = '';
if (active.zoomedHd) {
active.zoomedHd.style.transform = '';
}
// Fade out the template so it's not too abrupt
if (active.template) {
active.template.style.transition = 'opacity 150ms';
active.template.style.opacity = 0;
}
active.original.dispatchEvent(createCustomEvent('medium-zoom:close', {
detail: { zoom: zoom }
}));
active.zoomed.addEventListener('transitionend', _handleCloseEnd);
});
};
var toggle = function toggle() {
var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
target = _ref3.target;
if (active.original) {
return close();
}
return open({ target: target });
};
var getOptions = function getOptions() {
return zoomOptions;
};
var getImages = function getImages() {
return images;
};
var getZoomedImage = function getZoomedImage() {
return active.original;
};
var images = [];
var eventListeners = [];
var isAnimating = false;
var scrollTop = 0;
var zoomOptions = options;
var active = {
original: null,
zoomed: null,
zoomedHd: null,
template: null
// If the selector is omitted, it's replaced by the options
};if (Object.prototype.toString.call(selector) === '[object Object]') {
zoomOptions = selector;
} else if (selector || typeof selector === 'string' // to process empty string as a selector
) {
attach(selector);
}
// Apply the default option values
zoomOptions = _extends({
margin: 0,
background: '#fff',
scrollOffset: 40,
container: null,
template: null
}, zoomOptions);
var overlay = createOverlay(zoomOptions.background);
document.addEventListener('click', _handleClick);
document.addEventListener('keyup', _handleKeyUp);
document.addEventListener('scroll', _handleScroll);
window.addEventListener('resize', close);
var zoom = {
open: open,
close: close,
toggle: toggle,
update: update,
clone: clone,
attach: attach,
detach: detach,
on: on,
off: off,
getOptions: getOptions,
getImages: getImages,
getZoomedImage: getZoomedImage
};
return zoom;
};
function styleInject(css, ref) {
if ( ref === void 0 ) ref = {};
var insertAt = ref.insertAt;
if (!css || typeof document === 'undefined') { return; }
var head = document.head || document.getElementsByTagName('head')[0];
var style = document.createElement('style');
style.type = 'text/css';
if (insertAt === 'top') {
if (head.firstChild) {
head.insertBefore(style, head.firstChild);
} else {
head.appendChild(style);
}
} else {
head.appendChild(style);
}
if (style.styleSheet) {
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
}
var css = ".medium-zoom-overlay{position:fixed;top:0;right:0;bottom:0;left:0;opacity:0;transition:opacity .3s;will-change:opacity}.medium-zoom--opened .medium-zoom-overlay{cursor:pointer;cursor:zoom-out;opacity:1}.medium-zoom-image{cursor:pointer;cursor:zoom-in;transition:transform .3s cubic-bezier(.2,0,.2,1)!important}.medium-zoom-image--hidden{visibility:hidden}.medium-zoom-image--opened{position:relative;cursor:pointer;cursor:zoom-out;will-change:transform}";
styleInject(css);
export default mediumZoom;
@@ -1,164 +0,0 @@
/*************************************************
* Hugo Blox Builder
* https://github.com/HugoBlox/hugo-blox-builder
*
* Algolia based search algorithm.
**************************************************/
import {algoliaConfig, i18n, content_type} from '@params';
import algoliasearch from 'https://cdn.jsdelivr.net/npm/algoliasearch@4/dist/algoliasearch.esm.browser.js';
// import instantsearch from 'https://cdn.jsdelivr.net/npm/instantsearch.js@4/es/index.js'
// import {searchBox, infiniteHits} from 'https://cdn.jsdelivr.net/npm/instantsearch.js@4/es/widgets/index.js';
// Optional integration of Algolia Search Analytics (configured in site params)
if (algoliaConfig.analytics) {
let ALGOLIA_INSIGHTS_SRC = 'https://cdn.jsdelivr.net/npm/search-insights@2.0.2/dist/search-insights.iife.min.js';
!(function (e, a, t, n, s, i, c) {
(e.AlgoliaAnalyticsObject = s),
(e[s] =
e[s] ||
function () {
(e[s].queue = e[s].queue || []).push(arguments);
}),
(i = a.createElement(t)),
(c = a.getElementsByTagName(t)[0]),
(i.async = 1),
(i.src = n),
c.parentNode.insertBefore(i, c);
})(window, document, 'script', ALGOLIA_INSIGHTS_SRC, 'aa');
}
function getTemplate(templateName) {
return document.querySelector(`#${templateName}-template`).innerHTML;
}
// Get query from URI.
function getSearchQuery(name) {
return decodeURIComponent((location.search.split(name + '=')[1] || '').split('&')[0]).replace(/\+/g, ' ');
}
// On page load, check for search query in URL.
document.addEventListener('DOMContentLoaded', () => {
let queryURL = getSearchQuery('q');
if (queryURL) {
document.querySelector('body').classList.add('searching');
$('.search-results').css({opacity: 0, visibility: 'visible'}).animate({opacity: 1}, 200);
let commonQueries = document.querySelector('#search-common-queries');
// Displaying common search queries in the search modal is an optional feature, so check if the element exists.
if (commonQueries !== null) {
commonQueries.style.display = 'none';
}
}
if (typeof instantsearch === 'function' && $('#search-box').length) {
const search = instantsearch({
indexName: algoliaConfig.indexName,
searchClient: algoliasearch(algoliaConfig.appId, algoliaConfig.apiKey),
searchParameters: {
clickAnalytics: algoliaConfig.analytics,
enablePersonalization: algoliaConfig.personalization,
},
searchFunction(helper) {
if (helper.state.query) {
helper.search();
}
},
routing: {
router: instantsearch.routers.history({
parseURL() {
return {
q: getSearchQuery('q'),
};
},
}),
stateMapping: {
stateToRoute(uiState) {
const indexUiState = uiState[algoliaConfig.indexName];
return {
q: indexUiState.query,
};
},
routeToState(routeState) {
return {
[algoliaConfig.indexName]: {
query: routeState.q,
},
};
},
},
},
});
let timerId = undefined;
let searchResults = document.querySelector('#search-hits');
let commonQueries = document.querySelector('#search-common-queries');
// Initialize search box.
search.addWidget(
instantsearch.widgets.searchBox({
container: '#search-box',
autofocus: true,
showReset: true,
placeholder: i18n.placeholder,
queryHook(query, refine) {
if (query === '') {
searchResults.style.display = 'none';
if (commonQueries !== null) {
commonQueries.style.display = 'block';
}
} else {
if (commonQueries !== null) {
commonQueries.style.display = 'none';
}
searchResults.style.display = 'block';
}
if (timerId) {
clearTimeout(timerId);
}
timerId = setTimeout(() => refine(query), 300);
},
}),
);
// Initialize search results.
search.addWidget(
instantsearch.widgets.infiniteHits({
container: '#search-hits',
escapeHTML: true,
templates: {
empty: '<div class="search-no-results">' + i18n.no_results + '</div>',
item: getTemplate('search-hit-algolia'),
},
cssClasses: {
loadMore: 'btn btn-outline-primary',
},
}),
);
// On render search results, localize the content type metadata.
search.on('render', function () {
$('.search-hit-type').each(function () {
let content_key = $(this).text();
if (content_key in content_type) {
$(this).text(content_type[content_key]);
}
});
});
if (algoliaConfig.analytics) {
const insightsMiddleware = instantsearch.middlewares.createInsightsMiddleware({
insightsClient: window.aa,
insightsInitParams: {
useCookie: true,
},
});
search.use(insightsMiddleware);
}
// Start search.
search.start();
}
});
@@ -1,26 +0,0 @@
// MathJax Configuration
//
// v2 to v3 upgrade notes:
// - The CommonHTML.linebreaks option is not yet implemented (but may be in a future release)
// - The TeX.noUndefined.attributes option is not yet implemented (but may be in a future release)
window.MathJax = {
options: {
// Don't render math in mindmaps as Markmap has its own math renderer.
ignoreHtmlClass: 'markmap',
},
tex: {
inlineMath: [
['$', '$'],
['\\(', '\\)'],
],
displayMath: [
['$$', '$$'],
['\\[', '\\]'],
],
processEscapes: false,
packages: {'[+]': ['noerrors']},
},
loader: {
load: ['[tex]/noerrors'],
},
};
@@ -1,22 +0,0 @@
/*************************************************
* Hugo Blox Builder
* https://github.com/HugoBlox/hugo-blox-builder
*
* Hugo Blox Builder Animation
**************************************************/
function fadeIn(element, duration = 600) {
element.style.display = '';
element.style.opacity = '0';
let last = +new Date();
let tick = function () {
element.style.opacity = (+element.style.opacity + (new Date() - last) / duration).toString();
last = +new Date();
if (+element.style.opacity < 1) {
(window.requestAnimationFrame && requestAnimationFrame(tick)) || setTimeout(tick, 16);
}
};
tick();
}
export {fadeIn};
@@ -1,33 +0,0 @@
/* ---------------------------------------------------------------------------
* Hugo Blox Builder
* https://github.com/HugoBlox/hugo-blox-builder
*
* Announcement Bar component
* --------------------------------------------------------------------------- */
let announcement = document.getElementById('announcement');
// Check if the page has an announcement defined for it
if (announcement !== null) {
console.debug('Announcement detected!');
let announcement_id = announcement.dataset.id;
// Check local storage for the announcement status
Object.keys(localStorage).forEach(function(key) {
if (/^wc-announcement-/.test(key)) {
if (key !== announcement_id ) {
localStorage.removeItem(key);
document.documentElement.removeAttribute('data-wc-announcement-status');
console.debug('Announcement key removed!');
}
}
});
// Dismiss announcement
// TODO: for BS5 upgrade with vanilla JS, change to `announcement.addEventListener('closed.bs.alert', () => {`
$('#announcement').on('closed.bs.alert', function () {
console.debug(`Announcement ${announcement_id} dismissed!`);
localStorage.setItem(announcement_id, 'dismissed');
});
}
@@ -1,25 +0,0 @@
/* ---------------------------------------------------------------------------
* Normalize Bootstrap Carousel Slide Heights.
* --------------------------------------------------------------------------- */
function normalizeCarouselSlideHeights() {
let carousels = document.querySelectorAll('.carousel');
carousels.forEach((carousel) => {
let items = carousel.querySelector('.carousel-item');
let maxHeight = Math.max.apply(
null,
items
.map(function () {
return this.outerHeight();
})
.get(),
);
items.forEach((item) => {
item.style.minHeight = maxHeight + 'px';
});
});
}
window.addEventListener('load', normalizeCarouselSlideHeights);
window.addEventListener('resize', normalizeCarouselSlideHeights);
window.addEventListener('orientationchange', normalizeCarouselSlideHeights);
@@ -1,21 +0,0 @@
import {hugoEnvironment} from '@params';
/* ---------------------------------------------------------------------------
* GitHub API.
* --------------------------------------------------------------------------- */
function printLatestRelease(selector, repo) {
if (hugoEnvironment === 'production') {
$.getJSON('https://api.github.com/repos/' + repo + '/tags')
.done(function (json) {
let release = json[0];
$(selector).append(' ' + release.name);
})
.fail(function (jqxhr, textStatus, error) {
let err = textStatus + ', ' + error;
console.log('Request Failed: ' + err);
});
}
}
export {printLatestRelease};
@@ -1,25 +0,0 @@
/*************************************************
* Hugo Blox Builder
* https://github.com/HugoBlox/hugo-blox-builder
*
* Hugo Blox Builder Headroom
**************************************************/
import Headroom from './_vendor/headroom.min.js';
document.addEventListener('DOMContentLoaded', function () {
// Get config
let pageData = JSON.parse(document.getElementById('page-data').textContent);
console.debug(`Use headroom on this page? ${pageData['use_headroom']}`);
// Grab header element
let $header = document.querySelector('.page-header');
// Use Headroom on this page?
if ($header && pageData['use_headroom'] === true) {
// Construct an instance of Headroom, passing the header
let headroom = new Headroom($header);
// Initialise Headroom
headroom.init();
}
});
@@ -1,40 +0,0 @@
/*************************************************
* Hugo Blox Builder
* https://github.com/HugoBlox/hugo-blox-builder
*
* Hugo Blox Builder Initialization
**************************************************/
import {initThemeVariation} from './wowchemy-theming';
import {wcDarkLightEnabled, wcIsSiteThemeDark} from '@params';
window.wc = {
darkLightEnabled: wcDarkLightEnabled,
isSiteThemeDark: wcIsSiteThemeDark,
};
// CMS authentication
if (window.netlifyIdentity) {
window.netlifyIdentity.on('init', (user) => {
if (!user) {
window.netlifyIdentity.on('login', () => {
document.location.href = '/admin/';
});
}
});
}
// Initialize theme variation and set body theme class.
initThemeVariation();
// For Plotly compatibility with MathJax (must appear prior to loading Plotly).
window.PlotlyConfig = {MathJaxConfig: 'local'};
// Check for any dismissed announcements that should be hidden on load
Object.keys(localStorage).forEach(function(key) {
if (/^wc-announcement-/.test(key)) {
document.documentElement.setAttribute('data-wc-announcement-status', 'dismissed');
console.debug('Hiding announcement...');
}
});
@@ -1,76 +0,0 @@
/*************************************************
* Hugo Blox Builder
* https://github.com/HugoBlox/hugo-blox-builder
*
* Hugo Blox Builder Maps
**************************************************/
// Initialize Google Maps or OpenStreetMap via Leaflet.
function initMap() {
if ($('#map').length) {
let map_provider = $('#map-provider').val();
let lat = $('#map-lat').val();
let lng = $('#map-lng').val();
let zoom = parseInt($('#map-zoom').val());
let address = $('#map-dir').val();
let api_key = $('#map-api-key').val();
if (map_provider === 'google') {
let map = new GMaps({
div: '#map',
lat: lat,
lng: lng,
zoom: zoom,
zoomControl: true,
zoomControlOpt: {
style: 'SMALL',
position: 'TOP_LEFT',
},
streetViewControl: false,
mapTypeControl: false,
gestureHandling: 'cooperative',
});
map.addMarker({
lat: lat,
lng: lng,
click: function () {
let url = 'https://www.google.com/maps/place/' + encodeURIComponent(address) + '/@' + lat + ',' + lng + '/';
window.open(url, '_blank');
},
title: address,
});
} else {
let map = new L.map('map').setView([lat, lng], zoom);
if (map_provider === 'mapbox' && api_key.length) {
L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
attribution:
'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="http://mapbox.com">Mapbox</a>',
tileSize: 512,
maxZoom: 18,
zoomOffset: -1,
id: 'mapbox/streets-v11',
accessToken: api_key,
}).addTo(map);
} else {
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
}).addTo(map);
}
let marker = L.marker([lat, lng]).addTo(map);
let url = lat + ',' + lng + '#map=' + zoom + '/' + lat + '/' + lng + '&layers=N';
marker.bindPopup(
address +
'<p><a href="https://www.openstreetmap.org/directions?engine=osrm_car&route=' +
url +
'">Routing via OpenStreetMap</a></p>',
);
}
}
}
document.addEventListener('DOMContentLoaded', function () {
// Initialise street maps if necessary.
initMap();
});
@@ -1,124 +0,0 @@
/* ---------------------------------------------------------------------------
* Responsive scrolling for URL hashes.
* --------------------------------------------------------------------------- */
// Dynamically get responsive navigation bar height for offsetting Scrollspy.
function getNavBarHeight() {
let navbar = document.getElementById('navbar-main');
let navbarHeight = navbar ? navbar.getBoundingClientRect().height : 0;
console.debug('Navbar height: ' + navbarHeight);
return navbarHeight;
}
/**
* Responsive hash scrolling.
* Check for a URL hash as an anchor.
* If page anchor matches hash, scroll to it responsively considering dynamic height elements.
* If `target` argument omitted (e.g. after event), assume it's the window's hash.
* Default to 0ms animation duration as don't want animation for fixing scrollspy Book page ToC highlighting.
*/
function scrollToAnchor(target, duration = 0) {
// If `target` is undefined or HashChangeEvent object, set it to window's hash.
// Decode the hash as browsers can encode non-ASCII characters (e.g. Chinese symbols).
target =
typeof target === 'undefined' || typeof target === 'object' ? decodeURIComponent(window.location.hash) : target;
// If target element exists, scroll to it taking into account fixed navigation bar offset.
if ($(target).length) {
// Escape special chars from IDs, such as colons found in Markdown footnote links.
target = '#' + $.escapeSelector(target.substring(1)); // Previously, `target = target.replace(/:/g, '\\:');`
let elementOffset = Math.ceil($(target).offset().top - getNavBarHeight()); // Round up to highlight right ID!
document.querySelector('body').classList.add('scrolling');
$('html, body').animate(
{
scrollTop: elementOffset,
},
duration,
function () {
document.querySelector('body').classList.remove('scrolling');
},
);
} else {
console.debug('Cannot scroll to target `#' + target + '`. ID not found!');
}
}
// Make Scrollspy responsive.
function fixScrollspy() {
let $body = $('body');
let data = $body.data('bs.scrollspy');
if (data) {
data._config.offset = getNavBarHeight();
$body.data('bs.scrollspy', data);
$body.scrollspy('refresh');
}
}
/* ---------------------------------------------------------------------------
* Add smooth scrolling to all links inside the main navbar.
* --------------------------------------------------------------------------- */
$('#navbar-main li.nav-item a.nav-link, .js-scroll').on('click', function (event) {
// Store requested URL hash.
let hash = this.hash;
// If we are on a widget page and the navbar link is to a section on the same page.
if (this.pathname === window.location.pathname && hash && $(hash).length && $('.js-widget-page').length > 0) {
// Prevent default click behavior.
event.preventDefault();
// Use jQuery's animate() method for smooth page scrolling.
// The numerical parameter specifies the time (ms) taken to scroll to the specified hash.
let elementOffset = Math.ceil($(hash).offset().top - getNavBarHeight()); // Round up to highlight right ID!
// Uncomment to debug.
// let scrollTop = $(window).scrollTop();
// let scrollDelta = (elementOffset - scrollTop);
// console.debug('Scroll Delta: ' + scrollDelta);
$('html, body').animate(
{
scrollTop: elementOffset,
},
800,
);
}
});
/* ---------------------------------------------------------------------------
* Hide mobile collapsable menu on clicking a link.
* --------------------------------------------------------------------------- */
$(document).on('click', '.navbar-collapse.show', function (e) {
//get the <a> element that was clicked, even if the <span> element that is inside the <a> element is e.target
let targetElement = $(e.target).is('a') ? $(e.target) : $(e.target).parent();
if (targetElement.is('a') && targetElement.attr('class') != 'dropdown-toggle') {
$(this).collapse('hide');
}
});
// Automatic main menu dropdowns on mouse over.
$('body').on('mouseenter mouseleave', '.dropdown', function (e) {
var dropdown = $(e.target).closest('.dropdown');
var menu = $('.dropdown-menu', dropdown);
dropdown.addClass('show');
menu.addClass('show');
setTimeout(function () {
dropdown[dropdown.is(':hover') ? 'addClass' : 'removeClass']('show');
menu[dropdown.is(':hover') ? 'addClass' : 'removeClass']('show');
}, 300);
});
// Call `fixScrollspy` when window is resized.
let resizeTimer;
$(window).resize(function () {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(fixScrollspy, 200);
});
// Check for hash change event and fix responsive offset for hash links (e.g. Markdown footnotes).
window.addEventListener('hashchange', scrollToAnchor);
export {fixScrollspy, scrollToAnchor};
@@ -1,162 +0,0 @@
/*************************************************
* Hugo Blox Builder
* https://github.com/HugoBlox/hugo-blox-builder
*
* Hugo Blox Builder Publications
**************************************************/
// Active publication filters.
let pubFilters = {};
// Search term.
let searchRegex;
// Filter values (concatenated).
let filterValues;
// Publication container.
let $grid_pubs = $('#container-publications');
// Initialise Isotope publication layout if required.
if ($grid_pubs.length) {
$grid_pubs.isotope({
itemSelector: '.isotope-item',
percentPosition: true,
masonry: {
// Use Bootstrap compatible grid layout.
columnWidth: '.grid-sizer',
},
filter: function () {
let $this = $(this);
let searchResults = searchRegex ? $this.text().match(searchRegex) : true;
let filterResults = filterValues ? $this.is(filterValues) : true;
return searchResults && filterResults;
},
});
// Filter by search term.
let $quickSearch = $('.filter-search').keyup(
debounce(function () {
searchRegex = new RegExp($quickSearch.val(), 'gi');
$grid_pubs.isotope();
}),
);
$('.pub-filters').on('change', function () {
let $this = $(this);
// Get group key.
let filterGroup = $this[0].getAttribute('data-filter-group');
// Set filter for group.
pubFilters[filterGroup] = this.value;
// Combine filters.
filterValues = concatValues(pubFilters);
// Activate filters.
$grid_pubs.isotope();
// If filtering by publication type, update the URL hash to enable direct linking to results.
if (filterGroup === 'pubtype') {
// Set hash URL to current filter.
let url = $(this).val();
if (url.substr(0, 9) === '.pubtype-') {
window.location.hash = url.substr(9);
} else {
window.location.hash = '';
}
}
});
}
// Debounce input to prevent spamming filter requests.
function debounce(fn, threshold) {
let timeout;
threshold = threshold || 100;
return function debounced() {
clearTimeout(timeout);
let args = arguments;
let _this = this;
function delayed() {
fn.apply(_this, args);
}
timeout = setTimeout(delayed, threshold);
};
}
// Flatten object by concatenating values.
function concatValues(obj) {
let value = '';
for (let prop in obj) {
value += obj[prop];
}
return value;
}
// Filter publications according to hash in URL.
function filter_publications() {
// Check for Isotope publication layout.
if (!$grid_pubs.length) return;
let urlHash = window.location.hash.replace('#', '');
let filterValue = '*';
// Check if hash is set.
if (urlHash != '') {
filterValue = '.pubtype-' + urlHash;
}
// Set filter.
let filterGroup = 'pubtype';
pubFilters[filterGroup] = filterValue;
filterValues = concatValues(pubFilters);
// Activate filters.
$grid_pubs.isotope();
// Set selected option.
$('.pubtype-select').val(filterValue);
}
document.addEventListener('DOMContentLoaded', function () {
// Enable publication filter for publication index page.
if ($('.pub-filters-select')) {
filter_publications();
// Useful for changing hash manually (e.g. in development):
// window.addEventListener('hashchange', filter_publications, false);
}
// Load citation modal on 'Cite' click.
$('.js-cite-modal').click(function (e) {
e.preventDefault();
let filename = $(this).attr('data-filename');
let modal = $('#modal');
modal.find('.modal-body code').load(filename, function (response, status, xhr) {
if (status == 'error') {
let msg = 'Error: ';
$('#modal-error').html(msg + xhr.status + ' ' + xhr.statusText);
} else {
$('.js-download-cite').attr('href', filename);
}
});
modal.modal('show');
});
// Copy citation text on 'Copy' click.
$('.js-copy-cite').click(function (e) {
e.preventDefault();
// Get text to copy.
let citation = document.querySelector('#modal .modal-body code').innerHTML;
navigator.clipboard
.writeText(citation)
.then(function () {
console.debug('Citation copied!');
})
.catch(function () {
console.error('Citation copy failed!');
});
});
});
@@ -1,206 +0,0 @@
/*************************************************
* Hugo Blox Builder
* https://github.com/HugoBlox/hugo-blox-builder
*
* In-built Fuse based search algorithm.
**************************************************/
import {search_config, i18n, content_type} from '@params';
/* ---------------------------------------------------------------------------
* Configuration.
* --------------------------------------------------------------------------- */
// Configure Fuse.
let fuseOptions = {
shouldSort: true,
includeMatches: true,
tokenize: true,
threshold: search_config.threshold, // Set to ~0.3 for parsing diacritics and CJK languages.
location: 0,
distance: 100,
maxPatternLength: 32,
minMatchCharLength: search_config.minLength, // Set to 1 for parsing CJK languages.
keys: [
{name: 'title', weight: 0.99} /* 1.0 doesn't work o_O */,
{name: 'summary', weight: 0.6},
{name: 'authors', weight: 0.5},
{name: 'content', weight: 0.2},
{name: 'tags', weight: 0.5},
{name: 'categories', weight: 0.5},
],
};
// Configure summary.
let summaryLength = 60;
/* ---------------------------------------------------------------------------
* Functions.
* --------------------------------------------------------------------------- */
// Get query from URI.
function getSearchQuery(name) {
return decodeURIComponent((location.search.split(name + '=')[1] || '').split('&')[0]).replace(/\+/g, ' ');
}
// Set query in URI without reloading the page.
function updateURL(url) {
if (history.replaceState) {
window.history.replaceState({path: url}, '', url);
}
}
// Pre-process new search query.
function initSearch(force, fuse) {
let query = $('#search-query').val();
// If query deleted, clear results.
if (query.length < 1) {
$('#search-hits').empty();
$('#search-common-queries').show();
}
// Check for timer event (enter key not pressed) and query less than minimum length required.
if (!force && query.length < fuseOptions.minMatchCharLength) return;
// Do search.
$('#search-hits').empty();
$('#search-common-queries').hide();
searchAcademic(query, fuse);
let newURL =
window.location.protocol +
'//' +
window.location.host +
window.location.pathname +
'?q=' +
encodeURIComponent(query) +
window.location.hash;
updateURL(newURL);
}
// Perform search.
function searchAcademic(query, fuse) {
let results = fuse.search(query);
// console.log({"results": results});
if (results.length > 0) {
$('#search-hits').append('<h3 class="mt-0">' + results.length + ' ' + i18n.results + '</h3>');
parseResults(query, results);
} else {
$('#search-hits').append('<div class="search-no-results">' + i18n.no_results + '</div>');
}
}
// Parse search results.
function parseResults(query, results) {
$.each(results, function (key, value) {
let content_key = value.item.section;
let content = '';
let snippet = '';
let snippetHighlights = [];
// Show abstract in results for content types where the abstract is often the primary content.
if (['publication', 'event'].includes(content_key)) {
content = value.item.summary;
} else {
content = value.item.content;
}
if (fuseOptions.tokenize) {
snippetHighlights.push(query);
} else {
$.each(value.matches, function (matchKey, matchValue) {
if (matchValue.key == 'content') {
let start = matchValue.indices[0][0] - summaryLength > 0 ? matchValue.indices[0][0] - summaryLength : 0;
let end =
matchValue.indices[0][1] + summaryLength < content.length
? matchValue.indices[0][1] + summaryLength
: content.length;
snippet += content.substring(start, end);
snippetHighlights.push(
matchValue.value.substring(
matchValue.indices[0][0],
matchValue.indices[0][1] - matchValue.indices[0][0] + 1,
),
);
}
});
}
if (snippet.length < 1) {
snippet += value.item.summary; // Alternative fallback: `content.substring(0, summaryLength*2);`
}
// Load template.
let template = $('#search-hit-fuse-template').html();
// Localize content types.
if (content_key in content_type) {
content_key = content_type[content_key];
}
// Parse template.
let templateData = {
key: key,
title: value.item.title,
type: content_key,
relpermalink: value.item.relpermalink,
snippet: snippet,
};
let output = render(template, templateData);
$('#search-hits').append(output);
// Highlight search terms in result.
$.each(snippetHighlights, function (hlKey, hlValue) {
$('#summary-' + key).mark(hlValue);
});
});
}
function render(template, data) {
// Replace placeholders with their values.
let key, find, re;
for (key in data) {
find = '\\{\\{\\s*' + key + '\\s*\\}\\}'; // Expect placeholder in the form `{{x}}`.
re = new RegExp(find, 'g');
template = template.replace(re, data[key]);
}
return template;
}
/* ---------------------------------------------------------------------------
* Initialize.
* --------------------------------------------------------------------------- */
// If Academic's in-built search is enabled and Fuse loaded, then initialize it.
if (typeof Fuse === 'function') {
// Wait for Fuse to initialize.
$.getJSON(search_config.indexURI, function (search_index) {
let fuse = new Fuse(search_index, fuseOptions);
// On page load, check for search query in URL.
let query = getSearchQuery('q');
if (query) {
document.querySelector('body').classList.add('searching');
$('.search-results').css({opacity: 0, visibility: 'visible'}).animate({opacity: 1}, 200);
$('#search-query').val(query);
$('#search-query').focus();
initSearch(true, fuse);
}
// On search box key up, process query.
$('#search-query').keyup(function (e) {
clearTimeout($.data(this, 'searchTimer')); // Ensure only one timer runs!
if (e.keyCode == 13) {
initSearch(true, fuse);
} else {
$(this).data(
'searchTimer',
setTimeout(function () {
initSearch(false, fuse);
}, 250),
);
}
});
});
}
@@ -1,266 +0,0 @@
/*************************************************
* Hugo Blox Builder
* https://github.com/HugoBlox/hugo-blox-builder
*
* Hugo Blox Builder Theming System
* Supported Modes: {0: Light, 1: Dark, 2: Auto}
**************************************************/
import {fadeIn} from './wowchemy-animation';
const body = document.body;
function getThemeMode() {
return parseInt(localStorage.getItem('wcTheme') || 2);
}
function canChangeTheme() {
// If var is set, then user is allowed to change the theme variation.
return Boolean(window.wc.darkLightEnabled);
}
// initThemeVariation is first called directly after <body> to prevent
// flashing between the default theme mode and the user's choice.
function initThemeVariation() {
if (!canChangeTheme()) {
console.debug('User theming disabled.');
return {
isDarkTheme: window.wc.isSiteThemeDark,
themeMode: window.wc.isSiteThemeDark ? 1 : 0,
};
}
console.debug('User theming enabled.');
let isDarkTheme;
let currentThemeMode = getThemeMode();
console.debug(`User's theme variation: ${currentThemeMode}`);
switch (currentThemeMode) {
case 0:
isDarkTheme = false;
break;
case 1:
isDarkTheme = true;
break;
default:
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
// The visitor prefers dark themes and switching to the dark variation is allowed by admin.
isDarkTheme = true;
} else if (window.matchMedia('(prefers-color-scheme: light)').matches) {
// The visitor prefers light themes and switching to the light variation is allowed by admin.
isDarkTheme = false;
} else {
// Use the site's default theme variation based on `light` in the theme file.
isDarkTheme = window.wc.isSiteThemeDark;
}
break;
}
if (isDarkTheme && !body.classList.contains('dark')) {
console.debug('Applying Hugo Blox Builder dark theme');
document.body.classList.add('dark');
} else if (!isDarkTheme && body.classList.contains('dark')) {
console.debug('Applying Hugo Blox Builder light theme');
document.body.classList.remove('dark');
}
return {
isDarkTheme: isDarkTheme,
themeMode: currentThemeMode,
};
}
function changeThemeModeClick(newMode) {
if (!canChangeTheme()) {
console.debug('Cannot change theme - user theming disabled.');
return;
}
let isDarkTheme;
switch (newMode) {
case 0:
localStorage.setItem('wcTheme', '0');
isDarkTheme = false;
console.debug('User changed theme variation to Light.');
break;
case 1:
localStorage.setItem('wcTheme', '1');
isDarkTheme = true;
console.debug('User changed theme variation to Dark.');
break;
default:
localStorage.setItem('wcTheme', '2');
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
// The visitor prefers dark themes and switching to the dark variation is allowed by admin.
isDarkTheme = true;
} else if (window.matchMedia('(prefers-color-scheme: light)').matches) {
// The visitor prefers light themes and switching to the light variation is allowed by admin.
isDarkTheme = false;
} else {
// Use the site's default theme variation based on `light` in the theme file.
isDarkTheme = window.wc.isSiteThemeDark;
}
console.debug('User changed theme variation to Auto.');
break;
}
renderThemeVariation(isDarkTheme, newMode);
}
function showActiveTheme(mode) {
let linkLight = document.querySelector('.js-set-theme-light');
let linkDark = document.querySelector('.js-set-theme-dark');
let linkAuto = document.querySelector('.js-set-theme-auto');
if (linkLight === null) {
return;
}
switch (mode) {
case 0:
// Light.
linkLight.classList.add('dropdown-item-active');
linkDark.classList.remove('dropdown-item-active');
linkAuto.classList.remove('dropdown-item-active');
break;
case 1:
// Dark.
linkLight.classList.remove('dropdown-item-active');
linkDark.classList.add('dropdown-item-active');
linkAuto.classList.remove('dropdown-item-active');
break;
default:
// Auto.
linkLight.classList.remove('dropdown-item-active');
linkDark.classList.remove('dropdown-item-active');
linkAuto.classList.add('dropdown-item-active');
break;
}
}
/**
* Render theme variation (day or night).
*
* @param {boolean} isDarkTheme
* @param {int} themeMode - {0: Light, 1: Dark, 2: Auto}
* @param {boolean} init - true only when called on document ready
* @returns {undefined}
*/
function renderThemeVariation(isDarkTheme, themeMode = 2, init = false) {
// Is code highlighting enabled in site config?
const codeHlLight = document.querySelector('link[title=hl-light]');
const codeHlDark = document.querySelector('link[title=hl-dark]');
const codeHlEnabled = codeHlLight !== null || codeHlDark !== null;
const diagramEnabled = document.querySelector('script[title=mermaid]') !== null;
// Update active theme mode in navbar theme selector.
showActiveTheme(themeMode);
// Dispatch `wcThemeChange` event to support themeable user plugins.
const themeChangeEvent = new CustomEvent('wcThemeChange', {detail: {isDarkTheme: () => isDarkTheme}});
document.dispatchEvent(themeChangeEvent);
// Check if re-render required.
if (!init) {
// If request to render light when light variation already rendered, return.
// If request to render dark when dark variation already rendered, return.
if (
(isDarkTheme === false && !body.classList.contains('dark')) ||
(isDarkTheme === true && body.classList.contains('dark'))
) {
return;
}
}
if (isDarkTheme === false) {
if (!init) {
// Only fade in the page when changing the theme variation.
Object.assign(document.body.style, {opacity: 0, visibility: 'visible'});
fadeIn(document.body, 600);
}
body.classList.remove('dark');
if (codeHlEnabled) {
console.debug('Setting HLJS theme to light');
if (codeHlLight) {
codeHlLight.disabled = false;
}
if (codeHlDark) {
codeHlDark.disabled = true;
}
}
if (diagramEnabled) {
console.debug('Initializing Mermaid with light theme');
if (init) {
/** @namespace window.mermaid **/
window.mermaid.initialize({startOnLoad: true, theme: 'default', securityLevel: 'loose'});
} else {
// Have to reload to re-initialise Mermaid with the new theme and re-parse the Mermaid code blocks.
location.reload();
}
}
} else if (isDarkTheme === true) {
if (!init) {
// Only fade in the page when changing the theme variation.
Object.assign(document.body.style, {opacity: 0, visibility: 'visible'});
fadeIn(document.body, 600);
}
body.classList.add('dark');
if (codeHlEnabled) {
console.debug('Setting HLJS theme to dark');
if (codeHlLight) {
codeHlLight.disabled = true;
}
if (codeHlDark) {
codeHlDark.disabled = false;
}
}
if (diagramEnabled) {
console.debug('Initializing Mermaid with dark theme');
if (init) {
/** @namespace window.mermaid **/
window.mermaid.initialize({startOnLoad: true, theme: 'dark', securityLevel: 'loose'});
} else {
// Have to reload to re-initialise Mermaid with the new theme and re-parse the Mermaid code blocks.
location.reload();
}
}
}
}
/**
* onMediaQueryListEvent.
*
* @param {MediaQueryListEvent} event
* @returns {undefined}
*/
function onMediaQueryListEvent(event) {
if (!canChangeTheme()) {
// Changing theme variation is not allowed by admin.
return;
}
const darkModeOn = event.matches;
console.debug(`OS dark mode preference changed to ${darkModeOn ? '🌒 on' : '☀️ off'}.`);
let currentThemeVariation = getThemeMode();
let isDarkTheme;
if (currentThemeVariation === 2) {
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
// The visitor prefers dark themes.
isDarkTheme = true;
} else if (window.matchMedia('(prefers-color-scheme: light)').matches) {
// The visitor prefers light themes.
isDarkTheme = false;
} else {
// The visitor does not have a day or night preference, so use the theme's default setting.
isDarkTheme = window.wc.isSiteThemeDark;
}
renderThemeVariation(isDarkTheme, currentThemeVariation);
}
}
export {
canChangeTheme,
initThemeVariation,
changeThemeModeClick,
renderThemeVariation,
getThemeMode,
onMediaQueryListEvent,
};
@@ -1,36 +0,0 @@
/*************************************************
* Hugo Blox Builder
* https://github.com/HugoBlox/hugo-blox-builder
*
* Hugo Blox Builder Utilities
**************************************************/
/**
* @param {Element} parent
* @param {Element} child
*/
function scrollParentToChild(parent, child) {
// Where is the parent on the page?
const parentRect = parent.getBoundingClientRect();
// What can the client see?
const parentViewableArea = {
height: parent.clientHeight,
width: parent.clientWidth,
};
// Where is the child?
const childRect = child.getBoundingClientRect();
// Is the child in view?
const isChildInView =
childRect.top >= parentRect.top && childRect.bottom <= parentRect.top + parentViewableArea.height;
// If the child isn't in view, attempt to scroll the parent to it.
if (!isChildInView) {
// Scroll by offset relative to parent.
parent.scrollTop = childRect.top + parent.scrollTop - parentRect.top;
}
}
export {scrollParentToChild};
@@ -1,370 +0,0 @@
/*************************************************
* Hugo Blox Builder
* https://github.com/HugoBlox/hugo-blox-builder
*
* Core JS functions and initialization.
**************************************************/
import mediumZoom from './_vendor/medium-zoom.esm';
import {hugoEnvironment, searchEnabled, i18n} from '@params';
import {scrollParentToChild} from './wowchemy-utils';
import {fixScrollspy, scrollToAnchor} from './wowchemy-navigation';
import {printLatestRelease} from './wowchemy-github';
import {
changeThemeModeClick,
initThemeVariation,
renderThemeVariation,
onMediaQueryListEvent,
} from './wowchemy-theming';
console.debug(`Environment: ${hugoEnvironment}`);
function removeQueryParamsFromUrl() {
if (window.history.replaceState) {
let urlWithoutSearchParams =
window.location.protocol + '//' + window.location.host + window.location.pathname + window.location.hash;
window.history.replaceState({path: urlWithoutSearchParams}, '', urlWithoutSearchParams);
}
}
/* ---------------------------------------------------------------------------
* Toggle search dialog.
* --------------------------------------------------------------------------- */
function toggleSearchDialog() {
const body = document.querySelector('body');
if (body.classList.contains('searching')) {
// Clear search query and hide search modal.
document.getElementById('search-query').blur();
body.classList.remove('searching', 'compensate-for-scrollbar');
// Remove search query params from URL as user has finished searching.
removeQueryParamsFromUrl();
// Prevent fixed positioned elements (e.g. navbar) moving due to scrollbars.
$('#fancybox-style-noscroll').remove();
} else {
// Prevent fixed positioned elements (e.g. navbar) moving due to scrollbars.
if (!$('#fancybox-style-noscroll').length && document.body.scrollHeight > window.innerHeight) {
$('head').append(
'<style id="fancybox-style-noscroll">.compensate-for-scrollbar{margin-right:' +
(window.innerWidth - document.documentElement.clientWidth) +
'px;}</style>',
);
body.classList.add('compensate-for-scrollbar');
}
// Show search modal.
body.classList.add('searching');
// I assume that is broken
$('.search-results').css({opacity: 0, visibility: 'visible'}).animate({opacity: 1}, 200);
let algoliaSearchBox = document.querySelector('.ais-SearchBox-input');
if (algoliaSearchBox) {
algoliaSearchBox.focus();
} else {
document.getElementById('search-query').focus();
}
}
}
/* ---------------------------------------------------------------------------
* Fix Hugo's Goldmark output and Mermaid code blocks.
* --------------------------------------------------------------------------- */
/**
* Fix Hugo's Goldmark output.
*/
function fixHugoOutput() {
// Fix Goldmark table of contents.
// - Must be performed prior to initializing ScrollSpy.
if (document.querySelector('#TableOfContents')) {
document.querySelector('#TableOfContents').classList.add('nav', 'flex-column');
}
document.querySelectorAll('#TableOfContents li').forEach((item) => {
item.classList.add('nav-item')
});
document.querySelectorAll('#TableOfContents li a').forEach((link) => {
link.classList.add('nav-link');
});
// Fix Goldmark task lists (remove bullet points).
document.querySelectorAll('input[type=\'checkbox\'][disabled]').forEach((checkbox) => {
checkbox.closest('ul').classList.add('task-list');
});
// Bootstrap table style is opt-in and Goldmark doesn't add it.
document.querySelectorAll('table').forEach((table) => {
table.classList.add('table');
});
}
// Get an element's siblings.
function getSiblings(elem) {
// Filter out itself.
return Array.prototype.filter.call(elem.parentNode.children, function (sibling) {
return sibling !== elem;
});
}
/* ---------------------------------------------------------------------------
* On document ready.
* --------------------------------------------------------------------------- */
document.addEventListener('DOMContentLoaded', function () {
fixHugoOutput();
// Render theme variation, including any HLJS and Mermaid themes.
let {isDarkTheme, themeMode} = initThemeVariation();
renderThemeVariation(isDarkTheme, themeMode, true);
// Scroll Book page's active menu sidebar link into view.
let child = document.querySelector('.docs-links .active');
let parent = document.querySelector('.docs-links');
if (child && parent) {
scrollParentToChild(parent, child);
}
// Print latest version of GitHub projects.
let githubReleaseSelector = '.js-github-release';
if ($(githubReleaseSelector).length > 0) {
printLatestRelease(githubReleaseSelector, $(githubReleaseSelector).data('repo'));
}
});
/* ---------------------------------------------------------------------------
* On window loaded.
* --------------------------------------------------------------------------- */
window.addEventListener('load', function () {
// Re-initialize Scrollspy with dynamic navbar height offset.
fixScrollspy();
// Detect instances of the Portfolio widget.
let isotopeInstances = document.querySelectorAll('.projects-container');
let isotopeInstancesCount = isotopeInstances.length;
// Fix ScrollSpy highlighting previous Book page ToC link for some anchors.
// Check if isotopeInstancesCount>0 as that case performs its own scrollToAnchor.
if (window.location.hash && isotopeInstancesCount === 0) {
scrollToAnchor(decodeURIComponent(window.location.hash), 0);
}
// Scroll Book page's active ToC sidebar link into view.
// Action after calling scrollToAnchor to fix Scrollspy highlighting otherwise wrong link may have active class.
let child = document.querySelector('.docs-toc .nav-link.active');
let parent = document.querySelector('.docs-toc');
if (child && parent) {
scrollParentToChild(parent, child);
}
// Enable images to be zoomed.
let zoomOptions = {};
if (document.body.classList.contains('dark')) {
zoomOptions.background = 'rgba(0,0,0,0.9)';
} else {
zoomOptions.background = 'rgba(255,255,255,0.9)';
}
mediumZoom('[data-zoomable]', zoomOptions);
// Init Isotope Layout Engine for instances of the Portfolio widget.
let isotopeCounter = 0;
isotopeInstances.forEach(function (isotopeInstance, index) {
console.debug(`Loading Isotope instance ${index}`);
// Isotope instance
let iso;
// Get the layout for this Isotope instance
let isoSection = isotopeInstance.closest('section');
let layout = '';
if (isoSection.querySelector('.isotope').classList.contains('js-layout-row')) {
layout = 'fitRows';
} else {
layout = 'masonry';
}
// Get default filter (if any) for this instance
let defaultFilter = isoSection.querySelector('.default-project-filter');
let filterText = '*';
if (defaultFilter !== null) {
filterText = defaultFilter.textContent;
}
console.debug(`Default Isotope filter: ${filterText}`);
// Init Isotope instance once its images have loaded.
imagesLoaded(isotopeInstance, function () {
iso = new Isotope(isotopeInstance, {
itemSelector: '.isotope-item',
layoutMode: layout,
masonry: {
gutter: 20,
},
filter: filterText,
});
// Filter Isotope items when a toolbar filter button is clicked.
let isoFilterButtons = isoSection.querySelectorAll('.project-filters a');
isoFilterButtons.forEach((button) =>
button.addEventListener('click', (e) => {
e.preventDefault();
let selector = button.getAttribute('data-filter');
// Apply filter
console.debug(`Updating Isotope filter to ${selector}`);
iso.arrange({filter: selector});
// Update active toolbar filter button
button.classList.remove('active');
button.classList.add('active');
let buttonSiblings = getSiblings(button);
buttonSiblings.forEach((buttonSibling) => {
buttonSibling.classList.remove('active');
buttonSibling.classList.remove('all');
});
}),
);
// Check if all Isotope instances have loaded.
incrementIsotopeCounter();
});
});
// Hook to perform actions once all Isotope instances have loaded.
function incrementIsotopeCounter() {
isotopeCounter++;
if (isotopeCounter === isotopeInstancesCount) {
console.debug(`All Portfolio Isotope instances loaded.`);
// Once all Isotope instances and their images have loaded, scroll to hash (if set).
// Prevents scrolling to the wrong location due to the dynamic height of Isotope instances.
// Each Isotope instance height is affected by applying filters and loading images.
// Without this logic, the scroll location can appear correct, but actually a few pixels out and hence Scrollspy
// can highlight the wrong nav link.
if (window.location.hash) {
scrollToAnchor(decodeURIComponent(window.location.hash), 0);
}
}
}
// Parse Hugo Blox Builder keyboard shortcuts.
document.addEventListener('keyup', (event) => {
if (event.code === 'Escape') {
const body = document.body;
if (body.classList.contains('searching')) {
// Close search dialog.
toggleSearchDialog();
}
}
// Use `key` to check for slash. Otherwise, with `code` we need to check for modifiers.
if (event.key === '/') {
let focusedElement =
(document.hasFocus() &&
document.activeElement !== document.body &&
document.activeElement !== document.documentElement &&
document.activeElement) ||
null;
let isInputFocused = focusedElement instanceof HTMLInputElement || focusedElement instanceof HTMLTextAreaElement;
if (searchEnabled && !isInputFocused) {
// Open search dialog.
event.preventDefault();
toggleSearchDialog();
}
}
});
// Search event handler
// Check that built-in search or Algolia enabled.
if (searchEnabled) {
// On search icon click toggle search dialog.
document.querySelectorAll('.js-search').forEach((element) => {
element.addEventListener('click', (e) => {
e.preventDefault();
toggleSearchDialog();
});
})
}
// Init. author notes (tooltips).
$('[data-toggle="tooltip"]').tooltip();
});
// Theme chooser events.
let linkLight = document.querySelector('.js-set-theme-light');
let linkDark = document.querySelector('.js-set-theme-dark');
let linkAuto = document.querySelector('.js-set-theme-auto');
if (linkLight && linkDark && linkAuto) {
linkLight.addEventListener('click', (event) => {
event.preventDefault();
changeThemeModeClick(0);
});
linkDark.addEventListener('click', (event) => {
event.preventDefault();
changeThemeModeClick(1);
});
linkAuto.addEventListener('click', (event) => {
event.preventDefault();
changeThemeModeClick(2);
});
}
// Media Query events.
// Live update of day/night mode on system preferences update (no refresh required).
// Note: since we listen only for *dark* events, we won't detect other scheme changes such as light to no-preference.
const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
darkModeMediaQuery.addEventListener('change', (event) => {
onMediaQueryListEvent(event);
});
// Code block copy button
document.querySelectorAll('pre > code').forEach((codeblock) => {
const container = codeblock.parentNode.parentNode;
const copyBtn = document.createElement('button');
let classesToAdd = ['btn', 'btn-primary', 'btn-copy-code'];
copyBtn.classList.add(...classesToAdd);
copyBtn.innerHTML = i18n['copy'];
function copiedNotification() {
copyBtn.innerHTML = i18n['copied'];
setTimeout(() => {
copyBtn.innerHTML = i18n['copy'];
}, 2000);
}
copyBtn.addEventListener('click', () => {
console.debug('Code block copy click. Is secure context for Clipboard API? ' + window.isSecureContext);
if ('clipboard' in navigator) {
// Note: Clipboard API requires HTTPS or localhost
navigator.clipboard.writeText(codeblock.textContent);
copiedNotification();
return;
} else {
console.debug('Falling back to legacy clipboard copy');
const range = document.createRange();
range.selectNodeContents(codeblock);
const selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
try {
document.execCommand('copy');
copiedNotification();
} catch (e) {
console.error(e);
}
selection.removeRange(range);
}
});
if (container.classList.contains('highlight')) {
// Parent when Hugo line numbers disabled
container.appendChild(copyBtn);
} else if (codeblock.parentNode.parentNode.parentNode.parentNode.parentNode.nodeName == 'TABLE') {
// Parent when Hugo line numbers enabled
codeblock.parentNode.parentNode.parentNode.parentNode.parentNode.appendChild(copyBtn);
} else {
// Parent when Hugo `highlight` class not applied to code block
codeblock.parentNode.appendChild(copyBtn);
}
});
@@ -1 +0,0 @@
<svg fill="none" height="600" viewBox="0 0 600 600" width="600" xmlns="http://www.w3.org/2000/svg"><path d="m307.031 292.969h-14.062v14.062h14.062z" fill="#fff"/><path d="m600 0h-600v600h600z" fill="#fff"/><path d="m600 0h-600v600h600z" fill="#0056d2"/><g fill="#fff"><path d="m117.913 300.434c0-19.301 15.923-34.875 35.859-34.875 20.07 0 35.992 15.574 35.992 34.875 0 19.167-15.922 35.007-35.992 35.007-19.936 0-35.859-15.973-35.859-35.007zm54.725 0c0-9.583-8.43-18.104-18.866-18.104-10.303 0-18.598 8.521-18.598 18.104 0 9.717 8.429 18.236 18.598 18.236 10.436 0 18.866-8.519 18.866-18.236z"/><path d="m478.15 300.965c0-21.164 17.326-35.406 33.036-35.406 10.747 0 16.924 3.194 21.086 9.452l1.612-8.253h16.116v67.353h-16.116l-2.015-6.923c-4.701 5.059-10.61 8.253-20.546 8.253-15.713 0-33.173-13.577-33.173-34.476zm54.795-.133c0-10.247-8.463-18.502-18.936-18.502-10.341 0-18.668 8.388-18.668 18.771 0 9.316 8.461 17.702 18.668 17.702 10.607-.133 18.936-8.519 18.936-17.971z"/><path d="m458.833 274.982v-7.721h-17.101v66.211h17.101v-35.724c0-10.729 5.221-16.356 14.487-16.356.652 0 1.176 0 1.697.131l3.133-15.964c-8.875.131-15.272 3.14-19.317 9.423z"/><path d="m284.158 274.982v-7.721h-17.623l.135 66.211h17.625l-.137-35.724c0-10.729 5.382-16.356 14.801-16.356.672 0 1.209 0 1.75.131l3.228-15.964c-9.15.131-15.741 3.14-19.779 9.423z"/><path d="m196.654 307.776v-41.233h17.209v39.104c0 8.645 4.73 13.699 13.006 13.699 9.196 0 14.583-5.718 14.583-16.624v-36.179h17.209v67.3h-17.209v-7.845c-4.073 6.383-10.641 9.442-19.706 9.442-15.502.133-25.092-11.172-25.092-27.664z"/><path d="m365.945 300.369c0-18.867 13.621-34.942 34.985-34.809 19.893 0 33.913 15.942 33.913 34.541 0 1.861-.134 3.854-.401 5.582l-51.405-.133c2.004 8.104 8.678 13.816 18.693 13.949 6.141 0 12.685-2.259 16.69-7.308l11.885 9.567c-6.144 8.634-16.959 13.683-28.441 13.683-20.297-.265-35.919-15.411-35.919-35.072zm51.408-6.909c-.937-6.777-8.145-12.091-16.423-12.091-8.145 0-14.689 4.783-17.226 11.958z"/><path d="m303.937 319.559 15.522-8.073c2.542 5.558 7.76 8.734 14.984 8.734 6.691 0 9.234-2.118 9.234-5.029 0-10.721-36.93-4.234-36.93-28.853 0-13.631 12.043-20.779 26.894-20.779 11.239 0 21.274 4.897 26.76 14.163l-15.388 8.073c-2.272-4.5-6.555-7.015-12.041-7.015-5.352 0-7.894 1.854-7.894 4.897 0 10.456 36.93 3.837 36.93 28.853 0 12.97-10.704 20.911-27.966 20.911-14.717-.132-25.02-4.897-30.105-15.882z"/><path d="m50 300.074c0-19.161 15.7897-34.515 35.5599-34.515 12.7377 0 23.7511 6.301 30.1201 15.747l-14.861 8.532c-3.4503-4.724-8.8902-7.873-15.2591-7.873-10.2169 0-18.4434 8.398-18.4434 17.978 0 9.578 8.359 17.976 18.4434 17.976 6.6342 0 12.4724-3.411 15.6571-8.529l14.728 8.66c-6.236 9.843-17.5148 16.406-30.3851 16.406-19.7702.131-35.5599-15.616-35.5599-34.382z"/></g></svg>

Before

Width:  |  Height:  |  Size: 2.7 KiB

@@ -1 +0,0 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 34" height="56" width="56"><path d="M14.001 25.028v-7.224l11.393-6.498-2.77-1.588-8.623 4.918V7.391c0-.491-.265-.95-.69-1.194L2.938.245a1.974 1.974 0 00-2.006.06A1.98 1.98 0 000 1.992v20.375c0 .69.35 1.321.934 1.687a1.973 1.973 0 002.002.061l8.317-4.743v6.457c0 .494.266.952.695 1.196l10.658 6.067 2.771-1.589-11.376-6.475zm-2.748-16.84v8.016l-8.504 4.85V3.31l8.504 4.88z" fill="#03EF62" fill-rule="evenodd"></path></svg>

Before

Width:  |  Height:  |  Size: 492 B

@@ -1,36 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.1.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 552.88 310.72" style="enable-background:new 0 0 552.88 310.72;" xml:space="preserve">
<style type="text/css">
.st0{fill:#02262B;}
.st1{fill:#FFFFFF;}
</style>
<polygon class="st0" points="353.43,50.96 364.08,0 51.3,0 0,245.01 261.52,245.01 247.12,310.72 497.63,310.72 552.88,50.96 "/>
<path class="st1" d="M106.6,213.73c-7.09,0-13.79-1.16-20.09-3.49c-6.3-2.32-11.8-5.75-16.49-10.28
c-4.69-4.53-8.39-10.1-11.11-16.72c-2.72-6.62-4.08-14.22-4.08-22.81c0-11.74,1.63-22.44,4.9-32.09
c3.27-9.65,7.82-17.92,13.65-24.82c5.83-6.89,12.82-12.23,20.98-16.01c8.15-3.78,17.08-5.67,26.77-5.67
c6.54,0,12.74,1.14,18.62,3.43c5.87,2.29,11.01,5.61,15.42,9.99c4.41,4.37,7.92,9.75,10.52,16.13c2.6,6.38,3.9,13.71,3.9,21.98
c0,1.26-0.04,2.74-0.12,4.43c-0.08,1.7-0.2,3.43-0.36,5.2c-0.16,1.77-0.32,3.51-0.47,5.2c-0.16,1.69-0.35,3.13-0.59,4.31H76.22
c-0.08,1.11-0.14,2.17-0.18,3.19c-0.04,1.03-0.06,2.09-0.06,3.19c0,6.54,0.95,12.11,2.84,16.72c1.89,4.61,4.35,8.37,7.39,11.29
c3.03,2.92,6.44,5.02,10.22,6.32c3.78,1.3,7.6,1.95,11.46,1.95c8.43,0,15.21-1.46,20.33-4.37c5.12-2.91,9.02-6.85,11.7-11.82h21.63
c-1.34,4.89-3.55,9.46-6.62,13.71c-3.07,4.25-6.95,7.94-11.64,11.05c-4.69,3.11-10.13,5.56-16.31,7.33
C120.8,212.84,114,213.73,106.6,213.73z M148.08,136.08c0.08-0.39,0.14-1.12,0.18-2.19c0.04-1.06,0.06-2.11,0.06-3.13
c0-4.18-0.61-8.14-1.83-11.88c-1.22-3.74-3.05-7.03-5.5-9.87c-2.44-2.84-5.48-5.08-9.1-6.74c-3.63-1.65-7.84-2.48-12.65-2.48
c-4.89,0-9.46,0.87-13.71,2.6c-4.26,1.73-8.12,4.2-11.58,7.39c-3.47,3.19-6.46,7.01-8.98,11.46c-2.52,4.45-4.53,9.4-6.03,14.83
H148.08z"/>
<path class="st1" d="M227.58,213.73c-6.38,0-12.37-1.2-17.97-3.61c-5.6-2.4-10.5-5.85-14.71-10.34c-4.22-4.49-7.55-9.93-9.99-16.31
c-2.44-6.38-3.66-13.51-3.66-21.39c0-7.64,0.77-14.95,2.3-21.92s3.72-13.43,6.56-19.38c2.84-5.95,6.24-11.33,10.22-16.13
c3.98-4.81,8.39-8.9,13.24-12.29c4.85-3.39,10.08-5.99,15.72-7.8c5.63-1.81,11.52-2.72,17.67-2.72c4.57,0,8.92,0.63,13.06,1.89
c4.14,1.26,7.88,3.01,11.23,5.26c3.35,2.25,6.22,4.96,8.63,8.15c2.4,3.19,4.16,6.68,5.26,10.46h1.89l15.72-74.11h20.68l-37.82,178
h-19.62l3.66-17.37h-1.89c-4.65,6.07-10.48,10.85-17.49,14.36C243.26,211.97,235.69,213.73,227.58,213.73z M234.08,195.41
c6.62,0,12.74-1.55,18.38-4.67c5.63-3.11,10.54-7.37,14.71-12.76c4.18-5.4,7.45-11.74,9.81-19.03c2.36-7.29,3.55-15.15,3.55-23.58
c0-5.44-0.75-10.32-2.25-14.66c-1.5-4.33-3.63-8.02-6.38-11.05c-2.76-3.03-6.11-5.38-10.05-7.03c-3.94-1.66-8.39-2.48-13.36-2.48
c-6.54,0-12.61,1.46-18.2,4.37c-5.6,2.92-10.44,6.97-14.54,12.17c-4.1,5.2-7.33,11.41-9.69,18.61s-3.55,15.11-3.55,23.7
c0,5.36,0.77,10.28,2.31,14.77c1.54,4.49,3.68,8.33,6.44,11.52c2.76,3.19,6.07,5.67,9.93,7.45
C225.05,194.52,229.35,195.41,234.08,195.41z"/>
<g>
<polygon class="st1" points="508.94,84.45 462.81,84.45 412.49,146.75 410.01,146.75 383.4,84.45 336.74,84.45 376.74,174.94
290.39,277.23 335.9,277.23 391.32,211.52 395.06,211.52 425,277.23 470.79,277.23 426.51,179.47 "/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.1 KiB

@@ -1,52 +0,0 @@
//
// Base styles
//
.alert {
position: relative;
padding: $alert-padding-y $alert-padding-x;
margin-bottom: $alert-margin-bottom;
border: $alert-border-width solid transparent;
@include border-radius($alert-border-radius);
}
// Headings for larger alerts
.alert-heading {
// Specified to prevent conflicts of changing $headings-color
color: inherit;
}
// Provide class for links that match alerts
.alert-link {
font-weight: $alert-link-font-weight;
}
// Dismissible alerts
//
// Expand the right padding and account for the close button's positioning.
.alert-dismissible {
padding-right: $close-font-size + $alert-padding-x * 2;
// Adjust close link position
.close {
position: absolute;
top: 0;
right: 0;
z-index: 2;
padding: $alert-padding-y $alert-padding-x;
color: inherit;
}
}
// Alternate styles
//
// Generate contextual modifier classes for colorizing the alert.
@each $color, $value in $theme-colors {
.alert-#{$color} {
@include alert-variant(theme-color-level($color, $alert-bg-level), theme-color-level($color, $alert-border-level), theme-color-level($color, $alert-color-level));
}
}
@@ -1,54 +0,0 @@
// Base class
//
// Requires one of the contextual, color modifier classes for `color` and
// `background-color`.
.badge {
display: inline-block;
padding: $badge-padding-y $badge-padding-x;
@include font-size($badge-font-size);
font-weight: $badge-font-weight;
line-height: 1;
text-align: center;
white-space: nowrap;
vertical-align: baseline;
@include border-radius($badge-border-radius);
@include transition($badge-transition);
@at-root a#{&} {
@include hover-focus() {
text-decoration: none;
}
}
// Empty badges collapse automatically
&:empty {
display: none;
}
}
// Quick fix for badges in buttons
.btn .badge {
position: relative;
top: -1px;
}
// Pill badges
//
// Make them extra rounded with a modifier to replace v3's badges.
.badge-pill {
padding-right: $badge-pill-padding-x;
padding-left: $badge-pill-padding-x;
@include border-radius($badge-pill-border-radius);
}
// Colors
//
// Contextual variations (linked badges get darker on :hover).
@each $color, $value in $theme-colors {
.badge-#{$color} {
@include badge-variant($value);
}
}
@@ -1,42 +0,0 @@
.breadcrumb {
display: flex;
flex-wrap: wrap;
padding: $breadcrumb-padding-y $breadcrumb-padding-x;
margin-bottom: $breadcrumb-margin-bottom;
@include font-size($breadcrumb-font-size);
list-style: none;
background-color: $breadcrumb-bg;
@include border-radius($breadcrumb-border-radius);
}
.breadcrumb-item {
// The separator between breadcrumbs (by default, a forward-slash: "/")
+ .breadcrumb-item {
padding-left: $breadcrumb-item-padding;
&::before {
float: left; // Suppress inline spacings and underlining of the separator
padding-right: $breadcrumb-item-padding;
color: $breadcrumb-divider-color;
content: escape-svg($breadcrumb-divider);
}
}
// IE9-11 hack to properly handle hyperlink underlines for breadcrumbs built
// without `<ul>`s. The `::before` pseudo-element generates an element
// *within* the .breadcrumb-item and thereby inherits the `text-decoration`.
//
// To trick IE into suppressing the underline, we give the pseudo-element an
// underline and then immediately remove it.
+ .breadcrumb-item:hover::before {
text-decoration: underline;
}
// stylelint-disable-next-line no-duplicate-selectors
+ .breadcrumb-item:hover::before {
text-decoration: none;
}
&.active {
color: $breadcrumb-active-color;
}
}
@@ -1,163 +0,0 @@
// stylelint-disable selector-no-qualifying-type
// Make the div behave like a button
.btn-group,
.btn-group-vertical {
position: relative;
display: inline-flex;
vertical-align: middle; // match .btn alignment given font-size hack above
> .btn {
position: relative;
flex: 1 1 auto;
// Bring the hover, focused, and "active" buttons to the front to overlay
// the borders properly
@include hover() {
z-index: 1;
}
&:focus,
&:active,
&.active {
z-index: 1;
}
}
}
// Optional: Group multiple button groups together for a toolbar
.btn-toolbar {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
.input-group {
width: auto;
}
}
.btn-group {
// Prevent double borders when buttons are next to each other
> .btn:not(:first-child),
> .btn-group:not(:first-child) {
margin-left: -$btn-border-width;
}
// Reset rounded corners
> .btn:not(:last-child):not(.dropdown-toggle),
> .btn-group:not(:last-child) > .btn {
@include border-right-radius(0);
}
> .btn:not(:first-child),
> .btn-group:not(:first-child) > .btn {
@include border-left-radius(0);
}
}
// Sizing
//
// Remix the default button sizing classes into new ones for easier manipulation.
.btn-group-sm > .btn { @extend .btn-sm; }
.btn-group-lg > .btn { @extend .btn-lg; }
//
// Split button dropdowns
//
.dropdown-toggle-split {
padding-right: $btn-padding-x * .75;
padding-left: $btn-padding-x * .75;
&::after,
.dropup &::after,
.dropright &::after {
margin-left: 0;
}
.dropleft &::before {
margin-right: 0;
}
}
.btn-sm + .dropdown-toggle-split {
padding-right: $btn-padding-x-sm * .75;
padding-left: $btn-padding-x-sm * .75;
}
.btn-lg + .dropdown-toggle-split {
padding-right: $btn-padding-x-lg * .75;
padding-left: $btn-padding-x-lg * .75;
}
// The clickable button for toggling the menu
// Set the same inset shadow as the :active state
.btn-group.show .dropdown-toggle {
@include box-shadow($btn-active-box-shadow);
// Show no shadow for `.btn-link` since it has no other button styles.
&.btn-link {
@include box-shadow(none);
}
}
//
// Vertical button groups
//
.btn-group-vertical {
flex-direction: column;
align-items: flex-start;
justify-content: center;
> .btn,
> .btn-group {
width: 100%;
}
> .btn:not(:first-child),
> .btn-group:not(:first-child) {
margin-top: -$btn-border-width;
}
// Reset rounded corners
> .btn:not(:last-child):not(.dropdown-toggle),
> .btn-group:not(:last-child) > .btn {
@include border-bottom-radius(0);
}
> .btn:not(:first-child),
> .btn-group:not(:first-child) > .btn {
@include border-top-radius(0);
}
}
// Checkbox and radio options
//
// In order to support the browser's form validation feedback, powered by the
// `required` attribute, we have to "hide" the inputs via `clip`. We cannot use
// `display: none;` or `visibility: hidden;` as that also hides the popover.
// Simply visually hiding the inputs via `opacity` would leave them clickable in
// certain cases which is prevented by using `clip` and `pointer-events`.
// This way, we ensure a DOM element is visible to position the popover from.
//
// See https://github.com/twbs/bootstrap/pull/12794 and
// https://github.com/twbs/bootstrap/pull/14559 for more information.
.btn-group-toggle {
> .btn,
> .btn-group > .btn {
margin-bottom: 0; // Override default `<label>` value
input[type="radio"],
input[type="checkbox"] {
position: absolute;
clip: rect(0, 0, 0, 0);
pointer-events: none;
}
}
}
@@ -1,142 +0,0 @@
// stylelint-disable selector-no-qualifying-type
//
// Base styles
//
.btn {
display: inline-block;
font-family: $btn-font-family;
font-weight: $btn-font-weight;
color: $body-color;
text-align: center;
text-decoration: if($link-decoration == none, null, none);
white-space: $btn-white-space;
vertical-align: middle;
user-select: none;
background-color: transparent;
border: $btn-border-width solid transparent;
@include button-size($btn-padding-y, $btn-padding-x, $btn-font-size, $btn-line-height, $btn-border-radius);
@include transition($btn-transition);
@include hover() {
color: $body-color;
text-decoration: none;
}
&:focus,
&.focus {
outline: 0;
box-shadow: $btn-focus-box-shadow;
}
// Disabled comes first so active can properly restyle
&.disabled,
&:disabled {
opacity: $btn-disabled-opacity;
@include box-shadow(none);
}
&:not(:disabled):not(.disabled) {
cursor: if($enable-pointer-cursor-for-buttons, pointer, null);
&:active,
&.active {
@include box-shadow($btn-active-box-shadow);
&:focus {
@include box-shadow($btn-focus-box-shadow, $btn-active-box-shadow);
}
}
}
}
// Future-proof disabling of clicks on `<a>` elements
a.btn.disabled,
fieldset:disabled a.btn {
pointer-events: none;
}
//
// Alternate buttons
//
@each $color, $value in $theme-colors {
.btn-#{$color} {
@include button-variant($value, $value);
}
}
@each $color, $value in $theme-colors {
.btn-outline-#{$color} {
@include button-outline-variant($value);
}
}
//
// Link buttons
//
// Make a button look and behave like a link
.btn-link {
font-weight: $font-weight-normal;
color: $link-color;
text-decoration: $link-decoration;
@include hover() {
color: $link-hover-color;
text-decoration: $link-hover-decoration;
}
&:focus,
&.focus {
text-decoration: $link-hover-decoration;
}
&:disabled,
&.disabled {
color: $btn-link-disabled-color;
pointer-events: none;
}
// No need for an active state here
}
//
// Button Sizes
//
.btn-lg {
@include button-size($btn-padding-y-lg, $btn-padding-x-lg, $btn-font-size-lg, $btn-line-height-lg, $btn-border-radius-lg);
}
.btn-sm {
@include button-size($btn-padding-y-sm, $btn-padding-x-sm, $btn-font-size-sm, $btn-line-height-sm, $btn-border-radius-sm);
}
//
// Block button
//
.btn-block {
display: block;
width: 100%;
// Vertically space out multiple block buttons
+ .btn-block {
margin-top: $btn-block-spacing-y;
}
}
// Specificity overrides
input[type="submit"],
input[type="reset"],
input[type="button"] {
&.btn-block {
width: 100%;
}
}
@@ -1,286 +0,0 @@
//
// Base styles
//
.card {
position: relative;
display: flex;
flex-direction: column;
min-width: 0; // See https://github.com/twbs/bootstrap/pull/22740#issuecomment-305868106
height: $card-height;
word-wrap: break-word;
background-color: $card-bg;
background-clip: border-box;
border: $card-border-width solid $card-border-color;
@include border-radius($card-border-radius);
> hr {
margin-right: 0;
margin-left: 0;
}
> .list-group {
border-top: inherit;
border-bottom: inherit;
&:first-child {
border-top-width: 0;
@include border-top-radius($card-inner-border-radius);
}
&:last-child {
border-bottom-width: 0;
@include border-bottom-radius($card-inner-border-radius);
}
}
// Due to specificity of the above selector (`.card > .list-group`), we must
// use a child selector here to prevent double borders.
> .card-header + .list-group,
> .list-group + .card-footer {
border-top: 0;
}
}
.card-body {
// Enable `flex-grow: 1` for decks and groups so that card blocks take up
// as much space as possible, ensuring footers are aligned to the bottom.
flex: 1 1 auto;
// Workaround for the image size bug in IE
// See: https://github.com/twbs/bootstrap/pull/28855
min-height: 1px;
padding: $card-spacer-x;
color: $card-color;
}
.card-title {
margin-bottom: $card-spacer-y;
}
.card-subtitle {
margin-top: -$card-spacer-y * .5;
margin-bottom: 0;
}
.card-text:last-child {
margin-bottom: 0;
}
.card-link {
@include hover() {
text-decoration: none;
}
+ .card-link {
margin-left: $card-spacer-x;
}
}
//
// Optional textual caps
//
.card-header {
padding: $card-spacer-y $card-spacer-x;
margin-bottom: 0; // Removes the default margin-bottom of <hN>
color: $card-cap-color;
background-color: $card-cap-bg;
border-bottom: $card-border-width solid $card-border-color;
&:first-child {
@include border-radius($card-inner-border-radius $card-inner-border-radius 0 0);
}
}
.card-footer {
padding: $card-spacer-y $card-spacer-x;
color: $card-cap-color;
background-color: $card-cap-bg;
border-top: $card-border-width solid $card-border-color;
&:last-child {
@include border-radius(0 0 $card-inner-border-radius $card-inner-border-radius);
}
}
//
// Header navs
//
.card-header-tabs {
margin-right: -$card-spacer-x * .5;
margin-bottom: -$card-spacer-y;
margin-left: -$card-spacer-x * .5;
border-bottom: 0;
}
.card-header-pills {
margin-right: -$card-spacer-x * .5;
margin-left: -$card-spacer-x * .5;
}
// Card image
.card-img-overlay {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
padding: $card-img-overlay-padding;
@include border-radius($card-inner-border-radius);
}
.card-img,
.card-img-top,
.card-img-bottom {
flex-shrink: 0; // For IE: https://github.com/twbs/bootstrap/issues/29396
width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch
}
.card-img,
.card-img-top {
@include border-top-radius($card-inner-border-radius);
}
.card-img,
.card-img-bottom {
@include border-bottom-radius($card-inner-border-radius);
}
// Card deck
.card-deck {
.card {
margin-bottom: $card-deck-margin;
}
@include media-breakpoint-up(sm) {
display: flex;
flex-flow: row wrap;
margin-right: -$card-deck-margin;
margin-left: -$card-deck-margin;
.card {
// Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4
flex: 1 0 0%;
margin-right: $card-deck-margin;
margin-bottom: 0; // Override the default
margin-left: $card-deck-margin;
}
}
}
//
// Card groups
//
.card-group {
// The child selector allows nested `.card` within `.card-group`
// to display properly.
> .card {
margin-bottom: $card-group-margin;
}
@include media-breakpoint-up(sm) {
display: flex;
flex-flow: row wrap;
// The child selector allows nested `.card` within `.card-group`
// to display properly.
> .card {
// Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4
flex: 1 0 0%;
margin-bottom: 0;
+ .card {
margin-left: 0;
border-left: 0;
}
// Handle rounded corners
@if $enable-rounded {
&:not(:last-child) {
@include border-right-radius(0);
.card-img-top,
.card-header {
// stylelint-disable-next-line property-disallowed-list
border-top-right-radius: 0;
}
.card-img-bottom,
.card-footer {
// stylelint-disable-next-line property-disallowed-list
border-bottom-right-radius: 0;
}
}
&:not(:first-child) {
@include border-left-radius(0);
.card-img-top,
.card-header {
// stylelint-disable-next-line property-disallowed-list
border-top-left-radius: 0;
}
.card-img-bottom,
.card-footer {
// stylelint-disable-next-line property-disallowed-list
border-bottom-left-radius: 0;
}
}
}
}
}
}
//
// Columns
//
.card-columns {
.card {
margin-bottom: $card-columns-margin;
}
@include media-breakpoint-up(sm) {
column-count: $card-columns-count;
column-gap: $card-columns-gap;
orphans: 1;
widows: 1;
.card {
display: inline-block; // Don't let them vertically span multiple columns
width: 100%; // Don't let their width change
}
}
}
//
// Accordion
//
.accordion {
overflow-anchor: none;
> .card {
overflow: hidden;
&:not(:last-of-type) {
border-bottom: 0;
@include border-bottom-radius(0);
}
&:not(:first-of-type) {
@include border-top-radius(0);
}
> .card-header {
@include border-radius(0);
margin-bottom: -$card-border-width;
}
}
}
@@ -1,200 +0,0 @@
// Notes on the classes:
//
// 1. .carousel.pointer-event should ideally be pan-y (to allow for users to scroll vertically)
// even when their scroll action started on a carousel, but for compatibility (with Firefox)
// we're preventing all actions instead
// 2. The .carousel-item-left and .carousel-item-right is used to indicate where
// the active slide is heading.
// 3. .active.carousel-item is the current slide.
// 4. .active.carousel-item-left and .active.carousel-item-right is the current
// slide in its in-transition state. Only one of these occurs at a time.
// 5. .carousel-item-next.carousel-item-left and .carousel-item-prev.carousel-item-right
// is the upcoming slide in transition.
.carousel {
position: relative;
}
.carousel.pointer-event {
touch-action: pan-y;
}
.carousel-inner {
position: relative;
width: 100%;
overflow: hidden;
@include clearfix();
}
.carousel-item {
position: relative;
display: none;
float: left;
width: 100%;
margin-right: -100%;
backface-visibility: hidden;
@include transition($carousel-transition);
}
.carousel-item.active,
.carousel-item-next,
.carousel-item-prev {
display: block;
}
.carousel-item-next:not(.carousel-item-left),
.active.carousel-item-right {
transform: translateX(100%);
}
.carousel-item-prev:not(.carousel-item-right),
.active.carousel-item-left {
transform: translateX(-100%);
}
//
// Alternate transitions
//
.carousel-fade {
.carousel-item {
opacity: 0;
transition-property: opacity;
transform: none;
}
.carousel-item.active,
.carousel-item-next.carousel-item-left,
.carousel-item-prev.carousel-item-right {
z-index: 1;
opacity: 1;
}
.active.carousel-item-left,
.active.carousel-item-right {
z-index: 0;
opacity: 0;
@include transition(opacity 0s $carousel-transition-duration);
}
}
//
// Left/right controls for nav
//
.carousel-control-prev,
.carousel-control-next {
position: absolute;
top: 0;
bottom: 0;
z-index: 1;
// Use flex for alignment (1-3)
display: flex; // 1. allow flex styles
align-items: center; // 2. vertically center contents
justify-content: center; // 3. horizontally center contents
width: $carousel-control-width;
padding: 0;
color: $carousel-control-color;
text-align: center;
background: none;
border: 0;
opacity: $carousel-control-opacity;
@include transition($carousel-control-transition);
// Hover/focus state
@include hover-focus() {
color: $carousel-control-color;
text-decoration: none;
outline: 0;
opacity: $carousel-control-hover-opacity;
}
}
.carousel-control-prev {
left: 0;
@if $enable-gradients {
background-image: linear-gradient(90deg, rgba($black, .25), rgba($black, .001));
}
}
.carousel-control-next {
right: 0;
@if $enable-gradients {
background-image: linear-gradient(270deg, rgba($black, .25), rgba($black, .001));
}
}
// Icons for within
.carousel-control-prev-icon,
.carousel-control-next-icon {
display: inline-block;
width: $carousel-control-icon-width;
height: $carousel-control-icon-width;
background: 50% / 100% 100% no-repeat;
}
.carousel-control-prev-icon {
background-image: escape-svg($carousel-control-prev-icon-bg);
}
.carousel-control-next-icon {
background-image: escape-svg($carousel-control-next-icon-bg);
}
// Optional indicator pips
//
// Add an ordered list with the following class and add a list item for each
// slide your carousel holds.
.carousel-indicators {
position: absolute;
right: 0;
bottom: 0;
left: 0;
z-index: 15;
display: flex;
justify-content: center;
padding-left: 0; // override <ol> default
// Use the .carousel-control's width as margin so we don't overlay those
margin-right: $carousel-control-width;
margin-left: $carousel-control-width;
list-style: none;
li {
box-sizing: content-box;
flex: 0 1 auto;
width: $carousel-indicator-width;
height: $carousel-indicator-height;
margin-right: $carousel-indicator-spacer;
margin-left: $carousel-indicator-spacer;
text-indent: -999px;
cursor: pointer;
background-color: $carousel-indicator-active-bg;
background-clip: padding-box;
// Use transparent borders to increase the hit area by 10px on top and bottom.
border-top: $carousel-indicator-hit-area-height solid transparent;
border-bottom: $carousel-indicator-hit-area-height solid transparent;
opacity: .5;
@include transition($carousel-indicator-transition);
}
.active {
opacity: 1;
}
}
// Optional captions
//
//
.carousel-caption {
position: absolute;
right: (100% - $carousel-caption-width) * .5;
bottom: 20px;
left: (100% - $carousel-caption-width) * .5;
z-index: 10;
padding-top: 20px;
padding-bottom: 20px;
color: $carousel-caption-color;
text-align: center;
}
@@ -1,40 +0,0 @@
.close {
float: right;
@include font-size($close-font-size);
font-weight: $close-font-weight;
line-height: 1;
color: $close-color;
text-shadow: $close-text-shadow;
opacity: .5;
// Override <a>'s hover style
@include hover() {
color: $close-color;
text-decoration: none;
}
&:not(:disabled):not(.disabled) {
@include hover-focus() {
opacity: .75;
}
}
}
// Additional properties for button version
// iOS requires the button element instead of an anchor tag.
// If you want the anchor version, it requires `href="#"`.
// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile
// stylelint-disable-next-line selector-no-qualifying-type
button.close {
padding: 0;
background-color: transparent;
border: 0;
}
// Future-proof disabling of clicks on `<a>` elements
// stylelint-disable-next-line selector-no-qualifying-type
a.close.disabled {
pointer-events: none;
}
@@ -1,48 +0,0 @@
// Inline code
code {
@include font-size($code-font-size);
color: $code-color;
word-wrap: break-word;
// Streamline the style when inside anchors to avoid broken underline and more
a > & {
color: inherit;
}
}
// User input typically entered via keyboard
kbd {
padding: $kbd-padding-y $kbd-padding-x;
@include font-size($kbd-font-size);
color: $kbd-color;
background-color: $kbd-bg;
@include border-radius($border-radius-sm);
@include box-shadow($kbd-box-shadow);
kbd {
padding: 0;
@include font-size(100%);
font-weight: $nested-kbd-font-weight;
@include box-shadow(none);
}
}
// Blocks of code
pre {
display: block;
@include font-size($code-font-size);
color: $pre-color;
// Account for some code outputs that place code tags in pre tags
code {
@include font-size(inherit);
color: inherit;
word-break: normal;
}
}
// Enable scrollable blocks of code
.pre-scrollable {
max-height: $pre-scrollable-max-height;
overflow-y: scroll;
}
@@ -1,526 +0,0 @@
// Embedded icons from Open Iconic.
// Released under MIT and copyright 2014 Waybury.
// https://useiconic.com/open
// Checkboxes and radios
//
// Base class takes care of all the key behavioral aspects.
.custom-control {
position: relative;
z-index: 1;
display: block;
min-height: $font-size-base * $line-height-base;
padding-left: $custom-control-gutter + $custom-control-indicator-size;
print-color-adjust: exact; // Keep themed appearance for print
}
.custom-control-inline {
display: inline-flex;
margin-right: $custom-control-spacer-x;
}
.custom-control-input {
position: absolute;
left: 0;
z-index: -1; // Put the input behind the label so it doesn't overlay text
width: $custom-control-indicator-size;
height: ($font-size-base * $line-height-base + $custom-control-indicator-size) * .5;
opacity: 0;
&:checked ~ .custom-control-label::before {
color: $custom-control-indicator-checked-color;
border-color: $custom-control-indicator-checked-border-color;
@include gradient-bg($custom-control-indicator-checked-bg);
@include box-shadow($custom-control-indicator-checked-box-shadow);
}
&:focus ~ .custom-control-label::before {
// the mixin is not used here to make sure there is feedback
@if $enable-shadows {
box-shadow: $input-box-shadow, $custom-control-indicator-focus-box-shadow;
} @else {
box-shadow: $custom-control-indicator-focus-box-shadow;
}
}
&:focus:not(:checked) ~ .custom-control-label::before {
border-color: $custom-control-indicator-focus-border-color;
}
&:not(:disabled):active ~ .custom-control-label::before {
color: $custom-control-indicator-active-color;
background-color: $custom-control-indicator-active-bg;
border-color: $custom-control-indicator-active-border-color;
@include box-shadow($custom-control-indicator-active-box-shadow);
}
// Use [disabled] and :disabled to work around https://github.com/twbs/bootstrap/issues/28247
&[disabled],
&:disabled {
~ .custom-control-label {
color: $custom-control-label-disabled-color;
&::before {
background-color: $custom-control-indicator-disabled-bg;
}
}
}
}
// Custom control indicators
//
// Build the custom controls out of pseudo-elements.
.custom-control-label {
position: relative;
margin-bottom: 0;
color: $custom-control-label-color;
vertical-align: top;
cursor: $custom-control-cursor;
// Background-color and (when enabled) gradient
&::before {
position: absolute;
top: ($font-size-base * $line-height-base - $custom-control-indicator-size) * .5;
left: -($custom-control-gutter + $custom-control-indicator-size);
display: block;
width: $custom-control-indicator-size;
height: $custom-control-indicator-size;
pointer-events: none;
content: "";
background-color: $custom-control-indicator-bg;
border: $custom-control-indicator-border-width solid $custom-control-indicator-border-color;
@include box-shadow($custom-control-indicator-box-shadow);
}
// Foreground (icon)
&::after {
position: absolute;
top: ($font-size-base * $line-height-base - $custom-control-indicator-size) * .5;
left: -($custom-control-gutter + $custom-control-indicator-size);
display: block;
width: $custom-control-indicator-size;
height: $custom-control-indicator-size;
content: "";
background: 50% / #{$custom-control-indicator-bg-size} no-repeat;
}
}
// Checkboxes
//
// Tweak just a few things for checkboxes.
.custom-checkbox {
.custom-control-label::before {
@include border-radius($custom-checkbox-indicator-border-radius);
}
.custom-control-input:checked ~ .custom-control-label {
&::after {
background-image: escape-svg($custom-checkbox-indicator-icon-checked);
}
}
.custom-control-input:indeterminate ~ .custom-control-label {
&::before {
border-color: $custom-checkbox-indicator-indeterminate-border-color;
@include gradient-bg($custom-checkbox-indicator-indeterminate-bg);
@include box-shadow($custom-checkbox-indicator-indeterminate-box-shadow);
}
&::after {
background-image: escape-svg($custom-checkbox-indicator-icon-indeterminate);
}
}
.custom-control-input:disabled {
&:checked ~ .custom-control-label::before {
@include gradient-bg($custom-control-indicator-checked-disabled-bg);
}
&:indeterminate ~ .custom-control-label::before {
@include gradient-bg($custom-control-indicator-checked-disabled-bg);
}
}
}
// Radios
//
// Tweak just a few things for radios.
.custom-radio {
.custom-control-label::before {
// stylelint-disable-next-line property-disallowed-list
border-radius: $custom-radio-indicator-border-radius;
}
.custom-control-input:checked ~ .custom-control-label {
&::after {
background-image: escape-svg($custom-radio-indicator-icon-checked);
}
}
.custom-control-input:disabled {
&:checked ~ .custom-control-label::before {
@include gradient-bg($custom-control-indicator-checked-disabled-bg);
}
}
}
// switches
//
// Tweak a few things for switches
.custom-switch {
padding-left: $custom-switch-width + $custom-control-gutter;
.custom-control-label {
&::before {
left: -($custom-switch-width + $custom-control-gutter);
width: $custom-switch-width;
pointer-events: all;
// stylelint-disable-next-line property-disallowed-list
border-radius: $custom-switch-indicator-border-radius;
}
&::after {
top: add(($font-size-base * $line-height-base - $custom-control-indicator-size) * .5, $custom-control-indicator-border-width * 2);
left: add(-($custom-switch-width + $custom-control-gutter), $custom-control-indicator-border-width * 2);
width: $custom-switch-indicator-size;
height: $custom-switch-indicator-size;
background-color: $custom-control-indicator-border-color;
// stylelint-disable-next-line property-disallowed-list
border-radius: $custom-switch-indicator-border-radius;
@include transition(transform .15s ease-in-out, $custom-forms-transition);
}
}
.custom-control-input:checked ~ .custom-control-label {
&::after {
background-color: $custom-control-indicator-bg;
transform: translateX($custom-switch-width - $custom-control-indicator-size);
}
}
.custom-control-input:disabled {
&:checked ~ .custom-control-label::before {
@include gradient-bg($custom-control-indicator-checked-disabled-bg);
}
}
}
// Select
//
// Replaces the browser default select with a custom one, mostly pulled from
// https://primer.github.io/.
//
.custom-select {
display: inline-block;
width: 100%;
height: $custom-select-height;
padding: $custom-select-padding-y ($custom-select-padding-x + $custom-select-indicator-padding) $custom-select-padding-y $custom-select-padding-x;
font-family: $custom-select-font-family;
@include font-size($custom-select-font-size);
font-weight: $custom-select-font-weight;
line-height: $custom-select-line-height;
color: $custom-select-color;
vertical-align: middle;
background: $custom-select-bg $custom-select-background;
border: $custom-select-border-width solid $custom-select-border-color;
@include border-radius($custom-select-border-radius, 0);
@include box-shadow($custom-select-box-shadow);
appearance: none;
&:focus {
border-color: $custom-select-focus-border-color;
outline: 0;
@if $enable-shadows {
@include box-shadow($custom-select-box-shadow, $custom-select-focus-box-shadow);
} @else {
// Avoid using mixin so we can pass custom focus shadow properly
box-shadow: $custom-select-focus-box-shadow;
}
&::-ms-value {
// For visual consistency with other platforms/browsers,
// suppress the default white text on blue background highlight given to
// the selected option text when the (still closed) <select> receives focus
// in IE and (under certain conditions) Edge.
// See https://github.com/twbs/bootstrap/issues/19398.
color: $input-color;
background-color: $input-bg;
}
}
&[multiple],
&[size]:not([size="1"]) {
height: auto;
padding-right: $custom-select-padding-x;
background-image: none;
}
&:disabled {
color: $custom-select-disabled-color;
background-color: $custom-select-disabled-bg;
}
// Hides the default caret in IE11
&::-ms-expand {
display: none;
}
// Remove outline from select box in FF
&:-moz-focusring {
color: transparent;
text-shadow: 0 0 0 $custom-select-color;
}
}
.custom-select-sm {
height: $custom-select-height-sm;
padding-top: $custom-select-padding-y-sm;
padding-bottom: $custom-select-padding-y-sm;
padding-left: $custom-select-padding-x-sm;
@include font-size($custom-select-font-size-sm);
}
.custom-select-lg {
height: $custom-select-height-lg;
padding-top: $custom-select-padding-y-lg;
padding-bottom: $custom-select-padding-y-lg;
padding-left: $custom-select-padding-x-lg;
@include font-size($custom-select-font-size-lg);
}
// File
//
// Custom file input.
.custom-file {
position: relative;
display: inline-block;
width: 100%;
height: $custom-file-height;
margin-bottom: 0;
}
.custom-file-input {
position: relative;
z-index: 2;
width: 100%;
height: $custom-file-height;
margin: 0;
overflow: hidden;
opacity: 0;
&:focus ~ .custom-file-label {
border-color: $custom-file-focus-border-color;
box-shadow: $custom-file-focus-box-shadow;
}
// Use [disabled] and :disabled to work around https://github.com/twbs/bootstrap/issues/28247
&[disabled] ~ .custom-file-label,
&:disabled ~ .custom-file-label {
background-color: $custom-file-disabled-bg;
}
@each $lang, $value in $custom-file-text {
&:lang(#{$lang}) ~ .custom-file-label::after {
content: $value;
}
}
~ .custom-file-label[data-browse]::after {
content: attr(data-browse);
}
}
.custom-file-label {
position: absolute;
top: 0;
right: 0;
left: 0;
z-index: 1;
height: $custom-file-height;
padding: $custom-file-padding-y $custom-file-padding-x;
overflow: hidden;
font-family: $custom-file-font-family;
font-weight: $custom-file-font-weight;
line-height: $custom-file-line-height;
color: $custom-file-color;
background-color: $custom-file-bg;
border: $custom-file-border-width solid $custom-file-border-color;
@include border-radius($custom-file-border-radius);
@include box-shadow($custom-file-box-shadow);
&::after {
position: absolute;
top: 0;
right: 0;
bottom: 0;
z-index: 3;
display: block;
height: $custom-file-height-inner;
padding: $custom-file-padding-y $custom-file-padding-x;
line-height: $custom-file-line-height;
color: $custom-file-button-color;
content: "Browse";
@include gradient-bg($custom-file-button-bg);
border-left: inherit;
@include border-radius(0 $custom-file-border-radius $custom-file-border-radius 0);
}
}
// Range
//
// Style range inputs the same across browsers. Vendor-specific rules for pseudo
// elements cannot be mixed. As such, there are no shared styles for focus or
// active states on prefixed selectors.
.custom-range {
width: 100%;
height: add($custom-range-thumb-height, $custom-range-thumb-focus-box-shadow-width * 2);
padding: 0; // Need to reset padding
background-color: transparent;
appearance: none;
&:focus {
outline: 0;
// Pseudo-elements must be split across multiple rulesets to have an effect.
// No box-shadow() mixin for focus accessibility.
&::-webkit-slider-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }
&::-moz-range-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }
&::-ms-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }
}
&::-moz-focus-outer {
border: 0;
}
&::-webkit-slider-thumb {
width: $custom-range-thumb-width;
height: $custom-range-thumb-height;
margin-top: ($custom-range-track-height - $custom-range-thumb-height) * .5; // Webkit specific
@include gradient-bg($custom-range-thumb-bg);
border: $custom-range-thumb-border;
@include border-radius($custom-range-thumb-border-radius);
@include box-shadow($custom-range-thumb-box-shadow);
@include transition($custom-forms-transition);
appearance: none;
&:active {
@include gradient-bg($custom-range-thumb-active-bg);
}
}
&::-webkit-slider-runnable-track {
width: $custom-range-track-width;
height: $custom-range-track-height;
color: transparent; // Why?
cursor: $custom-range-track-cursor;
background-color: $custom-range-track-bg;
border-color: transparent;
@include border-radius($custom-range-track-border-radius);
@include box-shadow($custom-range-track-box-shadow);
}
&::-moz-range-thumb {
width: $custom-range-thumb-width;
height: $custom-range-thumb-height;
@include gradient-bg($custom-range-thumb-bg);
border: $custom-range-thumb-border;
@include border-radius($custom-range-thumb-border-radius);
@include box-shadow($custom-range-thumb-box-shadow);
@include transition($custom-forms-transition);
appearance: none;
&:active {
@include gradient-bg($custom-range-thumb-active-bg);
}
}
&::-moz-range-track {
width: $custom-range-track-width;
height: $custom-range-track-height;
color: transparent;
cursor: $custom-range-track-cursor;
background-color: $custom-range-track-bg;
border-color: transparent; // Firefox specific?
@include border-radius($custom-range-track-border-radius);
@include box-shadow($custom-range-track-box-shadow);
}
&::-ms-thumb {
width: $custom-range-thumb-width;
height: $custom-range-thumb-height;
margin-top: 0; // Edge specific
margin-right: $custom-range-thumb-focus-box-shadow-width; // Workaround that overflowed box-shadow is hidden.
margin-left: $custom-range-thumb-focus-box-shadow-width; // Workaround that overflowed box-shadow is hidden.
@include gradient-bg($custom-range-thumb-bg);
border: $custom-range-thumb-border;
@include border-radius($custom-range-thumb-border-radius);
@include box-shadow($custom-range-thumb-box-shadow);
@include transition($custom-forms-transition);
appearance: none;
&:active {
@include gradient-bg($custom-range-thumb-active-bg);
}
}
&::-ms-track {
width: $custom-range-track-width;
height: $custom-range-track-height;
color: transparent;
cursor: $custom-range-track-cursor;
background-color: transparent;
border-color: transparent;
border-width: $custom-range-thumb-height * .5;
@include box-shadow($custom-range-track-box-shadow);
}
&::-ms-fill-lower {
background-color: $custom-range-track-bg;
@include border-radius($custom-range-track-border-radius);
}
&::-ms-fill-upper {
margin-right: 15px; // arbitrary?
background-color: $custom-range-track-bg;
@include border-radius($custom-range-track-border-radius);
}
&:disabled {
&::-webkit-slider-thumb {
background-color: $custom-range-thumb-disabled-bg;
}
&::-webkit-slider-runnable-track {
cursor: default;
}
&::-moz-range-thumb {
background-color: $custom-range-thumb-disabled-bg;
}
&::-moz-range-track {
cursor: default;
}
&::-ms-thumb {
background-color: $custom-range-thumb-disabled-bg;
}
}
}
.custom-control-label::before,
.custom-file-label,
.custom-select {
@include transition($custom-forms-transition);
}
@@ -1,192 +0,0 @@
// The dropdown wrapper (`<div>`)
.dropup,
.dropright,
.dropdown,
.dropleft {
position: relative;
}
.dropdown-toggle {
white-space: nowrap;
// Generate the caret automatically
@include caret();
}
// The dropdown menu
.dropdown-menu {
position: absolute;
top: 100%;
left: 0;
z-index: $zindex-dropdown;
display: none; // none by default, but block on "open" of the menu
float: left;
min-width: $dropdown-min-width;
padding: $dropdown-padding-y $dropdown-padding-x;
margin: $dropdown-spacer 0 0; // override default ul
@include font-size($dropdown-font-size);
color: $dropdown-color;
text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)
list-style: none;
background-color: $dropdown-bg;
background-clip: padding-box;
border: $dropdown-border-width solid $dropdown-border-color;
@include border-radius($dropdown-border-radius);
@include box-shadow($dropdown-box-shadow);
}
@each $breakpoint in map-keys($grid-breakpoints) {
@include media-breakpoint-up($breakpoint) {
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
.dropdown-menu#{$infix}-left {
right: auto;
left: 0;
}
.dropdown-menu#{$infix}-right {
right: 0;
left: auto;
}
}
}
// Allow for dropdowns to go bottom up (aka, dropup-menu)
// Just add .dropup after the standard .dropdown class and you're set.
.dropup {
.dropdown-menu {
top: auto;
bottom: 100%;
margin-top: 0;
margin-bottom: $dropdown-spacer;
}
.dropdown-toggle {
@include caret(up);
}
}
.dropright {
.dropdown-menu {
top: 0;
right: auto;
left: 100%;
margin-top: 0;
margin-left: $dropdown-spacer;
}
.dropdown-toggle {
@include caret(right);
&::after {
vertical-align: 0;
}
}
}
.dropleft {
.dropdown-menu {
top: 0;
right: 100%;
left: auto;
margin-top: 0;
margin-right: $dropdown-spacer;
}
.dropdown-toggle {
@include caret(left);
&::before {
vertical-align: 0;
}
}
}
// When Popper is enabled, reset the basic dropdown position
// stylelint-disable-next-line no-duplicate-selectors
.dropdown-menu {
&[x-placement^="top"],
&[x-placement^="right"],
&[x-placement^="bottom"],
&[x-placement^="left"] {
right: auto;
bottom: auto;
}
}
// Dividers (basically an `<hr>`) within the dropdown
.dropdown-divider {
@include nav-divider($dropdown-divider-bg, $dropdown-divider-margin-y, true);
}
// Links, buttons, and more within the dropdown menu
//
// `<button>`-specific styles are denoted with `// For <button>s`
.dropdown-item {
display: block;
width: 100%; // For `<button>`s
padding: $dropdown-item-padding-y $dropdown-item-padding-x;
clear: both;
font-weight: $font-weight-normal;
color: $dropdown-link-color;
text-align: inherit; // For `<button>`s
text-decoration: if($link-decoration == none, null, none);
white-space: nowrap; // prevent links from randomly breaking onto new lines
background-color: transparent; // For `<button>`s
border: 0; // For `<button>`s
// Prevent dropdown overflow if there's no padding
// See https://github.com/twbs/bootstrap/pull/27703
@if $dropdown-padding-y == 0 {
&:first-child {
@include border-top-radius($dropdown-inner-border-radius);
}
&:last-child {
@include border-bottom-radius($dropdown-inner-border-radius);
}
}
@include hover-focus() {
color: $dropdown-link-hover-color;
text-decoration: none;
@include gradient-bg($dropdown-link-hover-bg);
}
&.active,
&:active {
color: $dropdown-link-active-color;
text-decoration: none;
@include gradient-bg($dropdown-link-active-bg);
}
&.disabled,
&:disabled {
color: $dropdown-link-disabled-color;
pointer-events: none;
background-color: transparent;
// Remove CSS gradients if they're enabled
@if $enable-gradients {
background-image: none;
}
}
}
.dropdown-menu.show {
display: block;
}
// Dropdown section headers
.dropdown-header {
display: block;
padding: $dropdown-header-padding;
margin-bottom: 0; // for use with heading elements
@include font-size($font-size-sm);
color: $dropdown-header-color;
white-space: nowrap; // as with > li > a
}
// Dropdown text
.dropdown-item-text {
display: block;
padding: $dropdown-item-padding-y $dropdown-item-padding-x;
color: $dropdown-link-color;
}
@@ -1,347 +0,0 @@
// stylelint-disable selector-no-qualifying-type
//
// Textual form controls
//
.form-control {
display: block;
width: 100%;
height: $input-height;
padding: $input-padding-y $input-padding-x;
font-family: $input-font-family;
@include font-size($input-font-size);
font-weight: $input-font-weight;
line-height: $input-line-height;
color: $input-color;
background-color: $input-bg;
background-clip: padding-box;
border: $input-border-width solid $input-border-color;
// Note: This has no effect on <select>s in some browsers, due to the limited stylability of `<select>`s in CSS.
@include border-radius($input-border-radius, 0);
@include box-shadow($input-box-shadow);
@include transition($input-transition);
// Unstyle the caret on `<select>`s in IE10+.
&::-ms-expand {
background-color: transparent;
border: 0;
}
// Customize the `:focus` state to imitate native WebKit styles.
@include form-control-focus($ignore-warning: true);
// Placeholder
&::placeholder {
color: $input-placeholder-color;
// Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526.
opacity: 1;
}
// Disabled and read-only inputs
//
// HTML5 says that controls under a fieldset > legend:first-child won't be
// disabled if the fieldset is disabled. Due to implementation difficulty, we
// don't honor that edge case; we style them as disabled anyway.
&:disabled,
&[readonly] {
background-color: $input-disabled-bg;
// iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655.
opacity: 1;
}
}
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"] {
&.form-control {
appearance: none; // Fix appearance for date inputs in Safari
}
}
select.form-control {
// Remove select outline from select box in FF
&:-moz-focusring {
color: transparent;
text-shadow: 0 0 0 $input-color;
}
&:focus::-ms-value {
// Suppress the nested default white text on blue background highlight given to
// the selected option text when the (still closed) <select> receives focus
// in IE and (under certain conditions) Edge, as it looks bad and cannot be made to
// match the appearance of the native widget.
// See https://github.com/twbs/bootstrap/issues/19398.
color: $input-color;
background-color: $input-bg;
}
}
// Make file inputs better match text inputs by forcing them to new lines.
.form-control-file,
.form-control-range {
display: block;
width: 100%;
}
//
// Labels
//
// For use with horizontal and inline forms, when you need the label (or legend)
// text to align with the form controls.
.col-form-label {
padding-top: add($input-padding-y, $input-border-width);
padding-bottom: add($input-padding-y, $input-border-width);
margin-bottom: 0; // Override the `<label>/<legend>` default
@include font-size(inherit); // Override the `<legend>` default
line-height: $input-line-height;
}
.col-form-label-lg {
padding-top: add($input-padding-y-lg, $input-border-width);
padding-bottom: add($input-padding-y-lg, $input-border-width);
@include font-size($input-font-size-lg);
line-height: $input-line-height-lg;
}
.col-form-label-sm {
padding-top: add($input-padding-y-sm, $input-border-width);
padding-bottom: add($input-padding-y-sm, $input-border-width);
@include font-size($input-font-size-sm);
line-height: $input-line-height-sm;
}
// Readonly controls as plain text
//
// Apply class to a readonly input to make it appear like regular plain
// text (without any border, background color, focus indicator)
.form-control-plaintext {
display: block;
width: 100%;
padding: $input-padding-y 0;
margin-bottom: 0; // match inputs if this class comes on inputs with default margins
@include font-size($input-font-size);
line-height: $input-line-height;
color: $input-plaintext-color;
background-color: transparent;
border: solid transparent;
border-width: $input-border-width 0;
&.form-control-sm,
&.form-control-lg {
padding-right: 0;
padding-left: 0;
}
}
// Form control sizing
//
// Build on `.form-control` with modifier classes to decrease or increase the
// height and font-size of form controls.
//
// Repeated in `_input_group.scss` to avoid Sass extend issues.
.form-control-sm {
height: $input-height-sm;
padding: $input-padding-y-sm $input-padding-x-sm;
@include font-size($input-font-size-sm);
line-height: $input-line-height-sm;
@include border-radius($input-border-radius-sm);
}
.form-control-lg {
height: $input-height-lg;
padding: $input-padding-y-lg $input-padding-x-lg;
@include font-size($input-font-size-lg);
line-height: $input-line-height-lg;
@include border-radius($input-border-radius-lg);
}
// stylelint-disable-next-line no-duplicate-selectors
select.form-control {
&[size],
&[multiple] {
height: auto;
}
}
textarea.form-control {
height: auto;
}
// Form groups
//
// Designed to help with the organization and spacing of vertical forms. For
// horizontal forms, use the predefined grid classes.
.form-group {
margin-bottom: $form-group-margin-bottom;
}
.form-text {
display: block;
margin-top: $form-text-margin-top;
}
// Form grid
//
// Special replacement for our grid system's `.row` for tighter form layouts.
.form-row {
display: flex;
flex-wrap: wrap;
margin-right: -$form-grid-gutter-width * .5;
margin-left: -$form-grid-gutter-width * .5;
> .col,
> [class*="col-"] {
padding-right: $form-grid-gutter-width * .5;
padding-left: $form-grid-gutter-width * .5;
}
}
// Checkboxes and radios
//
// Indent the labels to position radios/checkboxes as hanging controls.
.form-check {
position: relative;
display: block;
padding-left: $form-check-input-gutter;
}
.form-check-input {
position: absolute;
margin-top: $form-check-input-margin-y;
margin-left: -$form-check-input-gutter;
// Use [disabled] and :disabled for workaround https://github.com/twbs/bootstrap/issues/28247
&[disabled] ~ .form-check-label,
&:disabled ~ .form-check-label {
color: $text-muted;
}
}
.form-check-label {
margin-bottom: 0; // Override default `<label>` bottom margin
}
.form-check-inline {
display: inline-flex;
align-items: center;
padding-left: 0; // Override base .form-check
margin-right: $form-check-inline-margin-x;
// Undo .form-check-input defaults and add some `margin-right`.
.form-check-input {
position: static;
margin-top: 0;
margin-right: $form-check-inline-input-margin-x;
margin-left: 0;
}
}
// Form validation
//
// Provide feedback to users when form field values are valid or invalid. Works
// primarily for client-side validation via scoped `:invalid` and `:valid`
// pseudo-classes but also includes `.is-invalid` and `.is-valid` classes for
// server side validation.
@each $state, $data in $form-validation-states {
@include form-validation-state($state, map-get($data, color), map-get($data, icon));
}
// Inline forms
//
// Make forms appear inline(-block) by adding the `.form-inline` class. Inline
// forms begin stacked on extra small (mobile) devices and then go inline when
// viewports reach <768px.
//
// Requires wrapping inputs and labels with `.form-group` for proper display of
// default HTML form controls and our custom form controls (e.g., input groups).
.form-inline {
display: flex;
flex-flow: row wrap;
align-items: center; // Prevent shorter elements from growing to same height as others (e.g., small buttons growing to normal sized button height)
// Because we use flex, the initial sizing of checkboxes is collapsed and
// doesn't occupy the full-width (which is what we want for xs grid tier),
// so we force that here.
.form-check {
width: 100%;
}
// Kick in the inline
@include media-breakpoint-up(sm) {
label {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 0;
}
// Inline-block all the things for "inline"
.form-group {
display: flex;
flex: 0 0 auto;
flex-flow: row wrap;
align-items: center;
margin-bottom: 0;
}
// Allow folks to *not* use `.form-group`
.form-control {
display: inline-block;
width: auto; // Prevent labels from stacking above inputs in `.form-group`
vertical-align: middle;
}
// Make static controls behave like regular ones
.form-control-plaintext {
display: inline-block;
}
.input-group,
.custom-select {
width: auto;
}
// Remove default margin on radios/checkboxes that were used for stacking, and
// then undo the floating of radios and checkboxes to match.
.form-check {
display: flex;
align-items: center;
justify-content: center;
width: auto;
padding-left: 0;
}
.form-check-input {
position: relative;
flex-shrink: 0;
margin-top: 0;
margin-right: $form-check-input-margin-x;
margin-left: 0;
}
.custom-control {
align-items: center;
justify-content: center;
}
.custom-control-label {
margin-bottom: 0;
}
}
}
@@ -1,190 +0,0 @@
// Bootstrap functions
//
// Utility mixins and functions for evaluating source code across our variables, maps, and mixins.
// Ascending
// Used to evaluate Sass maps like our grid breakpoints.
@mixin _assert-ascending($map, $map-name) {
$prev-key: null;
$prev-num: null;
@each $key, $num in $map {
@if $prev-num == null or unit($num) == "%" or unit($prev-num) == "%" {
// Do nothing
} @else if not comparable($prev-num, $num) {
@warn "Potentially invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} whose unit makes it incomparable to #{$prev-num}, the value of the previous key '#{$prev-key}' !";
} @else if $prev-num >= $num {
@warn "Invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} which isn't greater than #{$prev-num}, the value of the previous key '#{$prev-key}' !";
}
$prev-key: $key;
$prev-num: $num;
}
}
// Starts at zero
// Used to ensure the min-width of the lowest breakpoint starts at 0.
@mixin _assert-starts-at-zero($map, $map-name: "$grid-breakpoints") {
@if length($map) > 0 {
$values: map-values($map);
$first-value: nth($values, 1);
@if $first-value != 0 {
@warn "First breakpoint in #{$map-name} must start at 0, but starts at #{$first-value}.";
}
}
}
// Replace `$search` with `$replace` in `$string`
// Used on our SVG icon backgrounds for custom forms.
//
// @author Hugo Giraudel
// @param {String} $string - Initial string
// @param {String} $search - Substring to replace
// @param {String} $replace ('') - New value
// @return {String} - Updated string
@function str-replace($string, $search, $replace: "") {
$index: str-index($string, $search);
@if $index {
@return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
}
@return $string;
}
// See https://codepen.io/kevinweber/pen/dXWoRw
//
// Requires the use of quotes around data URIs.
@function escape-svg($string) {
@if str-index($string, "data:image/svg+xml") {
@each $char, $encoded in $escaped-characters {
// Do not escape the url brackets
@if str-index($string, "url(") == 1 {
$string: url("#{str-replace(str-slice($string, 6, -3), $char, $encoded)}");
} @else {
$string: str-replace($string, $char, $encoded);
}
}
}
@return $string;
}
// Color contrast
@function color-yiq($color, $dark: $yiq-text-dark, $light: $yiq-text-light) {
$r: red($color);
$g: green($color);
$b: blue($color);
$yiq: (($r * 299) + ($g * 587) + ($b * 114)) * .001;
@if ($yiq >= $yiq-contrasted-threshold) {
@return $dark;
} @else {
@return $light;
}
}
// Retrieve color Sass maps
@function color($key: "blue") {
@return map-get($colors, $key);
}
@function theme-color($key: "primary") {
@return map-get($theme-colors, $key);
}
@function gray($key: "100") {
@return map-get($grays, $key);
}
// Request a theme color level
@function theme-color-level($color-name: "primary", $level: 0) {
$color: theme-color($color-name);
$color-base: if($level > 0, $black, $white);
$level: abs($level);
@return mix($color-base, $color, $level * $theme-color-interval);
}
// Return valid calc
@function add($value1, $value2, $return-calc: true) {
@if $value1 == null {
@return $value2;
}
@if $value2 == null {
@return $value1;
}
@if type-of($value1) == number and type-of($value2) == number and comparable($value1, $value2) {
@return $value1 + $value2;
}
@return if($return-calc == true, calc(#{$value1} + #{$value2}), $value1 + unquote(" + ") + $value2);
}
@function subtract($value1, $value2, $return-calc: true) {
@if $value1 == null and $value2 == null {
@return null;
}
@if $value1 == null {
@return -$value2;
}
@if $value2 == null {
@return $value1;
}
@if type-of($value1) == number and type-of($value2) == number and comparable($value1, $value2) {
@return $value1 - $value2;
}
@if type-of($value2) != number {
$value2: unquote("(") + $value2 + unquote(")");
}
@return if($return-calc == true, calc(#{$value1} - #{$value2}), $value1 + unquote(" - ") + $value2);
}
@function divide($dividend, $divisor, $precision: 10) {
$sign: if($dividend > 0 and $divisor > 0 or $dividend < 0 and $divisor < 0, 1, -1);
$dividend: abs($dividend);
$divisor: abs($divisor);
@if $dividend == 0 {
@return 0;
}
@if $divisor == 0 {
@error "Cannot divide by 0";
}
$remainder: $dividend;
$result: 0;
$factor: 10;
@while ($remainder > 0 and $precision >= 0) {
$quotient: 0;
@while ($remainder >= $divisor) {
$remainder: $remainder - $divisor;
$quotient: $quotient + 1;
}
$result: $result * 10 + $quotient;
$factor: $factor * .1;
$remainder: $remainder * 10;
$precision: $precision - 1;
@if ($precision < 0 and $remainder >= $divisor * 5) {
$result: $result + 1;
}
}
$result: $result * $factor * $sign;
$dividend-unit: unit($dividend);
$divisor-unit: unit($divisor);
$unit-map: (
"px": 1px,
"rem": 1rem,
"em": 1em,
"%": 1%
);
@if ($dividend-unit != $divisor-unit and map-has-key($unit-map, $dividend-unit)) {
$result: $result * map-get($unit-map, $dividend-unit);
}
@return $result;
}
@@ -1,73 +0,0 @@
// Container widths
//
// Set the container width, and override it for fixed navbars in media queries.
@if $enable-grid-classes {
// Single container class with breakpoint max-widths
.container,
// 100% wide container at all breakpoints
.container-fluid {
@include make-container();
}
// Responsive containers that are 100% wide until a breakpoint
@each $breakpoint, $container-max-width in $container-max-widths {
.container-#{$breakpoint} {
@extend .container-fluid;
}
@include media-breakpoint-up($breakpoint, $grid-breakpoints) {
%responsive-container-#{$breakpoint} {
max-width: $container-max-width;
}
// Extend each breakpoint which is smaller or equal to the current breakpoint
$extend-breakpoint: true;
@each $name, $width in $grid-breakpoints {
@if ($extend-breakpoint) {
.container#{breakpoint-infix($name, $grid-breakpoints)} {
@extend %responsive-container-#{$breakpoint};
}
// Once the current breakpoint is reached, stop extending
@if ($breakpoint == $name) {
$extend-breakpoint: false;
}
}
}
}
}
}
// Row
//
// Rows contain your columns.
@if $enable-grid-classes {
.row {
@include make-row();
}
// Remove the negative margin from default .row, then the horizontal padding
// from all immediate children columns (to prevent runaway style inheritance).
.no-gutters {
margin-right: 0;
margin-left: 0;
> .col,
> [class*="col-"] {
padding-right: 0;
padding-left: 0;
}
}
}
// Columns
//
// Common styles for small and large grid columns
@if $enable-grid-classes {
@include make-grid-columns();
}
@@ -1,42 +0,0 @@
// Responsive images (ensure images don't scale beyond their parents)
//
// This is purposefully opt-in via an explicit class rather than being the default for all `<img>`s.
// We previously tried the "images are responsive by default" approach in Bootstrap v2,
// and abandoned it in Bootstrap v3 because it breaks lots of third-party widgets (including Google Maps)
// which weren't expecting the images within themselves to be involuntarily resized.
// See also https://github.com/twbs/bootstrap/issues/18178
.img-fluid {
@include img-fluid();
}
// Image thumbnails
.img-thumbnail {
padding: $thumbnail-padding;
background-color: $thumbnail-bg;
border: $thumbnail-border-width solid $thumbnail-border-color;
@include border-radius($thumbnail-border-radius);
@include box-shadow($thumbnail-box-shadow);
// Keep them at most 100% wide
@include img-fluid();
}
//
// Figures
//
.figure {
// Ensures the caption's text aligns with the image.
display: inline-block;
}
.figure-img {
margin-bottom: $spacer * .5;
line-height: 1;
}
.figure-caption {
@include font-size($figure-caption-font-size);
color: $figure-caption-color;
}
@@ -1,211 +0,0 @@
// stylelint-disable selector-no-qualifying-type
//
// Base styles
//
.input-group {
position: relative;
display: flex;
flex-wrap: wrap; // For form validation feedback
align-items: stretch;
width: 100%;
> .form-control,
> .form-control-plaintext,
> .custom-select,
> .custom-file {
position: relative; // For focus state's z-index
flex: 1 1 auto;
width: 1%;
min-width: 0; // https://stackoverflow.com/questions/36247140/why-dont-flex-items-shrink-past-content-size
margin-bottom: 0;
+ .form-control,
+ .custom-select,
+ .custom-file {
margin-left: -$input-border-width;
}
}
// Bring the "active" form control to the top of surrounding elements
> .form-control:focus,
> .custom-select:focus,
> .custom-file .custom-file-input:focus ~ .custom-file-label {
z-index: 3;
}
// Bring the custom file input above the label
> .custom-file .custom-file-input:focus {
z-index: 4;
}
> .form-control,
> .custom-select {
&:not(:first-child) { @include border-left-radius(0); }
}
// Custom file inputs have more complex markup, thus requiring different
// border-radius overrides.
> .custom-file {
display: flex;
align-items: center;
&:not(:last-child) .custom-file-label,
&:not(:last-child) .custom-file-label::after { @include border-right-radius(0); }
&:not(:first-child) .custom-file-label { @include border-left-radius(0); }
}
&:not(.has-validation) {
> .form-control:not(:last-child),
> .custom-select:not(:last-child),
> .custom-file:not(:last-child) .custom-file-label,
> .custom-file:not(:last-child) .custom-file-label::after {
@include border-right-radius(0);
}
}
&.has-validation {
> .form-control:nth-last-child(n + 3),
> .custom-select:nth-last-child(n + 3),
> .custom-file:nth-last-child(n + 3) .custom-file-label,
> .custom-file:nth-last-child(n + 3) .custom-file-label::after {
@include border-right-radius(0);
}
}
}
// Prepend and append
//
// While it requires one extra layer of HTML for each, dedicated prepend and
// append elements allow us to 1) be less clever, 2) simplify our selectors, and
// 3) support HTML5 form validation.
.input-group-prepend,
.input-group-append {
display: flex;
// Ensure buttons are always above inputs for more visually pleasing borders.
// This isn't needed for `.input-group-text` since it shares the same border-color
// as our inputs.
.btn {
position: relative;
z-index: 2;
&:focus {
z-index: 3;
}
}
.btn + .btn,
.btn + .input-group-text,
.input-group-text + .input-group-text,
.input-group-text + .btn {
margin-left: -$input-border-width;
}
}
.input-group-prepend { margin-right: -$input-border-width; }
.input-group-append { margin-left: -$input-border-width; }
// Textual addons
//
// Serves as a catch-all element for any text or radio/checkbox input you wish
// to prepend or append to an input.
.input-group-text {
display: flex;
align-items: center;
padding: $input-padding-y $input-padding-x;
margin-bottom: 0; // Allow use of <label> elements by overriding our default margin-bottom
@include font-size($input-font-size); // Match inputs
font-weight: $font-weight-normal;
line-height: $input-line-height;
color: $input-group-addon-color;
text-align: center;
white-space: nowrap;
background-color: $input-group-addon-bg;
border: $input-border-width solid $input-group-addon-border-color;
@include border-radius($input-border-radius);
// Nuke default margins from checkboxes and radios to vertically center within.
input[type="radio"],
input[type="checkbox"] {
margin-top: 0;
}
}
// Sizing
//
// Remix the default form control sizing classes into new ones for easier
// manipulation.
.input-group-lg > .form-control:not(textarea),
.input-group-lg > .custom-select {
height: $input-height-lg;
}
.input-group-lg > .form-control,
.input-group-lg > .custom-select,
.input-group-lg > .input-group-prepend > .input-group-text,
.input-group-lg > .input-group-append > .input-group-text,
.input-group-lg > .input-group-prepend > .btn,
.input-group-lg > .input-group-append > .btn {
padding: $input-padding-y-lg $input-padding-x-lg;
@include font-size($input-font-size-lg);
line-height: $input-line-height-lg;
@include border-radius($input-border-radius-lg);
}
.input-group-sm > .form-control:not(textarea),
.input-group-sm > .custom-select {
height: $input-height-sm;
}
.input-group-sm > .form-control,
.input-group-sm > .custom-select,
.input-group-sm > .input-group-prepend > .input-group-text,
.input-group-sm > .input-group-append > .input-group-text,
.input-group-sm > .input-group-prepend > .btn,
.input-group-sm > .input-group-append > .btn {
padding: $input-padding-y-sm $input-padding-x-sm;
@include font-size($input-font-size-sm);
line-height: $input-line-height-sm;
@include border-radius($input-border-radius-sm);
}
.input-group-lg > .custom-select,
.input-group-sm > .custom-select {
padding-right: $custom-select-padding-x + $custom-select-indicator-padding;
}
// Prepend and append rounded corners
//
// These rulesets must come after the sizing ones to properly override sm and lg
// border-radius values when extending. They're more specific than we'd like
// with the `.input-group >` part, but without it, we cannot override the sizing.
.input-group > .input-group-prepend > .btn,
.input-group > .input-group-prepend > .input-group-text,
.input-group:not(.has-validation) > .input-group-append:not(:last-child) > .btn,
.input-group:not(.has-validation) > .input-group-append:not(:last-child) > .input-group-text,
.input-group.has-validation > .input-group-append:nth-last-child(n + 3) > .btn,
.input-group.has-validation > .input-group-append:nth-last-child(n + 3) > .input-group-text,
.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle),
.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) {
@include border-right-radius(0);
}
.input-group > .input-group-append > .btn,
.input-group > .input-group-append > .input-group-text,
.input-group > .input-group-prepend:not(:first-child) > .btn,
.input-group > .input-group-prepend:not(:first-child) > .input-group-text,
.input-group > .input-group-prepend:first-child > .btn:not(:first-child),
.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) {
@include border-left-radius(0);
}
@@ -1,17 +0,0 @@
.jumbotron {
padding: $jumbotron-padding ($jumbotron-padding * .5);
margin-bottom: $jumbotron-padding;
color: $jumbotron-color;
background-color: $jumbotron-bg;
@include border-radius($border-radius-lg);
@include media-breakpoint-up(sm) {
padding: ($jumbotron-padding * 2) $jumbotron-padding;
}
}
.jumbotron-fluid {
padding-right: 0;
padding-left: 0;
@include border-radius(0);
}
@@ -1,154 +0,0 @@
// Base class
//
// Easily usable on <ul>, <ol>, or <div>.
.list-group {
display: flex;
flex-direction: column;
// No need to set list-style: none; since .list-group-item is block level
padding-left: 0; // reset padding because ul and ol
margin-bottom: 0;
@include border-radius($list-group-border-radius);
}
// Interactive list items
//
// Use anchor or button elements instead of `li`s or `div`s to create interactive
// list items. Includes an extra `.active` modifier class for selected items.
.list-group-item-action {
width: 100%; // For `<button>`s (anchors become 100% by default though)
color: $list-group-action-color;
text-align: inherit; // For `<button>`s (anchors inherit)
// Hover state
@include hover-focus() {
z-index: 1; // Place hover/focus items above their siblings for proper border styling
color: $list-group-action-hover-color;
text-decoration: none;
background-color: $list-group-hover-bg;
}
&:active {
color: $list-group-action-active-color;
background-color: $list-group-action-active-bg;
}
}
// Individual list items
//
// Use on `li`s or `div`s within the `.list-group` parent.
.list-group-item {
position: relative;
display: block;
padding: $list-group-item-padding-y $list-group-item-padding-x;
color: $list-group-color;
text-decoration: if($link-decoration == none, null, none);
background-color: $list-group-bg;
border: $list-group-border-width solid $list-group-border-color;
&:first-child {
@include border-top-radius(inherit);
}
&:last-child {
@include border-bottom-radius(inherit);
}
&.disabled,
&:disabled {
color: $list-group-disabled-color;
pointer-events: none;
background-color: $list-group-disabled-bg;
}
// Include both here for `<a>`s and `<button>`s
&.active {
z-index: 2; // Place active items above their siblings for proper border styling
color: $list-group-active-color;
background-color: $list-group-active-bg;
border-color: $list-group-active-border-color;
}
& + & {
border-top-width: 0;
&.active {
margin-top: -$list-group-border-width;
border-top-width: $list-group-border-width;
}
}
}
// Horizontal
//
// Change the layout of list group items from vertical (default) to horizontal.
@each $breakpoint in map-keys($grid-breakpoints) {
@include media-breakpoint-up($breakpoint) {
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
.list-group-horizontal#{$infix} {
flex-direction: row;
> .list-group-item {
&:first-child {
@include border-bottom-left-radius($list-group-border-radius);
@include border-top-right-radius(0);
}
&:last-child {
@include border-top-right-radius($list-group-border-radius);
@include border-bottom-left-radius(0);
}
&.active {
margin-top: 0;
}
+ .list-group-item {
border-top-width: $list-group-border-width;
border-left-width: 0;
&.active {
margin-left: -$list-group-border-width;
border-left-width: $list-group-border-width;
}
}
}
}
}
}
// Flush list items
//
// Remove borders and border-radius to keep list group items edge-to-edge. Most
// useful within other components (e.g., cards).
.list-group-flush {
@include border-radius(0);
> .list-group-item {
border-width: 0 0 $list-group-border-width;
&:last-child {
border-bottom-width: 0;
}
}
}
// Contextual variants
//
// Add modifier classes to change text and background color on individual items.
// Organizationally, this must come after the `:hover` states.
@each $color, $value in $theme-colors {
@include list-group-item-variant($color, theme-color-level($color, -9), theme-color-level($color, 6));
}
@@ -1,8 +0,0 @@
.media {
display: flex;
align-items: flex-start;
}
.media-body {
flex: 1;
}
@@ -1,47 +0,0 @@
// Toggles
//
// Used in conjunction with global variables to enable certain theme features.
// Vendor
@import "_vendor/rfs";
// Deprecate
@import "mixins/deprecate";
// Utilities
@import "mixins/breakpoints";
@import "mixins/hover";
@import "mixins/image";
@import "mixins/badge";
@import "mixins/resize";
@import "mixins/screen-reader";
@import "mixins/size";
@import "mixins/reset-text";
@import "mixins/text-emphasis";
@import "mixins/text-hide";
@import "mixins/text-truncate";
@import "mixins/visibility";
// Components
@import "mixins/alert";
@import "mixins/buttons";
@import "mixins/caret";
@import "mixins/pagination";
@import "mixins/lists";
@import "mixins/list-group";
@import "mixins/nav-divider";
@import "mixins/forms";
@import "mixins/table-row";
// Skins
@import "mixins/background-variant";
@import "mixins/border-radius";
@import "mixins/box-shadow";
@import "mixins/gradients";
@import "mixins/transition";
// Layout
@import "mixins/clearfix";
@import "mixins/grid-framework";
@import "mixins/grid";
@import "mixins/float";
@@ -1,240 +0,0 @@
// .modal-open - body class for killing the scroll
// .modal - container to scroll within
// .modal-dialog - positioning shell for the actual modal
// .modal-content - actual modal w/ bg and corners and stuff
.modal-open {
// Kill the scroll on the body
overflow: hidden;
.modal {
overflow-x: hidden;
overflow-y: auto;
}
}
// Container that the modal scrolls within
.modal {
position: fixed;
top: 0;
left: 0;
z-index: $zindex-modal;
display: none;
width: 100%;
height: 100%;
overflow: hidden;
// Prevent Chrome on Windows from adding a focus outline. For details, see
// https://github.com/twbs/bootstrap/pull/10951.
outline: 0;
// We deliberately don't use `-webkit-overflow-scrolling: touch;` due to a
// gnarly iOS Safari bug: https://bugs.webkit.org/show_bug.cgi?id=158342
// See also https://github.com/twbs/bootstrap/issues/17695
}
// Shell div to position the modal with bottom padding
.modal-dialog {
position: relative;
width: auto;
margin: $modal-dialog-margin;
// allow clicks to pass through for custom click handling to close modal
pointer-events: none;
// When fading in the modal, animate it to slide down
.modal.fade & {
@include transition($modal-transition);
transform: $modal-fade-transform;
}
.modal.show & {
transform: $modal-show-transform;
}
// When trying to close, animate focus to scale
.modal.modal-static & {
transform: $modal-scale-transform;
}
}
.modal-dialog-scrollable {
display: flex; // IE10/11
max-height: subtract(100%, $modal-dialog-margin * 2);
.modal-content {
max-height: subtract(100vh, $modal-dialog-margin * 2); // IE10/11
overflow: hidden;
}
.modal-header,
.modal-footer {
flex-shrink: 0;
}
.modal-body {
overflow-y: auto;
}
}
.modal-dialog-centered {
display: flex;
align-items: center;
min-height: subtract(100%, $modal-dialog-margin * 2);
// Ensure `modal-dialog-centered` extends the full height of the view (IE10/11)
&::before {
display: block; // IE10
height: subtract(100vh, $modal-dialog-margin * 2);
height: min-content; // Reset height to 0 except on IE
content: "";
}
// Ensure `.modal-body` shows scrollbar (IE10/11)
&.modal-dialog-scrollable {
flex-direction: column;
justify-content: center;
height: 100%;
.modal-content {
max-height: none;
}
&::before {
content: none;
}
}
}
// Actual modal
.modal-content {
position: relative;
display: flex;
flex-direction: column;
width: 100%; // Ensure `.modal-content` extends the full width of the parent `.modal-dialog`
// counteract the pointer-events: none; in the .modal-dialog
color: $modal-content-color;
pointer-events: auto;
background-color: $modal-content-bg;
background-clip: padding-box;
border: $modal-content-border-width solid $modal-content-border-color;
@include border-radius($modal-content-border-radius);
@include box-shadow($modal-content-box-shadow-xs);
// Remove focus outline from opened modal
outline: 0;
}
// Modal background
.modal-backdrop {
position: fixed;
top: 0;
left: 0;
z-index: $zindex-modal-backdrop;
width: 100vw;
height: 100vh;
background-color: $modal-backdrop-bg;
// Fade for backdrop
&.fade { opacity: 0; }
&.show { opacity: $modal-backdrop-opacity; }
}
// Modal header
// Top section of the modal w/ title and dismiss
.modal-header {
display: flex;
align-items: flex-start; // so the close btn always stays on the upper right corner
justify-content: space-between; // Put modal header elements (title and dismiss) on opposite ends
padding: $modal-header-padding;
border-bottom: $modal-header-border-width solid $modal-header-border-color;
@include border-top-radius($modal-content-inner-border-radius);
.close {
padding: $modal-header-padding;
// auto on the left force icon to the right even when there is no .modal-title
margin: (-$modal-header-padding-y) (-$modal-header-padding-x) (-$modal-header-padding-y) auto;
}
}
// Title text within header
.modal-title {
margin-bottom: 0;
line-height: $modal-title-line-height;
}
// Modal body
// Where all modal content resides (sibling of .modal-header and .modal-footer)
.modal-body {
position: relative;
// Enable `flex-grow: 1` so that the body take up as much space as possible
// when there should be a fixed height on `.modal-dialog`.
flex: 1 1 auto;
padding: $modal-inner-padding;
}
// Footer (for actions)
.modal-footer {
display: flex;
flex-wrap: wrap;
align-items: center; // vertically center
justify-content: flex-end; // Right align buttons with flex property because text-align doesn't work on flex items
padding: $modal-inner-padding - $modal-footer-margin-between * .5;
border-top: $modal-footer-border-width solid $modal-footer-border-color;
@include border-bottom-radius($modal-content-inner-border-radius);
// Place margin between footer elements
// This solution is far from ideal because of the universal selector usage,
// but is needed to fix https://github.com/twbs/bootstrap/issues/24800
> * {
margin: $modal-footer-margin-between * .5;
}
}
// Measure scrollbar width for padding body during modal show/hide
.modal-scrollbar-measure {
position: absolute;
top: -9999px;
width: 50px;
height: 50px;
overflow: scroll;
}
// Scale up the modal
@include media-breakpoint-up(sm) {
// Automatically set modal's width for larger viewports
.modal-dialog {
max-width: $modal-md;
margin: $modal-dialog-margin-y-sm-up auto;
}
.modal-dialog-scrollable {
max-height: subtract(100%, $modal-dialog-margin-y-sm-up * 2);
.modal-content {
max-height: subtract(100vh, $modal-dialog-margin-y-sm-up * 2);
}
}
.modal-dialog-centered {
min-height: subtract(100%, $modal-dialog-margin-y-sm-up * 2);
&::before {
height: subtract(100vh, $modal-dialog-margin-y-sm-up * 2);
height: min-content;
}
}
.modal-content {
@include box-shadow($modal-content-box-shadow-sm-up);
}
.modal-sm { max-width: $modal-sm; }
}
@include media-breakpoint-up(lg) {
.modal-lg,
.modal-xl {
max-width: $modal-lg;
}
}
@include media-breakpoint-up(xl) {
.modal-xl { max-width: $modal-xl; }
}
@@ -1,125 +0,0 @@
// Base class
//
// Kickstart any navigation component with a set of style resets. Works with
// `<nav>`s, `<ul>`s or `<ol>`s.
.nav {
display: flex;
flex-wrap: wrap;
padding-left: 0;
margin-bottom: 0;
list-style: none;
}
.nav-link {
display: block;
padding: $nav-link-padding-y $nav-link-padding-x;
text-decoration: if($link-decoration == none, null, none);
@include hover-focus() {
text-decoration: none;
}
// Disabled state lightens text
&.disabled {
color: $nav-link-disabled-color;
pointer-events: none;
cursor: default;
}
}
//
// Tabs
//
.nav-tabs {
border-bottom: $nav-tabs-border-width solid $nav-tabs-border-color;
.nav-link {
margin-bottom: -$nav-tabs-border-width;
background-color: transparent;
border: $nav-tabs-border-width solid transparent;
@include border-top-radius($nav-tabs-border-radius);
@include hover-focus() {
// Prevents active .nav-link tab overlapping focus outline of previous/next .nav-link
isolation: isolate;
border-color: $nav-tabs-link-hover-border-color;
}
&.disabled {
color: $nav-link-disabled-color;
background-color: transparent;
border-color: transparent;
}
}
.nav-link.active,
.nav-item.show .nav-link {
color: $nav-tabs-link-active-color;
background-color: $nav-tabs-link-active-bg;
border-color: $nav-tabs-link-active-border-color;
}
.dropdown-menu {
// Make dropdown border overlap tab border
margin-top: -$nav-tabs-border-width;
// Remove the top rounded corners here since there is a hard edge above the menu
@include border-top-radius(0);
}
}
//
// Pills
//
.nav-pills {
.nav-link {
background: none;
border: 0;
@include border-radius($nav-pills-border-radius);
}
.nav-link.active,
.show > .nav-link {
color: $nav-pills-link-active-color;
background-color: $nav-pills-link-active-bg;
}
}
//
// Justified variants
//
.nav-fill {
> .nav-link,
.nav-item {
flex: 1 1 auto;
text-align: center;
}
}
.nav-justified {
> .nav-link,
.nav-item {
flex-basis: 0;
flex-grow: 1;
text-align: center;
}
}
// Tabbable tabs
//
// Hide tabbable panes to start, show them when `.active`
.tab-content {
> .tab-pane {
display: none;
}
> .active {
display: block;
}
}
@@ -1,332 +0,0 @@
// Contents
//
// Navbar
// Navbar brand
// Navbar nav
// Navbar text
// Navbar divider
// Responsive navbar
// Navbar position
// Navbar themes
// Navbar
//
// Provide a static navbar from which we expand to create full-width, fixed, and
// other navbar variations.
.navbar {
position: relative;
display: flex;
flex-wrap: wrap; // allow us to do the line break for collapsing content
align-items: center;
justify-content: space-between; // space out brand from logo
padding: $navbar-padding-y $navbar-padding-x;
// Because flex properties aren't inherited, we need to redeclare these first
// few properties so that content nested within behave properly.
%container-flex-properties {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
}
.container,
.container-fluid {
@extend %container-flex-properties;
}
@each $breakpoint, $container-max-width in $container-max-widths {
> .container#{breakpoint-infix($breakpoint, $container-max-widths)} {
@extend %container-flex-properties;
}
}
}
// Navbar brand
//
// Used for brand, project, or site names.
.navbar-brand {
display: inline-block;
padding-top: $navbar-brand-padding-y;
padding-bottom: $navbar-brand-padding-y;
margin-right: $navbar-padding-x;
@include font-size($navbar-brand-font-size);
line-height: inherit;
white-space: nowrap;
@include hover-focus() {
text-decoration: none;
}
}
// Navbar nav
//
// Custom navbar navigation (doesn't require `.nav`, but does make use of `.nav-link`).
.navbar-nav {
display: flex;
flex-direction: column; // cannot use `inherit` to get the `.navbar`s value
padding-left: 0;
margin-bottom: 0;
list-style: none;
.nav-link {
padding-right: 0;
padding-left: 0;
}
.dropdown-menu {
position: static;
float: none;
}
}
// Navbar text
//
//
.navbar-text {
display: inline-block;
padding-top: $nav-link-padding-y;
padding-bottom: $nav-link-padding-y;
}
// Responsive navbar
//
// Custom styles for responsive collapsing and toggling of navbar contents.
// Powered by the collapse Bootstrap JavaScript plugin.
// When collapsed, prevent the toggleable navbar contents from appearing in
// the default flexbox row orientation. Requires the use of `flex-wrap: wrap`
// on the `.navbar` parent.
.navbar-collapse {
flex-basis: 100%;
flex-grow: 1;
// For always expanded or extra full navbars, ensure content aligns itself
// properly vertically. Can be easily overridden with flex utilities.
align-items: center;
}
// Button for toggling the navbar when in its collapsed state
.navbar-toggler {
padding: $navbar-toggler-padding-y $navbar-toggler-padding-x;
@include font-size($navbar-toggler-font-size);
line-height: 1;
background-color: transparent; // remove default button style
border: $border-width solid transparent; // remove default button style
@include border-radius($navbar-toggler-border-radius);
@include hover-focus() {
text-decoration: none;
}
}
// Keep as a separate element so folks can easily override it with another icon
// or image file as needed.
.navbar-toggler-icon {
display: inline-block;
width: 1.5em;
height: 1.5em;
vertical-align: middle;
content: "";
background: 50% / 100% 100% no-repeat;
}
.navbar-nav-scroll {
max-height: $navbar-nav-scroll-max-height;
overflow-y: auto;
}
// Generate series of `.navbar-expand-*` responsive classes for configuring
// where your navbar collapses.
.navbar-expand {
@each $breakpoint in map-keys($grid-breakpoints) {
$next: breakpoint-next($breakpoint, $grid-breakpoints);
$infix: breakpoint-infix($next, $grid-breakpoints);
&#{$infix} {
@include media-breakpoint-down($breakpoint) {
%container-navbar-expand-#{$breakpoint} {
padding-right: 0;
padding-left: 0;
}
> .container,
> .container-fluid {
@extend %container-navbar-expand-#{$breakpoint};
}
@each $size, $container-max-width in $container-max-widths {
> .container#{breakpoint-infix($size, $container-max-widths)} {
@extend %container-navbar-expand-#{$breakpoint};
}
}
}
@include media-breakpoint-up($next) {
flex-flow: row nowrap;
justify-content: flex-start;
.navbar-nav {
flex-direction: row;
.dropdown-menu {
position: absolute;
}
.nav-link {
padding-right: $navbar-nav-link-padding-x;
padding-left: $navbar-nav-link-padding-x;
}
}
// For nesting containers, have to redeclare for alignment purposes
%container-nesting-#{$breakpoint} {
flex-wrap: nowrap;
}
> .container,
> .container-fluid {
@extend %container-nesting-#{$breakpoint};
}
@each $size, $container-max-width in $container-max-widths {
> .container#{breakpoint-infix($size, $container-max-widths)} {
@extend %container-nesting-#{$breakpoint};
}
}
.navbar-nav-scroll {
overflow: visible;
}
.navbar-collapse {
display: flex !important; // stylelint-disable-line declaration-no-important
// Changes flex-bases to auto because of an IE10 bug
flex-basis: auto;
}
.navbar-toggler {
display: none;
}
}
}
}
}
// Navbar themes
//
// Styles for switching between navbars with light or dark background.
// Dark links against a light background
.navbar-light {
.navbar-brand {
color: $navbar-light-brand-color;
@include hover-focus() {
color: $navbar-light-brand-hover-color;
}
}
.navbar-nav {
.nav-link {
color: $navbar-light-color;
@include hover-focus() {
color: $navbar-light-hover-color;
}
&.disabled {
color: $navbar-light-disabled-color;
}
}
.show > .nav-link,
.active > .nav-link,
.nav-link.show,
.nav-link.active {
color: $navbar-light-active-color;
}
}
.navbar-toggler {
color: $navbar-light-color;
border-color: $navbar-light-toggler-border-color;
}
.navbar-toggler-icon {
background-image: escape-svg($navbar-light-toggler-icon-bg);
}
.navbar-text {
color: $navbar-light-color;
a {
color: $navbar-light-active-color;
@include hover-focus() {
color: $navbar-light-active-color;
}
}
}
}
// White links against a dark background
.navbar-dark {
.navbar-brand {
color: $navbar-dark-brand-color;
@include hover-focus() {
color: $navbar-dark-brand-hover-color;
}
}
.navbar-nav {
.nav-link {
color: $navbar-dark-color;
@include hover-focus() {
color: $navbar-dark-hover-color;
}
&.disabled {
color: $navbar-dark-disabled-color;
}
}
.show > .nav-link,
.active > .nav-link,
.nav-link.show,
.nav-link.active {
color: $navbar-dark-active-color;
}
}
.navbar-toggler {
color: $navbar-dark-color;
border-color: $navbar-dark-toggler-border-color;
}
.navbar-toggler-icon {
background-image: escape-svg($navbar-dark-toggler-icon-bg);
}
.navbar-text {
color: $navbar-dark-color;
a {
color: $navbar-dark-active-color;
@include hover-focus() {
color: $navbar-dark-active-color;
}
}
}
}
@@ -1,74 +0,0 @@
.pagination {
display: flex;
@include list-unstyled();
@include border-radius();
}
.page-link {
position: relative;
display: block;
padding: $pagination-padding-y $pagination-padding-x;
margin-left: -$pagination-border-width;
line-height: $pagination-line-height;
color: $pagination-color;
text-decoration: if($link-decoration == none, null, none);
background-color: $pagination-bg;
border: $pagination-border-width solid $pagination-border-color;
&:hover {
z-index: 2;
color: $pagination-hover-color;
text-decoration: none;
background-color: $pagination-hover-bg;
border-color: $pagination-hover-border-color;
}
&:focus {
z-index: 3;
outline: $pagination-focus-outline;
box-shadow: $pagination-focus-box-shadow;
}
}
.page-item {
&:first-child {
.page-link {
margin-left: 0;
@include border-left-radius($border-radius);
}
}
&:last-child {
.page-link {
@include border-right-radius($border-radius);
}
}
&.active .page-link {
z-index: 3;
color: $pagination-active-color;
background-color: $pagination-active-bg;
border-color: $pagination-active-border-color;
}
&.disabled .page-link {
color: $pagination-disabled-color;
pointer-events: none;
// Opinionated: remove the "hand" cursor set previously for .page-link
cursor: auto;
background-color: $pagination-disabled-bg;
border-color: $pagination-disabled-border-color;
}
}
//
// Sizing
//
.pagination-lg {
@include pagination-size($pagination-padding-y-lg, $pagination-padding-x-lg, $font-size-lg, $line-height-lg, $pagination-border-radius-lg);
}
.pagination-sm {
@include pagination-size($pagination-padding-y-sm, $pagination-padding-x-sm, $font-size-sm, $line-height-sm, $pagination-border-radius-sm);
}
@@ -1,170 +0,0 @@
.popover {
position: absolute;
top: 0;
left: 0;
z-index: $zindex-popover;
display: block;
max-width: $popover-max-width;
// Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.
// So reset our font and text properties to avoid inheriting weird values.
@include reset-text();
@include font-size($popover-font-size);
// Allow breaking very long words so they don't overflow the popover's bounds
word-wrap: break-word;
background-color: $popover-bg;
background-clip: padding-box;
border: $popover-border-width solid $popover-border-color;
@include border-radius($popover-border-radius);
@include box-shadow($popover-box-shadow);
.arrow {
position: absolute;
display: block;
width: $popover-arrow-width;
height: $popover-arrow-height;
margin: 0 $popover-border-radius;
&::before,
&::after {
position: absolute;
display: block;
content: "";
border-color: transparent;
border-style: solid;
}
}
}
.bs-popover-top {
margin-bottom: $popover-arrow-height;
> .arrow {
bottom: subtract(-$popover-arrow-height, $popover-border-width);
&::before {
bottom: 0;
border-width: $popover-arrow-height ($popover-arrow-width * .5) 0;
border-top-color: $popover-arrow-outer-color;
}
&::after {
bottom: $popover-border-width;
border-width: $popover-arrow-height ($popover-arrow-width * .5) 0;
border-top-color: $popover-arrow-color;
}
}
}
.bs-popover-right {
margin-left: $popover-arrow-height;
> .arrow {
left: subtract(-$popover-arrow-height, $popover-border-width);
width: $popover-arrow-height;
height: $popover-arrow-width;
margin: $popover-border-radius 0; // make sure the arrow does not touch the popover's rounded corners
&::before {
left: 0;
border-width: ($popover-arrow-width * .5) $popover-arrow-height ($popover-arrow-width * .5) 0;
border-right-color: $popover-arrow-outer-color;
}
&::after {
left: $popover-border-width;
border-width: ($popover-arrow-width * .5) $popover-arrow-height ($popover-arrow-width * .5) 0;
border-right-color: $popover-arrow-color;
}
}
}
.bs-popover-bottom {
margin-top: $popover-arrow-height;
> .arrow {
top: subtract(-$popover-arrow-height, $popover-border-width);
&::before {
top: 0;
border-width: 0 ($popover-arrow-width * .5) $popover-arrow-height ($popover-arrow-width * .5);
border-bottom-color: $popover-arrow-outer-color;
}
&::after {
top: $popover-border-width;
border-width: 0 ($popover-arrow-width * .5) $popover-arrow-height ($popover-arrow-width * .5);
border-bottom-color: $popover-arrow-color;
}
}
// This will remove the popover-header's border just below the arrow
.popover-header::before {
position: absolute;
top: 0;
left: 50%;
display: block;
width: $popover-arrow-width;
margin-left: -$popover-arrow-width * .5;
content: "";
border-bottom: $popover-border-width solid $popover-header-bg;
}
}
.bs-popover-left {
margin-right: $popover-arrow-height;
> .arrow {
right: subtract(-$popover-arrow-height, $popover-border-width);
width: $popover-arrow-height;
height: $popover-arrow-width;
margin: $popover-border-radius 0; // make sure the arrow does not touch the popover's rounded corners
&::before {
right: 0;
border-width: ($popover-arrow-width * .5) 0 ($popover-arrow-width * .5) $popover-arrow-height;
border-left-color: $popover-arrow-outer-color;
}
&::after {
right: $popover-border-width;
border-width: ($popover-arrow-width * .5) 0 ($popover-arrow-width * .5) $popover-arrow-height;
border-left-color: $popover-arrow-color;
}
}
}
.bs-popover-auto {
&[x-placement^="top"] {
@extend .bs-popover-top;
}
&[x-placement^="right"] {
@extend .bs-popover-right;
}
&[x-placement^="bottom"] {
@extend .bs-popover-bottom;
}
&[x-placement^="left"] {
@extend .bs-popover-left;
}
}
// Offset the popover to account for the popover arrow
.popover-header {
padding: $popover-header-padding-y $popover-header-padding-x;
margin-bottom: 0; // Reset the default from Reboot
@include font-size($font-size-base);
color: $popover-header-color;
background-color: $popover-header-bg;
border-bottom: $popover-border-width solid darken($popover-header-bg, 5%);
@include border-top-radius($popover-inner-border-radius);
&:empty {
display: none;
}
}
.popover-body {
padding: $popover-body-padding-y $popover-body-padding-x;
color: $popover-body-color;
}
@@ -1,132 +0,0 @@
// stylelint-disable declaration-no-important, selector-no-qualifying-type
// Source: https://github.com/h5bp/main.css/blob/master/src/_print.css
// ==========================================================================
// Print styles.
// Inlined to avoid the additional HTTP request:
// https://www.phpied.com/delay-loading-your-print-css/
// ==========================================================================
@if $enable-print-styles {
@media print {
*,
*::before,
*::after {
// Bootstrap specific; comment out `color` and `background`
//color: $black !important; // Black prints faster
text-shadow: none !important;
//background: transparent !important;
box-shadow: none !important;
}
a {
&:not(.btn) {
text-decoration: underline;
}
}
// Bootstrap specific; comment the following selector out
//a[href]::after {
// content: " (" attr(href) ")";
//}
abbr[title]::after {
content: " (" attr(title) ")";
}
// Bootstrap specific; comment the following selector out
//
// Don't show links that are fragment identifiers,
// or use the `javascript:` pseudo protocol
//
//a[href^="#"]::after,
//a[href^="javascript:"]::after {
// content: "";
//}
pre {
white-space: pre-wrap !important;
}
pre,
blockquote {
border: $border-width solid $gray-500; // Bootstrap custom code; using `$border-width` instead of 1px
page-break-inside: avoid;
}
tr,
img {
page-break-inside: avoid;
}
p,
h2,
h3 {
orphans: 3;
widows: 3;
}
h2,
h3 {
page-break-after: avoid;
}
// Bootstrap specific changes start
// Specify a size and min-width to make printing closer across browsers.
// We don't set margin here because it breaks `size` in Chrome. We also
// don't use `!important` on `size` as it breaks in Chrome.
@page {
size: $print-page-size;
}
body {
min-width: $print-body-min-width !important;
}
.container {
min-width: $print-body-min-width !important;
}
// Bootstrap components
.navbar {
display: none;
}
.badge {
border: $border-width solid $black;
}
.table {
border-collapse: collapse !important;
td,
th {
background-color: $white !important;
}
}
.table-bordered {
th,
td {
border: 1px solid $gray-300 !important;
}
}
.table-dark {
color: inherit;
th,
td,
thead th,
tbody + tbody {
border-color: $table-border-color;
}
}
.table .thead-dark th {
color: inherit;
border-color: $table-border-color;
}
// Bootstrap specific changes end
}
}
@@ -1,47 +0,0 @@
// Disable animation if transitions are disabled
@if $enable-transitions {
@keyframes progress-bar-stripes {
from { background-position: $progress-height 0; }
to { background-position: 0 0; }
}
}
.progress {
display: flex;
height: $progress-height;
overflow: hidden; // force rounded corners by cropping it
line-height: 0;
@include font-size($progress-font-size);
background-color: $progress-bg;
@include border-radius($progress-border-radius);
@include box-shadow($progress-box-shadow);
}
.progress-bar {
display: flex;
flex-direction: column;
justify-content: center;
overflow: hidden;
color: $progress-bar-color;
text-align: center;
white-space: nowrap;
background-color: $progress-bar-bg;
@include transition($progress-bar-transition);
}
.progress-bar-striped {
@include gradient-striped();
background-size: $progress-height $progress-height;
}
@if $enable-transitions {
.progress-bar-animated {
animation: $progress-bar-animation-timing progress-bar-stripes;
@if $enable-prefers-reduced-motion-media-query {
@media (prefers-reduced-motion: reduce) {
animation: none;
}
}
}
}
@@ -1,484 +0,0 @@
// stylelint-disable declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix
// Reboot
//
// Normalization of HTML elements, manually forked from Normalize.css to remove
// styles targeting irrelevant browsers while applying new styles.
//
// Normalize is licensed MIT. https://github.com/necolas/normalize.css
// Document
//
// 1. Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.
// 2. Change the default font family in all browsers.
// 3. Correct the line height in all browsers.
// 4. Prevent adjustments of font size after orientation changes in IE on Windows Phone and in iOS.
// 5. Change the default tap highlight to be completely transparent in iOS.
*,
*::before,
*::after {
box-sizing: border-box; // 1
}
html {
font-family: sans-serif; // 2
line-height: 1.15; // 3
-webkit-text-size-adjust: 100%; // 4
-webkit-tap-highlight-color: rgba($black, 0); // 5
}
// Shim for "new" HTML5 structural elements to display correctly (IE10, older browsers)
// TODO: remove in v5
// stylelint-disable-next-line selector-list-comma-newline-after
article, aside, figcaption, figure, footer, header, hgroup, main, nav, section {
display: block;
}
// Body
//
// 1. Remove the margin in all browsers.
// 2. As a best practice, apply a default `background-color`.
// 3. Set an explicit initial text-align value so that we can later use
// the `inherit` value on things like `<th>` elements.
body {
margin: 0; // 1
font-family: $font-family-base;
@include font-size($font-size-base);
font-weight: $font-weight-base;
line-height: $line-height-base;
color: $body-color;
text-align: left; // 3
background-color: $body-bg; // 2
}
// Future-proof rule: in browsers that support :focus-visible, suppress the focus outline
// on elements that programmatically receive focus but wouldn't normally show a visible
// focus outline. In general, this would mean that the outline is only applied if the
// interaction that led to the element receiving programmatic focus was a keyboard interaction,
// or the browser has somehow determined that the user is primarily a keyboard user and/or
// wants focus outlines to always be presented.
//
// See https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible
// and https://developer.paciellogroup.com/blog/2018/03/focus-visible-and-backwards-compatibility/
[tabindex="-1"]:focus:not(:focus-visible) {
outline: 0 !important;
}
// Content grouping
//
// 1. Add the correct box sizing in Firefox.
// 2. Show the overflow in Edge and IE.
hr {
box-sizing: content-box; // 1
height: 0; // 1
overflow: visible; // 2
}
//
// Typography
//
// Remove top margins from headings
//
// By default, `<h1>`-`<h6>` all receive top and bottom margins. We nuke the top
// margin for easier control within type scales as it avoids margin collapsing.
// stylelint-disable-next-line selector-list-comma-newline-after
h1, h2, h3, h4, h5, h6 {
margin-top: 0;
margin-bottom: $headings-margin-bottom;
}
// Reset margins on paragraphs
//
// Similarly, the top margin on `<p>`s get reset. However, we also reset the
// bottom margin to use `rem` units instead of `em`.
p {
margin-top: 0;
margin-bottom: $paragraph-margin-bottom;
}
// Abbreviations
//
// 1. Duplicate behavior to the data-* attribute for our tooltip plugin
// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
// 3. Add explicit cursor to indicate changed behavior.
// 4. Remove the bottom border in Firefox 39-.
// 5. Prevent the text-decoration to be skipped.
abbr[title],
abbr[data-original-title] { // 1
text-decoration: underline; // 2
text-decoration: underline dotted; // 2
cursor: help; // 3
border-bottom: 0; // 4
text-decoration-skip-ink: none; // 5
}
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: $dt-font-weight;
}
dd {
margin-bottom: .5rem;
margin-left: 0; // Undo browser default
}
blockquote {
margin: 0 0 1rem;
}
b,
strong {
font-weight: $font-weight-bolder; // Add the correct font weight in Chrome, Edge, and Safari
}
small {
@include font-size(80%); // Add the correct font size in all browsers
}
//
// Prevent `sub` and `sup` elements from affecting the line height in
// all browsers.
//
sub,
sup {
position: relative;
@include font-size(75%);
line-height: 0;
vertical-align: baseline;
}
sub { bottom: -.25em; }
sup { top: -.5em; }
//
// Links
//
a {
color: $link-color;
text-decoration: $link-decoration;
background-color: transparent; // Remove the gray background on active links in IE 10.
@include hover() {
color: $link-hover-color;
text-decoration: $link-hover-decoration;
}
}
// And undo these styles for placeholder links/named anchors (without href).
// It would be more straightforward to just use a[href] in previous block, but that
// causes specificity issues in many other styles that are too complex to fix.
// See https://github.com/twbs/bootstrap/issues/19402
a:not([href]):not([class]) {
color: inherit;
text-decoration: none;
@include hover() {
color: inherit;
text-decoration: none;
}
}
//
// Code
//
pre,
code,
kbd,
samp {
font-family: $font-family-monospace;
@include font-size(1em); // Correct the odd `em` font sizing in all browsers.
}
pre {
// Remove browser default top margin
margin-top: 0;
// Reset browser default of `1em` to use `rem`s
margin-bottom: 1rem;
// Don't allow content to break outside
overflow: auto;
// Disable auto-hiding scrollbar in IE & legacy Edge to avoid overlap,
// making it impossible to interact with the content
-ms-overflow-style: scrollbar;
}
//
// Figures
//
figure {
// Apply a consistent margin strategy (matches our type styles).
margin: 0 0 1rem;
}
//
// Images and content
//
img {
vertical-align: middle;
border-style: none; // Remove the border on images inside links in IE 10-.
}
svg {
// Workaround for the SVG overflow bug in IE10/11 is still required.
// See https://github.com/twbs/bootstrap/issues/26878
overflow: hidden;
vertical-align: middle;
}
//
// Tables
//
table {
border-collapse: collapse; // Prevent double borders
}
caption {
padding-top: $table-cell-padding;
padding-bottom: $table-cell-padding;
color: $table-caption-color;
text-align: left;
caption-side: bottom;
}
// 1. Removes font-weight bold by inheriting
// 2. Matches default `<td>` alignment by inheriting `text-align`.
// 3. Fix alignment for Safari
th {
font-weight: $table-th-font-weight; // 1
text-align: inherit; // 2
text-align: -webkit-match-parent; // 3
}
//
// Forms
//
label {
// Allow labels to use `margin` for spacing.
display: inline-block;
margin-bottom: $label-margin-bottom;
}
// Remove the default `border-radius` that macOS Chrome adds.
//
// Details at https://github.com/twbs/bootstrap/issues/24093
button {
// stylelint-disable-next-line property-disallowed-list
border-radius: 0;
}
// Explicitly remove focus outline in Chromium when it shouldn't be
// visible (e.g. as result of mouse click or touch tap). It already
// should be doing this automatically, but seems to currently be
// confused and applies its very visible two-tone outline anyway.
button:focus:not(:focus-visible) {
outline: 0;
}
input,
button,
select,
optgroup,
textarea {
margin: 0; // Remove the margin in Firefox and Safari
font-family: inherit;
@include font-size(inherit);
line-height: inherit;
}
button,
input {
overflow: visible; // Show the overflow in Edge
}
button,
select {
text-transform: none; // Remove the inheritance of text transform in Firefox
}
// Set the cursor for non-`<button>` buttons
//
// Details at https://github.com/twbs/bootstrap/pull/30562
[role="button"] {
cursor: pointer;
}
// Remove the inheritance of word-wrap in Safari.
//
// Details at https://github.com/twbs/bootstrap/issues/24990
select {
word-wrap: normal;
}
// 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
// controls in Android 4.
// 2. Correct the inability to style clickable types in iOS and Safari.
button,
[type="button"], // 1
[type="reset"],
[type="submit"] {
-webkit-appearance: button; // 2
}
// Opinionated: add "hand" cursor to non-disabled button elements.
@if $enable-pointer-cursor-for-buttons {
button,
[type="button"],
[type="reset"],
[type="submit"] {
&:not(:disabled) {
cursor: pointer;
}
}
}
// Remove inner border and padding from Firefox, but don't restore the outline like Normalize.
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
padding: 0;
border-style: none;
}
input[type="radio"],
input[type="checkbox"] {
box-sizing: border-box; // 1. Add the correct box sizing in IE 10-
padding: 0; // 2. Remove the padding in IE 10-
}
textarea {
overflow: auto; // Remove the default vertical scrollbar in IE.
// Textareas should really only resize vertically so they don't break their (horizontal) containers.
resize: vertical;
}
fieldset {
// Browsers set a default `min-width: min-content;` on fieldsets,
// unlike e.g. `<div>`s, which have `min-width: 0;` by default.
// So we reset that to ensure fieldsets behave more like a standard block element.
// See https://github.com/twbs/bootstrap/issues/12359
// and https://html.spec.whatwg.org/multipage/#the-fieldset-and-legend-elements
min-width: 0;
// Reset the default outline behavior of fieldsets so they don't affect page layout.
padding: 0;
margin: 0;
border: 0;
}
// 1. Correct the text wrapping in Edge and IE.
// 2. Correct the color inheritance from `fieldset` elements in IE.
legend {
display: block;
width: 100%;
max-width: 100%; // 1
padding: 0;
margin-bottom: .5rem;
@include font-size(1.5rem);
line-height: inherit;
color: inherit; // 2
white-space: normal; // 1
}
progress {
vertical-align: baseline; // Add the correct vertical alignment in Chrome, Firefox, and Opera.
}
// Correct the cursor style of increment and decrement buttons in Chrome.
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
[type="search"] {
// This overrides the extra rounded corners on search inputs in iOS so that our
// `.form-control` class can properly style them. Note that this cannot simply
// be added to `.form-control` as it's not specific enough. For details, see
// https://github.com/twbs/bootstrap/issues/11586.
outline-offset: -2px; // 2. Correct the outline style in Safari.
-webkit-appearance: none;
}
//
// Remove the inner padding in Chrome and Safari on macOS.
//
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
//
// 1. Correct the inability to style clickable types in iOS and Safari.
// 2. Change font properties to `inherit` in Safari.
//
::-webkit-file-upload-button {
font: inherit; // 2
-webkit-appearance: button; // 1
}
//
// Correct element displays
//
output {
display: inline-block;
}
summary {
display: list-item; // Add the correct display in all browsers
cursor: pointer;
}
template {
display: none; // Add the correct display in IE
}
// Always hide an element with the `hidden` HTML attribute (from PureCSS).
// Needed for proper display in IE 10-.
[hidden] {
display: none !important;
}
@@ -1,19 +0,0 @@
:root {
// Custom variable values only support SassScript inside `#{}`.
@each $color, $value in $colors {
--#{$color}: #{$value};
}
@each $color, $value in $theme-colors {
--#{$color}: #{$value};
}
@each $bp, $value in $grid-breakpoints {
--breakpoint-#{$bp}: #{$value};
}
// Use `inspect` for lists so that quoted items keep the quotes.
// See https://github.com/sass/sass/issues/2383#issuecomment-336349172
--font-family-sans-serif: #{inspect($font-family-sans-serif)};
--font-family-monospace: #{inspect($font-family-monospace)};
}
@@ -1,65 +0,0 @@
//
// Rotating border
//
@keyframes spinner-border {
to { transform: rotate(360deg); }
}
.spinner-border {
display: inline-block;
width: $spinner-width;
height: $spinner-height;
vertical-align: $spinner-vertical-align;
border: $spinner-border-width solid currentcolor;
border-right-color: transparent;
// stylelint-disable-next-line property-disallowed-list
border-radius: 50%;
animation: .75s linear infinite spinner-border;
}
.spinner-border-sm {
width: $spinner-width-sm;
height: $spinner-height-sm;
border-width: $spinner-border-width-sm;
}
//
// Growing circle
//
@keyframes spinner-grow {
0% {
transform: scale(0);
}
50% {
opacity: 1;
transform: none;
}
}
.spinner-grow {
display: inline-block;
width: $spinner-width;
height: $spinner-height;
vertical-align: $spinner-vertical-align;
background-color: currentcolor;
// stylelint-disable-next-line property-disallowed-list
border-radius: 50%;
opacity: 0;
animation: .75s linear infinite spinner-grow;
}
.spinner-grow-sm {
width: $spinner-width-sm;
height: $spinner-height-sm;
}
@if $enable-prefers-reduced-motion-media-query {
@media (prefers-reduced-motion: reduce) {
.spinner-border,
.spinner-grow {
animation-duration: 1.5s;
}
}
}
@@ -1,185 +0,0 @@
//
// Basic Bootstrap table
//
.table {
width: 100%;
margin-bottom: $spacer;
color: $table-color;
background-color: $table-bg; // Reset for nesting within parents with `background-color`.
th,
td {
padding: $table-cell-padding;
vertical-align: top;
border-top: $table-border-width solid $table-border-color;
}
thead th {
vertical-align: bottom;
border-bottom: (2 * $table-border-width) solid $table-border-color;
}
tbody + tbody {
border-top: (2 * $table-border-width) solid $table-border-color;
}
}
//
// Condensed table w/ half padding
//
.table-sm {
th,
td {
padding: $table-cell-padding-sm;
}
}
// Border versions
//
// Add or remove borders all around the table and between all the columns.
.table-bordered {
border: $table-border-width solid $table-border-color;
th,
td {
border: $table-border-width solid $table-border-color;
}
thead {
th,
td {
border-bottom-width: 2 * $table-border-width;
}
}
}
.table-borderless {
th,
td,
thead th,
tbody + tbody {
border: 0;
}
}
// Zebra-striping
//
// Default zebra-stripe styles (alternating gray and transparent backgrounds)
.table-striped {
tbody tr:nth-of-type(#{$table-striped-order}) {
background-color: $table-accent-bg;
}
}
// Hover effect
//
// Placed here since it has to come after the potential zebra striping
.table-hover {
tbody tr {
@include hover() {
color: $table-hover-color;
background-color: $table-hover-bg;
}
}
}
// Table backgrounds
//
// Exact selectors below required to override `.table-striped` and prevent
// inheritance to nested tables.
@each $color, $value in $theme-colors {
@include table-row-variant($color, theme-color-level($color, $table-bg-level), theme-color-level($color, $table-border-level));
}
@include table-row-variant(active, $table-active-bg);
// Dark styles
//
// Same table markup, but inverted color scheme: dark background and light text.
// stylelint-disable-next-line no-duplicate-selectors
.table {
.thead-dark {
th {
color: $table-dark-color;
background-color: $table-dark-bg;
border-color: $table-dark-border-color;
}
}
.thead-light {
th {
color: $table-head-color;
background-color: $table-head-bg;
border-color: $table-border-color;
}
}
}
.table-dark {
color: $table-dark-color;
background-color: $table-dark-bg;
th,
td,
thead th {
border-color: $table-dark-border-color;
}
&.table-bordered {
border: 0;
}
&.table-striped {
tbody tr:nth-of-type(#{$table-striped-order}) {
background-color: $table-dark-accent-bg;
}
}
&.table-hover {
tbody tr {
@include hover() {
color: $table-dark-hover-color;
background-color: $table-dark-hover-bg;
}
}
}
}
// Responsive tables
//
// Generate series of `.table-responsive-*` classes for configuring the screen
// size of where your table will overflow.
.table-responsive {
@each $breakpoint in map-keys($grid-breakpoints) {
$next: breakpoint-next($breakpoint, $grid-breakpoints);
$infix: breakpoint-infix($next, $grid-breakpoints);
&#{$infix} {
@include media-breakpoint-down($breakpoint) {
display: block;
width: 100%;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
// Prevent double border on horizontal scroll due to use of `display: block;`
> .table-bordered {
border: 0;
}
}
}
}
}
@@ -1,46 +0,0 @@
.toast {
// Prevents from shrinking in IE11, when in a flex container
// See https://github.com/twbs/bootstrap/issues/28341
flex-basis: $toast-max-width;
max-width: $toast-max-width;
@include font-size($toast-font-size);
color: $toast-color;
background-color: $toast-background-color;
background-clip: padding-box;
border: $toast-border-width solid $toast-border-color;
box-shadow: $toast-box-shadow;
opacity: 0;
@include border-radius($toast-border-radius);
&:not(:last-child) {
margin-bottom: $toast-padding-x;
}
&.showing {
opacity: 1;
}
&.show {
display: block;
opacity: 1;
}
&.hide {
display: none;
}
}
.toast-header {
display: flex;
align-items: center;
padding: $toast-padding-y $toast-padding-x;
color: $toast-header-color;
background-color: $toast-header-background-color;
background-clip: padding-box;
border-bottom: $toast-border-width solid $toast-header-border-color;
@include border-top-radius(subtract($toast-border-radius, $toast-border-width));
}
.toast-body {
padding: $toast-padding-x; // apply to both vertical and horizontal
}
@@ -1,115 +0,0 @@
// Base class
.tooltip {
position: absolute;
z-index: $zindex-tooltip;
display: block;
margin: $tooltip-margin;
// Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.
// So reset our font and text properties to avoid inheriting weird values.
@include reset-text();
@include font-size($tooltip-font-size);
// Allow breaking very long words so they don't overflow the tooltip's bounds
word-wrap: break-word;
opacity: 0;
&.show { opacity: $tooltip-opacity; }
.arrow {
position: absolute;
display: block;
width: $tooltip-arrow-width;
height: $tooltip-arrow-height;
&::before {
position: absolute;
content: "";
border-color: transparent;
border-style: solid;
}
}
}
.bs-tooltip-top {
padding: $tooltip-arrow-height 0;
.arrow {
bottom: 0;
&::before {
top: 0;
border-width: $tooltip-arrow-height ($tooltip-arrow-width * .5) 0;
border-top-color: $tooltip-arrow-color;
}
}
}
.bs-tooltip-right {
padding: 0 $tooltip-arrow-height;
.arrow {
left: 0;
width: $tooltip-arrow-height;
height: $tooltip-arrow-width;
&::before {
right: 0;
border-width: ($tooltip-arrow-width * .5) $tooltip-arrow-height ($tooltip-arrow-width * .5) 0;
border-right-color: $tooltip-arrow-color;
}
}
}
.bs-tooltip-bottom {
padding: $tooltip-arrow-height 0;
.arrow {
top: 0;
&::before {
bottom: 0;
border-width: 0 ($tooltip-arrow-width * .5) $tooltip-arrow-height;
border-bottom-color: $tooltip-arrow-color;
}
}
}
.bs-tooltip-left {
padding: 0 $tooltip-arrow-height;
.arrow {
right: 0;
width: $tooltip-arrow-height;
height: $tooltip-arrow-width;
&::before {
left: 0;
border-width: ($tooltip-arrow-width * .5) 0 ($tooltip-arrow-width * .5) $tooltip-arrow-height;
border-left-color: $tooltip-arrow-color;
}
}
}
.bs-tooltip-auto {
&[x-placement^="top"] {
@extend .bs-tooltip-top;
}
&[x-placement^="right"] {
@extend .bs-tooltip-right;
}
&[x-placement^="bottom"] {
@extend .bs-tooltip-bottom;
}
&[x-placement^="left"] {
@extend .bs-tooltip-left;
}
}
// Wrapper for the tooltip content
.tooltip-inner {
max-width: $tooltip-max-width;
padding: $tooltip-padding-y $tooltip-padding-x;
color: $tooltip-color;
text-align: center;
background-color: $tooltip-bg;
@include border-radius($tooltip-border-radius);
}
@@ -1,26 +0,0 @@
.fade {
@include transition($transition-fade);
&:not(.show) {
opacity: 0;
}
}
.collapse {
&:not(.show) {
display: none;
}
}
.collapsing {
position: relative;
height: 0;
overflow: hidden;
@include transition($transition-collapse);
&.width {
width: 0;
height: auto;
@include transition($transition-collapse-width);
}
}
@@ -1,125 +0,0 @@
// stylelint-disable selector-list-comma-newline-after
//
// Headings
//
h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
margin-bottom: $headings-margin-bottom;
font-family: $headings-font-family;
font-weight: $headings-font-weight;
line-height: $headings-line-height;
color: $headings-color;
}
h1, .h1 { @include font-size($h1-font-size); }
h2, .h2 { @include font-size($h2-font-size); }
h3, .h3 { @include font-size($h3-font-size); }
h4, .h4 { @include font-size($h4-font-size); }
h5, .h5 { @include font-size($h5-font-size); }
h6, .h6 { @include font-size($h6-font-size); }
.lead {
@include font-size($lead-font-size);
font-weight: $lead-font-weight;
}
// Type display classes
.display-1 {
@include font-size($display1-size);
font-weight: $display1-weight;
line-height: $display-line-height;
}
.display-2 {
@include font-size($display2-size);
font-weight: $display2-weight;
line-height: $display-line-height;
}
.display-3 {
@include font-size($display3-size);
font-weight: $display3-weight;
line-height: $display-line-height;
}
.display-4 {
@include font-size($display4-size);
font-weight: $display4-weight;
line-height: $display-line-height;
}
//
// Horizontal rules
//
hr {
margin-top: $hr-margin-y;
margin-bottom: $hr-margin-y;
border: 0;
border-top: $hr-border-width solid $hr-border-color;
}
//
// Emphasis
//
small,
.small {
@include font-size($small-font-size);
font-weight: $font-weight-normal;
}
mark,
.mark {
padding: $mark-padding;
background-color: $mark-bg;
}
//
// Lists
//
.list-unstyled {
@include list-unstyled();
}
// Inline turns list items into inline-block
.list-inline {
@include list-unstyled();
}
.list-inline-item {
display: inline-block;
&:not(:last-child) {
margin-right: $list-inline-padding;
}
}
//
// Misc
//
// Builds on `abbr`
.initialism {
@include font-size(90%);
text-transform: uppercase;
}
// Blockquotes
.blockquote {
margin-bottom: $spacer;
@include font-size($blockquote-font-size);
}
.blockquote-footer {
display: block;
@include font-size($blockquote-small-font-size);
color: $blockquote-small-color;
&::before {
content: "\2014\00A0"; // em dash, nbsp
}
}
@@ -1,18 +0,0 @@
@import "utilities/align";
@import "utilities/background";
@import "utilities/borders";
@import "utilities/clearfix";
@import "utilities/display";
@import "utilities/embed";
@import "utilities/flex";
@import "utilities/float";
@import "utilities/interactions";
@import "utilities/overflow";
@import "utilities/position";
@import "utilities/screenreaders";
@import "utilities/shadows";
@import "utilities/sizing";
@import "utilities/spacing";
@import "utilities/stretched-link";
@import "utilities/text";
@import "utilities/visibility";
File diff suppressed because it is too large. Load diff
@@ -1,228 +0,0 @@
// stylelint-disable property-blacklist, scss/dollar-variable-default
// SCSS RFS mixin
//
// Automated responsive font sizes
//
// Licensed under MIT (https://github.com/twbs/rfs/blob/v8.x/LICENSE)
// Configuration
// Base font size
$rfs-base-font-size: 1.25rem !default;
$rfs-font-size-unit: rem !default;
@if $rfs-font-size-unit != rem and $rfs-font-size-unit != px {
@error "`#{$rfs-font-size-unit}` is not a valid unit for $rfs-font-size-unit. Use `px` or `rem`.";
}
// Breakpoint at where font-size starts decreasing if screen width is smaller
$rfs-breakpoint: 1200px !default;
$rfs-breakpoint-unit: px !default;
@if $rfs-breakpoint-unit != px and $rfs-breakpoint-unit != em and $rfs-breakpoint-unit != rem {
@error "`#{$rfs-breakpoint-unit}` is not a valid unit for $rfs-breakpoint-unit. Use `px`, `em` or `rem`.";
}
// Resize font size based on screen height and width
$rfs-two-dimensional: false !default;
// Factor of decrease
$rfs-factor: 10 !default;
@if type-of($rfs-factor) != "number" or $rfs-factor <= 1 {
@error "`#{$rfs-factor}` is not a valid $rfs-factor, it must be greater than 1.";
}
// Generate enable or disable classes. Possibilities: false, "enable" or "disable"
$rfs-class: false !default;
// 1 rem = $rfs-rem-value px
$rfs-rem-value: 16 !default;
// Safari iframe resize bug: https://github.com/twbs/rfs/issues/14
$rfs-safari-iframe-resize-bug-fix: false !default;
// Disable RFS by setting $enable-responsive-font-sizes to false
$enable-responsive-font-sizes: true !default;
// Cache $rfs-base-font-size unit
$rfs-base-font-size-unit: unit($rfs-base-font-size);
@function divide($dividend, $divisor, $precision: 10) {
$sign: if($dividend > 0 and $divisor > 0 or $dividend < 0 and $divisor < 0, 1, -1);
$dividend: abs($dividend);
$divisor: abs($divisor);
@if $dividend == 0 {
@return 0;
}
@if $divisor == 0 {
@error "Cannot divide by 0";
}
$remainder: $dividend;
$result: 0;
$factor: 10;
@while ($remainder > 0 and $precision >= 0) {
$quotient: 0;
@while ($remainder >= $divisor) {
$remainder: $remainder - $divisor;
$quotient: $quotient + 1;
}
$result: $result * 10 + $quotient;
$factor: $factor * .1;
$remainder: $remainder * 10;
$precision: $precision - 1;
@if ($precision < 0 and $remainder >= $divisor * 5) {
$result: $result + 1;
}
}
$result: $result * $factor * $sign;
$dividend-unit: unit($dividend);
$divisor-unit: unit($divisor);
$unit-map: (
"px": 1px,
"rem": 1rem,
"em": 1em,
"%": 1%
);
@if ($dividend-unit != $divisor-unit and map-has-key($unit-map, $dividend-unit)) {
$result: $result * map-get($unit-map, $dividend-unit);
}
@return $result;
}
// Remove px-unit from $rfs-base-font-size for calculations
@if $rfs-base-font-size-unit == "px" {
$rfs-base-font-size: divide($rfs-base-font-size, $rfs-base-font-size * 0 + 1);
}
@else if $rfs-base-font-size-unit == "rem" {
$rfs-base-font-size: divide($rfs-base-font-size, divide($rfs-base-font-size * 0 + 1, $rfs-rem-value));
}
// Cache $rfs-breakpoint unit to prevent multiple calls
$rfs-breakpoint-unit-cache: unit($rfs-breakpoint);
// Remove unit from $rfs-breakpoint for calculations
@if $rfs-breakpoint-unit-cache == "px" {
$rfs-breakpoint: divide($rfs-breakpoint, $rfs-breakpoint * 0 + 1);
}
@else if $rfs-breakpoint-unit-cache == "rem" or $rfs-breakpoint-unit-cache == "em" {
$rfs-breakpoint: divide($rfs-breakpoint, divide($rfs-breakpoint * 0 + 1, $rfs-rem-value));
}
// Internal mixin that adds disable classes to the selector if needed.
@mixin _rfs-disable-class {
@if $rfs-class == "disable" {
// Adding an extra class increases specificity, which prevents the media query to override the font size
&,
.disable-responsive-font-size &,
&.disable-responsive-font-size {
@content;
}
}
@else {
@content;
}
}
// Internal mixin that adds enable classes to the selector if needed.
@mixin _rfs-enable-class {
@if $rfs-class == "enable" {
.enable-responsive-font-size &,
&.enable-responsive-font-size {
@content;
}
}
@else {
@content;
}
}
// Internal mixin used to determine which media query needs to be used
@mixin _rfs-media-query($mq-value) {
@if $rfs-two-dimensional {
@media (max-width: #{$mq-value}), (max-height: #{$mq-value}) {
@content;
}
}
@else {
@media (max-width: #{$mq-value}) {
@content;
}
}
}
// Responsive font size mixin
@mixin rfs($fs, $important: false) {
// Cache $fs unit
$fs-unit: if(type-of($fs) == "number", unit($fs), false);
// Add !important suffix if needed
$rfs-suffix: if($important, " !important", "");
// If $fs isn't a number (like inherit) or $fs has a unit (not px or rem, like 1.5em) or $ is 0, just print the value
@if not $fs-unit or $fs-unit != "" and $fs-unit != "px" and $fs-unit != "rem" or $fs == 0 {
font-size: #{$fs}#{$rfs-suffix};
}
@else {
// Remove unit from $fs for calculations
@if $fs-unit == "px" {
$fs: divide($fs, $fs * 0 + 1);
}
@else if $fs-unit == "rem" {
$fs: divide($fs, divide($fs * 0 + 1, $rfs-rem-value));
}
// Set default font size
$rfs-static: if($rfs-font-size-unit == rem, #{divide($fs, $rfs-rem-value)}rem, #{$fs}px);
// Only add the media query if the font size is bigger than the minimum font size
@if $fs <= $rfs-base-font-size or not $enable-responsive-font-sizes {
font-size: #{$rfs-static}#{$rfs-suffix};
}
@else {
// Calculate the minimum font size for $fs
$fs-min: $rfs-base-font-size + divide($fs - $rfs-base-font-size, $rfs-factor);
// Calculate difference between $fs and the minimum font size
$fs-diff: $fs - $fs-min;
// Base font-size formatting
$min-width: if($rfs-font-size-unit == rem, #{divide($fs-min, $rfs-rem-value)}rem, #{$fs-min}px);
// Use `vmin` if two-dimensional is enabled
$variable-unit: if($rfs-two-dimensional, vmin, vw);
// Calculate the variable width between 0 and $rfs-breakpoint
$variable-width: #{divide($fs-diff * 100, $rfs-breakpoint)}#{$variable-unit};
// Set the calculated font-size
$rfs-fluid: calc(#{$min-width} + #{$variable-width}) #{$rfs-suffix};
// Breakpoint formatting
$mq-value: if($rfs-breakpoint-unit == px, #{$rfs-breakpoint}px, #{divide($rfs-breakpoint, $rfs-rem-value)}#{$rfs-breakpoint-unit});
@include _rfs-disable-class {
font-size: #{$rfs-static}#{$rfs-suffix};
}
@include _rfs-media-query($mq-value) {
@include _rfs-enable-class {
font-size: $rfs-fluid;
}
// Include safari iframe resize fix if needed
min-width: if($rfs-safari-iframe-resize-bug-fix, (0 * 1vw), null);
}
}
}
}
// The font-size & responsive-font-size mixins use RFS to rescale the font size
@mixin font-size($fs, $important: false) {
@include rfs($fs, $important);
}
@mixin responsive-font-size($fs, $important: false) {
@include rfs($fs, $important);
}
@@ -1,30 +0,0 @@
/*!
* Bootstrap Grid v4.6.2 (https://getbootstrap.com/)
* Copyright 2011-2022 The Bootstrap Authors
* Copyright 2011-2022 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
html {
box-sizing: border-box;
-ms-overflow-style: scrollbar;
}
*,
*::before,
*::after {
box-sizing: inherit;
}
@import "functions";
@import "variables";
@import "mixins/deprecate";
@import "mixins/breakpoints";
@import "mixins/grid-framework";
@import "mixins/grid";
@import "grid";
@import "utilities/display";
@import "utilities/flex";
@import "utilities/spacing";
@@ -1,12 +0,0 @@
/*!
* Bootstrap Reboot v4.6.2 (https://getbootstrap.com/)
* Copyright 2011-2022 The Bootstrap Authors
* Copyright 2011-2022 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/
@import "functions";
@import "variables";
@import "mixins";
@import "reboot";
@@ -1,44 +0,0 @@
/*!
* Bootstrap v4.6.2 (https://getbootstrap.com/)
* Copyright 2011-2022 The Bootstrap Authors
* Copyright 2011-2022 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
@import "functions";
@import "variables";
@import "mixins";
@import "root";
@import "reboot";
@import "type";
@import "images";
@import "code";
@import "grid";
@import "tables";
@import "forms";
@import "buttons";
@import "transitions";
@import "dropdown";
@import "button-group";
@import "input-group";
@import "custom-forms";
@import "nav";
@import "navbar";
@import "card";
@import "breadcrumb";
@import "pagination";
@import "badge";
@import "jumbotron";
@import "alert";
@import "progress";
@import "media";
@import "list-group";
@import "close";
@import "toasts";
@import "modal";
@import "tooltip";
@import "popover";
@import "carousel";
@import "spinners";
@import "utilities";
@import "print";
@@ -1,13 +0,0 @@
@mixin alert-variant($background, $border, $color) {
color: $color;
@include gradient-bg($background);
border-color: $border;
hr {
border-top-color: darken($border, 5%);
}
.alert-link {
color: darken($color, 10%);
}
}
@@ -1,23 +0,0 @@
// stylelint-disable declaration-no-important
// Contextual backgrounds
@mixin bg-variant($parent, $color, $ignore-warning: false) {
#{$parent} {
background-color: $color !important;
}
a#{$parent},
button#{$parent} {
@include hover-focus() {
background-color: darken($color, 10%) !important;
}
}
@include deprecate("The `bg-variant` mixin", "v4.4.0", "v5", $ignore-warning);
}
@mixin bg-gradient-variant($parent, $color, $ignore-warning: false) {
#{$parent} {
background: $color linear-gradient(180deg, mix($body-bg, $color, 15%), $color) repeat-x !important;
}
@include deprecate("The `bg-gradient-variant` mixin", "v4.5.0", "v5", $ignore-warning);
}
@@ -1,17 +0,0 @@
@mixin badge-variant($bg) {
color: color-yiq($bg);
background-color: $bg;
@at-root a#{&} {
@include hover-focus() {
color: color-yiq($bg);
background-color: darken($bg, 10%);
}
&:focus,
&.focus {
outline: 0;
box-shadow: 0 0 0 $badge-focus-width rgba($bg, .5);
}
}
}
@@ -1,76 +0,0 @@
// stylelint-disable property-disallowed-list
// Single side border-radius
// Helper function to replace negative values with 0
@function valid-radius($radius) {
$return: ();
@each $value in $radius {
@if type-of($value) == number {
$return: append($return, max($value, 0));
} @else {
$return: append($return, $value);
}
}
@return $return;
}
@mixin border-radius($radius: $border-radius, $fallback-border-radius: false) {
@if $enable-rounded {
border-radius: valid-radius($radius);
}
@else if $fallback-border-radius != false {
border-radius: $fallback-border-radius;
}
}
@mixin border-top-radius($radius) {
@if $enable-rounded {
border-top-left-radius: valid-radius($radius);
border-top-right-radius: valid-radius($radius);
}
}
@mixin border-right-radius($radius) {
@if $enable-rounded {
border-top-right-radius: valid-radius($radius);
border-bottom-right-radius: valid-radius($radius);
}
}
@mixin border-bottom-radius($radius) {
@if $enable-rounded {
border-bottom-right-radius: valid-radius($radius);
border-bottom-left-radius: valid-radius($radius);
}
}
@mixin border-left-radius($radius) {
@if $enable-rounded {
border-top-left-radius: valid-radius($radius);
border-bottom-left-radius: valid-radius($radius);
}
}
@mixin border-top-left-radius($radius) {
@if $enable-rounded {
border-top-left-radius: valid-radius($radius);
}
}
@mixin border-top-right-radius($radius) {
@if $enable-rounded {
border-top-right-radius: valid-radius($radius);
}
}
@mixin border-bottom-right-radius($radius) {
@if $enable-rounded {
border-bottom-right-radius: valid-radius($radius);
}
}
@mixin border-bottom-left-radius($radius) {
@if $enable-rounded {
border-bottom-left-radius: valid-radius($radius);
}
}
@@ -1,20 +0,0 @@
@mixin box-shadow($shadow...) {
@if $enable-shadows {
$result: ();
@if (length($shadow) == 1) {
// We can pass `@include box-shadow(none);`
$result: $shadow;
} @else {
// Filter to avoid invalid properties for example `box-shadow: none, 1px 1px black;`
@for $i from 1 through length($shadow) {
@if nth($shadow, $i) != "none" {
$result: append($result, nth($shadow, $i), "comma");
}
}
}
@if (length($result) > 0) {
box-shadow: $result;
}
}
}
@@ -1,123 +0,0 @@
// Breakpoint viewport sizes and media queries.
//
// Breakpoints are defined as a map of (name: minimum width), order from small to large:
//
// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)
//
// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.
// Name of the next breakpoint, or null for the last breakpoint.
//
// >> breakpoint-next(sm)
// md
// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
// md
// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl))
// md
@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {
$n: index($breakpoint-names, $name);
@return if($n != null and $n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);
}
// Minimum breakpoint width. Null for the smallest (first) breakpoint.
//
// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
// 576px
@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {
$min: map-get($breakpoints, $name);
@return if($min != 0, $min, null);
}
// Maximum breakpoint width. Null for the largest (last) breakpoint.
// The maximum value is calculated as the minimum of the next one less 0.02px
// to work around the limitations of `min-` and `max-` prefixes and viewports with fractional widths.
// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max
// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.
// See https://bugs.webkit.org/show_bug.cgi?id=178261
//
// >> breakpoint-max(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
// 767.98px
@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {
$next: breakpoint-next($name, $breakpoints);
@return if($next, breakpoint-min($next, $breakpoints) - .02, null);
}
// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash in front.
// Useful for making responsive utilities.
//
// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
// "" (Returns a blank string)
// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
// "-sm"
@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {
@return if(breakpoint-min($name, $breakpoints) == null, "", "-#{$name}");
}
// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.
// Makes the @content apply to the given breakpoint and wider.
@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {
$min: breakpoint-min($name, $breakpoints);
@if $min {
@media (min-width: $min) {
@content;
}
} @else {
@content;
}
}
// Media of at most the maximum breakpoint width. No query for the largest breakpoint.
// Makes the @content apply to the given breakpoint and narrower.
@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) {
$max: breakpoint-max($name, $breakpoints);
@if $max {
@media (max-width: $max) {
@content;
}
} @else {
@content;
}
}
// Media that spans multiple breakpoint widths.
// Makes the @content apply between the min and max breakpoints
@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {
$min: breakpoint-min($lower, $breakpoints);
$max: breakpoint-max($upper, $breakpoints);
@if $min != null and $max != null {
@media (min-width: $min) and (max-width: $max) {
@content;
}
} @else if $max == null {
@include media-breakpoint-up($lower, $breakpoints) {
@content;
}
} @else if $min == null {
@include media-breakpoint-down($upper, $breakpoints) {
@content;
}
}
}
// Media between the breakpoint's minimum and maximum widths.
// No minimum for the smallest breakpoint, and no maximum for the largest one.
// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower.
@mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) {
$min: breakpoint-min($name, $breakpoints);
$max: breakpoint-max($name, $breakpoints);
@if $min != null and $max != null {
@media (min-width: $min) and (max-width: $max) {
@content;
}
} @else if $max == null {
@include media-breakpoint-up($name, $breakpoints) {
@content;
}
} @else if $min == null {
@include media-breakpoint-down($name, $breakpoints) {
@content;
}
}
}
@@ -1,110 +0,0 @@
// Button variants
//
// Easily pump out default styles, as well as :hover, :focus, :active,
// and disabled options for all buttons
@mixin button-variant($background, $border, $hover-background: darken($background, 7.5%), $hover-border: darken($border, 10%), $active-background: darken($background, 10%), $active-border: darken($border, 12.5%)) {
color: color-yiq($background);
@include gradient-bg($background);
border-color: $border;
@include box-shadow($btn-box-shadow);
@include hover() {
color: color-yiq($hover-background);
@include gradient-bg($hover-background);
border-color: $hover-border;
}
&:focus,
&.focus {
color: color-yiq($hover-background);
@include gradient-bg($hover-background);
border-color: $hover-border;
@if $enable-shadows {
@include box-shadow($btn-box-shadow, 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5));
} @else {
// Avoid using mixin so we can pass custom focus shadow properly
box-shadow: 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5);
}
}
// Disabled comes first so active can properly restyle
&.disabled,
&:disabled {
color: color-yiq($background);
background-color: $background;
border-color: $border;
// Remove CSS gradients if they're enabled
@if $enable-gradients {
background-image: none;
}
}
&:not(:disabled):not(.disabled):active,
&:not(:disabled):not(.disabled).active,
.show > &.dropdown-toggle {
color: color-yiq($active-background);
background-color: $active-background;
@if $enable-gradients {
background-image: none; // Remove the gradient for the pressed/active state
}
border-color: $active-border;
&:focus {
@if $enable-shadows and $btn-active-box-shadow != none {
@include box-shadow($btn-active-box-shadow, 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5));
} @else {
// Avoid using mixin so we can pass custom focus shadow properly
box-shadow: 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5);
}
}
}
}
@mixin button-outline-variant($color, $color-hover: color-yiq($color), $active-background: $color, $active-border: $color) {
color: $color;
border-color: $color;
@include hover() {
color: $color-hover;
background-color: $active-background;
border-color: $active-border;
}
&:focus,
&.focus {
box-shadow: 0 0 0 $btn-focus-width rgba($color, .5);
}
&.disabled,
&:disabled {
color: $color;
background-color: transparent;
}
&:not(:disabled):not(.disabled):active,
&:not(:disabled):not(.disabled).active,
.show > &.dropdown-toggle {
color: color-yiq($active-background);
background-color: $active-background;
border-color: $active-border;
&:focus {
@if $enable-shadows and $btn-active-box-shadow != none {
@include box-shadow($btn-active-box-shadow, 0 0 0 $btn-focus-width rgba($color, .5));
} @else {
// Avoid using mixin so we can pass custom focus shadow properly
box-shadow: 0 0 0 $btn-focus-width rgba($color, .5);
}
}
}
}
// Button sizes
@mixin button-size($padding-y, $padding-x, $font-size, $line-height, $border-radius) {
padding: $padding-y $padding-x;
@include font-size($font-size);
line-height: $line-height;
// Manually declare to provide an override to the browser default
@include border-radius($border-radius, 0);
}
@@ -1,62 +0,0 @@
@mixin caret-down() {
border-top: $caret-width solid;
border-right: $caret-width solid transparent;
border-bottom: 0;
border-left: $caret-width solid transparent;
}
@mixin caret-up() {
border-top: 0;
border-right: $caret-width solid transparent;
border-bottom: $caret-width solid;
border-left: $caret-width solid transparent;
}
@mixin caret-right() {
border-top: $caret-width solid transparent;
border-right: 0;
border-bottom: $caret-width solid transparent;
border-left: $caret-width solid;
}
@mixin caret-left() {
border-top: $caret-width solid transparent;
border-right: $caret-width solid;
border-bottom: $caret-width solid transparent;
}
@mixin caret($direction: down) {
@if $enable-caret {
&::after {
display: inline-block;
margin-left: $caret-spacing;
vertical-align: $caret-vertical-align;
content: "";
@if $direction == down {
@include caret-down();
} @else if $direction == up {
@include caret-up();
} @else if $direction == right {
@include caret-right();
}
}
@if $direction == left {
&::after {
display: none;
}
&::before {
display: inline-block;
margin-right: $caret-spacing;
vertical-align: $caret-vertical-align;
content: "";
@include caret-left();
}
}
&:empty::after {
margin-left: 0;
}
}
}
@@ -1,7 +0,0 @@
@mixin clearfix() {
&::after {
display: block;
clear: both;
content: "";
}
}
@@ -1,10 +0,0 @@
// Deprecate mixin
//
// This mixin can be used to deprecate mixins or functions.
// `$enable-deprecation-messages` is a global variable, `$ignore-warning` is a variable that can be passed to
// some deprecated mixins to suppress the warning (for example if the mixin is still be used in the current version of Bootstrap)
@mixin deprecate($name, $deprecate-version, $remove-version, $ignore-warning: false) {
@if ($enable-deprecation-messages != false and $ignore-warning != true) {
@warn "#{$name} has been deprecated as of #{$deprecate-version}. It will be removed entirely in #{$remove-version}.";
}
}
@@ -1,14 +0,0 @@
// stylelint-disable declaration-no-important
@mixin float-left() {
float: left !important;
@include deprecate("The `float-left` mixin", "v4.3.0", "v5");
}
@mixin float-right() {
float: right !important;
@include deprecate("The `float-right` mixin", "v4.3.0", "v5");
}
@mixin float-none() {
float: none !important;
@include deprecate("The `float-none` mixin", "v4.3.0", "v5");
}
@@ -1,195 +0,0 @@
// Form control focus state
//
// Generate a customized focus state and for any input with the specified color,
// which defaults to the `$input-focus-border-color` variable.
//
// We highly encourage you to not customize the default value, but instead use
// this to tweak colors on an as-needed basis. This aesthetic change is based on
// WebKit's default styles, but applicable to a wider range of browsers. Its
// usability and accessibility should be taken into account with any change.
//
// Example usage: change the default blue border and shadow to white for better
// contrast against a dark gray background.
@mixin form-control-focus($ignore-warning: false) {
&:focus {
color: $input-focus-color;
background-color: $input-focus-bg;
border-color: $input-focus-border-color;
outline: 0;
@if $enable-shadows {
@include box-shadow($input-box-shadow, $input-focus-box-shadow);
} @else {
// Avoid using mixin so we can pass custom focus shadow properly
box-shadow: $input-focus-box-shadow;
}
}
@include deprecate("The `form-control-focus()` mixin", "v4.4.0", "v5", $ignore-warning);
}
// This mixin uses an `if()` technique to be compatible with Dart Sass
// See https://github.com/sass/sass/issues/1873#issuecomment-152293725 for more details
@mixin form-validation-state-selector($state) {
@if ($state == "valid" or $state == "invalid") {
.was-validated #{if(&, "&", "")}:#{$state},
#{if(&, "&", "")}.is-#{$state} {
@content;
}
} @else {
#{if(&, "&", "")}.is-#{$state} {
@content;
}
}
}
@mixin form-validation-state($state, $color, $icon) {
.#{$state}-feedback {
display: none;
width: 100%;
margin-top: $form-feedback-margin-top;
@include font-size($form-feedback-font-size);
color: $color;
}
.#{$state}-tooltip {
position: absolute;
top: 100%;
left: 0;
z-index: 5;
display: none;
max-width: 100%; // Contain to parent when possible
padding: $form-feedback-tooltip-padding-y $form-feedback-tooltip-padding-x;
margin-top: .1rem;
@include font-size($form-feedback-tooltip-font-size);
line-height: $form-feedback-tooltip-line-height;
color: color-yiq($color);
background-color: rgba($color, $form-feedback-tooltip-opacity);
@include border-radius($form-feedback-tooltip-border-radius);
// See https://github.com/twbs/bootstrap/pull/31557
// Align tooltip to form elements
.form-row > .col > &,
.form-row > [class*="col-"] > & {
left: $form-grid-gutter-width * .5;
}
}
@include form-validation-state-selector($state) {
~ .#{$state}-feedback,
~ .#{$state}-tooltip {
display: block;
}
}
.form-control {
@include form-validation-state-selector($state) {
border-color: $color;
@if $enable-validation-icons {
padding-right: $input-height-inner !important; // stylelint-disable-line declaration-no-important
background-image: escape-svg($icon);
background-repeat: no-repeat;
background-position: right $input-height-inner-quarter center;
background-size: $input-height-inner-half $input-height-inner-half;
}
&:focus {
border-color: $color;
box-shadow: 0 0 0 $input-focus-width rgba($color, .25);
}
}
}
// stylelint-disable-next-line selector-no-qualifying-type
select.form-control {
@include form-validation-state-selector($state) {
@if $enable-validation-icons {
padding-right: $input-padding-x * 4 !important; // stylelint-disable-line declaration-no-important
background-position: right $input-padding-x * 2 center;
}
}
}
// stylelint-disable-next-line selector-no-qualifying-type
textarea.form-control {
@include form-validation-state-selector($state) {
@if $enable-validation-icons {
padding-right: $input-height-inner;
background-position: top $input-height-inner-quarter right $input-height-inner-quarter;
}
}
}
.custom-select {
@include form-validation-state-selector($state) {
border-color: $color;
@if $enable-validation-icons {
padding-right: $custom-select-feedback-icon-padding-right !important; // stylelint-disable-line declaration-no-important
background: $custom-select-background, $custom-select-bg escape-svg($icon) $custom-select-feedback-icon-position / $custom-select-feedback-icon-size no-repeat;
}
&:focus {
border-color: $color;
box-shadow: 0 0 0 $input-focus-width rgba($color, .25);
}
}
}
.form-check-input {
@include form-validation-state-selector($state) {
~ .form-check-label {
color: $color;
}
~ .#{$state}-feedback,
~ .#{$state}-tooltip {
display: block;
}
}
}
.custom-control-input {
@include form-validation-state-selector($state) {
~ .custom-control-label {
color: $color;
&::before {
border-color: $color;
}
}
&:checked {
~ .custom-control-label::before {
border-color: lighten($color, 10%);
@include gradient-bg(lighten($color, 10%));
}
}
&:focus {
~ .custom-control-label::before {
box-shadow: 0 0 0 $input-focus-width rgba($color, .25);
}
&:not(:checked) ~ .custom-control-label::before {
border-color: $color;
}
}
}
}
// custom file
.custom-file-input {
@include form-validation-state-selector($state) {
~ .custom-file-label {
border-color: $color;
}
&:focus {
~ .custom-file-label {
border-color: $color;
box-shadow: 0 0 0 $input-focus-width rgba($color, .25);
}
}
}
}
}
@@ -1,45 +0,0 @@
// Gradients
@mixin gradient-bg($color) {
@if $enable-gradients {
background: $color linear-gradient(180deg, mix($body-bg, $color, 15%), $color) repeat-x;
} @else {
background-color: $color;
}
}
// Horizontal gradient, from left to right
//
// Creates two color stops, start and end, by specifying a color and position for each color stop.
@mixin gradient-x($start-color: $gray-700, $end-color: $gray-800, $start-percent: 0%, $end-percent: 100%) {
background-image: linear-gradient(to right, $start-color $start-percent, $end-color $end-percent);
background-repeat: repeat-x;
}
// Vertical gradient, from top to bottom
//
// Creates two color stops, start and end, by specifying a color and position for each color stop.
@mixin gradient-y($start-color: $gray-700, $end-color: $gray-800, $start-percent: 0%, $end-percent: 100%) {
background-image: linear-gradient(to bottom, $start-color $start-percent, $end-color $end-percent);
background-repeat: repeat-x;
}
@mixin gradient-directional($start-color: $gray-700, $end-color: $gray-800, $deg: 45deg) {
background-image: linear-gradient($deg, $start-color, $end-color);
background-repeat: repeat-x;
}
@mixin gradient-x-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) {
background-image: linear-gradient(to right, $start-color, $mid-color $color-stop, $end-color);
background-repeat: no-repeat;
}
@mixin gradient-y-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) {
background-image: linear-gradient($start-color, $mid-color $color-stop, $end-color);
background-repeat: no-repeat;
}
@mixin gradient-radial($inner-color: $gray-700, $outer-color: $gray-800) {
background-image: radial-gradient(circle, $inner-color, $outer-color);
background-repeat: no-repeat;
}
@mixin gradient-striped($color: rgba($white, .15), $angle: 45deg) {
background-image: linear-gradient($angle, $color 25%, transparent 25%, transparent 50%, $color 50%, $color 75%, transparent 75%, transparent);
}
@@ -1,80 +0,0 @@
// Framework grid generation
//
// Used only by Bootstrap to generate the correct number of grid classes given
// any value of `$grid-columns`.
@mixin make-grid-columns($columns: $grid-columns, $gutter: $grid-gutter-width, $breakpoints: $grid-breakpoints) {
// Common properties for all breakpoints
%grid-column {
position: relative;
width: 100%;
padding-right: $gutter * .5;
padding-left: $gutter * .5;
}
@each $breakpoint in map-keys($breakpoints) {
$infix: breakpoint-infix($breakpoint, $breakpoints);
@if $columns > 0 {
// Allow columns to stretch full width below their breakpoints
@for $i from 1 through $columns {
.col#{$infix}-#{$i} {
@extend %grid-column;
}
}
}
.col#{$infix},
.col#{$infix}-auto {
@extend %grid-column;
}
@include media-breakpoint-up($breakpoint, $breakpoints) {
// Provide basic `.col-{bp}` classes for equal-width flexbox columns
.col#{$infix} {
flex-basis: 0;
flex-grow: 1;
max-width: 100%;
}
@if $grid-row-columns > 0 {
@for $i from 1 through $grid-row-columns {
.row-cols#{$infix}-#{$i} {
@include row-cols($i);
}
}
}
.col#{$infix}-auto {
@include make-col-auto();
}
@if $columns > 0 {
@for $i from 1 through $columns {
.col#{$infix}-#{$i} {
@include make-col($i, $columns);
}
}
}
.order#{$infix}-first { order: -1; }
.order#{$infix}-last { order: $columns + 1; }
@for $i from 0 through $columns {
.order#{$infix}-#{$i} { order: $i; }
}
@if $columns > 0 {
// `$columns - 1` because offsetting by the width of an entire row isn't possible
@for $i from 0 through ($columns - 1) {
@if not ($infix == "" and $i == 0) { // Avoid emitting useless .offset-0
.offset#{$infix}-#{$i} {
@include make-col-offset($i, $columns);
}
}
}
}
}
}
}
@@ -1,69 +0,0 @@
/// Grid system
//
// Generate semantic grid columns with these mixins.
@mixin make-container($gutter: $grid-gutter-width) {
width: 100%;
padding-right: $gutter * .5;
padding-left: $gutter * .5;
margin-right: auto;
margin-left: auto;
}
@mixin make-row($gutter: $grid-gutter-width) {
display: flex;
flex-wrap: wrap;
margin-right: -$gutter * .5;
margin-left: -$gutter * .5;
}
// For each breakpoint, define the maximum width of the container in a media query
@mixin make-container-max-widths($max-widths: $container-max-widths, $breakpoints: $grid-breakpoints) {
@each $breakpoint, $container-max-width in $max-widths {
@include media-breakpoint-up($breakpoint, $breakpoints) {
max-width: $container-max-width;
}
}
@include deprecate("The `make-container-max-widths` mixin", "v4.5.2", "v5");
}
@mixin make-col-ready($gutter: $grid-gutter-width) {
position: relative;
// Prevent columns from becoming too narrow when at smaller grid tiers by
// always setting `width: 100%;`. This works because we use `flex` values
// later on to override this initial width.
width: 100%;
padding-right: $gutter * .5;
padding-left: $gutter * .5;
}
@mixin make-col($size, $columns: $grid-columns) {
flex: 0 0 percentage(divide($size, $columns));
// Add a `max-width` to ensure content within each column does not blow out
// the width of the column. Applies to IE10+ and Firefox. Chrome and Safari
// do not appear to require this.
max-width: percentage(divide($size, $columns));
}
@mixin make-col-auto() {
flex: 0 0 auto;
width: auto;
max-width: 100%; // Reset earlier grid tiers
}
@mixin make-col-offset($size, $columns: $grid-columns) {
$num: divide($size, $columns);
margin-left: if($num == 0, 0, percentage($num));
}
// Row columns
//
// Specify on a parent element(e.g., .row) to force immediate children into NN
// numberof columns. Supports wrapping to new lines, but does not do a Masonry
// style grid.
@mixin row-cols($count) {
> * {
flex: 0 0 divide(100%, $count);
max-width: divide(100%, $count);
}
}
@@ -1,37 +0,0 @@
// Hover mixin and `$enable-hover-media-query` are deprecated.
//
// Originally added during our alphas and maintained during betas, this mixin was
// designed to prevent `:hover` stickiness on iOS-an issue where hover styles
// would persist after initial touch.
//
// For backward compatibility, we've kept these mixins and updated them to
// always return their regular pseudo-classes instead of a shimmed media query.
//
// Issue: https://github.com/twbs/bootstrap/issues/25195
@mixin hover() {
&:hover { @content; }
}
@mixin hover-focus() {
&:hover,
&:focus {
@content;
}
}
@mixin plain-hover-focus() {
&,
&:hover,
&:focus {
@content;
}
}
@mixin hover-focus-active() {
&:hover,
&:focus,
&:active {
@content;
}
}
Loaded 100 of 677 files, more files were not shown because too many files have changed in this diff. Show more