`s.
5 |
6 | .nav {
7 | display: flex;
8 | flex-wrap: wrap;
9 | padding-left: 0;
10 | margin-bottom: 0;
11 | list-style: none;
12 | }
13 |
14 | .nav-link {
15 | display: block;
16 | padding: $nav-link-padding-y $nav-link-padding-x;
17 |
18 | @include hover-focus {
19 | text-decoration: none;
20 | }
21 |
22 | // Disabled state lightens text
23 | &.disabled {
24 | color: $nav-link-disabled-color;
25 | }
26 | }
27 |
28 |
29 | //
30 | // Pills
31 | //
32 |
33 | .nav-pills {
34 | .nav-link {
35 | @include border-radius($nav-pills-border-radius);
36 | }
37 |
38 | .nav-link.active,
39 | .show > .nav-link {
40 | color: $nav-pills-link-active-color;
41 | background-color: $nav-pills-link-active-bg;
42 | }
43 | }
44 |
45 |
46 | //
47 | // Justified variants
48 | //
49 |
50 | .nav-fill {
51 | .nav-item {
52 | flex: 1 1 auto;
53 | text-align: center;
54 | }
55 | }
56 |
57 | .nav-justified {
58 | .nav-item {
59 | flex-basis: 0;
60 | flex-grow: 1;
61 | text-align: center;
62 | }
63 | }
64 |
65 |
66 | // Tabbable tabs
67 | //
68 | // Hide tabbable panes to start, show them when `.active`
69 |
70 | .tab-content {
71 | > .tab-pane {
72 | display: none;
73 | }
74 | > .active {
75 | display: block;
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/_pagination.scss:
--------------------------------------------------------------------------------
1 | .pagination {
2 | display: flex;
3 | @include list-unstyled();
4 | @include border-radius();
5 | }
6 |
7 | .page-link {
8 | position: relative;
9 | display: block;
10 | padding: $pagination-padding-y $pagination-padding-x;
11 | margin-left: -$pagination-border-width;
12 | line-height: $pagination-line-height;
13 | color: $pagination-color;
14 | background-color: $pagination-bg;
15 | border: $pagination-border-width solid $pagination-border-color;
16 |
17 | &:hover {
18 | color: $pagination-hover-color;
19 | text-decoration: none;
20 | background-color: $pagination-hover-bg;
21 | border-color: $pagination-hover-border-color;
22 | }
23 |
24 | &:focus {
25 | z-index: 2;
26 | outline: 0;
27 | box-shadow: $pagination-focus-box-shadow;
28 | }
29 |
30 | // Opinionated: add "hand" cursor to non-disabled .page-link elements
31 | &:not(:disabled):not(.disabled) {
32 | cursor: pointer;
33 | }
34 | }
35 |
36 | .page-item {
37 | &:first-child {
38 | .page-link {
39 | margin-left: 0;
40 | @include border-left-radius($border-radius);
41 | }
42 | }
43 | &:last-child {
44 | .page-link {
45 | @include border-right-radius($border-radius);
46 | }
47 | }
48 |
49 | &.active .page-link {
50 | z-index: 1;
51 | color: $pagination-active-color;
52 | background-color: $pagination-active-bg;
53 | border-color: $pagination-active-border-color;
54 | }
55 |
56 | &.disabled .page-link {
57 | color: $pagination-disabled-color;
58 | pointer-events: none;
59 | // Opinionated: remove the "hand" cursor set previously for .page-link
60 | cursor: auto;
61 | background-color: $pagination-disabled-bg;
62 | border-color: $pagination-disabled-border-color;
63 | }
64 | }
65 |
66 |
67 | //
68 | // Sizing
69 | //
70 |
71 | .pagination-lg {
72 | @include pagination-size($pagination-padding-y-lg, $pagination-padding-x-lg, $font-size-lg, $line-height-lg, $border-radius-lg);
73 | }
74 |
75 | .pagination-sm {
76 | @include pagination-size($pagination-padding-y-sm, $pagination-padding-x-sm, $font-size-sm, $line-height-sm, $border-radius-sm);
77 | }
78 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/_popover.scss:
--------------------------------------------------------------------------------
1 | .popover {
2 | position: absolute;
3 | top: 0;
4 | left: 0;
5 | z-index: $zindex-popover;
6 | display: block;
7 | max-width: $popover-max-width;
8 | // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.
9 | // So reset our font and text properties to avoid inheriting weird values.
10 | @include reset-text();
11 | font-size: $popover-font-size;
12 | // Allow breaking very long words so they don't overflow the popover's bounds
13 | word-wrap: break-word;
14 | background-color: $popover-bg;
15 | background-clip: padding-box;
16 | border: $popover-border-width solid $popover-border-color;
17 | @include border-radius($popover-border-radius);
18 | @include box-shadow($popover-box-shadow);
19 |
20 | .arrow {
21 | position: absolute;
22 | display: block;
23 | width: $popover-arrow-width;
24 | height: $popover-arrow-height;
25 | margin: 0 $border-radius-lg;
26 |
27 | &::before,
28 | &::after {
29 | position: absolute;
30 | display: block;
31 | content: "";
32 | border-color: transparent;
33 | border-style: solid;
34 | }
35 | }
36 | }
37 |
38 | .bs-popover-top {
39 | margin-bottom: $popover-arrow-height;
40 |
41 | .arrow {
42 | bottom: calc((#{$popover-arrow-height} + #{$popover-border-width}) * -1);
43 | }
44 |
45 | .arrow::before,
46 | .arrow::after {
47 | border-width: $popover-arrow-height ($popover-arrow-width / 2) 0;
48 | }
49 |
50 | .arrow::before {
51 | bottom: 0;
52 | border-top-color: $popover-arrow-outer-color;
53 | }
54 |
55 | .arrow::after {
56 | bottom: $popover-border-width;
57 | border-top-color: $popover-arrow-color;
58 | }
59 | }
60 |
61 | .bs-popover-right {
62 | margin-left: $popover-arrow-height;
63 |
64 | .arrow {
65 | left: calc((#{$popover-arrow-height} + #{$popover-border-width}) * -1);
66 | width: $popover-arrow-height;
67 | height: $popover-arrow-width;
68 | margin: $border-radius-lg 0; // make sure the arrow does not touch the popover's rounded corners
69 | }
70 |
71 | .arrow::before,
72 | .arrow::after {
73 | border-width: ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2) 0;
74 | }
75 |
76 | .arrow::before {
77 | left: 0;
78 | border-right-color: $popover-arrow-outer-color;
79 | }
80 |
81 | .arrow::after {
82 | left: $popover-border-width;
83 | border-right-color: $popover-arrow-color;
84 | }
85 | }
86 |
87 | .bs-popover-bottom {
88 | margin-top: $popover-arrow-height;
89 |
90 | .arrow {
91 | top: calc((#{$popover-arrow-height} + #{$popover-border-width}) * -1);
92 | }
93 |
94 | .arrow::before,
95 | .arrow::after {
96 | border-width: 0 ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2);
97 | }
98 |
99 | .arrow::before {
100 | top: 0;
101 | border-bottom-color: $popover-arrow-outer-color;
102 | }
103 |
104 | .arrow::after {
105 | top: $popover-border-width;
106 | border-bottom-color: $popover-arrow-color;
107 | }
108 |
109 | // This will remove the popover-header's border just below the arrow
110 | .popover-header::before {
111 | position: absolute;
112 | top: 0;
113 | left: 50%;
114 | display: block;
115 | width: $popover-arrow-width;
116 | margin-left: ($popover-arrow-width / -2);
117 | content: "";
118 | border-bottom: $popover-border-width solid $popover-header-bg;
119 | }
120 | }
121 |
122 | .bs-popover-left {
123 | margin-right: $popover-arrow-height;
124 |
125 | .arrow {
126 | right: calc((#{$popover-arrow-height} + #{$popover-border-width}) * -1);
127 | width: $popover-arrow-height;
128 | height: $popover-arrow-width;
129 | margin: $border-radius-lg 0; // make sure the arrow does not touch the popover's rounded corners
130 | }
131 |
132 | .arrow::before,
133 | .arrow::after {
134 | border-width: ($popover-arrow-width / 2) 0 ($popover-arrow-width / 2) $popover-arrow-height;
135 | }
136 |
137 | .arrow::before {
138 | right: 0;
139 | border-left-color: $popover-arrow-outer-color;
140 | }
141 |
142 | .arrow::after {
143 | right: $popover-border-width;
144 | border-left-color: $popover-arrow-color;
145 | }
146 | }
147 |
148 | .bs-popover-auto {
149 | &[x-placement^="top"] {
150 | @extend .bs-popover-top;
151 | }
152 | &[x-placement^="right"] {
153 | @extend .bs-popover-right;
154 | }
155 | &[x-placement^="bottom"] {
156 | @extend .bs-popover-bottom;
157 | }
158 | &[x-placement^="left"] {
159 | @extend .bs-popover-left;
160 | }
161 | }
162 |
163 |
164 | // Offset the popover to account for the popover arrow
165 | .popover-header {
166 | padding: $popover-header-padding-y $popover-header-padding-x;
167 | margin-bottom: 0; // Reset the default from Reboot
168 | font-size: $font-size-base;
169 | color: $popover-header-color;
170 | background-color: $popover-header-bg;
171 | border-bottom: $popover-border-width solid darken($popover-header-bg, 5%);
172 | $offset-border-width: calc(#{$border-radius-lg} - #{$popover-border-width});
173 | @include border-top-radius($offset-border-width);
174 |
175 | &:empty {
176 | display: none;
177 | }
178 | }
179 |
180 | .popover-body {
181 | padding: $popover-body-padding-y $popover-body-padding-x;
182 | color: $popover-body-color;
183 | }
184 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/_print.scss:
--------------------------------------------------------------------------------
1 | // stylelint-disable declaration-no-important, selector-no-qualifying-type
2 |
3 | // Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css
4 |
5 | // ==========================================================================
6 | // Print styles.
7 | // Inlined to avoid the additional HTTP request:
8 | // http://www.phpied.com/delay-loading-your-print-css/
9 | // ==========================================================================
10 |
11 | @if $enable-print-styles {
12 | @media print {
13 | *,
14 | *::before,
15 | *::after {
16 | // Bootstrap specific; comment out `color` and `background`
17 | //color: #000 !important; // Black prints faster: http://www.sanbeiji.com/archives/953
18 | text-shadow: none !important;
19 | //background: transparent !important;
20 | box-shadow: none !important;
21 | }
22 |
23 | a {
24 | &:not(.btn) {
25 | text-decoration: underline;
26 | }
27 | }
28 |
29 | // Bootstrap specific; comment the following selector out
30 | //a[href]::after {
31 | // content: " (" attr(href) ")";
32 | //}
33 |
34 | abbr[title]::after {
35 | content: " (" attr(title) ")";
36 | }
37 |
38 | // Bootstrap specific; comment the following selector out
39 | //
40 | // Don't show links that are fragment identifiers,
41 | // or use the `javascript:` pseudo protocol
42 | //
43 |
44 | //a[href^="#"]::after,
45 | //a[href^="javascript:"]::after {
46 | // content: "";
47 | //}
48 |
49 | pre {
50 | white-space: pre-wrap !important;
51 | }
52 | pre,
53 | blockquote {
54 | border: $border-width solid #999; // Bootstrap custom code; using `$border-width` instead of 1px
55 | page-break-inside: avoid;
56 | }
57 |
58 | //
59 | // Printing Tables:
60 | // http://css-discuss.incutio.com/wiki/Printing_Tables
61 | //
62 |
63 | thead {
64 | display: table-header-group;
65 | }
66 |
67 | tr,
68 | img {
69 | page-break-inside: avoid;
70 | }
71 |
72 | p,
73 | h2,
74 | h3 {
75 | orphans: 3;
76 | widows: 3;
77 | }
78 |
79 | h2,
80 | h3 {
81 | page-break-after: avoid;
82 | }
83 |
84 | // Bootstrap specific changes start
85 |
86 | // Specify a size and min-width to make printing closer across browsers.
87 | // We don't set margin here because it breaks `size` in Chrome. We also
88 | // don't use `!important` on `size` as it breaks in Chrome.
89 | @page {
90 | size: $print-page-size;
91 | }
92 | body {
93 | min-width: $print-body-min-width !important;
94 | }
95 | .container {
96 | min-width: $print-body-min-width !important;
97 | }
98 |
99 | // Bootstrap components
100 | .navbar {
101 | display: none;
102 | }
103 | .badge {
104 | border: $border-width solid #000;
105 | }
106 |
107 | .table {
108 | border-collapse: collapse !important;
109 |
110 | td,
111 | th {
112 | background-color: #fff !important;
113 | }
114 | }
115 | .table-bordered {
116 | th,
117 | td {
118 | border: 1px solid #ddd !important;
119 | }
120 | }
121 |
122 | // Bootstrap specific changes end
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/_progress.scss:
--------------------------------------------------------------------------------
1 | @keyframes progress-bar-stripes {
2 | from { background-position: $progress-height 0; }
3 | to { background-position: 0 0; }
4 | }
5 |
6 | .progress {
7 | display: flex;
8 | height: $progress-height;
9 | overflow: hidden; // force rounded corners by cropping it
10 | font-size: $progress-font-size;
11 | background-color: $progress-bg;
12 | @include border-radius($progress-border-radius);
13 | @include box-shadow($progress-box-shadow);
14 | }
15 |
16 | .progress-bar {
17 | display: flex;
18 | flex-direction: column;
19 | justify-content: center;
20 | color: $progress-bar-color;
21 | text-align: center;
22 | background-color: $progress-bar-bg;
23 | @include transition($progress-bar-transition);
24 | }
25 |
26 | .progress-bar-striped {
27 | @include gradient-striped();
28 | background-size: $progress-height $progress-height;
29 | }
30 |
31 | .progress-bar-animated {
32 | animation: progress-bar-stripes $progress-bar-animation-timing;
33 | }
34 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/_root.scss:
--------------------------------------------------------------------------------
1 | :root {
2 | // Custom variable values only support SassScript inside `#{}`.
3 | @each $color, $value in $colors {
4 | --#{$color}: #{$value};
5 | }
6 |
7 | @each $color, $value in $theme-colors {
8 | --#{$color}: #{$value};
9 | }
10 |
11 | @each $bp, $value in $grid-breakpoints {
12 | --breakpoint-#{$bp}: #{$value};
13 | }
14 |
15 | // Use `inspect` for lists so that quoted items keep the quotes.
16 | // See https://github.com/sass/sass/issues/2383#issuecomment-336349172
17 | --font-family-sans-serif: #{inspect($font-family-sans-serif)};
18 | --font-family-monospace: #{inspect($font-family-monospace)};
19 | }
20 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/_tables.scss:
--------------------------------------------------------------------------------
1 | //
2 | // Basic Bootstrap table
3 | //
4 |
5 | .table {
6 | width: 100%;
7 | max-width: 100%;
8 | margin-bottom: $spacer;
9 | background-color: $table-bg; // Reset for nesting within parents with `background-color`.
10 |
11 | th,
12 | td {
13 | padding: $table-cell-padding;
14 | vertical-align: top;
15 | border-top: $table-border-width solid $table-border-color;
16 | }
17 |
18 | thead th {
19 | vertical-align: bottom;
20 | border-bottom: (2 * $table-border-width) solid $table-border-color;
21 | }
22 |
23 | tbody + tbody {
24 | border-top: (2 * $table-border-width) solid $table-border-color;
25 | }
26 |
27 | .table {
28 | background-color: $body-bg;
29 | }
30 | }
31 |
32 |
33 | //
34 | // Condensed table w/ half padding
35 | //
36 |
37 | .table-sm {
38 | th,
39 | td {
40 | padding: $table-cell-padding-sm;
41 | }
42 | }
43 |
44 |
45 | // Bordered version
46 | //
47 | // Add borders all around the table and between all the columns.
48 |
49 | .table-bordered {
50 | border: $table-border-width solid $table-border-color;
51 |
52 | th,
53 | td {
54 | border: $table-border-width solid $table-border-color;
55 | }
56 |
57 | thead {
58 | th,
59 | td {
60 | border-bottom-width: (2 * $table-border-width);
61 | }
62 | }
63 | }
64 |
65 |
66 | // Zebra-striping
67 | //
68 | // Default zebra-stripe styles (alternating gray and transparent backgrounds)
69 |
70 | .table-striped {
71 | tbody tr:nth-of-type(odd) {
72 | background-color: $table-accent-bg;
73 | }
74 | }
75 |
76 |
77 | // Hover effect
78 | //
79 | // Placed here since it has to come after the potential zebra striping
80 |
81 | .table-hover {
82 | tbody tr {
83 | @include hover {
84 | background-color: $table-hover-bg;
85 | }
86 | }
87 | }
88 |
89 |
90 | // Table backgrounds
91 | //
92 | // Exact selectors below required to override `.table-striped` and prevent
93 | // inheritance to nested tables.
94 |
95 | @each $color, $value in $theme-colors {
96 | @include table-row-variant($color, theme-color-level($color, -9));
97 | }
98 |
99 | @include table-row-variant(active, $table-active-bg);
100 |
101 |
102 | // Dark styles
103 | //
104 | // Same table markup, but inverted color scheme: dark background and light text.
105 |
106 | // stylelint-disable-next-line no-duplicate-selectors
107 | .table {
108 | .thead-dark {
109 | th {
110 | color: $table-dark-color;
111 | background-color: $table-dark-bg;
112 | border-color: $table-dark-border-color;
113 | }
114 | }
115 |
116 | .thead-light {
117 | th {
118 | color: $table-head-color;
119 | background-color: $table-head-bg;
120 | border-color: $table-border-color;
121 | }
122 | }
123 | }
124 |
125 | .table-dark {
126 | color: $table-dark-color;
127 | background-color: $table-dark-bg;
128 |
129 | th,
130 | td,
131 | thead th {
132 | border-color: $table-dark-border-color;
133 | }
134 |
135 | &.table-bordered {
136 | border: 0;
137 | }
138 |
139 | &.table-striped {
140 | tbody tr:nth-of-type(odd) {
141 | background-color: $table-dark-accent-bg;
142 | }
143 | }
144 |
145 | &.table-hover {
146 | tbody tr {
147 | @include hover {
148 | background-color: $table-dark-hover-bg;
149 | }
150 | }
151 | }
152 | }
153 |
154 |
155 | // Responsive tables
156 | //
157 | // Generate series of `.table-responsive-*` classes for configuring the screen
158 | // size of where your table will overflow.
159 |
160 | .table-responsive {
161 | @each $breakpoint in map-keys($grid-breakpoints) {
162 | $next: breakpoint-next($breakpoint, $grid-breakpoints);
163 | $infix: breakpoint-infix($next, $grid-breakpoints);
164 |
165 | {$infix} {
166 | @include media-breakpoint-down($breakpoint) {
167 | display: block;
168 | width: 100%;
169 | overflow-x: auto;
170 | -webkit-overflow-scrolling: touch;
171 | -ms-overflow-style: -ms-autohiding-scrollbar; // See https://github.com/twbs/bootstrap/pull/10057
172 |
173 | // Prevent double border on horizontal scroll due to use of `display: block;`
174 | > .table-bordered {
175 | border: 0;
176 | }
177 | }
178 | }
179 | }
180 | }
181 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/_tooltip.scss:
--------------------------------------------------------------------------------
1 | // Base class
2 | .tooltip {
3 | position: absolute;
4 | z-index: $zindex-tooltip;
5 | display: block;
6 | margin: $tooltip-margin;
7 | // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.
8 | // So reset our font and text properties to avoid inheriting weird values.
9 | @include reset-text();
10 | font-size: $tooltip-font-size;
11 | // Allow breaking very long words so they don't overflow the tooltip's bounds
12 | word-wrap: break-word;
13 | opacity: 0;
14 |
15 | &.show { opacity: $tooltip-opacity; }
16 |
17 | .arrow {
18 | position: absolute;
19 | display: block;
20 | width: $tooltip-arrow-width;
21 | height: $tooltip-arrow-height;
22 |
23 | &::before {
24 | position: absolute;
25 | content: "";
26 | border-color: transparent;
27 | border-style: solid;
28 | }
29 | }
30 | }
31 |
32 | .bs-tooltip-top {
33 | padding: $tooltip-arrow-height 0;
34 |
35 | .arrow {
36 | bottom: 0;
37 |
38 | &::before {
39 | top: 0;
40 | border-width: $tooltip-arrow-height ($tooltip-arrow-width / 2) 0;
41 | border-top-color: $tooltip-arrow-color;
42 | }
43 | }
44 | }
45 |
46 | .bs-tooltip-right {
47 | padding: 0 $tooltip-arrow-height;
48 |
49 | .arrow {
50 | left: 0;
51 | width: $tooltip-arrow-height;
52 | height: $tooltip-arrow-width;
53 |
54 | &::before {
55 | right: 0;
56 | border-width: ($tooltip-arrow-width / 2) $tooltip-arrow-height ($tooltip-arrow-width / 2) 0;
57 | border-right-color: $tooltip-arrow-color;
58 | }
59 | }
60 | }
61 |
62 | .bs-tooltip-bottom {
63 | padding: $tooltip-arrow-height 0;
64 |
65 | .arrow {
66 | top: 0;
67 |
68 | &::before {
69 | bottom: 0;
70 | border-width: 0 ($tooltip-arrow-width / 2) $tooltip-arrow-height;
71 | border-bottom-color: $tooltip-arrow-color;
72 | }
73 | }
74 | }
75 |
76 | .bs-tooltip-left {
77 | padding: 0 $tooltip-arrow-height;
78 |
79 | .arrow {
80 | right: 0;
81 | width: $tooltip-arrow-height;
82 | height: $tooltip-arrow-width;
83 |
84 | &::before {
85 | left: 0;
86 | border-width: ($tooltip-arrow-width / 2) 0 ($tooltip-arrow-width / 2) $tooltip-arrow-height;
87 | border-left-color: $tooltip-arrow-color;
88 | }
89 | }
90 | }
91 |
92 | .bs-tooltip-auto {
93 | &[x-placement^="top"] {
94 | @extend .bs-tooltip-top;
95 | }
96 | &[x-placement^="right"] {
97 | @extend .bs-tooltip-right;
98 | }
99 | &[x-placement^="bottom"] {
100 | @extend .bs-tooltip-bottom;
101 | }
102 | &[x-placement^="left"] {
103 | @extend .bs-tooltip-left;
104 | }
105 | }
106 |
107 | // Wrapper for the tooltip content
108 | .tooltip-inner {
109 | max-width: $tooltip-max-width;
110 | padding: $tooltip-padding-y $tooltip-padding-x;
111 | color: $tooltip-color;
112 | text-align: center;
113 | background-color: $tooltip-bg;
114 | @include border-radius($tooltip-border-radius);
115 | }
116 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/_transitions.scss:
--------------------------------------------------------------------------------
1 | // stylelint-disable selector-no-qualifying-type
2 |
3 | .fade {
4 | opacity: 0;
5 | @include transition($transition-fade);
6 |
7 | &.show {
8 | opacity: 1;
9 | }
10 | }
11 |
12 | .collapse {
13 | display: none;
14 | &.show {
15 | display: block;
16 | }
17 | }
18 |
19 | tr {
20 | &.collapse.show {
21 | display: table-row;
22 | }
23 | }
24 |
25 | tbody {
26 | &.collapse.show {
27 | display: table-row-group;
28 | }
29 | }
30 |
31 | .collapsing {
32 | position: relative;
33 | height: 0;
34 | overflow: hidden;
35 | @include transition($transition-collapse);
36 | }
37 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/_type.scss:
--------------------------------------------------------------------------------
1 | // stylelint-disable declaration-no-important, selector-list-comma-newline-after
2 |
3 | //
4 | // Headings
5 | //
6 |
7 | h1, h2, h3, h4, h5, h6,
8 | .h1, .h2, .h3, .h4, .h5, .h6 {
9 | margin-bottom: $headings-margin-bottom;
10 | font-family: $headings-font-family;
11 | font-weight: $headings-font-weight;
12 | line-height: $headings-line-height;
13 | color: $headings-color;
14 | }
15 |
16 | h1, .h1 { font-size: $h1-font-size; }
17 | h2, .h2 { font-size: $h2-font-size; }
18 | h3, .h3 { font-size: $h3-font-size; }
19 | h4, .h4 { font-size: $h4-font-size; }
20 | h5, .h5 { font-size: $h5-font-size; }
21 | h6, .h6 { font-size: $h6-font-size; }
22 |
23 | .lead {
24 | font-size: $lead-font-size;
25 | font-weight: $lead-font-weight;
26 | }
27 |
28 | // Type display classes
29 | .display-1 {
30 | font-size: $display1-size;
31 | font-weight: $display1-weight;
32 | line-height: $display-line-height;
33 | }
34 | .display-2 {
35 | font-size: $display2-size;
36 | font-weight: $display2-weight;
37 | line-height: $display-line-height;
38 | }
39 | .display-3 {
40 | font-size: $display3-size;
41 | font-weight: $display3-weight;
42 | line-height: $display-line-height;
43 | }
44 | .display-4 {
45 | font-size: $display4-size;
46 | font-weight: $display4-weight;
47 | line-height: $display-line-height;
48 | }
49 |
50 |
51 | //
52 | // Horizontal rules
53 | //
54 |
55 | hr {
56 | margin-top: $hr-margin-y;
57 | margin-bottom: $hr-margin-y;
58 | border: 0;
59 | border-top: $hr-border-width solid $hr-border-color;
60 | }
61 |
62 |
63 | //
64 | // Emphasis
65 | //
66 |
67 | small,
68 | .small {
69 | font-size: $small-font-size;
70 | font-weight: $font-weight-normal;
71 | }
72 |
73 | mark,
74 | .mark {
75 | padding: $mark-padding;
76 | background-color: $mark-bg;
77 | }
78 |
79 |
80 | //
81 | // Lists
82 | //
83 |
84 | .list-unstyled {
85 | @include list-unstyled;
86 | }
87 |
88 | // Inline turns list items into inline-block
89 | .list-inline {
90 | @include list-unstyled;
91 | }
92 | .list-inline-item {
93 | display: inline-block;
94 |
95 | &:not(:last-child) {
96 | margin-right: $list-inline-padding;
97 | }
98 | }
99 |
100 |
101 | //
102 | // Misc
103 | //
104 |
105 | // Builds on `abbr`
106 | .initialism {
107 | font-size: 90%;
108 | text-transform: uppercase;
109 | }
110 |
111 | // Blockquotes
112 | .blockquote {
113 | margin-bottom: $spacer;
114 | font-size: $blockquote-font-size;
115 | }
116 |
117 | .blockquote-footer {
118 | display: block;
119 | font-size: 80%; // back to default font-size
120 | color: $blockquote-small-color;
121 |
122 | &::before {
123 | content: "\2014 \00A0"; // em dash, nbsp
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/_utilities.scss:
--------------------------------------------------------------------------------
1 | @import "utilities/align";
2 | @import "utilities/background";
3 | @import "utilities/borders";
4 | @import "utilities/clearfix";
5 | @import "utilities/display";
6 | @import "utilities/embed";
7 | @import "utilities/flex";
8 | @import "utilities/float";
9 | @import "utilities/position";
10 | @import "utilities/screenreaders";
11 | @import "utilities/sizing";
12 | @import "utilities/spacing";
13 | @import "utilities/text";
14 | @import "utilities/visibility";
15 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/bootstrap.scss:
--------------------------------------------------------------------------------
1 | @import "functions";
2 | @import "variables";
3 | @import "mixins";
4 | @import "root";
5 | @import "reboot";
6 | @import "type";
7 | @import "images";
8 | @import "code";
9 | @import "grid";
10 | @import "tables";
11 | @import "forms";
12 | @import "buttons";
13 | // @import "transitions";
14 | // @import "dropdown";
15 | @import "button-group";
16 | @import "input-group";
17 | // @import "custom-forms";
18 | @import "nav";
19 | @import "navbar";
20 | // @import "card";
21 | // @import "breadcrumb";
22 | // @import "pagination";
23 | @import "badge";
24 | @import "jumbotron";
25 | // @import "alert";
26 | // @import "progress";
27 | // @import "media";
28 | // @import "list-group";
29 | // @import "close";
30 | // @import "modal";
31 | // @import "tooltip";
32 | // @import "popover";
33 | // @import "carousel";
34 | @import "utilities";
35 | @import "print";
36 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/mixins/_alert.scss:
--------------------------------------------------------------------------------
1 | @mixin alert-variant($background, $border, $color) {
2 | color: $color;
3 | @include gradient-bg($background);
4 | border-color: $border;
5 |
6 | hr {
7 | border-top-color: darken($border, 5%);
8 | }
9 |
10 | .alert-link {
11 | color: darken($color, 10%);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/mixins/_background-variant.scss:
--------------------------------------------------------------------------------
1 | // stylelint-disable declaration-no-important
2 |
3 | // Contextual backgrounds
4 |
5 | @mixin bg-variant($parent, $color) {
6 | #{$parent} {
7 | background-color: $color !important;
8 | }
9 | a#{$parent},
10 | button#{$parent} {
11 | @include hover-focus {
12 | background-color: darken($color, 10%) !important;
13 | }
14 | }
15 | }
16 |
17 | @mixin bg-gradient-variant($parent, $color) {
18 | #{$parent} {
19 | background: $color linear-gradient(180deg, mix($body-bg, $color, 15%), $color) repeat-x !important;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/mixins/_badge.scss:
--------------------------------------------------------------------------------
1 | @mixin badge-variant($bg) {
2 | color: color-yiq($bg);
3 | background-color: $bg;
4 |
5 | &[href] {
6 | @include hover-focus {
7 | color: color-yiq($bg);
8 | text-decoration: none;
9 | background-color: darken($bg, 10%);
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/mixins/_border-radius.scss:
--------------------------------------------------------------------------------
1 | // Single side border-radius
2 |
3 | @mixin border-radius($radius: $border-radius) {
4 | @if $enable-rounded {
5 | border-radius: $radius;
6 | }
7 | }
8 |
9 | @mixin border-top-radius($radius) {
10 | @if $enable-rounded {
11 | border-top-left-radius: $radius;
12 | border-top-right-radius: $radius;
13 | }
14 | }
15 |
16 | @mixin border-right-radius($radius) {
17 | @if $enable-rounded {
18 | border-top-right-radius: $radius;
19 | border-bottom-right-radius: $radius;
20 | }
21 | }
22 |
23 | @mixin border-bottom-radius($radius) {
24 | @if $enable-rounded {
25 | border-bottom-right-radius: $radius;
26 | border-bottom-left-radius: $radius;
27 | }
28 | }
29 |
30 | @mixin border-left-radius($radius) {
31 | @if $enable-rounded {
32 | border-top-left-radius: $radius;
33 | border-bottom-left-radius: $radius;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/mixins/_box-shadow.scss:
--------------------------------------------------------------------------------
1 | @mixin box-shadow($shadow...) {
2 | @if $enable-shadows {
3 | box-shadow: $shadow;
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/mixins/_breakpoints.scss:
--------------------------------------------------------------------------------
1 | // Breakpoint viewport sizes and media queries.
2 | //
3 | // Breakpoints are defined as a map of (name: minimum width), order from small to large:
4 | //
5 | // (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)
6 | //
7 | // The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.
8 |
9 | // Name of the next breakpoint, or null for the last breakpoint.
10 | //
11 | // >> breakpoint-next(sm)
12 | // md
13 | // >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
14 | // md
15 | // >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl))
16 | // md
17 | @function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {
18 | $n: index($breakpoint-names, $name);
19 | @return if($n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);
20 | }
21 |
22 | // Minimum breakpoint width. Null for the smallest (first) breakpoint.
23 | //
24 | // >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
25 | // 576px
26 | @function breakpoint-min($name, $breakpoints: $grid-breakpoints) {
27 | $min: map-get($breakpoints, $name);
28 | @return if($min != 0, $min, null);
29 | }
30 |
31 | // Maximum breakpoint width. Null for the largest (last) breakpoint.
32 | // The maximum value is calculated as the minimum of the next one less 0.02px
33 | // to work around the limitations of `min-` and `max-` prefixes and viewports with fractional widths.
34 | // See https://www.w3.org/TR/mediaqueries-4/#mq-min-max
35 | // Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.
36 | // See https://bugs.webkit.org/show_bug.cgi?id=178261
37 | //
38 | // >> breakpoint-max(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
39 | // 767.98px
40 | @function breakpoint-max($name, $breakpoints: $grid-breakpoints) {
41 | $next: breakpoint-next($name, $breakpoints);
42 | @return if($next, breakpoint-min($next, $breakpoints) - .02px, null);
43 | }
44 |
45 | // Returns a blank string if smallest breakpoint, otherwise returns the name with a dash infront.
46 | // Useful for making responsive utilities.
47 | //
48 | // >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
49 | // "" (Returns a blank string)
50 | // >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
51 | // "-sm"
52 | @function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {
53 | @return if(breakpoint-min($name, $breakpoints) == null, "", "-#{$name}");
54 | }
55 |
56 | // Media of at least the minimum breakpoint width. No query for the smallest breakpoint.
57 | // Makes the @content apply to the given breakpoint and wider.
58 | @mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {
59 | $min: breakpoint-min($name, $breakpoints);
60 | @if $min {
61 | @media (min-width: $min) {
62 | @content;
63 | }
64 | } @else {
65 | @content;
66 | }
67 | }
68 |
69 | // Media of at most the maximum breakpoint width. No query for the largest breakpoint.
70 | // Makes the @content apply to the given breakpoint and narrower.
71 | @mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) {
72 | $max: breakpoint-max($name, $breakpoints);
73 | @if $max {
74 | @media (max-width: $max) {
75 | @content;
76 | }
77 | } @else {
78 | @content;
79 | }
80 | }
81 |
82 | // Media that spans multiple breakpoint widths.
83 | // Makes the @content apply between the min and max breakpoints
84 | @mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {
85 | $min: breakpoint-min($lower, $breakpoints);
86 | $max: breakpoint-max($upper, $breakpoints);
87 |
88 | @if $min != null and $max != null {
89 | @media (min-width: $min) and (max-width: $max) {
90 | @content;
91 | }
92 | } @else if $max == null {
93 | @include media-breakpoint-up($lower, $breakpoints) {
94 | @content;
95 | }
96 | } @else if $min == null {
97 | @include media-breakpoint-down($upper, $breakpoints) {
98 | @content;
99 | }
100 | }
101 | }
102 |
103 | // Media between the breakpoint's minimum and maximum widths.
104 | // No minimum for the smallest breakpoint, and no maximum for the largest one.
105 | // Makes the @content apply only to the given breakpoint, not viewports any wider or narrower.
106 | @mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) {
107 | $min: breakpoint-min($name, $breakpoints);
108 | $max: breakpoint-max($name, $breakpoints);
109 |
110 | @if $min != null and $max != null {
111 | @media (min-width: $min) and (max-width: $max) {
112 | @content;
113 | }
114 | } @else if $max == null {
115 | @include media-breakpoint-up($name, $breakpoints) {
116 | @content;
117 | }
118 | } @else if $min == null {
119 | @include media-breakpoint-down($name, $breakpoints) {
120 | @content;
121 | }
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/mixins/_buttons.scss:
--------------------------------------------------------------------------------
1 | // Button variants
2 | //
3 | // Easily pump out default styles, as well as :hover, :focus, :active,
4 | // and disabled options for all buttons
5 |
6 | @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%)) {
7 | color: color-yiq($background);
8 | @include gradient-bg($background);
9 | border-color: $border;
10 | @include box-shadow($btn-box-shadow);
11 |
12 | @include hover {
13 | color: color-yiq($hover-background);
14 | @include gradient-bg($hover-background);
15 | border-color: $hover-border;
16 | }
17 |
18 | &:focus,
19 | &.focus {
20 | // Avoid using mixin so we can pass custom focus shadow properly
21 | @if $enable-shadows {
22 | box-shadow: $btn-box-shadow, 0 0 0 $btn-focus-width rgba($border, .5);
23 | } @else {
24 | box-shadow: 0 0 0 $btn-focus-width rgba($border, .5);
25 | }
26 | }
27 |
28 | // Disabled comes first so active can properly restyle
29 | &.disabled,
30 | &:disabled {
31 | color: color-yiq($background);
32 | background-color: $background;
33 | border-color: $border;
34 | }
35 |
36 | &:not(:disabled):not(.disabled):active,
37 | &:not(:disabled):not(.disabled).active,
38 | .show > &.dropdown-toggle {
39 | color: color-yiq($active-background);
40 | background-color: $active-background;
41 | @if $enable-gradients {
42 | background-image: none; // Remove the gradient for the pressed/active state
43 | }
44 | border-color: $active-border;
45 |
46 | &:focus {
47 | // Avoid using mixin so we can pass custom focus shadow properly
48 | @if $enable-shadows {
49 | box-shadow: $btn-active-box-shadow, 0 0 0 $btn-focus-width rgba($border, .5);
50 | } @else {
51 | box-shadow: 0 0 0 $btn-focus-width rgba($border, .5);
52 | }
53 | }
54 | }
55 | }
56 |
57 | @mixin button-outline-variant($color, $color-hover: color-yiq($color), $active-background: $color, $active-border: $color) {
58 | color: $color;
59 | background-color: transparent;
60 | background-image: none;
61 | border-color: $color;
62 |
63 | &:hover {
64 | color: $color-hover;
65 | background-color: $active-background;
66 | border-color: $active-border;
67 | }
68 |
69 | &:focus,
70 | &.focus {
71 | box-shadow: 0 0 0 $btn-focus-width rgba($color, .5);
72 | }
73 |
74 | &.disabled,
75 | &:disabled {
76 | color: $color;
77 | background-color: transparent;
78 | }
79 |
80 | &:not(:disabled):not(.disabled):active,
81 | &:not(:disabled):not(.disabled).active,
82 | .show > &.dropdown-toggle {
83 | color: color-yiq($active-background);
84 | background-color: $active-background;
85 | border-color: $active-border;
86 |
87 | &:focus {
88 | // Avoid using mixin so we can pass custom focus shadow properly
89 | @if $enable-shadows and $btn-active-box-shadow != none {
90 | box-shadow: $btn-active-box-shadow, 0 0 0 $btn-focus-width rgba($color, .5);
91 | } @else {
92 | box-shadow: 0 0 0 $btn-focus-width rgba($color, .5);
93 | }
94 | }
95 | }
96 | }
97 |
98 | // Button sizes
99 | @mixin button-size($padding-y, $padding-x, $font-size, $line-height, $border-radius) {
100 | padding: $padding-y $padding-x;
101 | font-size: $font-size;
102 | line-height: $line-height;
103 | // Manually declare to provide an override to the browser default
104 | @if $enable-rounded {
105 | border-radius: $border-radius;
106 | } @else {
107 | border-radius: 0;
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/mixins/_caret.scss:
--------------------------------------------------------------------------------
1 | @mixin caret-down {
2 | border-top: $caret-width solid;
3 | border-right: $caret-width solid transparent;
4 | border-bottom: 0;
5 | border-left: $caret-width solid transparent;
6 | }
7 |
8 | @mixin caret-up {
9 | border-top: 0;
10 | border-right: $caret-width solid transparent;
11 | border-bottom: $caret-width solid;
12 | border-left: $caret-width solid transparent;
13 | }
14 |
15 | @mixin caret-right {
16 | border-top: $caret-width solid transparent;
17 | border-bottom: $caret-width solid transparent;
18 | border-left: $caret-width solid;
19 | }
20 |
21 | @mixin caret-left {
22 | border-top: $caret-width solid transparent;
23 | border-right: $caret-width solid;
24 | border-bottom: $caret-width solid transparent;
25 | }
26 |
27 | @mixin caret($direction: down) {
28 | @if $enable-caret {
29 | &::after {
30 | display: inline-block;
31 | width: 0;
32 | height: 0;
33 | margin-left: $caret-width * .85;
34 | vertical-align: $caret-width * .85;
35 | content: "";
36 | @if $direction == down {
37 | @include caret-down;
38 | } @else if $direction == up {
39 | @include caret-up;
40 | } @else if $direction == right {
41 | @include caret-right;
42 | }
43 | }
44 |
45 | @if $direction == left {
46 | &::after {
47 | display: none;
48 | }
49 |
50 | &::before {
51 | display: inline-block;
52 | width: 0;
53 | height: 0;
54 | margin-right: $caret-width * .85;
55 | vertical-align: $caret-width * .85;
56 | content: "";
57 | @include caret-left;
58 | }
59 | }
60 |
61 | &:empty::after {
62 | margin-left: 0;
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/mixins/_clearfix.scss:
--------------------------------------------------------------------------------
1 | @mixin clearfix() {
2 | &::after {
3 | display: block;
4 | clear: both;
5 | content: "";
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/mixins/_float.scss:
--------------------------------------------------------------------------------
1 | // stylelint-disable declaration-no-important
2 |
3 | @mixin float-left {
4 | float: left !important;
5 | }
6 | @mixin float-right {
7 | float: right !important;
8 | }
9 | @mixin float-none {
10 | float: none !important;
11 | }
12 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/mixins/_forms.scss:
--------------------------------------------------------------------------------
1 | // Form control focus state
2 | //
3 | // Generate a customized focus state and for any input with the specified color,
4 | // which defaults to the `$input-focus-border-color` variable.
5 | //
6 | // We highly encourage you to not customize the default value, but instead use
7 | // this to tweak colors on an as-needed basis. This aesthetic change is based on
8 | // WebKit's default styles, but applicable to a wider range of browsers. Its
9 | // usability and accessibility should be taken into account with any change.
10 | //
11 | // Example usage: change the default blue border and shadow to white for better
12 | // contrast against a dark gray background.
13 | @mixin form-control-focus() {
14 | &:focus {
15 | color: $input-focus-color;
16 | background-color: $input-focus-bg;
17 | border-color: $input-focus-border-color;
18 | outline: 0;
19 | // Avoid using mixin so we can pass custom focus shadow properly
20 | @if $enable-shadows {
21 | box-shadow: $input-box-shadow, $input-focus-box-shadow;
22 | } @else {
23 | box-shadow: $input-focus-box-shadow;
24 | }
25 | }
26 | }
27 |
28 |
29 | @mixin form-validation-state($state, $color) {
30 | .#{$state}-feedback {
31 | display: none;
32 | width: 100%;
33 | margin-top: $form-feedback-margin-top;
34 | font-size: $form-feedback-font-size;
35 | color: $color;
36 | }
37 |
38 | .#{$state}-tooltip {
39 | position: absolute;
40 | top: 100%;
41 | z-index: 5;
42 | display: none;
43 | max-width: 100%; // Contain to parent when possible
44 | padding: .5rem;
45 | margin-top: .1rem;
46 | font-size: .875rem;
47 | line-height: 1;
48 | color: #fff;
49 | background-color: rgba($color, .8);
50 | border-radius: .2rem;
51 | }
52 |
53 | .form-control,
54 | .custom-select {
55 | .was-validated &:#{$state},
56 | &.is-#{$state} {
57 | border-color: $color;
58 |
59 | &:focus {
60 | border-color: $color;
61 | box-shadow: 0 0 0 $input-focus-width rgba($color, .25);
62 | }
63 |
64 | ~ .#{$state}-feedback,
65 | ~ .#{$state}-tooltip {
66 | display: block;
67 | }
68 | }
69 | }
70 |
71 | .form-check-input {
72 | .was-validated &:#{$state},
73 | &.is-#{$state} {
74 | ~ .form-check-label {
75 | color: $color;
76 | }
77 |
78 | ~ .#{$state}-feedback,
79 | ~ .#{$state}-tooltip {
80 | display: block;
81 | }
82 | }
83 | }
84 |
85 | .custom-control-input {
86 | .was-validated &:#{$state},
87 | &.is-#{$state} {
88 | ~ .custom-control-label {
89 | color: $color;
90 |
91 | &::before {
92 | background-color: lighten($color, 25%);
93 | }
94 | }
95 |
96 | ~ .#{$state}-feedback,
97 | ~ .#{$state}-tooltip {
98 | display: block;
99 | }
100 |
101 | &:checked {
102 | ~ .custom-control-label::before {
103 | @include gradient-bg(lighten($color, 10%));
104 | }
105 | }
106 |
107 | &:focus {
108 | ~ .custom-control-label::before {
109 | box-shadow: 0 0 0 1px $body-bg, 0 0 0 $input-focus-width rgba($color, .25);
110 | }
111 | }
112 | }
113 | }
114 |
115 | // custom file
116 | .custom-file-input {
117 | .was-validated &:#{$state},
118 | &.is-#{$state} {
119 | ~ .custom-file-label {
120 | border-color: $color;
121 |
122 | &::before { border-color: inherit; }
123 | }
124 |
125 | ~ .#{$state}-feedback,
126 | ~ .#{$state}-tooltip {
127 | display: block;
128 | }
129 |
130 | &:focus {
131 | ~ .custom-file-label {
132 | box-shadow: 0 0 0 $input-focus-width rgba($color, .25);
133 | }
134 | }
135 | }
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/mixins/_gradients.scss:
--------------------------------------------------------------------------------
1 | // Gradients
2 |
3 | @mixin gradient-bg($color) {
4 | @if $enable-gradients {
5 | background: $color linear-gradient(180deg, mix($body-bg, $color, 15%), $color) repeat-x;
6 | } @else {
7 | background-color: $color;
8 | }
9 | }
10 |
11 | // Horizontal gradient, from left to right
12 | //
13 | // Creates two color stops, start and end, by specifying a color and position for each color stop.
14 | @mixin gradient-x($start-color: #555, $end-color: #333, $start-percent: 0%, $end-percent: 100%) {
15 | background-image: linear-gradient(to right, $start-color $start-percent, $end-color $end-percent);
16 | background-repeat: repeat-x;
17 | }
18 |
19 | // Vertical gradient, from top to bottom
20 | //
21 | // Creates two color stops, start and end, by specifying a color and position for each color stop.
22 | @mixin gradient-y($start-color: #555, $end-color: #333, $start-percent: 0%, $end-percent: 100%) {
23 | background-image: linear-gradient(to bottom, $start-color $start-percent, $end-color $end-percent);
24 | background-repeat: repeat-x;
25 | }
26 |
27 | @mixin gradient-directional($start-color: #555, $end-color: #333, $deg: 45deg) {
28 | background-image: linear-gradient($deg, $start-color, $end-color);
29 | background-repeat: repeat-x;
30 | }
31 | @mixin gradient-x-three-colors($start-color: #00b3ee, $mid-color: #7a43b6, $color-stop: 50%, $end-color: #c3325f) {
32 | background-image: linear-gradient(to right, $start-color, $mid-color $color-stop, $end-color);
33 | background-repeat: no-repeat;
34 | }
35 | @mixin gradient-y-three-colors($start-color: #00b3ee, $mid-color: #7a43b6, $color-stop: 50%, $end-color: #c3325f) {
36 | background-image: linear-gradient($start-color, $mid-color $color-stop, $end-color);
37 | background-repeat: no-repeat;
38 | }
39 | @mixin gradient-radial($inner-color: #555, $outer-color: #333) {
40 | background-image: radial-gradient(circle, $inner-color, $outer-color);
41 | background-repeat: no-repeat;
42 | }
43 | @mixin gradient-striped($color: rgba(255,255,255,.15), $angle: 45deg) {
44 | background-image: linear-gradient($angle, $color 25%, transparent 25%, transparent 50%, $color 50%, $color 75%, transparent 75%, transparent);
45 | }
46 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/mixins/_grid-framework.scss:
--------------------------------------------------------------------------------
1 | // Framework grid generation
2 | //
3 | // Used only by Bootstrap to generate the correct number of grid classes given
4 | // any value of `$grid-columns`.
5 |
6 | @mixin make-grid-columns($columns: $grid-columns, $gutter: $grid-gutter-width, $breakpoints: $grid-breakpoints) {
7 | // Common properties for all breakpoints
8 | %grid-column {
9 | position: relative;
10 | width: 100%;
11 | min-height: 1px; // Prevent columns from collapsing when empty
12 | padding-right: ($gutter / 2);
13 | padding-left: ($gutter / 2);
14 | }
15 |
16 | @each $breakpoint in map-keys($breakpoints) {
17 | $infix: breakpoint-infix($breakpoint, $breakpoints);
18 |
19 | // Allow columns to stretch full width below their breakpoints
20 | @for $i from 1 through $columns {
21 | .col#{$infix}-#{$i} {
22 | @extend %grid-column;
23 | }
24 | }
25 | .col#{$infix},
26 | .col#{$infix}-auto {
27 | @extend %grid-column;
28 | }
29 |
30 | @include media-breakpoint-up($breakpoint, $breakpoints) {
31 | // Provide basic `.col-{bp}` classes for equal-width flexbox columns
32 | .col#{$infix} {
33 | flex-basis: 0;
34 | flex-grow: 1;
35 | max-width: 100%;
36 | }
37 | .col#{$infix}-auto {
38 | flex: 0 0 auto;
39 | width: auto;
40 | max-width: none; // Reset earlier grid tiers
41 | }
42 |
43 | @for $i from 1 through $columns {
44 | .col#{$infix}-#{$i} {
45 | @include make-col($i, $columns);
46 | }
47 | }
48 |
49 | .order#{$infix}-first { order: -1; }
50 |
51 | .order#{$infix}-last { order: $columns + 1; }
52 |
53 | @for $i from 0 through $columns {
54 | .order#{$infix}-#{$i} { order: $i; }
55 | }
56 |
57 | // `$columns - 1` because offsetting by the width of an entire row isn't possible
58 | @for $i from 0 through ($columns - 1) {
59 | @if not ($infix == "" and $i == 0) { // Avoid emitting useless .offset-0
60 | .offset#{$infix}-#{$i} {
61 | @include make-col-offset($i, $columns);
62 | }
63 | }
64 | }
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/mixins/_grid.scss:
--------------------------------------------------------------------------------
1 | /// Grid system
2 | //
3 | // Generate semantic grid columns with these mixins.
4 |
5 | @mixin make-container() {
6 | width: 100%;
7 | padding-right: ($grid-gutter-width / 2);
8 | padding-left: ($grid-gutter-width / 2);
9 | margin-right: auto;
10 | margin-left: auto;
11 | }
12 |
13 |
14 | // For each breakpoint, define the maximum width of the container in a media query
15 | @mixin make-container-max-widths($max-widths: $container-max-widths, $breakpoints: $grid-breakpoints) {
16 | @each $breakpoint, $container-max-width in $max-widths {
17 | @include media-breakpoint-up($breakpoint, $breakpoints) {
18 | max-width: $container-max-width;
19 | }
20 | }
21 | }
22 |
23 | @mixin make-row() {
24 | display: flex;
25 | flex-wrap: wrap;
26 | margin-right: ($grid-gutter-width / -2);
27 | margin-left: ($grid-gutter-width / -2);
28 | }
29 |
30 | @mixin make-col-ready() {
31 | position: relative;
32 | // Prevent columns from becoming too narrow when at smaller grid tiers by
33 | // always setting `width: 100%;`. This works because we use `flex` values
34 | // later on to override this initial width.
35 | width: 100%;
36 | min-height: 1px; // Prevent collapsing
37 | padding-right: ($grid-gutter-width / 2);
38 | padding-left: ($grid-gutter-width / 2);
39 | }
40 |
41 | @mixin make-col($size, $columns: $grid-columns) {
42 | flex: 0 0 percentage($size / $columns);
43 | // Add a `max-width` to ensure content within each column does not blow out
44 | // the width of the column. Applies to IE10+ and Firefox. Chrome and Safari
45 | // do not appear to require this.
46 | max-width: percentage($size / $columns);
47 | }
48 |
49 | @mixin make-col-offset($size, $columns: $grid-columns) {
50 | $num: $size / $columns;
51 | margin-left: if($num == 0, 0, percentage($num));
52 | }
53 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/mixins/_hover.scss:
--------------------------------------------------------------------------------
1 | // stylelint-disable indentation
2 |
3 | // Hover mixin and `$enable-hover-media-query` are deprecated.
4 | //
5 | // Origally added during our alphas and maintained during betas, this mixin was
6 | // designed to prevent `:hover` stickiness on iOS—an issue where hover styles
7 | // would persist after initial touch.
8 | //
9 | // For backward compatibility, we've kept these mixins and updated them to
10 | // always return their regular psuedo-classes instead of a shimmed media query.
11 | //
12 | // Issue: https://github.com/twbs/bootstrap/issues/25195
13 |
14 | @mixin hover {
15 | &:hover { @content; }
16 | }
17 |
18 | @mixin hover-focus {
19 | &:hover,
20 | &:focus {
21 | @content;
22 | }
23 | }
24 |
25 | @mixin plain-hover-focus {
26 | &,
27 | &:hover,
28 | &:focus {
29 | @content;
30 | }
31 | }
32 |
33 | @mixin hover-focus-active {
34 | &:hover,
35 | &:focus,
36 | &:active {
37 | @content;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/mixins/_image.scss:
--------------------------------------------------------------------------------
1 | // Image Mixins
2 | // - Responsive image
3 | // - Retina image
4 |
5 |
6 | // Responsive image
7 | //
8 | // Keep images from scaling beyond the width of their parents.
9 |
10 | @mixin img-fluid {
11 | // Part 1: Set a maximum relative to the parent
12 | max-width: 100%;
13 | // Part 2: Override the height to auto, otherwise images will be stretched
14 | // when setting a width and height attribute on the img element.
15 | height: auto;
16 | }
17 |
18 |
19 | // Retina image
20 | //
21 | // Short retina mixin for setting background-image and -size.
22 |
23 | // stylelint-disable indentation, media-query-list-comma-newline-after
24 | @mixin img-retina($file-1x, $file-2x, $width-1x, $height-1x) {
25 | background-image: url($file-1x);
26 |
27 | // Autoprefixer takes care of adding -webkit-min-device-pixel-ratio and -o-min-device-pixel-ratio,
28 | // but doesn't convert dppx=>dpi.
29 | // There's no such thing as unprefixed min-device-pixel-ratio since it's nonstandard.
30 | // Compatibility info: https://caniuse.com/#feat=css-media-resolution
31 | @media only screen and (min-resolution: 192dpi), // IE9-11 don't support dppx
32 | only screen and (min-resolution: 2dppx) { // Standardized
33 | background-image: url($file-2x);
34 | background-size: $width-1x $height-1x;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/mixins/_list-group.scss:
--------------------------------------------------------------------------------
1 | // List Groups
2 |
3 | @mixin list-group-item-variant($state, $background, $color) {
4 | .list-group-item-#{$state} {
5 | color: $color;
6 | background-color: $background;
7 |
8 | &.list-group-item-action {
9 | @include hover-focus {
10 | color: $color;
11 | background-color: darken($background, 5%);
12 | }
13 |
14 | &.active {
15 | color: #fff;
16 | background-color: $color;
17 | border-color: $color;
18 | }
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/mixins/_lists.scss:
--------------------------------------------------------------------------------
1 | // Lists
2 |
3 | // Unstyled keeps list items block level, just removes default browser padding and list-style
4 | @mixin list-unstyled {
5 | padding-left: 0;
6 | list-style: none;
7 | }
8 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/mixins/_nav-divider.scss:
--------------------------------------------------------------------------------
1 | // Horizontal dividers
2 | //
3 | // Dividers (basically an hr) within dropdowns and nav lists
4 |
5 | @mixin nav-divider($color: #e5e5e5) {
6 | height: 0;
7 | margin: ($spacer / 2) 0;
8 | overflow: hidden;
9 | border-top: 1px solid $color;
10 | }
11 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/mixins/_navbar-align.scss:
--------------------------------------------------------------------------------
1 | // Navbar vertical align
2 | //
3 | // Vertically center elements in the navbar.
4 | // Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);`
5 | // to calculate the appropriate top margin.
6 |
7 | // @mixin navbar-vertical-align($element-height) {
8 | // margin-top: (($navbar-height - $element-height) / 2);
9 | // margin-bottom: (($navbar-height - $element-height) / 2);
10 | // }
11 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/mixins/_pagination.scss:
--------------------------------------------------------------------------------
1 | // Pagination
2 |
3 | @mixin pagination-size($padding-y, $padding-x, $font-size, $line-height, $border-radius) {
4 | .page-link {
5 | padding: $padding-y $padding-x;
6 | font-size: $font-size;
7 | line-height: $line-height;
8 | }
9 |
10 | .page-item {
11 | &:first-child {
12 | .page-link {
13 | @include border-left-radius($border-radius);
14 | }
15 | }
16 | &:last-child {
17 | .page-link {
18 | @include border-right-radius($border-radius);
19 | }
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/mixins/_reset-text.scss:
--------------------------------------------------------------------------------
1 | @mixin reset-text {
2 | font-family: $font-family-base;
3 | // We deliberately do NOT reset font-size or word-wrap.
4 | font-style: normal;
5 | font-weight: $font-weight-normal;
6 | line-height: $line-height-base;
7 | text-align: left; // Fallback for where `start` is not supported
8 | text-align: start; // stylelint-disable-line declaration-block-no-duplicate-properties
9 | text-decoration: none;
10 | text-shadow: none;
11 | text-transform: none;
12 | letter-spacing: normal;
13 | word-break: normal;
14 | word-spacing: normal;
15 | white-space: normal;
16 | line-break: auto;
17 | }
18 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/mixins/_resize.scss:
--------------------------------------------------------------------------------
1 | // Resize anything
2 |
3 | @mixin resizable($direction) {
4 | overflow: auto; // Per CSS3 UI, `resize` only applies when `overflow` isn't `visible`
5 | resize: $direction; // Options: horizontal, vertical, both
6 | }
7 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/mixins/_screen-reader.scss:
--------------------------------------------------------------------------------
1 | // Only display content to screen readers
2 | //
3 | // See: http://a11yproject.com/posts/how-to-hide-content/
4 | // See: https://hugogiraudel.com/2016/10/13/css-hide-and-seek/
5 |
6 | @mixin sr-only {
7 | position: absolute;
8 | width: 1px;
9 | height: 1px;
10 | padding: 0;
11 | overflow: hidden;
12 | clip: rect(0, 0, 0, 0);
13 | white-space: nowrap;
14 | clip-path: inset(50%);
15 | border: 0;
16 | }
17 |
18 | // Use in conjunction with .sr-only to only display content when it's focused.
19 | //
20 | // Useful for "Skip to main content" links; see https://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1
21 | //
22 | // Credit: HTML5 Boilerplate
23 |
24 | @mixin sr-only-focusable {
25 | &:active,
26 | &:focus {
27 | position: static;
28 | width: auto;
29 | height: auto;
30 | overflow: visible;
31 | clip: auto;
32 | white-space: normal;
33 | clip-path: none;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/mixins/_size.scss:
--------------------------------------------------------------------------------
1 | // Sizing shortcuts
2 |
3 | @mixin size($width, $height: $width) {
4 | width: $width;
5 | height: $height;
6 | }
7 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/mixins/_table-row.scss:
--------------------------------------------------------------------------------
1 | // Tables
2 |
3 | @mixin table-row-variant($state, $background) {
4 | // Exact selectors below required to override `.table-striped` and prevent
5 | // inheritance to nested tables.
6 | .table-#{$state} {
7 | &,
8 | > th,
9 | > td {
10 | background-color: $background;
11 | }
12 | }
13 |
14 | // Hover states for `.table-hover`
15 | // Note: this is not available for cells or rows within `thead` or `tfoot`.
16 | .table-hover {
17 | $hover-background: darken($background, 5%);
18 |
19 | .table-#{$state} {
20 | @include hover {
21 | background-color: $hover-background;
22 |
23 | > td,
24 | > th {
25 | background-color: $hover-background;
26 | }
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/mixins/_text-emphasis.scss:
--------------------------------------------------------------------------------
1 | // stylelint-disable declaration-no-important
2 |
3 | // Typography
4 |
5 | @mixin text-emphasis-variant($parent, $color) {
6 | #{$parent} {
7 | color: $color !important;
8 | }
9 | a#{$parent} {
10 | @include hover-focus {
11 | color: darken($color, 10%) !important;
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/mixins/_text-hide.scss:
--------------------------------------------------------------------------------
1 | // CSS image replacement
2 | @mixin text-hide() {
3 | // stylelint-disable-next-line font-family-no-missing-generic-family-keyword
4 | font: 0/0 a;
5 | color: transparent;
6 | text-shadow: none;
7 | background-color: transparent;
8 | border: 0;
9 | }
10 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/mixins/_text-truncate.scss:
--------------------------------------------------------------------------------
1 | // Text truncate
2 | // Requires inline-block or block for proper styling
3 |
4 | @mixin text-truncate() {
5 | overflow: hidden;
6 | text-overflow: ellipsis;
7 | white-space: nowrap;
8 | }
9 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/mixins/_transition.scss:
--------------------------------------------------------------------------------
1 | @mixin transition($transition...) {
2 | @if $enable-transitions {
3 | @if length($transition) == 0 {
4 | transition: $transition-base;
5 | } @else {
6 | transition: $transition;
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/mixins/_visibility.scss:
--------------------------------------------------------------------------------
1 | // stylelint-disable declaration-no-important
2 |
3 | // Visibility
4 |
5 | @mixin invisible($visibility) {
6 | visibility: $visibility !important;
7 | }
8 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/utilities/_align.scss:
--------------------------------------------------------------------------------
1 | // stylelint-disable declaration-no-important
2 |
3 | .align-baseline { vertical-align: baseline !important; } // Browser default
4 | .align-top { vertical-align: top !important; }
5 | .align-middle { vertical-align: middle !important; }
6 | .align-bottom { vertical-align: bottom !important; }
7 | .align-text-bottom { vertical-align: text-bottom !important; }
8 | .align-text-top { vertical-align: text-top !important; }
9 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/utilities/_background.scss:
--------------------------------------------------------------------------------
1 | // stylelint-disable declaration-no-important
2 |
3 | @each $color, $value in $theme-colors {
4 | @include bg-variant(".bg-#{$color}", $value);
5 | }
6 |
7 | @if $enable-gradients {
8 | @each $color, $value in $theme-colors {
9 | @include bg-gradient-variant(".bg-gradient-#{$color}", $value);
10 | }
11 | }
12 |
13 | .bg-white {
14 | background-color: $white !important;
15 | }
16 |
17 | .bg-transparent {
18 | background-color: transparent !important;
19 | }
20 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/utilities/_borders.scss:
--------------------------------------------------------------------------------
1 | // stylelint-disable declaration-no-important
2 |
3 | //
4 | // Border
5 | //
6 |
7 | .border { border: $border-width solid $border-color !important; }
8 | .border-top { border-top: $border-width solid $border-color !important; }
9 | .border-right { border-right: $border-width solid $border-color !important; }
10 | .border-bottom { border-bottom: $border-width solid $border-color !important; }
11 | .border-left { border-left: $border-width solid $border-color !important; }
12 |
13 | .border-0 { border: 0 !important; }
14 | .border-top-0 { border-top: 0 !important; }
15 | .border-right-0 { border-right: 0 !important; }
16 | .border-bottom-0 { border-bottom: 0 !important; }
17 | .border-left-0 { border-left: 0 !important; }
18 |
19 | @each $color, $value in $theme-colors {
20 | .border-#{$color} {
21 | border-color: $value !important;
22 | }
23 | }
24 |
25 | .border-white {
26 | border-color: $white !important;
27 | }
28 |
29 | //
30 | // Border-radius
31 | //
32 |
33 | .rounded {
34 | border-radius: $border-radius !important;
35 | }
36 | .rounded-top {
37 | border-top-left-radius: $border-radius !important;
38 | border-top-right-radius: $border-radius !important;
39 | }
40 | .rounded-right {
41 | border-top-right-radius: $border-radius !important;
42 | border-bottom-right-radius: $border-radius !important;
43 | }
44 | .rounded-bottom {
45 | border-bottom-right-radius: $border-radius !important;
46 | border-bottom-left-radius: $border-radius !important;
47 | }
48 | .rounded-left {
49 | border-top-left-radius: $border-radius !important;
50 | border-bottom-left-radius: $border-radius !important;
51 | }
52 |
53 | .rounded-circle {
54 | border-radius: 50% !important;
55 | }
56 |
57 | .rounded-0 {
58 | border-radius: 0 !important;
59 | }
60 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/utilities/_clearfix.scss:
--------------------------------------------------------------------------------
1 | .clearfix {
2 | @include clearfix();
3 | }
4 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/utilities/_display.scss:
--------------------------------------------------------------------------------
1 | // stylelint-disable declaration-no-important
2 |
3 | //
4 | // Utilities for common `display` values
5 | //
6 |
7 | @each $breakpoint in map-keys($grid-breakpoints) {
8 | @include media-breakpoint-up($breakpoint) {
9 | $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
10 |
11 | .d#{$infix}-none { display: none !important; }
12 | .d#{$infix}-inline { display: inline !important; }
13 | .d#{$infix}-inline-block { display: inline-block !important; }
14 | .d#{$infix}-block { display: block !important; }
15 | .d#{$infix}-table { display: table !important; }
16 | .d#{$infix}-table-row { display: table-row !important; }
17 | .d#{$infix}-table-cell { display: table-cell !important; }
18 | .d#{$infix}-flex { display: flex !important; }
19 | .d#{$infix}-inline-flex { display: inline-flex !important; }
20 | }
21 | }
22 |
23 |
24 | //
25 | // Utilities for toggling `display` in print
26 | //
27 |
28 | @media print {
29 | .d-print-none { display: none !important; }
30 | .d-print-inline { display: inline !important; }
31 | .d-print-inline-block { display: inline-block !important; }
32 | .d-print-block { display: block !important; }
33 | .d-print-table { display: table !important; }
34 | .d-print-table-row { display: table-row !important; }
35 | .d-print-table-cell { display: table-cell !important; }
36 | .d-print-flex { display: flex !important; }
37 | .d-print-inline-flex { display: inline-flex !important; }
38 | }
39 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/utilities/_embed.scss:
--------------------------------------------------------------------------------
1 | // Credit: Nicolas Gallagher and SUIT CSS.
2 |
3 | .embed-responsive {
4 | position: relative;
5 | display: block;
6 | width: 100%;
7 | padding: 0;
8 | overflow: hidden;
9 |
10 | &::before {
11 | display: block;
12 | content: "";
13 | }
14 |
15 | .embed-responsive-item,
16 | iframe,
17 | embed,
18 | object,
19 | video {
20 | position: absolute;
21 | top: 0;
22 | bottom: 0;
23 | left: 0;
24 | width: 100%;
25 | height: 100%;
26 | border: 0;
27 | }
28 | }
29 |
30 | .embed-responsive-21by9 {
31 | &::before {
32 | padding-top: percentage(9 / 21);
33 | }
34 | }
35 |
36 | .embed-responsive-16by9 {
37 | &::before {
38 | padding-top: percentage(9 / 16);
39 | }
40 | }
41 |
42 | .embed-responsive-4by3 {
43 | &::before {
44 | padding-top: percentage(3 / 4);
45 | }
46 | }
47 |
48 | .embed-responsive-1by1 {
49 | &::before {
50 | padding-top: percentage(1 / 1);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/utilities/_flex.scss:
--------------------------------------------------------------------------------
1 | // stylelint-disable declaration-no-important
2 |
3 | // Flex variation
4 | //
5 | // Custom styles for additional flex alignment options.
6 |
7 | @each $breakpoint in map-keys($grid-breakpoints) {
8 | @include media-breakpoint-up($breakpoint) {
9 | $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
10 |
11 | .flex#{$infix}-row { flex-direction: row !important; }
12 | .flex#{$infix}-column { flex-direction: column !important; }
13 | .flex#{$infix}-row-reverse { flex-direction: row-reverse !important; }
14 | .flex#{$infix}-column-reverse { flex-direction: column-reverse !important; }
15 |
16 | .flex#{$infix}-wrap { flex-wrap: wrap !important; }
17 | .flex#{$infix}-nowrap { flex-wrap: nowrap !important; }
18 | .flex#{$infix}-wrap-reverse { flex-wrap: wrap-reverse !important; }
19 |
20 | .justify-content#{$infix}-start { justify-content: flex-start !important; }
21 | .justify-content#{$infix}-end { justify-content: flex-end !important; }
22 | .justify-content#{$infix}-center { justify-content: center !important; }
23 | .justify-content#{$infix}-between { justify-content: space-between !important; }
24 | .justify-content#{$infix}-around { justify-content: space-around !important; }
25 |
26 | .align-items#{$infix}-start { align-items: flex-start !important; }
27 | .align-items#{$infix}-end { align-items: flex-end !important; }
28 | .align-items#{$infix}-center { align-items: center !important; }
29 | .align-items#{$infix}-baseline { align-items: baseline !important; }
30 | .align-items#{$infix}-stretch { align-items: stretch !important; }
31 |
32 | .align-content#{$infix}-start { align-content: flex-start !important; }
33 | .align-content#{$infix}-end { align-content: flex-end !important; }
34 | .align-content#{$infix}-center { align-content: center !important; }
35 | .align-content#{$infix}-between { align-content: space-between !important; }
36 | .align-content#{$infix}-around { align-content: space-around !important; }
37 | .align-content#{$infix}-stretch { align-content: stretch !important; }
38 |
39 | .align-self#{$infix}-auto { align-self: auto !important; }
40 | .align-self#{$infix}-start { align-self: flex-start !important; }
41 | .align-self#{$infix}-end { align-self: flex-end !important; }
42 | .align-self#{$infix}-center { align-self: center !important; }
43 | .align-self#{$infix}-baseline { align-self: baseline !important; }
44 | .align-self#{$infix}-stretch { align-self: stretch !important; }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/utilities/_float.scss:
--------------------------------------------------------------------------------
1 | @each $breakpoint in map-keys($grid-breakpoints) {
2 | @include media-breakpoint-up($breakpoint) {
3 | $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
4 |
5 | .float#{$infix}-left { @include float-left; }
6 | .float#{$infix}-right { @include float-right; }
7 | .float#{$infix}-none { @include float-none; }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/utilities/_position.scss:
--------------------------------------------------------------------------------
1 | // stylelint-disable declaration-no-important
2 |
3 | // Common values
4 |
5 | // Sass list not in variables since it's not intended for customization.
6 | $positions: static, relative, absolute, fixed, sticky;
7 |
8 | @each $position in $positions {
9 | .position-#{$position} { position: $position !important; }
10 | }
11 |
12 | // Shorthand
13 |
14 | .fixed-top {
15 | position: fixed;
16 | top: 0;
17 | right: 0;
18 | left: 0;
19 | z-index: $zindex-fixed;
20 | }
21 |
22 | .fixed-bottom {
23 | position: fixed;
24 | right: 0;
25 | bottom: 0;
26 | left: 0;
27 | z-index: $zindex-fixed;
28 | }
29 |
30 | .sticky-top {
31 | @supports (position: sticky) {
32 | position: sticky;
33 | top: 0;
34 | z-index: $zindex-sticky;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/utilities/_screenreaders.scss:
--------------------------------------------------------------------------------
1 | //
2 | // Screenreaders
3 | //
4 |
5 | .sr-only {
6 | @include sr-only();
7 | }
8 |
9 | .sr-only-focusable {
10 | @include sr-only-focusable();
11 | }
12 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/utilities/_sizing.scss:
--------------------------------------------------------------------------------
1 | // stylelint-disable declaration-no-important
2 |
3 | // Width and height
4 |
5 | @each $prop, $abbrev in (width: w, height: h) {
6 | @each $size, $length in $sizes {
7 | .#{$abbrev}-#{$size} { #{$prop}: $length !important; }
8 | }
9 | }
10 |
11 | .mw-100 { max-width: 100% !important; }
12 | .mh-100 { max-height: 100% !important; }
13 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/utilities/_spacing.scss:
--------------------------------------------------------------------------------
1 | // stylelint-disable declaration-no-important
2 |
3 | // Margin and Padding
4 |
5 | @each $breakpoint in map-keys($grid-breakpoints) {
6 | @include media-breakpoint-up($breakpoint) {
7 | $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
8 |
9 | @each $prop, $abbrev in (margin: m, padding: p) {
10 | @each $size, $length in $spacers {
11 |
12 | .#{$abbrev}#{$infix}-#{$size} { #{$prop}: $length !important; }
13 | .#{$abbrev}t#{$infix}-#{$size},
14 | .#{$abbrev}y#{$infix}-#{$size} {
15 | #{$prop}-top: $length !important;
16 | }
17 | .#{$abbrev}r#{$infix}-#{$size},
18 | .#{$abbrev}x#{$infix}-#{$size} {
19 | #{$prop}-right: $length !important;
20 | }
21 | .#{$abbrev}b#{$infix}-#{$size},
22 | .#{$abbrev}y#{$infix}-#{$size} {
23 | #{$prop}-bottom: $length !important;
24 | }
25 | .#{$abbrev}l#{$infix}-#{$size},
26 | .#{$abbrev}x#{$infix}-#{$size} {
27 | #{$prop}-left: $length !important;
28 | }
29 | }
30 | }
31 |
32 | // Some special margin utils
33 | .m#{$infix}-auto { margin: auto !important; }
34 | .mt#{$infix}-auto,
35 | .my#{$infix}-auto {
36 | margin-top: auto !important;
37 | }
38 | .mr#{$infix}-auto,
39 | .mx#{$infix}-auto {
40 | margin-right: auto !important;
41 | }
42 | .mb#{$infix}-auto,
43 | .my#{$infix}-auto {
44 | margin-bottom: auto !important;
45 | }
46 | .ml#{$infix}-auto,
47 | .mx#{$infix}-auto {
48 | margin-left: auto !important;
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/utilities/_text.scss:
--------------------------------------------------------------------------------
1 | // stylelint-disable declaration-no-important
2 |
3 | //
4 | // Text
5 | //
6 |
7 | // Alignment
8 |
9 | .text-justify { text-align: justify !important; }
10 | .text-nowrap { white-space: nowrap !important; }
11 | .text-truncate { @include text-truncate; }
12 |
13 | // Responsive alignment
14 |
15 | @each $breakpoint in map-keys($grid-breakpoints) {
16 | @include media-breakpoint-up($breakpoint) {
17 | $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
18 |
19 | .text#{$infix}-left { text-align: left !important; }
20 | .text#{$infix}-right { text-align: right !important; }
21 | .text#{$infix}-center { text-align: center !important; }
22 | }
23 | }
24 |
25 | // Transformation
26 |
27 | .text-lowercase { text-transform: lowercase !important; }
28 | .text-uppercase { text-transform: uppercase !important; }
29 | .text-capitalize { text-transform: capitalize !important; }
30 |
31 | // Weight and italics
32 |
33 | .font-weight-light { font-weight: $font-weight-light !important; }
34 | .font-weight-normal { font-weight: $font-weight-normal !important; }
35 | .font-weight-bold { font-weight: $font-weight-bold !important; }
36 | .font-italic { font-style: italic !important; }
37 |
38 | // Contextual colors
39 |
40 | .text-white { color: #fff !important; }
41 |
42 | @each $color, $value in $theme-colors {
43 | @include text-emphasis-variant(".text-#{$color}", $value);
44 | }
45 |
46 | .text-muted { color: $text-muted !important; }
47 |
48 | // Misc
49 |
50 | .text-hide {
51 | @include text-hide();
52 | }
53 |
--------------------------------------------------------------------------------
/docs/_sass/bootstrap/utilities/_visibility.scss:
--------------------------------------------------------------------------------
1 | //
2 | // Visibility utilities
3 | //
4 |
5 | .visible {
6 | @include invisible(visible);
7 | }
8 |
9 | .invisible {
10 | @include invisible(hidden);
11 | }
12 |
--------------------------------------------------------------------------------
/docs/_sass/resume/_bootstrap-overrides.scss:
--------------------------------------------------------------------------------
1 | .bg-primary {
2 | background-color: $primary !important;
3 | }
4 |
5 | .text-primary {
6 | color: $primary !important;
7 | }
8 |
9 | a {
10 | color: $primary;
11 | &:hover,
12 | &:focus,
13 | &:active {
14 | color: darken($primary, 15%);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/docs/_sass/resume/_global.scss:
--------------------------------------------------------------------------------
1 | // Global styling for this template
2 |
3 | body {
4 | @include body-font;
5 | padding-top: 54px;
6 | color: $gray-600;
7 | }
8 | @media (min-width: 992px) {
9 | body {
10 | padding-top: 0;
11 | padding-left: $sidebar-base-width;
12 | }
13 | }
14 |
15 | h1,
16 | h2,
17 | h3,
18 | h4,
19 | h5,
20 | h6 {
21 | @include heading-font;
22 | font-weight: 700;
23 | text-transform: uppercase;
24 | color: $gray-800;
25 | }
26 |
27 | h1 {
28 | font-size: 6rem;
29 | line-height: 5.5rem;
30 | }
31 |
32 | h2 {
33 | font-size: 3.5rem;
34 | }
35 |
36 | .subheading {
37 | text-transform: uppercase;
38 | font-weight: 500;
39 | @include heading-font;
40 | font-size: 1.35rem;
41 | }
42 |
43 | .list-social-icons {
44 | a {
45 | color: $gray-700;
46 | &:hover {
47 | color: $primary;
48 | }
49 | .fa-lg {
50 | font-size: 1.75rem;
51 | }
52 | }
53 | }
54 |
55 | .list-icons {
56 | font-size: 3rem;
57 | .list-inline-item i {
58 | &:hover {
59 | color: $primary;
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/docs/_sass/resume/_mixins.scss:
--------------------------------------------------------------------------------
1 | // Mixins
2 | // Bootstrap Button Variant
3 | @mixin background-cover {
4 | -webkit-background-size: cover;
5 | -moz-background-size: cover;
6 | -o-background-size: cover;
7 | background-size: cover;
8 | }
9 | @mixin body-font {
10 | font-family: 'Open Sans', serif;
11 | }
12 | @mixin heading-font {
13 | font-family: 'Saira Extra Condensed', serif;
14 | }
15 |
--------------------------------------------------------------------------------
/docs/_sass/resume/_nav.scss:
--------------------------------------------------------------------------------
1 | #sideNav {
2 | .navbar-brand {}
3 | .navbar-nav .nav-item .nav-link {
4 | font-weight: 600;
5 |
6 | }
7 | .nav-section * {
8 | text-decoration: underline;
9 | }
10 | }
11 |
12 | @media (min-width: 992px) {
13 | #sideNav {
14 | text-align: center;
15 | position: fixed;
16 | top: 0;
17 | left: 0;
18 |
19 | display: flex;
20 | flex-direction: column;
21 |
22 | width: $sidebar-base-width;
23 | height: 100vh;
24 | .navbar-brand {
25 | display: flex;
26 |
27 | margin: auto auto 0;
28 | padding: 0.5rem;
29 | .img-profile {
30 | max-width: 10rem;
31 | max-height: 10rem;
32 | border: 0.5rem solid fade-out($white, 0.8);
33 | }
34 | }
35 | .navbar-collapse {
36 | display: flex;
37 | align-items: flex-start;
38 | flex-grow: 0;
39 |
40 | width: 100%;
41 | margin-bottom: auto;
42 | .navbar-nav {
43 | flex-direction: column;
44 |
45 | width: 100%;
46 | .nav-item {
47 | display: block;
48 | .nav-link {
49 | display: block;
50 | }
51 | }
52 | }
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/docs/_sass/resume/_resume-item.scss:
--------------------------------------------------------------------------------
1 | section.resume-section {
2 | border-bottom: 1px solid $gray-300;
3 | padding-top: 5rem !important;
4 | padding-bottom: 5rem !important;
5 | .resume-item {
6 | .resume-content {}
7 | .resume-date {
8 | min-width: none;
9 | }
10 | }
11 | }
12 | @media (min-width: 768px) {
13 | section.resume-section {
14 | min-height: 100vh;
15 | .resume-item {
16 | .resume-content {}
17 | .resume-date {
18 | min-width: 18rem;
19 | }
20 | }
21 | }
22 | }
23 | @media (min-width: 992px) {
24 | section.resume-section {
25 | padding-top: 3rem !important;
26 | padding-bottom: 3rem !important;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/docs/_sass/resume/_variables.scss:
--------------------------------------------------------------------------------
1 | // Variables
2 |
3 | // Restate Bootstrap Variables
4 |
5 | $white: #fff !default;
6 | $gray-100: #f8f9fa !default;
7 | $gray-200: #e9ecef !default;
8 | $gray-300: #dee2e6 !default;
9 | $gray-400: #ced4da !default;
10 | $gray-500: #adb5bd !default;
11 | $gray-600: #868e96 !default;
12 | $gray-700: #495057 !default;
13 | $gray-800: #343a40 !default;
14 | $gray-900: #212529 !default;
15 | $black: #000 !default;
16 |
17 | $blue: #007bff !default;
18 | $indigo: #6610f2 !default;
19 | $purple: #6f42c1 !default;
20 | $pink: #e83e8c !default;
21 | $red: #dc3545 !default;
22 | $orange: #BD5D38 !default;
23 | $yellow: #ffc107 !default;
24 | $green: #28a745 !default;
25 | $teal: #20c997 !default;
26 | $cyan: #17a2b8 !default;
27 |
28 | $primary: $orange !default;
29 | $secondary: $gray-600 !default;
30 | $success: $green !default;
31 | $info: $cyan !default;
32 | $warning: $yellow !default;
33 | $danger: $red !default;
34 | $light: $gray-100 !default;
35 | $dark: $gray-800 !default;
36 |
37 | // Page Variables
38 |
39 | $sidebar-base-width: 17rem;
40 |
--------------------------------------------------------------------------------
/docs/_sass/resume/resume.scss:
--------------------------------------------------------------------------------
1 | // Core variables and mixins
2 | @import "variables.scss";
3 | @import "mixins.scss";
4 | // Global CSS
5 | @import "global.scss";
6 | @import "nav.scss";
7 | @import "resume-item.scss";
8 | @import "bootstrap-overrides.scss";
9 | // Components
10 |
--------------------------------------------------------------------------------
/docs/assets/img/speccy.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wework/speccy/3c2cc952261c4cb314b6a8729da99032417375bd/docs/assets/img/speccy.jpg
--------------------------------------------------------------------------------
/docs/assets/main.scss:
--------------------------------------------------------------------------------
1 | ---
2 | # Only the main Sass file needs front matter (the dashes are enough)
3 | ---
4 |
5 | @import "_base";
6 | @import "_layout";
7 |
--------------------------------------------------------------------------------
/docs/rules.html:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | permalink: /rules
4 | ---
5 |
6 |
19 |
20 |
21 | This page has moved. Click here if you are not redirected.
22 |
--------------------------------------------------------------------------------
/docs/rules/1-rulesets.md.html:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | title: Rulesets
4 | permalink: /rules/1-rulesets
5 | ---
6 |
7 | Speccy ships with two rulesets, default
and strict
. These rulesets can be invoked with `--rules=`, and of course `default` is used by default. You can also create your own custom rulesets.
8 |
9 | Remember, linting is more than validaiton, so these rules will do more than simply make sure your files
10 | are valid. They'll make your specs better than valid, they'll make them useful.
11 |
12 |
13 |
Default
14 |
$ speccy lint openapi.yaml --rules=default
15 | {% include rules-list.html rules=site.data.rules.default %}
16 |
17 |
18 |
19 |
Strict
20 |
$ speccy lint openapi.yaml --rules=strict
21 | {% include rules-list.html rules=site.data.rules.strict %}
22 |
23 |
24 | You can also create your own rulesets with a simple `.yaml` file.
25 |
--------------------------------------------------------------------------------
/docs/rules/2-custom-rulesets.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | title: Custom Rulesets
4 | permalink: /rules/2-custom-rulesets
5 | ---
6 |
7 | Let's define some terminology:
8 |
9 | - *Rules:* Rules exist to assert certain things are true about a specification file. They exist in rulesets, and have one or more actions
10 | - *Rule Action:* Rule actions are defined in the code, and can be referenced in various combinations to power the logic of a rule
11 | - *Ruleset:* These group up rules (and all of their various actions) into a file, which can be distributed for others to use
12 |
13 | ### Ruleset file format
14 |
15 | A rules file is a YAML or JSON file containing an object with a `rules` property, which is an array of rule objects.
16 |
17 | There is a reserved `require` property (type `string`) at the top level, which can be used for ruleset chaining.
18 |
19 | #### Example
20 |
21 | ```yaml
22 | require: default
23 | rules:
24 | - name: openapi-tags
25 | object: openapi
26 | description: "openapi object should have non-empty tags array"
27 | truthy: tags
28 | - name: default-and-example-are-redundant
29 | object: "*"
30 | description: "don't need to define an example if its exactly the same as your default"
31 | notEqual: ["default", "example"]
32 | ```
33 |
34 | Since v0.9.0, Speccy uses [oas-linter], which is part of [oas-kit] by [Mike Ralphson].
35 |
36 | See the [full list of rule actions][linter-rules] available to be used in your rulesets.
37 |
38 | [linter-rules]: https://mermade.github.io/oas-kit/linter-rules.html
39 | [oas-linter]: https://www.npmjs.com/package/oas-linter
40 | [oas-kit]: https://github.com/Mermade/oas-kit/
41 | [Mike Ralphson]: https://twitter.com/permittedsoc
--------------------------------------------------------------------------------
/docs/vendor/devicons/fonts/devicons.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wework/speccy/3c2cc952261c4cb314b6a8729da99032417375bd/docs/vendor/devicons/fonts/devicons.eot
--------------------------------------------------------------------------------
/docs/vendor/devicons/fonts/devicons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wework/speccy/3c2cc952261c4cb314b6a8729da99032417375bd/docs/vendor/devicons/fonts/devicons.ttf
--------------------------------------------------------------------------------
/docs/vendor/devicons/fonts/devicons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wework/speccy/3c2cc952261c4cb314b6a8729da99032417375bd/docs/vendor/devicons/fonts/devicons.woff
--------------------------------------------------------------------------------
/docs/vendor/font-awesome/fonts/FontAwesome.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wework/speccy/3c2cc952261c4cb314b6a8729da99032417375bd/docs/vendor/font-awesome/fonts/FontAwesome.otf
--------------------------------------------------------------------------------
/docs/vendor/font-awesome/fonts/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wework/speccy/3c2cc952261c4cb314b6a8729da99032417375bd/docs/vendor/font-awesome/fonts/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/docs/vendor/font-awesome/fonts/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wework/speccy/3c2cc952261c4cb314b6a8729da99032417375bd/docs/vendor/font-awesome/fonts/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/docs/vendor/font-awesome/fonts/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wework/speccy/3c2cc952261c4cb314b6a8729da99032417375bd/docs/vendor/font-awesome/fonts/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/docs/vendor/font-awesome/fonts/fontawesome-webfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wework/speccy/3c2cc952261c4cb314b6a8729da99032417375bd/docs/vendor/font-awesome/fonts/fontawesome-webfont.woff2
--------------------------------------------------------------------------------
/docs/vendor/font-awesome/less/animated.less:
--------------------------------------------------------------------------------
1 | // Animated Icons
2 | // --------------------------
3 |
4 | .@{fa-css-prefix}-spin {
5 | -webkit-animation: fa-spin 2s infinite linear;
6 | animation: fa-spin 2s infinite linear;
7 | }
8 |
9 | .@{fa-css-prefix}-pulse {
10 | -webkit-animation: fa-spin 1s infinite steps(8);
11 | animation: fa-spin 1s infinite steps(8);
12 | }
13 |
14 | @-webkit-keyframes fa-spin {
15 | 0% {
16 | -webkit-transform: rotate(0deg);
17 | transform: rotate(0deg);
18 | }
19 | 100% {
20 | -webkit-transform: rotate(359deg);
21 | transform: rotate(359deg);
22 | }
23 | }
24 |
25 | @keyframes fa-spin {
26 | 0% {
27 | -webkit-transform: rotate(0deg);
28 | transform: rotate(0deg);
29 | }
30 | 100% {
31 | -webkit-transform: rotate(359deg);
32 | transform: rotate(359deg);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/docs/vendor/font-awesome/less/bordered-pulled.less:
--------------------------------------------------------------------------------
1 | // Bordered & Pulled
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-border {
5 | padding: .2em .25em .15em;
6 | border: solid .08em @fa-border-color;
7 | border-radius: .1em;
8 | }
9 |
10 | .@{fa-css-prefix}-pull-left { float: left; }
11 | .@{fa-css-prefix}-pull-right { float: right; }
12 |
13 | .@{fa-css-prefix} {
14 | &.@{fa-css-prefix}-pull-left { margin-right: .3em; }
15 | &.@{fa-css-prefix}-pull-right { margin-left: .3em; }
16 | }
17 |
18 | /* Deprecated as of 4.4.0 */
19 | .pull-right { float: right; }
20 | .pull-left { float: left; }
21 |
22 | .@{fa-css-prefix} {
23 | &.pull-left { margin-right: .3em; }
24 | &.pull-right { margin-left: .3em; }
25 | }
26 |
--------------------------------------------------------------------------------
/docs/vendor/font-awesome/less/core.less:
--------------------------------------------------------------------------------
1 | // Base Class Definition
2 | // -------------------------
3 |
4 | .@{fa-css-prefix} {
5 | display: inline-block;
6 | font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration
7 | font-size: inherit; // can't have font-size inherit on line above, so need to override
8 | text-rendering: auto; // optimizelegibility throws things off #1094
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/docs/vendor/font-awesome/less/fixed-width.less:
--------------------------------------------------------------------------------
1 | // Fixed Width Icons
2 | // -------------------------
3 | .@{fa-css-prefix}-fw {
4 | width: (18em / 14);
5 | text-align: center;
6 | }
7 |
--------------------------------------------------------------------------------
/docs/vendor/font-awesome/less/font-awesome.less:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
4 | */
5 |
6 | @import "variables.less";
7 | @import "mixins.less";
8 | @import "path.less";
9 | @import "core.less";
10 | @import "larger.less";
11 | @import "fixed-width.less";
12 | @import "list.less";
13 | @import "bordered-pulled.less";
14 | @import "animated.less";
15 | @import "rotated-flipped.less";
16 | @import "stacked.less";
17 | @import "icons.less";
18 | @import "screen-reader.less";
19 |
--------------------------------------------------------------------------------
/docs/vendor/font-awesome/less/larger.less:
--------------------------------------------------------------------------------
1 | // Icon Sizes
2 | // -------------------------
3 |
4 | /* makes the font 33% larger relative to the icon container */
5 | .@{fa-css-prefix}-lg {
6 | font-size: (4em / 3);
7 | line-height: (3em / 4);
8 | vertical-align: -15%;
9 | }
10 | .@{fa-css-prefix}-2x { font-size: 2em; }
11 | .@{fa-css-prefix}-3x { font-size: 3em; }
12 | .@{fa-css-prefix}-4x { font-size: 4em; }
13 | .@{fa-css-prefix}-5x { font-size: 5em; }
14 |
--------------------------------------------------------------------------------
/docs/vendor/font-awesome/less/list.less:
--------------------------------------------------------------------------------
1 | // List Icons
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-ul {
5 | padding-left: 0;
6 | margin-left: @fa-li-width;
7 | list-style-type: none;
8 | > li { position: relative; }
9 | }
10 | .@{fa-css-prefix}-li {
11 | position: absolute;
12 | left: -@fa-li-width;
13 | width: @fa-li-width;
14 | top: (2em / 14);
15 | text-align: center;
16 | &.@{fa-css-prefix}-lg {
17 | left: (-@fa-li-width + (4em / 14));
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/docs/vendor/font-awesome/less/mixins.less:
--------------------------------------------------------------------------------
1 | // Mixins
2 | // --------------------------
3 |
4 | .fa-icon() {
5 | display: inline-block;
6 | font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration
7 | font-size: inherit; // can't have font-size inherit on line above, so need to override
8 | text-rendering: auto; // optimizelegibility throws things off #1094
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 |
12 | }
13 |
14 | .fa-icon-rotate(@degrees, @rotation) {
15 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation})";
16 | -webkit-transform: rotate(@degrees);
17 | -ms-transform: rotate(@degrees);
18 | transform: rotate(@degrees);
19 | }
20 |
21 | .fa-icon-flip(@horiz, @vert, @rotation) {
22 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation}, mirror=1)";
23 | -webkit-transform: scale(@horiz, @vert);
24 | -ms-transform: scale(@horiz, @vert);
25 | transform: scale(@horiz, @vert);
26 | }
27 |
28 |
29 | // Only display content to screen readers. A la Bootstrap 4.
30 | //
31 | // See: http://a11yproject.com/posts/how-to-hide-content/
32 |
33 | .sr-only() {
34 | position: absolute;
35 | width: 1px;
36 | height: 1px;
37 | padding: 0;
38 | margin: -1px;
39 | overflow: hidden;
40 | clip: rect(0,0,0,0);
41 | border: 0;
42 | }
43 |
44 | // Use in conjunction with .sr-only to only display content when it's focused.
45 | //
46 | // Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1
47 | //
48 | // Credit: HTML5 Boilerplate
49 |
50 | .sr-only-focusable() {
51 | &:active,
52 | &:focus {
53 | position: static;
54 | width: auto;
55 | height: auto;
56 | margin: 0;
57 | overflow: visible;
58 | clip: auto;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/docs/vendor/font-awesome/less/path.less:
--------------------------------------------------------------------------------
1 | /* FONT PATH
2 | * -------------------------- */
3 |
4 | @font-face {
5 | font-family: 'FontAwesome';
6 | src: url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}');
7 | src: url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype'),
8 | url('@{fa-font-path}/fontawesome-webfont.woff2?v=@{fa-version}') format('woff2'),
9 | url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff'),
10 | url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype'),
11 | url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg');
12 | // src: url('@{fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
13 | font-weight: normal;
14 | font-style: normal;
15 | }
16 |
--------------------------------------------------------------------------------
/docs/vendor/font-awesome/less/rotated-flipped.less:
--------------------------------------------------------------------------------
1 | // Rotated & Flipped Icons
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-rotate-90 { .fa-icon-rotate(90deg, 1); }
5 | .@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); }
6 | .@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); }
7 |
8 | .@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); }
9 | .@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); }
10 |
11 | // Hook for IE8-9
12 | // -------------------------
13 |
14 | :root .@{fa-css-prefix}-rotate-90,
15 | :root .@{fa-css-prefix}-rotate-180,
16 | :root .@{fa-css-prefix}-rotate-270,
17 | :root .@{fa-css-prefix}-flip-horizontal,
18 | :root .@{fa-css-prefix}-flip-vertical {
19 | filter: none;
20 | }
21 |
--------------------------------------------------------------------------------
/docs/vendor/font-awesome/less/screen-reader.less:
--------------------------------------------------------------------------------
1 | // Screen Readers
2 | // -------------------------
3 |
4 | .sr-only { .sr-only(); }
5 | .sr-only-focusable { .sr-only-focusable(); }
6 |
--------------------------------------------------------------------------------
/docs/vendor/font-awesome/less/stacked.less:
--------------------------------------------------------------------------------
1 | // Stacked Icons
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-stack {
5 | position: relative;
6 | display: inline-block;
7 | width: 2em;
8 | height: 2em;
9 | line-height: 2em;
10 | vertical-align: middle;
11 | }
12 | .@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x {
13 | position: absolute;
14 | left: 0;
15 | width: 100%;
16 | text-align: center;
17 | }
18 | .@{fa-css-prefix}-stack-1x { line-height: inherit; }
19 | .@{fa-css-prefix}-stack-2x { font-size: 2em; }
20 | .@{fa-css-prefix}-inverse { color: @fa-inverse; }
21 |
--------------------------------------------------------------------------------
/docs/vendor/font-awesome/scss/_animated.scss:
--------------------------------------------------------------------------------
1 | // Spinning Icons
2 | // --------------------------
3 |
4 | .#{$fa-css-prefix}-spin {
5 | -webkit-animation: fa-spin 2s infinite linear;
6 | animation: fa-spin 2s infinite linear;
7 | }
8 |
9 | .#{$fa-css-prefix}-pulse {
10 | -webkit-animation: fa-spin 1s infinite steps(8);
11 | animation: fa-spin 1s infinite steps(8);
12 | }
13 |
14 | @-webkit-keyframes fa-spin {
15 | 0% {
16 | -webkit-transform: rotate(0deg);
17 | transform: rotate(0deg);
18 | }
19 | 100% {
20 | -webkit-transform: rotate(359deg);
21 | transform: rotate(359deg);
22 | }
23 | }
24 |
25 | @keyframes fa-spin {
26 | 0% {
27 | -webkit-transform: rotate(0deg);
28 | transform: rotate(0deg);
29 | }
30 | 100% {
31 | -webkit-transform: rotate(359deg);
32 | transform: rotate(359deg);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/docs/vendor/font-awesome/scss/_bordered-pulled.scss:
--------------------------------------------------------------------------------
1 | // Bordered & Pulled
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-border {
5 | padding: .2em .25em .15em;
6 | border: solid .08em $fa-border-color;
7 | border-radius: .1em;
8 | }
9 |
10 | .#{$fa-css-prefix}-pull-left { float: left; }
11 | .#{$fa-css-prefix}-pull-right { float: right; }
12 |
13 | .#{$fa-css-prefix} {
14 | &.#{$fa-css-prefix}-pull-left { margin-right: .3em; }
15 | &.#{$fa-css-prefix}-pull-right { margin-left: .3em; }
16 | }
17 |
18 | /* Deprecated as of 4.4.0 */
19 | .pull-right { float: right; }
20 | .pull-left { float: left; }
21 |
22 | .#{$fa-css-prefix} {
23 | &.pull-left { margin-right: .3em; }
24 | &.pull-right { margin-left: .3em; }
25 | }
26 |
--------------------------------------------------------------------------------
/docs/vendor/font-awesome/scss/_core.scss:
--------------------------------------------------------------------------------
1 | // Base Class Definition
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix} {
5 | display: inline-block;
6 | font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration
7 | font-size: inherit; // can't have font-size inherit on line above, so need to override
8 | text-rendering: auto; // optimizelegibility throws things off #1094
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/docs/vendor/font-awesome/scss/_fixed-width.scss:
--------------------------------------------------------------------------------
1 | // Fixed Width Icons
2 | // -------------------------
3 | .#{$fa-css-prefix}-fw {
4 | width: (18em / 14);
5 | text-align: center;
6 | }
7 |
--------------------------------------------------------------------------------
/docs/vendor/font-awesome/scss/_larger.scss:
--------------------------------------------------------------------------------
1 | // Icon Sizes
2 | // -------------------------
3 |
4 | /* makes the font 33% larger relative to the icon container */
5 | .#{$fa-css-prefix}-lg {
6 | font-size: (4em / 3);
7 | line-height: (3em / 4);
8 | vertical-align: -15%;
9 | }
10 | .#{$fa-css-prefix}-2x { font-size: 2em; }
11 | .#{$fa-css-prefix}-3x { font-size: 3em; }
12 | .#{$fa-css-prefix}-4x { font-size: 4em; }
13 | .#{$fa-css-prefix}-5x { font-size: 5em; }
14 |
--------------------------------------------------------------------------------
/docs/vendor/font-awesome/scss/_list.scss:
--------------------------------------------------------------------------------
1 | // List Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-ul {
5 | padding-left: 0;
6 | margin-left: $fa-li-width;
7 | list-style-type: none;
8 | > li { position: relative; }
9 | }
10 | .#{$fa-css-prefix}-li {
11 | position: absolute;
12 | left: -$fa-li-width;
13 | width: $fa-li-width;
14 | top: (2em / 14);
15 | text-align: center;
16 | &.#{$fa-css-prefix}-lg {
17 | left: -$fa-li-width + (4em / 14);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/docs/vendor/font-awesome/scss/_mixins.scss:
--------------------------------------------------------------------------------
1 | // Mixins
2 | // --------------------------
3 |
4 | @mixin fa-icon() {
5 | display: inline-block;
6 | font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration
7 | font-size: inherit; // can't have font-size inherit on line above, so need to override
8 | text-rendering: auto; // optimizelegibility throws things off #1094
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 |
12 | }
13 |
14 | @mixin fa-icon-rotate($degrees, $rotation) {
15 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation})";
16 | -webkit-transform: rotate($degrees);
17 | -ms-transform: rotate($degrees);
18 | transform: rotate($degrees);
19 | }
20 |
21 | @mixin fa-icon-flip($horiz, $vert, $rotation) {
22 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}, mirror=1)";
23 | -webkit-transform: scale($horiz, $vert);
24 | -ms-transform: scale($horiz, $vert);
25 | transform: scale($horiz, $vert);
26 | }
27 |
28 |
29 | // Only display content to screen readers. A la Bootstrap 4.
30 | //
31 | // See: http://a11yproject.com/posts/how-to-hide-content/
32 |
33 | @mixin sr-only {
34 | position: absolute;
35 | width: 1px;
36 | height: 1px;
37 | padding: 0;
38 | margin: -1px;
39 | overflow: hidden;
40 | clip: rect(0,0,0,0);
41 | border: 0;
42 | }
43 |
44 | // Use in conjunction with .sr-only to only display content when it's focused.
45 | //
46 | // Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1
47 | //
48 | // Credit: HTML5 Boilerplate
49 |
50 | @mixin sr-only-focusable {
51 | &:active,
52 | &:focus {
53 | position: static;
54 | width: auto;
55 | height: auto;
56 | margin: 0;
57 | overflow: visible;
58 | clip: auto;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/docs/vendor/font-awesome/scss/_path.scss:
--------------------------------------------------------------------------------
1 | /* FONT PATH
2 | * -------------------------- */
3 |
4 | @font-face {
5 | font-family: 'FontAwesome';
6 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}');
7 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'),
8 | url('#{$fa-font-path}/fontawesome-webfont.woff2?v=#{$fa-version}') format('woff2'),
9 | url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'),
10 | url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'),
11 | url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg');
12 | // src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
13 | font-weight: normal;
14 | font-style: normal;
15 | }
16 |
--------------------------------------------------------------------------------
/docs/vendor/font-awesome/scss/_rotated-flipped.scss:
--------------------------------------------------------------------------------
1 | // Rotated & Flipped Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); }
5 | .#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); }
6 | .#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); }
7 |
8 | .#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); }
9 | .#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); }
10 |
11 | // Hook for IE8-9
12 | // -------------------------
13 |
14 | :root .#{$fa-css-prefix}-rotate-90,
15 | :root .#{$fa-css-prefix}-rotate-180,
16 | :root .#{$fa-css-prefix}-rotate-270,
17 | :root .#{$fa-css-prefix}-flip-horizontal,
18 | :root .#{$fa-css-prefix}-flip-vertical {
19 | filter: none;
20 | }
21 |
--------------------------------------------------------------------------------
/docs/vendor/font-awesome/scss/_screen-reader.scss:
--------------------------------------------------------------------------------
1 | // Screen Readers
2 | // -------------------------
3 |
4 | .sr-only { @include sr-only(); }
5 | .sr-only-focusable { @include sr-only-focusable(); }
6 |
--------------------------------------------------------------------------------
/docs/vendor/font-awesome/scss/_stacked.scss:
--------------------------------------------------------------------------------
1 | // Stacked Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-stack {
5 | position: relative;
6 | display: inline-block;
7 | width: 2em;
8 | height: 2em;
9 | line-height: 2em;
10 | vertical-align: middle;
11 | }
12 | .#{$fa-css-prefix}-stack-1x, .#{$fa-css-prefix}-stack-2x {
13 | position: absolute;
14 | left: 0;
15 | width: 100%;
16 | text-align: center;
17 | }
18 | .#{$fa-css-prefix}-stack-1x { line-height: inherit; }
19 | .#{$fa-css-prefix}-stack-2x { font-size: 2em; }
20 | .#{$fa-css-prefix}-inverse { color: $fa-inverse; }
21 |
--------------------------------------------------------------------------------
/docs/vendor/font-awesome/scss/font-awesome.scss:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
4 | */
5 |
6 | @import "variables";
7 | @import "mixins";
8 | @import "path";
9 | @import "core";
10 | @import "larger";
11 | @import "fixed-width";
12 | @import "list";
13 | @import "bordered-pulled";
14 | @import "animated";
15 | @import "rotated-flipped";
16 | @import "stacked";
17 | @import "icons";
18 | @import "screen-reader";
19 |
--------------------------------------------------------------------------------
/docs/vendor/simple-line-icons/fonts/Simple-Line-Icons.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wework/speccy/3c2cc952261c4cb314b6a8729da99032417375bd/docs/vendor/simple-line-icons/fonts/Simple-Line-Icons.eot
--------------------------------------------------------------------------------
/docs/vendor/simple-line-icons/fonts/Simple-Line-Icons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wework/speccy/3c2cc952261c4cb314b6a8729da99032417375bd/docs/vendor/simple-line-icons/fonts/Simple-Line-Icons.ttf
--------------------------------------------------------------------------------
/docs/vendor/simple-line-icons/fonts/Simple-Line-Icons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wework/speccy/3c2cc952261c4cb314b6a8729da99032417375bd/docs/vendor/simple-line-icons/fonts/Simple-Line-Icons.woff
--------------------------------------------------------------------------------
/docs/vendor/simple-line-icons/fonts/Simple-Line-Icons.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wework/speccy/3c2cc952261c4cb314b6a8729da99032417375bd/docs/vendor/simple-line-icons/fonts/Simple-Line-Icons.woff2
--------------------------------------------------------------------------------
/examples/no-contact.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | openapi: 3.0.0
3 | info:
4 | version: 1.0.0
5 | title: Swagger 2.0 Without Scheme
6 | paths: {}
7 | components:
8 | schemas:
9 | foo:
10 | type: object
11 | bar:
12 | type: object
13 | baz:
14 | type: object
15 | ban:
16 | type: object
17 | basdf:
18 | type: object
19 |
--------------------------------------------------------------------------------
/lib/config.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const nconf = require('nconf');
4 |
5 | nconf.formats.yaml = require('nconf-yaml');
6 |
7 | class Config {
8 |
9 | init(args) {
10 | const configFile = (args.parent && args.parent.config) ? args.parent.config : './speccy.yaml';
11 |
12 | this.load(configFile, {
13 | quiet: args.quiet,
14 | jsonSchema: args.jsonSchema,
15 | verbose: args.verbose,
16 | // Command specific options
17 | lint: {
18 | rules: this.notEmptyArray(args.rules),
19 | skip: this.notEmptyArray(args.skip),
20 | },
21 | resolve: {
22 | output: args.output,
23 | internalRefs: args.internalRefs
24 | },
25 | serve: {
26 | port: args.port,
27 | }
28 | });
29 | }
30 |
31 | load(file, supplied) {
32 | // 1, check the supplied values
33 | nconf.add('supplied', {
34 | type: 'literal',
35 | store: this.cleanObject(supplied),
36 | });
37 |
38 | // 2, look in config file (e.g: speccy.yaml)
39 | nconf.add('local', {
40 | type: 'file',
41 | format: nconf.formats.yaml,
42 | file,
43 | });
44 |
45 | if (!nconf.get('quiet') && nconf.get('verbose') > 2) {
46 | console.error('LOADING CONFIG', file);
47 | }
48 | }
49 |
50 | get(key, defaultValue) {
51 | // Search through all known stores for the value
52 | const value = nconf.get(key);
53 | const result = (value === undefined) ? defaultValue : value;
54 | if (!nconf.get('quiet') && nconf.get('verbose') > 2) {
55 | console.error(`CONFIG VALUE ${key} = ${result} (default = ${defaultValue})`)
56 | }
57 | return result
58 | }
59 |
60 | // Don't want an object full of null
61 | cleanObject(object) {
62 | const cleaned = {};
63 | Object.keys(object).forEach(key => {
64 | const value = object[key];
65 | if (value === undefined || value === null || (Array.isArray(value) && value.length === 0)) {
66 | return;
67 | } else if (typeof value === "object" && !Array.isArray(value)) {
68 | cleaned[key] = this.cleanObject(value);
69 | } else {
70 | cleaned[key] = value;
71 | }
72 | });
73 | return cleaned;
74 | }
75 |
76 | /**
77 | * Check and returns the given array if it is not empty. Otherwise it returns 'undefined'.
78 | * Useful for configuration options where an empty array has no meaning.
79 | *
80 | * @param array The array instance to check.
81 | * @returns {array|undefined} The given array; or 'undefined' if array is 'undefined' or empty.
82 | */
83 | notEmptyArray(array) {
84 | return array && array.length > 0 ? array : undefined;
85 | }
86 | }
87 |
88 | module.exports = new Config;
89 |
--------------------------------------------------------------------------------
/lib/rules.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const documentationUrl = 'https://speccy.io/rules/1-rulesets';
4 | let activeRules = {};
5 | let skipRules = [];
6 |
7 | const init = (params = {}) => {
8 | activeRules = {};
9 | skipRules = params.skip || [];
10 | };
11 |
12 | const createNewRules = (rules, rulesetDocumentationUrl) => {
13 | rules.forEach(rule => createNewRule(rule, rulesetDocumentationUrl));
14 | };
15 |
16 | const createNewRule = (rule, rulesetDocumentationUrl) => {
17 | // @DEPRECATED in v0.9.0, use `disabled: true`
18 | if (rule.enabled !== undefined) {
19 | console.warn("WARNING: Property 'enabled' is deprecated and will be removed in 1.0.0. Use 'disabled' instead. Found in rule: " + rule.name)
20 | }
21 | if (rule.enabled === false && rule.disabled === undefined) {
22 | rule.disabled = true;
23 | }
24 |
25 | if (rule.disabled === true) {
26 | delete activeRules[rule.name];
27 | return;
28 | }
29 |
30 | if (!rule.url) rule.url = (rulesetDocumentationUrl) ? rulesetDocumentationUrl : documentationUrl;
31 |
32 | activeRules[rule.name] = rule;
33 | };
34 |
35 | const getRules = () => {
36 | return {
37 | "rules": relevantRules(Object.values(activeRules), skipRules)
38 | };
39 | };
40 |
41 | const relevantRules = (rulesList, skipList) => {
42 | if (skipList.length === 0) return rulesList;
43 | return rulesList.filter(rule => skipList.indexOf(rule.name) === -1);
44 | };
45 |
46 | module.exports = {
47 | createNewRule,
48 | createNewRules,
49 | init,
50 | getRules
51 | };
52 |
--------------------------------------------------------------------------------
/lib/server.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const ejs = require('ejs');
4 | const fs = require('fs');
5 | const path = require('path');
6 |
7 | function loadHTML(file) {
8 | const templateFile = path.resolve(__dirname, '../templates/index.html');
9 | const template = fs.readFileSync(templateFile, 'utf8');
10 | return ejs.render(template, { spec: file });
11 | }
12 |
13 | module.exports = { loadHTML };
14 |
--------------------------------------------------------------------------------
/lint.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | 'use strict'
4 |
5 | const config = require('./lib/config.js');
6 | const loader = require('./lib/loader.js');
7 | const linter = require('oas-linter');
8 | const rules = require('./lib/rules.js');
9 | const validator = require('oas-validator');
10 | const fromJsonSchema = require('json-schema-to-openapi-schema');
11 |
12 | const colors = process.env.NODE_DISABLE_COLORS ? {} : {
13 | red: '\x1b[31m',
14 | green: '\x1b[32m',
15 | yellow: '\x1b[33m',
16 | blue: '\x1b[34m',
17 | magenta: '\x1b[35m',
18 | cyan: '\x1b[36m',
19 | white: '\x1b[37m',
20 | reset: '\x1b[0m'
21 | };
22 |
23 | const formatSchemaError = (err, context) => {
24 | const pointer = context.pop();
25 | let output = `
26 | ${colors.yellow + pointer}
27 | `;
28 |
29 | if (err.name === 'AssertionError' || err.error.name === 'AssertionError') {
30 | output += colors.reset + truncateLongMessages(err.message);
31 | }
32 | else if (err instanceof validator.CLIError) {
33 | output += colors.reset + err.message;
34 | }
35 | else {
36 | output += colors.red + err.stack;
37 | }
38 | return output;
39 | }
40 |
41 | const truncateLongMessages = message => {
42 | let lines = message.split('\n');
43 | if (lines.length > 6) {
44 | lines = lines.slice(0, 5).concat(
45 | [' ... snip ...'],
46 | lines.slice(-1)
47 | );
48 | }
49 | return lines.join('\n');
50 | }
51 |
52 | const formatLintResults = lintResults => {
53 | let output = '';
54 | lintResults.forEach(result => {
55 | const { rule, error, pointer } = result;
56 |
57 | output += `
58 | ${colors.yellow + pointer} ${colors.cyan} R: ${rule.name} ${colors.white} D: ${rule.description}
59 | ${colors.reset + truncateLongMessages(error.message)}
60 |
61 | More information: ${rule.url}#${rule.name}
62 | `;
63 | });
64 |
65 | return output;
66 | }
67 |
68 | const command = async (specFile, cmd) => {
69 | config.init(cmd);
70 | const jsonSchema = config.get('jsonSchema');
71 | const verbose = config.get('quiet') ? 0 : config.get('verbose', 1);
72 | const rulesets = config.get('lint:rules', []);
73 | const skip = config.get('lint:skip', []);
74 |
75 | rules.init({
76 | skip
77 | });
78 | await loader.loadRulesets(rulesets, { verbose });
79 | linter.applyRules(rules.getRules());
80 |
81 | const spec = await loader.readOrError(
82 | specFile,
83 | buildLoaderOptions(jsonSchema, verbose)
84 | );
85 |
86 | return new Promise((resolve, reject) => {
87 | validator.validate(spec, buildValidatorOptions(skip, verbose), (err, _options) => {
88 | const { context, warnings, valid } = _options || err.options;
89 |
90 | if (err && valid === false) {
91 | console.error(colors.red + 'Specification schema is invalid.' + colors.reset);
92 | if (err.name === 'AssertionError') {
93 | console.error(formatSchemaError(err, context));
94 | }
95 |
96 | for (let linterResult of err.options.linterResults()) {
97 | console.error(formatSchemaError(linterResult, context));
98 | }
99 | return reject();
100 | }
101 |
102 | if (warnings.length) {
103 | console.error(colors.red + 'Specification contains lint errors: ' + warnings.length + colors.reset);
104 | console.warn(formatLintResults(warnings))
105 | return reject();
106 | }
107 |
108 | if (!cmd.quiet) {
109 | console.log(colors.green + 'Specification is valid, with 0 lint errors' + colors.reset)
110 | }
111 |
112 | return resolve();
113 | });
114 | });
115 | };
116 |
117 | const buildLoaderOptions = (jsonSchema, verbose) => {
118 | const options = {
119 | filters: [],
120 | resolve: true,
121 | verbose,
122 | };
123 |
124 | if (jsonSchema) {
125 | options.filters.push(fromJsonSchema);
126 | }
127 |
128 | return options;
129 | }
130 |
131 | const buildValidatorOptions = (skip, verbose) => {
132 | return {
133 | skip,
134 | lint: true,
135 | linter: linter.lint,
136 | linterResults: linter.getResults,
137 | prettify: true,
138 | verbose,
139 | };
140 | }
141 |
142 | module.exports = { command };
143 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "speccy",
3 | "version": "0.11.0",
4 | "description": "An OpenAPI v3.0 development workflow assistant",
5 | "homepage": "https://speccy.io/",
6 | "bin": {
7 | "speccy": "./speccy.js"
8 | },
9 | "scripts": {
10 | "test": "jest --coverage"
11 | },
12 | "preferGlobal": true,
13 | "repository": {
14 | "url": "https://github.com/wework/speccy.git",
15 | "type": "git"
16 | },
17 | "author": "Phil Sturgeon ",
18 | "license": "MIT",
19 | "bugs": {
20 | "url": "https://github.com/wework/speccy/issues"
21 | },
22 | "keywords": [
23 | "openapi",
24 | "openapi3",
25 | "swagger",
26 | "documentation",
27 | "validator",
28 | "validation",
29 | "resolver",
30 | "lint",
31 | "linter"
32 | ],
33 | "dependencies": {
34 | "commander": "^2.18.0",
35 | "ejs": "^2.5.2",
36 | "express": "^4.14.0",
37 | "json-schema-to-openapi-schema": "^0.3.0",
38 | "nconf": "^0.10.0",
39 | "nconf-yaml": "^1.0.2",
40 | "node-fetch": "^2.3.0",
41 | "node-readfiles": "^0.2.0",
42 | "oas-linter": "^3.0.0",
43 | "oas-resolver": "^2.2.4",
44 | "oas-validator": "^3.0.1",
45 | "redoc": "v2.0.0-rc.12",
46 | "yaml": "^1.5.0"
47 | },
48 | "devDependencies": {
49 | "babel-core": "^6.24.1",
50 | "babel-loader": "^8.0.5",
51 | "babel-preset-es2015": "^6.24.1",
52 | "coveralls": "^3.0.0",
53 | "jest": "^24.1.0",
54 | "mock-stdin": "^0.3.1",
55 | "nock": "^10.0.0"
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/resolve.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | 'use strict';
4 |
5 | const fs = require('fs');
6 | const yaml = require('yaml');
7 | const config = require('./lib/config.js');
8 | const loader = require('./lib/loader.js');
9 | const fromJsonSchema = require('json-schema-to-openapi-schema');
10 |
11 | const command = async (file, cmd) => {
12 | config.init(cmd);
13 | const jsonSchema = config.get('jsonSchema');
14 | const output = config.get('resolve:output');
15 | const verbose = config.get('quiet') ? 0 : config.get('verbose', 1);
16 | const internalRefs = config.get('resolve:internalRefs');
17 |
18 | const spec = await loader.readOrError(
19 | file,
20 | buildLoaderOptions(jsonSchema, verbose, internalRefs)
21 | );
22 | const content = yaml.stringify(spec);
23 |
24 | return new Promise((resolve, reject) => {
25 | if (output) {
26 | fs.writeFile(output, content, 'utf8', err => {
27 | if (err) {
28 | if (verbose) console.error('Failed to write file: ' + err.message);
29 | reject();
30 | } else {
31 | if (verbose) console.error('Resolved to ' + output);
32 | resolve();
33 | }
34 | });
35 | } else {
36 | process.stdout.write(content, () => {
37 | // Do not exit until the output is flushed (e.g. pipes)
38 | resolve();
39 | });
40 | }
41 | });
42 | };
43 |
44 | const buildLoaderOptions = (jsonSchema, verbose, internalRefs) => {
45 | const options = {
46 | resolve: true,
47 | cache: [],
48 | externals: [],
49 | externalRefs: {},
50 | rewriteRefs: true,
51 | status: 'undefined',
52 | filters: [],
53 | verbose,
54 | };
55 | if (jsonSchema) options.filters.push(fromJsonSchema);
56 | if (internalRefs) options.resolveInternal = true;
57 |
58 | return options;
59 | }
60 |
61 | module.exports = { command };
62 |
--------------------------------------------------------------------------------
/rules/default.yaml:
--------------------------------------------------------------------------------
1 | rules:
2 | - name: parameter-description
3 | object: parameter
4 | description: parameter objects should have a description
5 | truthy: description
6 | - name: parameter-name-regex
7 | object: parameter
8 | disabled: true
9 | description: parameter names should match RFC6570
10 | pattern:
11 | property: name
12 | value: ''
13 | - name: operation-operationId
14 | object: operation
15 | description: operation should have an operationId
16 | truthy: operationId
17 | - name: operation-summary-or-description
18 | object: operation
19 | description: operation should have summary or description
20 | or:
21 | - summary
22 | - description
23 | - name: operation-tags
24 | object: operation
25 | description: operation should have non-empty tags array
26 | truthy: tags
27 | skip: isCallback
28 | - name: path-keys-no-trailing-slash
29 | object: pathItem
30 | description: paths should not end with a slash
31 | notEndWith:
32 | property: "$key"
33 | value: "/"
34 | - name: server-trailing-slash
35 | object: server
36 | description: server url should not have a trailing slash
37 | notEndWith:
38 | property: url
39 | value: "/"
40 | - name: openapi-tags
41 | object: openapi
42 | description: openapi object should have non-empty tags array
43 | truthy: tags
44 | - name: openapi-tags-alphabetical
45 | object: openapi
46 | description: openapi object should have alphabetical tags
47 | alphabetical:
48 | properties:
49 | - tags
50 | keyedBy: name
51 | - name: reference-no-other-properties
52 | object: reference
53 | description: reference objects should only have a $ref property
54 | truthy: "$ref"
55 | properties: 1
56 | - name: example-value-or-externalValue
57 | object: example
58 | description: example should have either value or externalValue
59 | xor:
60 | - value
61 | - externalValue
62 | - name: default-and-example-are-redundant
63 | object: "*"
64 | description: don't need to define an example if its exactly the same as your default
65 | schema:
66 | dependencies:
67 | default:
68 | properties:
69 | example:
70 | not:
71 | const:
72 | "$data": "1/default"
73 | - name: reference-components-regex
74 | object: reference
75 | disabled: true
76 | description: reference components should all match regex ^[a-zA-Z0-9\.\-_]+
77 | pattern:
78 | property: "$ref"
79 | omit: "#"
80 | split: "/"
81 | value: "^[a-zA-Z0-9\\.\\-_]+$"
82 | - name: no-script-tags-in-markdown
83 | object: "*"
84 | description: markdown descriptions should not contain
22 |