├── .DS_Store ├── README.md ├── custom_theme ├── __init__.py ├── base.html ├── content.html ├── css │ ├── base.css │ ├── bootstrap-docs.css │ ├── bootstrap.min.css │ ├── font-awesome.min.css │ └── theme.css ├── fonts │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.svg │ ├── fontawesome-webfont.ttf │ └── fontawesome-webfont.woff ├── github-nav-item.html ├── header.html ├── images │ ├── .DS_Store │ └── logo │ │ ├── opencan.ai │ │ ├── opencan.png │ │ └── opencan.svg ├── js │ ├── base.js │ └── bootstrap.min.js ├── keyboard-modal.html ├── main.html ├── mkdocs_theme.yml ├── nav-toggle.html ├── nav.html ├── search-modal.html ├── secondary-nav.html ├── toc.html └── twitter-nav-item.html ├── docs ├── .DS_Store ├── Cycles.md ├── ICIP-1.md ├── ICIP-20.md ├── ICIP-721.md ├── Sudograph.md ├── fungible-tokens.md ├── getting-started.md ├── img │ ├── DIP20Init.png │ ├── create-ic-app.gif │ ├── deployCanister.png │ ├── dfinity-logo.svg │ ├── example.png │ ├── opencantrailer.mp4 │ ├── setup.png │ └── sudograph.png ├── index.md ├── learn.md ├── motoko-token.md └── non-fungible-tokens.md └── mkdocs.yml /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCan-io/opencan/7f224bad5e2a7fdbace3df012ad7713efac4ec9c/.DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Installation 2 | 3 | To install MkDocs, run the following command from the command line: 4 | 5 | mac 6 | ```bash 7 | brew install mkdocs 8 | ``` 9 | 10 | linux 11 | ```bash 12 | pip install mkdocs 13 | ``` 14 | 15 | theme 16 | ```bash 17 | pip install mkdocs-material 18 | ``` 19 | 20 | run locally 21 | ```bash 22 | mkdocs serve 23 | ``` 24 | -------------------------------------------------------------------------------- /custom_theme/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCan-io/opencan/7f224bad5e2a7fdbace3df012ad7713efac4ec9c/custom_theme/__init__.py -------------------------------------------------------------------------------- /custom_theme/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | {%- block site_meta %} 11 | 12 | 13 | 14 | {% if page and page.is_homepage %}{% endif %} 15 | {% if config.site_author %}{% endif %} 16 | {% if page and page.canonical_url %}{% endif %} 17 | {% if config.site_favicon %} 18 | {% else %}{% endif %} 19 | {%- endblock %} 20 | 21 | {%- block htmltitle %} 22 | {% if page and page.title and not page.is_homepage %}{{ page.title }} - {% endif %}{{ config.site_name }} 23 | {%- endblock %} 24 | 25 | {%- block styles %} 26 | 27 | 28 | 29 | {%- for path in config['extra_css'] %} 30 | 31 | {%- endfor %} 32 | {%- endblock %} 33 | 34 | 35 | 36 | {%- block extrahead %} {% endblock %} 37 | 38 | 39 | 40 | 41 | {% include "header.html" %} 42 | {% include "secondary-nav.html" %} 43 | 44 |
45 | {% include "nav.html" %} 46 |
47 |
{% include "content.html" %}
48 | {% include "toc.html" %} 49 |
50 | 51 | 52 | 62 | 63 | {%- block scripts %} 64 | 68 | 69 | {%- for path in config['extra_javascript'] %} 70 | 71 | {%- endfor %} 72 | {%- endblock %} 73 | 74 | {% if 'search' in config['plugins'] %}{%- include "search-modal.html" %}{% endif %} 75 | {%- include "keyboard-modal.html" %} 76 | 77 | 78 | 79 | {% if page and page.is_homepage %} 80 | 84 | {% endif %} -------------------------------------------------------------------------------- /custom_theme/content.html: -------------------------------------------------------------------------------- 1 | {% if page and page.meta.source %} 2 | 7 | {% endif %} 8 | 9 | {% if page and not page.meta.no_breadcrumb %} 10 | 22 | {% endif %} 23 | 24 | {{ page.content }} 25 | 26 | 45 | -------------------------------------------------------------------------------- /custom_theme/css/base.css: -------------------------------------------------------------------------------- 1 | .bd-content img { 2 | max-width: 100%; 3 | } 4 | 5 | video { 6 | max-width: 100%; 7 | } 8 | 9 | /* These pre selectors are hacks to get the */ 10 | /* markdown version of ``` code blocks */ 11 | /* to show bootstrap's css treatment */ 12 | /* since it translates to wrapping text in */ 13 | /*
TEXT
*/ 14 | /* and currently .bd-example gets this treatment */ 15 | /* but i'm applying now to any
 block */
 16 | pre {
 17 |     position:relative;
 18 |     padding:1rem;
 19 |     margin:1rem -.75rem 0;
 20 |     border:solid #dee2e6;
 21 |     border-width:1px 0 0;
 22 | }
 23 | @media (min-width: 576px) {
 24 |     pre { 
 25 |         padding:1.5rem;
 26 |         margin-right:0;
 27 |         margin-left:0;
 28 |         border-width:1px;
 29 |         border-top-left-radius:.25rem;
 30 |         border-top-right-radius:.25rem;
 31 |     }
 32 | }
 33 | /* *************************** */
 34 | 
 35 | a.navbar-brand img {
 36 |     width: 100px;
 37 | }
 38 | .metadata{
 39 |     list-style:none;
 40 |     padding:0;
 41 |     margin:0;
 42 |     margin-bottom: 15px;
 43 |     color: #999;
 44 |     font-size:0.85em;
 45 | }
 46 | .last-updated-holder {
 47 |     float: left;
 48 |     margin-right: 20px;
 49 | }
 50 | .metadata.page-metadata .last-updated-text,
 51 | .metadata.page-metadata .contributors-text{
 52 |     margin-right:5px
 53 | }
 54 | body[dir=rtl] .metadata.page-metadata .last-updated-text,
 55 | body[dir=rtl] .metadata.page-metadata .contributors-text{
 56 |     margin-right:0;
 57 |     margin-left:5px
 58 | }
 59 | .page-metadata .contributors{
 60 |     display:inline-block;
 61 |     list-style:none;
 62 |     margin:0!important;
 63 |     padding:0!important
 64 | }
 65 | .page-metadata .contributors li{
 66 |     display:inline-block;
 67 |     vertical-align:top;
 68 |     margin:0;
 69 |     padding:0
 70 | }
 71 | .page-metadata .contributors li img{
 72 |     border-radius:100%;
 73 |     height:16px;
 74 | /*    margin-top:5px;*/
 75 |     margin-top:-3px;
 76 |     overflow:hidden;
 77 |     width:16px
 78 | }
 79 | 
 80 | #content {
 81 |     padding-top: 80px;
 82 | }
 83 | 
 84 | .has-jumbotron #content {
 85 |     padding-top: 0px;
 86 | }
 87 | .jumbotron {
 88 |     margin-top: 30px;
 89 |     padding-top: 1.5rem;
 90 |     padding-bottom: 1rem;
 91 | }
 92 | .card-deck {
 93 |     margin-bottom: 20px;
 94 | }
 95 | .sticky-offset {
 96 |     top: 75px;
 97 | }
 98 | 
 99 | ul.nav li.main {
100 |     font-weight: bold;
101 | }
102 | 
103 | .dropdown-submenu{
104 |     position: relative;
105 | }
106 | .dropdown-submenu a::after{
107 |     transform: rotate(-90deg);
108 |     position: absolute;
109 |     right: 3px;
110 |     top: 40%;
111 | }
112 | .dropdown-submenu .dropdown-menu {
113 |     display: none !important;
114 | }
115 | .dropdown-submenu:hover .dropdown-menu,.dropdown-submenu:focus .dropdown-menu{
116 |     display: flex !important;
117 |     flex-direction: column;
118 |     position: absolute !important;
119 |     margin-top: -30px;
120 |     left: 100%;
121 | }
122 | @media (max-width: 992px) {
123 |     .dropdown-menu{
124 |         width: 50%;
125 |     }
126 |     .dropdown-menu .dropdown-submenu{
127 |         width: auto;
128 |     }
129 | }
130 | .btn:visited {
131 |     color: white;
132 | }
133 | /*
134 | h1[id]:before, h2[id]:before, h3[id]:before, h4[id]:before, h5[id]:before, h6[id]:before {
135 |     content: "";
136 |     display: block;
137 |     margin-top: -75px;
138 |     height: 75px;
139 | }
140 | div.col-md-9 {
141 |     padding-bottom: 100px;
142 | }
143 | 
144 | div.source-links {
145 |     float: right;
146 | }
147 | 
148 | div.col-md-9 img {
149 |   max-width: 100%;
150 | }
151 | */
152 | 
153 | /*
154 |  * Side navigation
155 |  *
156 |  * Scrollspy and affixed enhanced navigation to highlight sections and secondary
157 |  * sections of docs content.
158 |  */
159 | 
160 | /* By default it's not affixed in mobile views, so undo that */
161 | .bs-sidebar.affix {
162 | /*    position: static;*/
163 | }
164 | 
165 | .bs-sidebar.well {
166 |     padding: 0;
167 | }
168 | 
169 | /* First level of nav */
170 | .bs-sidenav {
171 |     margin-top: 0px;
172 |     margin-bottom: 0px;
173 |     padding-top:    10px;
174 |     padding-bottom: 10px;
175 |     border-radius: 5px;
176 | }
177 | 
178 | /* All levels of nav */
179 | .bs-sidebar .nav > li > a {
180 |     display: block;
181 |     padding: 5px 20px;
182 |     z-index: 1;
183 | }
184 | .bs-sidebar .nav > li > a:hover,
185 | .bs-sidebar .nav > li > a:focus {
186 |     text-decoration: none;
187 |     border-right: 1px solid;
188 | }
189 | .bs-sidebar .nav > .active > a,
190 | .bs-sidebar .nav > .active:hover > a,
191 | .bs-sidebar .nav > .active:focus > a {
192 |     font-weight: bold;
193 |     background-color: transparent;
194 |     border-right: 1px solid;
195 | }
196 | 
197 | /* Nav: second level (shown on .active) */
198 | .bs-sidebar .nav .nav {
199 |     display: none; /* Hide by default, but at >768px, show it */
200 |     margin-bottom: 8px;
201 | }
202 | .bs-sidebar .nav .nav > li > a {
203 |     padding-top:    3px;
204 |     padding-bottom: 3px;
205 |     padding-left: 30px;
206 |     font-size: 90%;
207 | }
208 | 
209 | /* Show and affix the side nav when space allows it */
210 | @media (min-width: 992px) {
211 |     .bs-sidebar .nav > .active > ul {
212 |         display: block;
213 |     }
214 |     /* Widen the fixed sidebar */
215 |     .bs-sidebar.affix,
216 |     .bs-sidebar.affix-bottom {
217 |         width: 213px;
218 |     }
219 |     .bs-sidebar.affix {
220 |         /*position: fixed;*/ /* Undo the static from mobile first approach */
221 |         top: 80px;
222 |     }
223 |     .bs-sidebar.affix-bottom {
224 |         /*position: absolute;*/ /* Undo the static from mobile first approach */
225 |     }
226 |     .bs-sidebar.affix-bottom .bs-sidenav,
227 |     .bs-sidebar.affix .bs-sidenav {
228 |         margin-top: 0;
229 |         margin-bottom: 0;
230 |     }
231 | }
232 | @media (min-width: 1200px) {
233 |     /* Widen the fixed sidebar again */
234 |     .bs-sidebar.affix-bottom,
235 |     .bs-sidebar.affix {
236 |         width: 263px;
237 |     }
238 | }
239 | 
240 | img {
241 |     height: auto;
242 |     width: auto;
243 |     transition: transform ease-in-out 0.3s;
244 | }
245 | 
246 | img[src*="#shadow"] {
247 |     box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
248 | }
249 | 
250 | img:active[src*="#zoom"] {
251 |     cursor: zoom-out;
252 |     transform: scale(2.0);
253 | }
254 | 
255 | img[src*="#zoom"] {
256 |     cursor: zoom-in;
257 | }
258 | 
259 | img[src*="#center"] {
260 |     display: block;
261 |     margin-left: auto;
262 |     margin-right: auto;
263 | }
264 | 
265 | img[src*="#no-border"] {
266 |     border: 0px;
267 |     width: 200px;
268 | }
269 | 
270 | a.md-logo img {
271 |     border: none;
272 | }


--------------------------------------------------------------------------------
/custom_theme/css/bootstrap-docs.css:
--------------------------------------------------------------------------------
1 | /*!
2 |  * Bootstrap Docs (https://getbootstrap.com/)
3 |  * Copyright 2011-2021 The Bootstrap Authors
4 |  * Copyright 2011-2021 Twitter, Inc.
5 |  * Licensed under the Creative Commons Attribution 3.0 Unported License.
6 |  * For details, see https://creativecommons.org/licenses/by/3.0/.
7 |  */.bd-navbar{padding:.75rem 0;background-color:#002338;}.bd-navbar .navbar-toggler{padding:0;border:0}.bd-navbar .navbar-nav .nav-link{padding-right:.25rem;padding-left:.25rem;color:rgba(255,255,255,0.85)}.bd-navbar .navbar-nav .nav-link:hover,.bd-navbar .navbar-nav .nav-link:focus{color:#fff}.bd-navbar .navbar-nav .nav-link.active{font-weight:600;color:#fff}.bd-navbar .navbar-nav-svg{width:1rem;height:1rem}.bd-subnavbar{position:relative;z-index:1020;background-color:rgba(255,255,255,0.95);box-shadow:0 0.5rem 1rem rgba(0,0,0,0.05),inset 0 -1px 0 rgba(0,0,0,0.15)}.bd-subnavbar .dropdown-menu{font-size:.875rem;box-shadow:0 0.5rem 1rem rgba(0,0,0,0.05)}.bd-subnavbar .dropdown-item.current{font-weight:600;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23292b2c' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right 1rem top 0.6rem;background-size:.75rem .75rem}@media (min-width: 768px){.bd-subnavbar{position:-webkit-sticky;position:sticky;top:0}}.bd-search{position:relative}.bd-search::after{position:absolute;top:.4rem;right:.4rem;display:flex;align-items:center;justify-content:center;height:1.5rem;padding-right:.25rem;padding-left:.25rem;font-size:.75rem;color:#6c757d;border:1px solid #dee2e6;border-radius:.125rem}@media (max-width: 767.98px){.bd-search{width:100%}}.bd-search .form-control{padding-right:3.75rem}.bd-search .form-control:focus{border-color:#7952b3;box-shadow:0 0 0 3px rgba(121,82,179,0.25)}.bd-sidebar-toggle{color:#6c757d}.bd-sidebar-toggle:hover,.bd-sidebar-toggle:focus{color:#7952b3}.bd-sidebar-toggle:focus{box-shadow:0 0 0 3px rgba(121,82,179,0.25)}.bd-sidebar-toggle .bi-collapse{display:none}.bd-sidebar-toggle:not(.collapsed) .bi-expand{display:none}.bd-sidebar-toggle:not(.collapsed) .bi-collapse{display:inline-block}.bd-masthead{padding:3rem 0;background:linear-gradient(165deg, #f7f5fb 50%, #fff 50%)}.bd-masthead h1{font-size:calc(1.525rem + 3.3vw);line-height:1}@media (min-width: 1200px){.bd-masthead h1{font-size:4rem}}.bd-masthead p:not(.lead){color:#495057}.bd-masthead .btn{padding:.8rem 2rem;font-weight:600}.bd-masthead .lead{font-size:calc(1.275rem + .3vw);font-weight:400;color:#495057}@media (min-width: 1200px){.bd-masthead .lead{font-size:1.5rem}}@media (min-width: 768px){.mw-md-75{max-width:75%}}.masthead-followup-icon{padding:.75rem;background-image:linear-gradient(to bottom right, rgba(255,255,255,0.2), rgba(255,255,255,0.01));border-radius:.75rem;box-shadow:0 0.125rem 0.25rem rgba(0,0,0,0.1)}.masthead-followup-svg{filter:drop-shadow(0 1px 0 rgba(0,0,0,0.125))}#carbonads{position:static;display:block;max-width:400px;padding:15px 15px 15px 160px;margin:2rem 0;overflow:hidden;font-size:.8125rem;line-height:1.4;text-align:left;background-color:rgba(0,0,0,0.05)}#carbonads a{color:#343a40;text-decoration:none}@media (min-width: 576px){#carbonads{max-width:330px;border-radius:4px}}.carbon-img{float:left;margin-left:-145px}.carbon-poweredby{display:block;margin-top:.75rem;color:#495057 !important}@media (min-width: 768px){:root{scroll-padding-top:4rem}}.bd-content>h2:not(:first-child){margin-top:3rem}.bd-content>h3{margin-top:2rem}.bd-content>ul li,.bd-content>ol li{margin-bottom:.25rem}.bd-content>ul li>ul,.bd-content>ol li>ul{margin-top:-.5rem;margin-bottom:1rem}.bd-content>.table{max-width:100%;margin-bottom:1.5rem;font-size:.875rem}@media (max-width: 991.98px){.bd-content>.table{display:block;overflow-x:auto}.bd-content>.table.table-bordered{border:0}}.bd-content>.table th:first-child,.bd-content>.table td:first-child{padding-left:0}.bd-content>.table th:not(:last-child),.bd-content>.table td:not(:last-child){padding-right:1.5rem}.bd-content>.table td:first-child>code{white-space:nowrap}.bd-title{font-size:calc(1.425rem + 2.1vw)}@media (min-width: 1200px){.bd-title{font-size:3rem}}.bd-lead{font-size:calc(1.275rem + .3vw);font-weight:300}@media (min-width: 1200px){.bd-lead{font-size:1.5rem}}.bd-text-purple-bright{color:#7952b3}.bd-bg-purple-bright{background-color:#7952b3}.skippy{background-color:#563d7c}.skippy a{color:#fff}@media (max-width: 767.98px){.bd-sidebar{margin:0 -.75rem 1rem}}.bd-links{overflow:auto;font-weight:600}@media (min-width: 768px){.bd-links{position:-webkit-sticky;position:sticky;top:5rem;display:block !important;height:calc(100vh - 7rem);padding-left:.25rem;margin-left:-.25rem;overflow-y:auto}}@media (max-width: 767.98px){.bd-links>ul{padding:1.5rem .75rem;background-color:#f8f9fa;border-bottom:1px solid #e9ecef}}.bd-links a{padding:.1875rem .5rem;margin-top:.125rem;margin-left:1.25rem;color:rgba(0,0,0,0.65);text-decoration:none}.bd-links a:hover,.bd-links a:focus{color:rgba(0,0,0,0.85);background-color:rgba(121,82,179,0.1)}.bd-links .btn{padding:.25rem .5rem;font-weight:600;color:rgba(0,0,0,0.65);background-color:transparent;border:0}.bd-links .btn:hover,.bd-links .btn:focus{color:rgba(0,0,0,0.85);background-color:rgba(121,82,179,0.1)}.bd-links .btn:focus{box-shadow:0 0 0 1px rgba(121,82,179,0.7)}.bd-links .btn::before{width:1.25em;line-height:0;content:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='rgba%280,0,0,.5%29' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M5 14l6-6-6-6'/%3e%3c/svg%3e");transition:transform 0.35s ease;transform-origin:.5em 50%}@media (prefers-reduced-motion: reduce){.bd-links .btn::before{transition:none}}.bd-links .btn[aria-expanded="true"]{color:rgba(0,0,0,0.85)}.bd-links .btn[aria-expanded="true"]::before{transform:rotate(90deg)}.bd-links .active{font-weight:600;color:rgba(0,0,0,0.85)}@media (min-width: 768px){.bd-layout{display:grid;gap:1.5rem;grid-template-areas:"sidebar main";grid-template-columns:1fr 3fr}}@media (min-width: 992px){.bd-layout{grid-template-columns:1fr 5fr}}.bd-sidebar{grid-area:sidebar}.bd-main{grid-area:main}@media (min-width: 768px){.bd-main{display:grid;gap:inherit;grid-template-areas:"intro" "toc" "content";grid-template-rows:auto auto 1fr}}@media (min-width: 992px){.bd-main{grid-template-areas:"intro   toc" "content toc";grid-template-columns:4fr 1fr;grid-template-rows:auto 1fr}}.bd-intro{grid-area:intro}.bd-toc{grid-area:toc}.bd-content{grid-area:content;min-width:1px}@media (min-width: 992px){.bd-toc{position:-webkit-sticky;position:sticky;top:5rem;right:0;z-index:2;height:calc(100vh - 7rem);overflow-y:auto}}.bd-toc nav{font-size:.875rem}.bd-toc nav ul{padding-left:0;list-style:none}.bd-toc nav ul ul{padding-left:1rem;margin-top:.25rem}.bd-toc nav li{margin-bottom:.25rem}.bd-toc nav a{color:inherit}.bd-toc nav a:not(:hover){text-decoration:none}.bd-toc nav a code{font:inherit}.bd-footer a{color:#495057;text-decoration:none}.bd-footer a:hover,.bd-footer a:focus{color:#0d6efd;text-decoration:underline}.bd-example-row .row>.col,.bd-example-row .row>[class^="col-"]{padding-top:.75rem;padding-bottom:.75rem;background-color:rgba(39,41,43,0.03);border:1px solid rgba(39,41,43,0.1)}.bd-example-row .row+.row{margin-top:1rem}.bd-example-row-flex-cols .row{min-height:10rem;background-color:rgba(255,0,0,0.1)}.bd-highlight{background-color:rgba(86,61,124,0.15);border:1px solid rgba(86,61,124,0.15)}.example-container{width:800px;width:100%;padding-right:var(--bs-gutter-x, .75rem);padding-left:var(--bs-gutter-x, .75rem);margin-right:auto;margin-left:auto}.example-row{--bs-gutter-x: 1.5rem;--bs-gutter-y: 0;display:flex;flex-wrap:wrap;margin-top:calc(var(--bs-gutter-y) * -1);margin-right:calc(var(--bs-gutter-x) / -2);margin-left:calc(var(--bs-gutter-x) / -2)}.example-content-main{flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) / 2);padding-left:calc(var(--bs-gutter-x) / 2);margin-top:var(--bs-gutter-y)}@media (min-width: 576px){.example-content-main{flex:0 0 auto;width:50%}}@media (min-width: 992px){.example-content-main{flex:0 0 auto;width:66.666667%}}.example-content-secondary{flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) / 2);padding-left:calc(var(--bs-gutter-x) / 2);margin-top:var(--bs-gutter-y)}@media (min-width: 576px){.example-content-secondary{flex:0 0 auto;width:50%}}@media (min-width: 992px){.example-content-secondary{flex:0 0 auto;width:33.333333%}}.bd-example{position:relative;padding:1rem;margin:1rem -.75rem 0;border:solid #dee2e6;border-width:1px 0 0}.bd-example::after{display:block;clear:both;content:""}@media (min-width: 576px){.bd-example{padding:1.5rem;margin-right:0;margin-left:0;border-width:1px;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.bd-example+.bd-clipboard+.highlight{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}}.bd-example+p{margin-top:2rem}.bd-example>.form-control+.form-control{margin-top:.5rem}.bd-example>.nav+.nav,.bd-example>.alert+.alert,.bd-example>.navbar+.navbar,.bd-example>.progress+.progress{margin-top:1rem}.bd-example>.dropdown-menu{position:static;display:block}.bd-example>:last-child{margin-bottom:0}.bd-example>svg+svg,.bd-example>img+img{margin-left:.5rem}.bd-example>.btn,.bd-example>.btn-group{margin:.25rem .125rem}.bd-example>.btn-toolbar+.btn-toolbar{margin-top:.5rem}.bd-example>.list-group{max-width:400px}.bd-example>[class*="list-group-horizontal"]{max-width:100%}.bd-example .fixed-top,.bd-example .sticky-top{position:static;margin:-1rem -1rem 1rem}.bd-example .fixed-bottom{position:static;margin:1rem -1rem -1rem}@media (min-width: 576px){.bd-example .fixed-top,.bd-example .sticky-top{margin:-1.5rem -1.5rem 1rem}.bd-example .fixed-bottom{margin:1rem -1.5rem -1.5rem}}.bd-example .pagination{margin-top:.5rem;margin-bottom:.5rem}.bd-example-ratios .ratio{display:inline-block;width:10rem;color:#6c757d;background-color:#f8f9fa;border:1px solid #dee2e6}.bd-example-ratios .ratio>div{display:flex;align-items:center;justify-content:center}.bd-example-ratios-breakpoint .ratio-4x3{width:16rem}@media (min-width: 768px){.bd-example-ratios-breakpoint .ratio-4x3{--bs-aspect-ratio: 50%}}.bd-example-modal{background-color:#fafafa}.bd-example-modal .modal{position:static;display:block}.bd-example-offcanvas{border-top-left-radius:0;border-bottom-left-radius:0}.bd-example-offcanvas .offcanvas{position:static;display:block;height:200px;visibility:visible;transform:translate(0)}.tooltip-demo a{white-space:nowrap}.scrollspy-example{position:relative;height:200px;margin-top:.5rem;overflow:auto}.scrollspy-example-2{position:relative;height:350px;overflow:auto}.bd-example-border-utils [class^="border"]{display:inline-block;width:5rem;height:5rem;margin:.25rem;background-color:#f5f5f5}.bd-example-border-utils-0 [class^="border"]{border:1px solid #dee2e6}.bd-example-rounded-utils [class*="rounded"]{margin:.25rem}.bd-example-position-utils{position:relative;padding:3em}.bd-example-position-utils .position-relative{height:200px;background-color:#f5f5f5}.bd-example-position-utils .position-absolute{width:2em;height:2em;background-color:#212529;border-radius:.25rem}.bd-example-position-examples::after{content:none}.bd-example-toasts{min-height:240px}.highlight{padding:1rem;margin-bottom:1rem;background-color:#f8f9fa}@media (min-width: 576px){.highlight{padding:1rem 1.5rem}}.highlight pre{padding:0;margin-top:.65rem;margin-bottom:.65rem;white-space:pre;background-color:transparent;border:0}.highlight pre code{font-size:inherit;color:#212529;word-wrap:normal}.bd-content .highlight{margin-right:-.75rem;margin-left:-.75rem}@media (min-width: 576px){.bd-content .highlight{margin-right:0;margin-left:0}}.btn-bd-primary{font-weight:600;color:#fff;background-color:#7952b3;border-color:#7952b3}.btn-bd-primary:hover,.btn-bd-primary:active{color:#fff;background-color:#61428f;border-color:#61428f}.btn-bd-primary:focus{box-shadow:0 0 0 3px rgba(121,82,179,0.25)}.btn-bd-download{font-weight:600;color:#ffe484;border-color:#ffe484}.btn-bd-download:hover,.btn-bd-download:active{color:#2a2730;background-color:#ffe484;border-color:#ffe484}.btn-bd-download:focus{box-shadow:0 0 0 3px rgba(255,228,132,0.25)}.btn-bd-light{color:#6c757d;border-color:#dee2e6}.show>.btn-bd-light,.btn-bd-light:hover,.btn-bd-light:active{color:#7952b3;background-color:#fff;border-color:#7952b3}.btn-bd-light:focus{box-shadow:0 0 0 3px rgba(121,82,179,0.25)}.bd-callout{padding:1.25rem;margin-top:1.25rem;margin-bottom:1.25rem;border:1px solid #e9ecef;border-left-width:.25rem;border-radius:.25rem}.bd-callout h4{margin-bottom:.25rem}.bd-callout p:last-child{margin-bottom:0}.bd-callout code{border-radius:.25rem}.bd-callout+.bd-callout{margin-top:-.25rem}.bd-callout-info{border-left-color:#5bc0de}.bd-callout-warning{border-left-color:#f0ad4e}.bd-callout-danger{border-left-color:#d9534f}.bd-brand-logos{color:#7952b3}.bd-brand-logos .inverse{color:#fff;background-color:#7952b3}.bd-brand-item+.bd-brand-item{border-top:1px solid #fff}@media (min-width: 768px){.bd-brand-item+.bd-brand-item{border-top:0;border-left:1px solid #fff}}.color-swatches{margin:0 -5px}.color-swatches .bd-purple{background-color:#563d7c}.color-swatches .bd-purple-light{background-color:#cbbde2}.color-swatches .bd-purple-lighter{background-color:#e5e1ea}.color-swatches .bd-gray{background-color:#f9f9f9}.color-swatch{width:4rem;height:4rem}@media (min-width: 768px){.color-swatch{width:6rem;height:6rem}}.swatch-blue{color:#fff;background-color:#0d6efd}.swatch-blue::after{position:absolute;top:1rem;right:1rem;padding-left:1rem;font-size:.75rem;line-height:1.35;white-space:pre;content:"4.50" "\a" "4.50" "\a" "4.66";background-color:#0d6efd;background-image:linear-gradient(to bottom, transparent 0.25rem, #fff 0.25rem 0.75rem, transparent 0.75rem 1.25rem, #fff 1.25rem 1.75rem, transparent 1.75rem 2.25rem, #000 2.25rem 2.75rem, transparent 2.75rem);background-repeat:no-repeat;background-size:.5rem 100%}.swatch-indigo{color:#fff;background-color:#6610f2}.swatch-indigo::after{position:absolute;top:1rem;right:1rem;padding-left:1rem;font-size:.75rem;line-height:1.35;white-space:pre;content:"7.18" "\a" "7.18" "\a" "2.92";background-color:#6610f2;background-image:linear-gradient(to bottom, transparent 0.25rem, #fff 0.25rem 0.75rem, transparent 0.75rem 1.25rem, #fff 1.25rem 1.75rem, transparent 1.75rem 2.25rem, #000 2.25rem 2.75rem, transparent 2.75rem);background-repeat:no-repeat;background-size:.5rem 100%}.swatch-purple{color:#fff;background-color:#6f42c1}.swatch-purple::after{position:absolute;top:1rem;right:1rem;padding-left:1rem;font-size:.75rem;line-height:1.35;white-space:pre;content:"6.51" "\a" "6.51" "\a" "3.22";background-color:#6f42c1;background-image:linear-gradient(to bottom, transparent 0.25rem, #fff 0.25rem 0.75rem, transparent 0.75rem 1.25rem, #fff 1.25rem 1.75rem, transparent 1.75rem 2.25rem, #000 2.25rem 2.75rem, transparent 2.75rem);background-repeat:no-repeat;background-size:.5rem 100%}.swatch-pink{color:#fff;background-color:#d63384}.swatch-pink::after{position:absolute;top:1rem;right:1rem;padding-left:1rem;font-size:.75rem;line-height:1.35;white-space:pre;content:"4.50" "\a" "4.50" "\a" "4.66";background-color:#d63384;background-image:linear-gradient(to bottom, transparent 0.25rem, #fff 0.25rem 0.75rem, transparent 0.75rem 1.25rem, #fff 1.25rem 1.75rem, transparent 1.75rem 2.25rem, #000 2.25rem 2.75rem, transparent 2.75rem);background-repeat:no-repeat;background-size:.5rem 100%}.swatch-red{color:#fff;background-color:#dc3545}.swatch-red::after{position:absolute;top:1rem;right:1rem;padding-left:1rem;font-size:.75rem;line-height:1.35;white-space:pre;content:"4.52" "\a" "4.52" "\a" "4.63";background-color:#dc3545;background-image:linear-gradient(to bottom, transparent 0.25rem, #fff 0.25rem 0.75rem, transparent 0.75rem 1.25rem, #fff 1.25rem 1.75rem, transparent 1.75rem 2.25rem, #000 2.25rem 2.75rem, transparent 2.75rem);background-repeat:no-repeat;background-size:.5rem 100%}.swatch-orange{color:#000;background-color:#fd7e14}.swatch-orange::after{position:absolute;top:1rem;right:1rem;padding-left:1rem;font-size:.75rem;line-height:1.35;white-space:pre;content:"8.17" "\a" "2.57" "\a" "8.17";background-color:#fd7e14;background-image:linear-gradient(to bottom, transparent 0.25rem, #000 0.25rem 0.75rem, transparent 0.75rem 1.25rem, #fff 1.25rem 1.75rem, transparent 1.75rem 2.25rem, #000 2.25rem 2.75rem, transparent 2.75rem);background-repeat:no-repeat;background-size:.5rem 100%}.swatch-yellow{color:#000;background-color:#ffc107}.swatch-yellow::after{position:absolute;top:1rem;right:1rem;padding-left:1rem;font-size:.75rem;line-height:1.35;white-space:pre;content:"12.8" "\a" "1.63" "\a" "12.8";background-color:#ffc107;background-image:linear-gradient(to bottom, transparent 0.25rem, #000 0.25rem 0.75rem, transparent 0.75rem 1.25rem, #fff 1.25rem 1.75rem, transparent 1.75rem 2.25rem, #000 2.25rem 2.75rem, transparent 2.75rem);background-repeat:no-repeat;background-size:.5rem 100%}.swatch-green{color:#fff;background-color:#198754}.swatch-green::after{position:absolute;top:1rem;right:1rem;padding-left:1rem;font-size:.75rem;line-height:1.35;white-space:pre;content:"4.53" "\a" "4.53" "\a" "4.63";background-color:#198754;background-image:linear-gradient(to bottom, transparent 0.25rem, #fff 0.25rem 0.75rem, transparent 0.75rem 1.25rem, #fff 1.25rem 1.75rem, transparent 1.75rem 2.25rem, #000 2.25rem 2.75rem, transparent 2.75rem);background-repeat:no-repeat;background-size:.5rem 100%}.swatch-teal{color:#000;background-color:#20c997}.swatch-teal::after{position:absolute;top:1rem;right:1rem;padding-left:1rem;font-size:.75rem;line-height:1.35;white-space:pre;content:"9.86" "\a" "2.12" "\a" "9.86";background-color:#20c997;background-image:linear-gradient(to bottom, transparent 0.25rem, #000 0.25rem 0.75rem, transparent 0.75rem 1.25rem, #fff 1.25rem 1.75rem, transparent 1.75rem 2.25rem, #000 2.25rem 2.75rem, transparent 2.75rem);background-repeat:no-repeat;background-size:.5rem 100%}.swatch-cyan{color:#000;background-color:#0dcaf0}.swatch-cyan::after{position:absolute;top:1rem;right:1rem;padding-left:1rem;font-size:.75rem;line-height:1.35;white-space:pre;content:"10.7" "\a" "1.95" "\a" "10.7";background-color:#0dcaf0;background-image:linear-gradient(to bottom, transparent 0.25rem, #000 0.25rem 0.75rem, transparent 0.75rem 1.25rem, #fff 1.25rem 1.75rem, transparent 1.75rem 2.25rem, #000 2.25rem 2.75rem, transparent 2.75rem);background-repeat:no-repeat;background-size:.5rem 100%}.swatch-white{color:#000;background-color:#fff}.swatch-white::after{position:absolute;top:1rem;right:1rem;padding-left:1rem;font-size:.75rem;line-height:1.35;white-space:pre;content:"21" "\a" "1" "\a" "21";background-color:#fff;background-image:linear-gradient(to bottom, transparent 0.25rem, #000 0.25rem 0.75rem, transparent 0.75rem 1.25rem, #fff 1.25rem 1.75rem, transparent 1.75rem 2.25rem, #000 2.25rem 2.75rem, transparent 2.75rem);background-repeat:no-repeat;background-size:.5rem 100%}.swatch-gray{color:#fff;background-color:#6c757d}.swatch-gray::after{position:absolute;top:1rem;right:1rem;padding-left:1rem;font-size:.75rem;line-height:1.35;white-space:pre;content:"4.68" "\a" "4.68" "\a" "4.47";background-color:#6c757d;background-image:linear-gradient(to bottom, transparent 0.25rem, #fff 0.25rem 0.75rem, transparent 0.75rem 1.25rem, #fff 1.25rem 1.75rem, transparent 1.75rem 2.25rem, #000 2.25rem 2.75rem, transparent 2.75rem);background-repeat:no-repeat;background-size:.5rem 100%}.swatch-gray-dark{color:#fff;background-color:#343a40}.swatch-gray-dark::after{position:absolute;top:1rem;right:1rem;padding-left:1rem;font-size:.75rem;line-height:1.35;white-space:pre;content:"11.5" "\a" "11.5" "\a" "1.82";background-color:#343a40;background-image:linear-gradient(to bottom, transparent 0.25rem, #fff 0.25rem 0.75rem, transparent 0.75rem 1.25rem, #fff 1.25rem 1.75rem, transparent 1.75rem 2.25rem, #000 2.25rem 2.75rem, transparent 2.75rem);background-repeat:no-repeat;background-size:.5rem 100%}.swatch-gray-500{color:#000;background-color:#adb5bd}.swatch-gray-500::after{position:absolute;top:1rem;right:1rem;padding-left:1rem;font-size:.75rem;line-height:1.35;white-space:pre;content:"10.1" "\a" "2.07" "\a" "10.1";background-color:#adb5bd;background-image:linear-gradient(to bottom, transparent 0.25rem, #000 0.25rem 0.75rem, transparent 0.75rem 1.25rem, #fff 1.25rem 1.75rem, transparent 1.75rem 2.25rem, #000 2.25rem 2.75rem, transparent 2.75rem);background-repeat:no-repeat;background-size:.5rem 100%}.bd-blue-100{color:#000;background-color:#cfe2ff}.bd-blue-200{color:#000;background-color:#9ec5fe}.bd-blue-300{color:#000;background-color:#6ea8fe}.bd-blue-400{color:#000;background-color:#3d8bfd}.bd-blue-500{color:#fff;background-color:#0d6efd}.bd-blue-600{color:#fff;background-color:#0a58ca}.bd-blue-700{color:#fff;background-color:#084298}.bd-blue-800{color:#fff;background-color:#052c65}.bd-blue-900{color:#fff;background-color:#031633}.bd-indigo-100{color:#000;background-color:#e0cffc}.bd-indigo-200{color:#000;background-color:#c29ffa}.bd-indigo-300{color:#000;background-color:#a370f7}.bd-indigo-400{color:#fff;background-color:#8540f5}.bd-indigo-500{color:#fff;background-color:#6610f2}.bd-indigo-600{color:#fff;background-color:#520dc2}.bd-indigo-700{color:#fff;background-color:#3d0a91}.bd-indigo-800{color:#fff;background-color:#290661}.bd-indigo-900{color:#fff;background-color:#140330}.bd-purple-100{color:#000;background-color:#e2d9f3}.bd-purple-200{color:#000;background-color:#c5b3e6}.bd-purple-300{color:#000;background-color:#a98eda}.bd-purple-400{color:#000;background-color:#8c68cd}.bd-purple-500{color:#fff;background-color:#6f42c1}.bd-purple-600{color:#fff;background-color:#59359a}.bd-purple-700{color:#fff;background-color:#432874}.bd-purple-800{color:#fff;background-color:#2c1a4d}.bd-purple-900{color:#fff;background-color:#160d27}.bd-pink-100{color:#000;background-color:#f7d6e6}.bd-pink-200{color:#000;background-color:#efadce}.bd-pink-300{color:#000;background-color:#e685b5}.bd-pink-400{color:#000;background-color:#de5c9d}.bd-pink-500{color:#fff;background-color:#d63384}.bd-pink-600{color:#fff;background-color:#ab296a}.bd-pink-700{color:#fff;background-color:#801f4f}.bd-pink-800{color:#fff;background-color:#561435}.bd-pink-900{color:#fff;background-color:#2b0a1a}.bd-red-100{color:#000;background-color:#f8d7da}.bd-red-200{color:#000;background-color:#f1aeb5}.bd-red-300{color:#000;background-color:#ea868f}.bd-red-400{color:#000;background-color:#e35d6a}.bd-red-500{color:#fff;background-color:#dc3545}.bd-red-600{color:#fff;background-color:#b02a37}.bd-red-700{color:#fff;background-color:#842029}.bd-red-800{color:#fff;background-color:#58151c}.bd-red-900{color:#fff;background-color:#2c0b0e}.bd-orange-100{color:#000;background-color:#ffe5d0}.bd-orange-200{color:#000;background-color:#fecba1}.bd-orange-300{color:#000;background-color:#feb272}.bd-orange-400{color:#000;background-color:#fd9843}.bd-orange-500{color:#000;background-color:#fd7e14}.bd-orange-600{color:#000;background-color:#ca6510}.bd-orange-700{color:#fff;background-color:#984c0c}.bd-orange-800{color:#fff;background-color:#653208}.bd-orange-900{color:#fff;background-color:#331904}.bd-yellow-100{color:#000;background-color:#fff3cd}.bd-yellow-200{color:#000;background-color:#ffe69c}.bd-yellow-300{color:#000;background-color:#ffda6a}.bd-yellow-400{color:#000;background-color:#ffcd39}.bd-yellow-500{color:#000;background-color:#ffc107}.bd-yellow-600{color:#000;background-color:#cc9a06}.bd-yellow-700{color:#000;background-color:#997404}.bd-yellow-800{color:#fff;background-color:#664d03}.bd-yellow-900{color:#fff;background-color:#332701}.bd-green-100{color:#000;background-color:#d1e7dd}.bd-green-200{color:#000;background-color:#a3cfbb}.bd-green-300{color:#000;background-color:#75b798}.bd-green-400{color:#000;background-color:#479f76}.bd-green-500{color:#fff;background-color:#198754}.bd-green-600{color:#fff;background-color:#146c43}.bd-green-700{color:#fff;background-color:#0f5132}.bd-green-800{color:#fff;background-color:#0a3622}.bd-green-900{color:#fff;background-color:#051b11}.bd-teal-100{color:#000;background-color:#d2f4ea}.bd-teal-200{color:#000;background-color:#a6e9d5}.bd-teal-300{color:#000;background-color:#79dfc1}.bd-teal-400{color:#000;background-color:#4dd4ac}.bd-teal-500{color:#000;background-color:#20c997}.bd-teal-600{color:#000;background-color:#1aa179}.bd-teal-700{color:#fff;background-color:#13795b}.bd-teal-800{color:#fff;background-color:#0d503c}.bd-teal-900{color:#fff;background-color:#06281e}.bd-cyan-100{color:#000;background-color:#cff4fc}.bd-cyan-200{color:#000;background-color:#9eeaf9}.bd-cyan-300{color:#000;background-color:#6edff6}.bd-cyan-400{color:#000;background-color:#3dd5f3}.bd-cyan-500{color:#000;background-color:#0dcaf0}.bd-cyan-600{color:#000;background-color:#0aa2c0}.bd-cyan-700{color:#fff;background-color:#087990}.bd-cyan-800{color:#fff;background-color:#055160}.bd-cyan-900{color:#fff;background-color:#032830}.bd-gray-100{color:#000;background-color:#f8f9fa}.bd-gray-200{color:#000;background-color:#e9ecef}.bd-gray-300{color:#000;background-color:#dee2e6}.bd-gray-400{color:#000;background-color:#ced4da}.bd-gray-500{color:#000;background-color:#adb5bd}.bd-gray-600{color:#fff;background-color:#6c757d}.bd-gray-700{color:#fff;background-color:#495057}.bd-gray-800{color:#fff;background-color:#343a40}.bd-gray-900{color:#fff;background-color:#212529}.bd-white{color:#000;background-color:#fff}.bd-black{color:#fff;background-color:#000}.bd-clipboard{position:relative;display:none;float:right}.bd-clipboard+.highlight{margin-top:0}@media (min-width: 768px){.bd-clipboard{display:block}}.btn-clipboard{position:absolute;top:.65rem;right:.65rem;z-index:10;display:block;padding:.25rem .5rem;font-size:.65em;color:#0d6efd;background-color:#fff;border:1px solid;border-radius:.25rem}.btn-clipboard:hover,.btn-clipboard:focus{color:#fff;background-color:#0d6efd}.bd-placeholder-img{font-size:1.125rem;text-anchor:middle;-webkit-user-select:none;-moz-user-select:none;user-select:none}.bd-placeholder-img-lg{font-size:calc(1.475rem + 2.7vw)}@media (min-width: 1200px){.bd-placeholder-img-lg{font-size:3.5rem}}.chroma .c{color:#727272}.chroma .ch{font-style:italic;color:#60a0b0}.chroma .cm{color:#727272}.chroma .cp{color:#008085}.chroma .cpf{color:#007020}.chroma .c1{color:#727272}.chroma .cs{color:#727272}.chroma .gd{background-color:#fcc;border:1px solid #c00}.chroma .ge{font-style:italic}.chroma .gr{color:#f00}.chroma .gh{color:#030}.chroma .gi{background-color:#cfc;border:1px solid #0c0}.chroma .go{color:#aaa}.chroma .gp{color:#009}.chroma .gs{font-weight:700}.chroma .gu{color:#030}.chroma .gt{color:#9c6}.chroma .gl{text-decoration:underline}.chroma .k{color:#069}.chroma .kc{color:#069}.chroma .kd{color:#069}.chroma .kn{color:#069}.chroma .kp{color:#069}.chroma .kr{color:#069}.chroma .kt{color:#078}.chroma .m{color:#c24f19}.chroma .mb{color:#40a070}.chroma .mf{color:#c24f19}.chroma .mh{color:#c24f19}.chroma .mi{color:#c24f19}.chroma .il{color:#c24f19}.chroma .mo{color:#c24f19}.chroma .s{color:#d73038}.chroma .sa{color:#4070a0}.chroma .sb{color:#c30}.chroma .sc{color:#c30}.chroma .dl{color:#4070a0}.chroma .sd{font-style:italic;color:#c30}.chroma .s2{color:#c30}.chroma .se{color:#c30}.chroma .sh{color:#c30}.chroma .si{color:#a00}.chroma .sx{color:#c30}.chroma .sr{color:#337e7e}.chroma .s1{color:#c30}.chroma .ss{color:#fc3}.chroma .na{color:#006ee0}.chroma .nb{color:#366}.chroma .nc{color:#168174}.chroma .no{color:#360}.chroma .nd{color:#6b62de}.chroma .ni{color:#727272}.chroma .ne{color:#c00}.chroma .nf{color:#b715f4}.chroma .nl{color:#6b62de}.chroma .nn{color:#007ca5}.chroma .nt{color:#2f6f9f}.chroma .nv{color:#033}.chroma .o{color:#555}.chroma .ow{color:#000}.chroma .w{color:#bbb}.chroma .language-bash::before,.chroma .language-sh::before{color:#009;content:"$ ";-webkit-user-select:none;-moz-user-select:none;user-select:none}.chroma .language-powershell::before{color:#009;content:"PM> ";-webkit-user-select:none;-moz-user-select:none;user-select:none}.anchorjs-link{font-weight:400;color:rgba(13,110,253,0.5);transition:color 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.anchorjs-link{transition:none}}.anchorjs-link:focus,.anchorjs-link:hover{color:#0d6efd;text-decoration:none}.algolia-autocomplete{width:100%}.ds-dropdown-menu{width:100%;padding:.5rem 0;margin:.125rem 0 0;font-size:.875rem;background-color:#fff;border:1px solid rgba(0,0,0,0.15);border-radius:.25rem}@media (min-width: 768px){.ds-dropdown-menu{width:400px}}.algolia-docsearch-suggestion--category-header{padding:.125rem 1rem;font-weight:600;color:#7952b3}:not(.algolia-docsearch-suggestion__main)>.algolia-docsearch-suggestion--category-header{display:none}.ds-suggestion:not(:first-child) .algolia-docsearch-suggestion--category-header{padding-top:.75rem;margin-top:.75rem;border-top:1px solid rgba(0,0,0,0.1)}.algolia-docsearch-suggestion--content{padding:.25rem 1rem}.ds-cursor .algolia-docsearch-suggestion--content{background-color:rgba(203,189,226,0.2)}.algolia-docsearch-suggestion{display:block;text-decoration:none}.algolia-docsearch-suggestion--subcategory-column{display:none}.algolia-docsearch-suggestion--subcategory-inline{display:inline;color:#495057}.algolia-docsearch-suggestion--subcategory-inline::after{padding:0 .25rem;content:"/"}.algolia-docsearch-suggestion--title{display:inline;font-weight:500;color:#343a40}.algolia-docsearch-suggestion--text{color:#343a40;font-size:.75rem}.algolia-docsearch-suggestion--highlight{color:#6f42c1;background-color:rgba(111,66,193,0.1)}.algolia-docsearch-footer{padding:.5rem 1rem 0;margin-top:.625rem;font-size:.75rem;color:#6c757d;border-top:1px solid rgba(0,0,0,0.1)}.algolia-docsearch-footer--logo{color:inherit}
8 | 


--------------------------------------------------------------------------------
/custom_theme/css/font-awesome.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 |  *  Font Awesome 4.3.0 by @davegandy - http://fontawesome.io - @fontawesome
3 |  *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
4 |  */
5 |  @font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.3.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.3.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.3.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.3.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.3.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.3.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;transform:translate(0, 0)}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-genderless:before,.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}


--------------------------------------------------------------------------------
/custom_theme/css/theme.css:
--------------------------------------------------------------------------------
1 | body {
2 |     margin: 1em;
3 | }
4 | 
5 | .active a {
6 |     color: red;
7 |     font-weight: bold;
8 | }
9 | 


--------------------------------------------------------------------------------
/custom_theme/fonts/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenCan-io/opencan/7f224bad5e2a7fdbace3df012ad7713efac4ec9c/custom_theme/fonts/fontawesome-webfont.eot


--------------------------------------------------------------------------------
/custom_theme/fonts/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenCan-io/opencan/7f224bad5e2a7fdbace3df012ad7713efac4ec9c/custom_theme/fonts/fontawesome-webfont.ttf


--------------------------------------------------------------------------------
/custom_theme/fonts/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenCan-io/opencan/7f224bad5e2a7fdbace3df012ad7713efac4ec9c/custom_theme/fonts/fontawesome-webfont.woff


--------------------------------------------------------------------------------
/custom_theme/github-nav-item.html:
--------------------------------------------------------------------------------
1 | 


--------------------------------------------------------------------------------
/custom_theme/header.html:
--------------------------------------------------------------------------------
 1 | 


--------------------------------------------------------------------------------
/custom_theme/images/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenCan-io/opencan/7f224bad5e2a7fdbace3df012ad7713efac4ec9c/custom_theme/images/.DS_Store


--------------------------------------------------------------------------------
/custom_theme/images/logo/opencan.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenCan-io/opencan/7f224bad5e2a7fdbace3df012ad7713efac4ec9c/custom_theme/images/logo/opencan.ai


--------------------------------------------------------------------------------
/custom_theme/images/logo/opencan.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenCan-io/opencan/7f224bad5e2a7fdbace3df012ad7713efac4ec9c/custom_theme/images/logo/opencan.png


--------------------------------------------------------------------------------
/custom_theme/js/base.js:
--------------------------------------------------------------------------------
 1 | /*
 2 | $('.dropdown-submenu > a').on("click", function(e) {
 3 |     var submenu = $(this);
 4 |     $('.dropdown-submenu .dropdown-menu').removeClass('show');
 5 |     submenu.next('.dropdown-menu').addClass('show');
 6 |     e.stopPropagation();
 7 | });
 8 | $('.dropdown').on("hidden.bs.dropdown", function() {
 9 |     // hide any open menus when parent closes
10 |     $('.dropdown-menu.show').removeClass('show');
11 | });
12 | */
13 | 
14 | // $( document ).ready( function () {
15 | 
16 | //     $( '.contributors img[data-src]' ).each( function() {
17 | //         src = $(this).attr("data-src");
18 | //         $(this).attr('src',src);
19 | //     });
20 | //     $('.metadata').detach().insertAfter( '#content h1:first' );
21 | // } );


--------------------------------------------------------------------------------
/custom_theme/js/bootstrap.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 |   * Bootstrap v5.0.1 (https://getbootstrap.com/)
3 |   * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
4 |   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
5 |   */
6 | !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("@popperjs/core")):"function"==typeof define&&define.amd?define(["@popperjs/core"],e):(t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap=e(t.Popper)}(this,(function(t){"use strict";function e(t){if(t&&t.__esModule)return t;var e=Object.create(null);return t&&Object.keys(t).forEach((function(s){if("default"!==s){var i=Object.getOwnPropertyDescriptor(t,s);Object.defineProperty(e,s,i.get?i:{enumerable:!0,get:function(){return t[s]}})}})),e.default=t,Object.freeze(e)}var s=e(t);const i={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter(t=>t.matches(e)),parents(t,e){const s=[];let i=t.parentNode;for(;i&&i.nodeType===Node.ELEMENT_NODE&&3!==i.nodeType;)i.matches(e)&&s.push(i),i=i.parentNode;return s},prev(t,e){let s=t.previousElementSibling;for(;s;){if(s.matches(e))return[s];s=s.previousElementSibling}return[]},next(t,e){let s=t.nextElementSibling;for(;s;){if(s.matches(e))return[s];s=s.nextElementSibling}return[]}},n=t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t},o=t=>{let e=t.getAttribute("data-bs-target");if(!e||"#"===e){let s=t.getAttribute("href");if(!s||!s.includes("#")&&!s.startsWith("."))return null;s.includes("#")&&!s.startsWith("#")&&(s="#"+s.split("#")[1]),e=s&&"#"!==s?s.trim():null}return e},r=t=>{const e=o(t);return e&&document.querySelector(e)?e:null},a=t=>{const e=o(t);return e?document.querySelector(e):null},l=t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:s}=window.getComputedStyle(t);const i=Number.parseFloat(e),n=Number.parseFloat(s);return i||n?(e=e.split(",")[0],s=s.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(s))):0},c=t=>{t.dispatchEvent(new Event("transitionend"))},h=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),d=t=>h(t)?t.jquery?t[0]:t:"string"==typeof t&&t.length>0?i.findOne(t):null,u=(t,e)=>{let s=!1;const i=e+5;t.addEventListener("transitionend",(function e(){s=!0,t.removeEventListener("transitionend",e)})),setTimeout(()=>{s||c(t)},i)},g=(t,e,s)=>{Object.keys(s).forEach(i=>{const n=s[i],o=e[i],r=o&&h(o)?"element":null==(a=o)?""+a:{}.toString.call(a).match(/\s([a-z]+)/i)[1].toLowerCase();var a;if(!new RegExp(n).test(r))throw new TypeError(`${t.toUpperCase()}: Option "${i}" provided type "${r}" but expected type "${n}".`)})},f=t=>{if(!t)return!1;if(t.style&&t.parentNode&&t.parentNode.style){const e=getComputedStyle(t),s=getComputedStyle(t.parentNode);return"none"!==e.display&&"none"!==s.display&&"hidden"!==e.visibility}return!1},p=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),m=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?m(t.parentNode):null},_=()=>{},b=t=>t.offsetHeight,v=()=>{const{jQuery:t}=window;return t&&!document.body.hasAttribute("data-bs-no-jquery")?t:null},y=()=>"rtl"===document.documentElement.dir,w=t=>{var e;e=()=>{const e=v();if(e){const s=t.NAME,i=e.fn[s];e.fn[s]=t.jQueryInterface,e.fn[s].Constructor=t,e.fn[s].noConflict=()=>(e.fn[s]=i,t.jQueryInterface)}},"loading"===document.readyState?document.addEventListener("DOMContentLoaded",e):e()},E=t=>{"function"==typeof t&&t()},T=new Map;var A={set(t,e,s){T.has(t)||T.set(t,new Map);const i=T.get(t);i.has(e)||0===i.size?i.set(e,s):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(i.keys())[0]}.`)},get:(t,e)=>T.has(t)&&T.get(t).get(e)||null,remove(t,e){if(!T.has(t))return;const s=T.get(t);s.delete(e),0===s.size&&T.delete(t)}};const k=/[^.]*(?=\..*)\.|.*/,L=/\..*/,C=/::\d+$/,D={};let N=1;const S={mouseenter:"mouseover",mouseleave:"mouseout"},O=/^(mouseenter|mouseleave)/i,I=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function x(t,e){return e&&`${e}::${N++}`||t.uidEvent||N++}function j(t){const e=x(t);return t.uidEvent=e,D[e]=D[e]||{},D[e]}function P(t,e,s=null){const i=Object.keys(t);for(let n=0,o=i.length;nfunction(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};i?i=t(i):s=t(s)}const[o,r,a]=M(e,s,i),l=j(t),c=l[a]||(l[a]={}),h=P(c,r,o?s:null);if(h)return void(h.oneOff=h.oneOff&&n);const d=x(r,e.replace(k,"")),u=o?function(t,e,s){return function i(n){const o=t.querySelectorAll(e);for(let{target:r}=n;r&&r!==this;r=r.parentNode)for(let a=o.length;a--;)if(o[a]===r)return n.delegateTarget=r,i.oneOff&&$.off(t,n.type,e,s),s.apply(r,[n]);return null}}(t,s,i):function(t,e){return function s(i){return i.delegateTarget=t,s.oneOff&&$.off(t,i.type,e),e.apply(t,[i])}}(t,s);u.delegationSelector=o?s:null,u.originalHandler=r,u.oneOff=n,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function R(t,e,s,i,n){const o=P(e[s],i,n);o&&(t.removeEventListener(s,o,Boolean(n)),delete e[s][o.uidEvent])}function B(t){return t=t.replace(L,""),S[t]||t}const $={on(t,e,s,i){H(t,e,s,i,!1)},one(t,e,s,i){H(t,e,s,i,!0)},off(t,e,s,i){if("string"!=typeof e||!t)return;const[n,o,r]=M(e,s,i),a=r!==e,l=j(t),c=e.startsWith(".");if(void 0!==o){if(!l||!l[r])return;return void R(t,l,r,o,n?s:null)}c&&Object.keys(l).forEach(s=>{!function(t,e,s,i){const n=e[s]||{};Object.keys(n).forEach(o=>{if(o.includes(i)){const i=n[o];R(t,e,s,i.originalHandler,i.delegationSelector)}})}(t,l,s,e.slice(1))});const h=l[r]||{};Object.keys(h).forEach(s=>{const i=s.replace(C,"");if(!a||e.includes(i)){const e=h[s];R(t,l,r,e.originalHandler,e.delegationSelector)}})},trigger(t,e,s){if("string"!=typeof e||!t)return null;const i=v(),n=B(e),o=e!==n,r=I.has(n);let a,l=!0,c=!0,h=!1,d=null;return o&&i&&(a=i.Event(e,s),i(t).trigger(a),l=!a.isPropagationStopped(),c=!a.isImmediatePropagationStopped(),h=a.isDefaultPrevented()),r?(d=document.createEvent("HTMLEvents"),d.initEvent(n,l,!0)):d=new CustomEvent(e,{bubbles:l,cancelable:!0}),void 0!==s&&Object.keys(s).forEach(t=>{Object.defineProperty(d,t,{get:()=>s[t]})}),h&&d.preventDefault(),c&&t.dispatchEvent(d),d.defaultPrevented&&void 0!==a&&a.preventDefault(),d}};class z{constructor(t){(t=d(t))&&(this._element=t,A.set(this._element,this.constructor.DATA_KEY,this))}dispose(){A.remove(this._element,this.constructor.DATA_KEY),$.off(this._element,this.constructor.EVENT_KEY),Object.getOwnPropertyNames(this).forEach(t=>{this[t]=null})}_queueCallback(t,e,s=!0){if(!s)return void E(t);const i=l(e);$.one(e,"transitionend",()=>E(t)),u(e,i)}static getInstance(t){return A.get(t,this.DATA_KEY)}static get VERSION(){return"5.0.1"}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}static get DATA_KEY(){return"bs."+this.NAME}static get EVENT_KEY(){return"."+this.DATA_KEY}}class U extends z{static get NAME(){return"alert"}close(t){const e=t?this._getRootElement(t):this._element,s=this._triggerCloseEvent(e);null===s||s.defaultPrevented||this._removeElement(e)}_getRootElement(t){return a(t)||t.closest(".alert")}_triggerCloseEvent(t){return $.trigger(t,"close.bs.alert")}_removeElement(t){t.classList.remove("show");const e=t.classList.contains("fade");this._queueCallback(()=>this._destroyElement(t),t,e)}_destroyElement(t){t.parentNode&&t.parentNode.removeChild(t),$.trigger(t,"closed.bs.alert")}static jQueryInterface(t){return this.each((function(){let e=A.get(this,"bs.alert");e||(e=new U(this)),"close"===t&&e[t](this)}))}static handleDismiss(t){return function(e){e&&e.preventDefault(),t.close(this)}}}$.on(document,"click.bs.alert.data-api",'[data-bs-dismiss="alert"]',U.handleDismiss(new U)),w(U);class q extends z{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){let e=A.get(this,"bs.button");e||(e=new q(this)),"toggle"===t&&e[t]()}))}}function F(t){return"true"===t||"false"!==t&&(t===Number(t).toString()?Number(t):""===t||"null"===t?null:t)}function W(t){return t.replace(/[A-Z]/g,t=>"-"+t.toLowerCase())}$.on(document,"click.bs.button.data-api",'[data-bs-toggle="button"]',t=>{t.preventDefault();const e=t.target.closest('[data-bs-toggle="button"]');let s=A.get(e,"bs.button");s||(s=new q(e)),s.toggle()}),w(q);const K={setDataAttribute(t,e,s){t.setAttribute("data-bs-"+W(e),s)},removeDataAttribute(t,e){t.removeAttribute("data-bs-"+W(e))},getDataAttributes(t){if(!t)return{};const e={};return Object.keys(t.dataset).filter(t=>t.startsWith("bs")).forEach(s=>{let i=s.replace(/^bs/,"");i=i.charAt(0).toLowerCase()+i.slice(1,i.length),e[i]=F(t.dataset[s])}),e},getDataAttribute:(t,e)=>F(t.getAttribute("data-bs-"+W(e))),offset(t){const e=t.getBoundingClientRect();return{top:e.top+document.body.scrollTop,left:e.left+document.body.scrollLeft}},position:t=>({top:t.offsetTop,left:t.offsetLeft})},V={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0,touch:!0},Q={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean",touch:"boolean"},X="next",Y="prev",G="left",Z="right";class J extends z{constructor(t,e){super(t),this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this.touchStartX=0,this.touchDeltaX=0,this._config=this._getConfig(e),this._indicatorsElement=i.findOne(".carousel-indicators",this._element),this._touchSupported="ontouchstart"in document.documentElement||navigator.maxTouchPoints>0,this._pointerEvent=Boolean(window.PointerEvent),this._addEventListeners()}static get Default(){return V}static get NAME(){return"carousel"}next(){this._isSliding||this._slide(X)}nextWhenVisible(){!document.hidden&&f(this._element)&&this.next()}prev(){this._isSliding||this._slide(Y)}pause(t){t||(this._isPaused=!0),i.findOne(".carousel-item-next, .carousel-item-prev",this._element)&&(c(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null}cycle(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config&&this._config.interval&&!this._isPaused&&(this._updateInterval(),this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))}to(t){this._activeElement=i.findOne(".active.carousel-item",this._element);const e=this._getItemIndex(this._activeElement);if(t>this._items.length-1||t<0)return;if(this._isSliding)return void $.one(this._element,"slid.bs.carousel",()=>this.to(t));if(e===t)return this.pause(),void this.cycle();const s=t>e?X:Y;this._slide(s,this._items[t])}_getConfig(t){return t={...V,...t},g("carousel",t,Q),t}_handleSwipe(){const t=Math.abs(this.touchDeltaX);if(t<=40)return;const e=t/this.touchDeltaX;this.touchDeltaX=0,e&&this._slide(e>0?Z:G)}_addEventListeners(){this._config.keyboard&&$.on(this._element,"keydown.bs.carousel",t=>this._keydown(t)),"hover"===this._config.pause&&($.on(this._element,"mouseenter.bs.carousel",t=>this.pause(t)),$.on(this._element,"mouseleave.bs.carousel",t=>this.cycle(t))),this._config.touch&&this._touchSupported&&this._addTouchEventListeners()}_addTouchEventListeners(){const t=t=>{!this._pointerEvent||"pen"!==t.pointerType&&"touch"!==t.pointerType?this._pointerEvent||(this.touchStartX=t.touches[0].clientX):this.touchStartX=t.clientX},e=t=>{this.touchDeltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this.touchStartX},s=t=>{!this._pointerEvent||"pen"!==t.pointerType&&"touch"!==t.pointerType||(this.touchDeltaX=t.clientX-this.touchStartX),this._handleSwipe(),"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout(t=>this.cycle(t),500+this._config.interval))};i.find(".carousel-item img",this._element).forEach(t=>{$.on(t,"dragstart.bs.carousel",t=>t.preventDefault())}),this._pointerEvent?($.on(this._element,"pointerdown.bs.carousel",e=>t(e)),$.on(this._element,"pointerup.bs.carousel",t=>s(t)),this._element.classList.add("pointer-event")):($.on(this._element,"touchstart.bs.carousel",e=>t(e)),$.on(this._element,"touchmove.bs.carousel",t=>e(t)),$.on(this._element,"touchend.bs.carousel",t=>s(t)))}_keydown(t){/input|textarea/i.test(t.target.tagName)||("ArrowLeft"===t.key?(t.preventDefault(),this._slide(Z)):"ArrowRight"===t.key&&(t.preventDefault(),this._slide(G)))}_getItemIndex(t){return this._items=t&&t.parentNode?i.find(".carousel-item",t.parentNode):[],this._items.indexOf(t)}_getItemByOrder(t,e){const s=t===X,i=t===Y,n=this._getItemIndex(e),o=this._items.length-1;if((i&&0===n||s&&n===o)&&!this._config.wrap)return e;const r=(n+(i?-1:1))%this._items.length;return-1===r?this._items[this._items.length-1]:this._items[r]}_triggerSlideEvent(t,e){const s=this._getItemIndex(t),n=this._getItemIndex(i.findOne(".active.carousel-item",this._element));return $.trigger(this._element,"slide.bs.carousel",{relatedTarget:t,direction:e,from:n,to:s})}_setActiveIndicatorElement(t){if(this._indicatorsElement){const e=i.findOne(".active",this._indicatorsElement);e.classList.remove("active"),e.removeAttribute("aria-current");const s=i.find("[data-bs-target]",this._indicatorsElement);for(let e=0;e{$.trigger(this._element,"slid.bs.carousel",{relatedTarget:r,direction:u,from:o,to:a})};if(this._element.classList.contains("slide")){r.classList.add(d),b(r),n.classList.add(h),r.classList.add(h);const t=()=>{r.classList.remove(h,d),r.classList.add("active"),n.classList.remove("active",d,h),this._isSliding=!1,setTimeout(g,0)};this._queueCallback(t,n,!0)}else n.classList.remove("active"),r.classList.add("active"),this._isSliding=!1,g();l&&this.cycle()}_directionToOrder(t){return[Z,G].includes(t)?y()?t===G?Y:X:t===G?X:Y:t}_orderToDirection(t){return[X,Y].includes(t)?y()?t===Y?G:Z:t===Y?Z:G:t}static carouselInterface(t,e){let s=A.get(t,"bs.carousel"),i={...V,...K.getDataAttributes(t)};"object"==typeof e&&(i={...i,...e});const n="string"==typeof e?e:i.slide;if(s||(s=new J(t,i)),"number"==typeof e)s.to(e);else if("string"==typeof n){if(void 0===s[n])throw new TypeError(`No method named "${n}"`);s[n]()}else i.interval&&i.ride&&(s.pause(),s.cycle())}static jQueryInterface(t){return this.each((function(){J.carouselInterface(this,t)}))}static dataApiClickHandler(t){const e=a(this);if(!e||!e.classList.contains("carousel"))return;const s={...K.getDataAttributes(e),...K.getDataAttributes(this)},i=this.getAttribute("data-bs-slide-to");i&&(s.interval=!1),J.carouselInterface(e,s),i&&A.get(e,"bs.carousel").to(i),t.preventDefault()}}$.on(document,"click.bs.carousel.data-api","[data-bs-slide], [data-bs-slide-to]",J.dataApiClickHandler),$.on(window,"load.bs.carousel.data-api",()=>{const t=i.find('[data-bs-ride="carousel"]');for(let e=0,s=t.length;et===this._element);null!==n&&o.length&&(this._selector=n,this._triggerArray.push(e))}this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle()}static get Default(){return tt}static get NAME(){return"collapse"}toggle(){this._element.classList.contains("show")?this.hide():this.show()}show(){if(this._isTransitioning||this._element.classList.contains("show"))return;let t,e;this._parent&&(t=i.find(".show, .collapsing",this._parent).filter(t=>"string"==typeof this._config.parent?t.getAttribute("data-bs-parent")===this._config.parent:t.classList.contains("collapse")),0===t.length&&(t=null));const s=i.findOne(this._selector);if(t){const i=t.find(t=>s!==t);if(e=i?A.get(i,"bs.collapse"):null,e&&e._isTransitioning)return}if($.trigger(this._element,"show.bs.collapse").defaultPrevented)return;t&&t.forEach(t=>{s!==t&&st.collapseInterface(t,"hide"),e||A.set(t,"bs.collapse",null)});const n=this._getDimension();this._element.classList.remove("collapse"),this._element.classList.add("collapsing"),this._element.style[n]=0,this._triggerArray.length&&this._triggerArray.forEach(t=>{t.classList.remove("collapsed"),t.setAttribute("aria-expanded",!0)}),this.setTransitioning(!0);const o="scroll"+(n[0].toUpperCase()+n.slice(1));this._queueCallback(()=>{this._element.classList.remove("collapsing"),this._element.classList.add("collapse","show"),this._element.style[n]="",this.setTransitioning(!1),$.trigger(this._element,"shown.bs.collapse")},this._element,!0),this._element.style[n]=this._element[o]+"px"}hide(){if(this._isTransitioning||!this._element.classList.contains("show"))return;if($.trigger(this._element,"hide.bs.collapse").defaultPrevented)return;const t=this._getDimension();this._element.style[t]=this._element.getBoundingClientRect()[t]+"px",b(this._element),this._element.classList.add("collapsing"),this._element.classList.remove("collapse","show");const e=this._triggerArray.length;if(e>0)for(let t=0;t{this.setTransitioning(!1),this._element.classList.remove("collapsing"),this._element.classList.add("collapse"),$.trigger(this._element,"hidden.bs.collapse")},this._element,!0)}setTransitioning(t){this._isTransitioning=t}_getConfig(t){return(t={...tt,...t}).toggle=Boolean(t.toggle),g("collapse",t,et),t}_getDimension(){return this._element.classList.contains("width")?"width":"height"}_getParent(){let{parent:t}=this._config;t=d(t);const e=`[data-bs-toggle="collapse"][data-bs-parent="${t}"]`;return i.find(e,t).forEach(t=>{const e=a(t);this._addAriaAndCollapsedClass(e,[t])}),t}_addAriaAndCollapsedClass(t,e){if(!t||!e.length)return;const s=t.classList.contains("show");e.forEach(t=>{s?t.classList.remove("collapsed"):t.classList.add("collapsed"),t.setAttribute("aria-expanded",s)})}static collapseInterface(t,e){let s=A.get(t,"bs.collapse");const i={...tt,...K.getDataAttributes(t),..."object"==typeof e&&e?e:{}};if(!s&&i.toggle&&"string"==typeof e&&/show|hide/.test(e)&&(i.toggle=!1),s||(s=new st(t,i)),"string"==typeof e){if(void 0===s[e])throw new TypeError(`No method named "${e}"`);s[e]()}}static jQueryInterface(t){return this.each((function(){st.collapseInterface(this,t)}))}}$.on(document,"click.bs.collapse.data-api",'[data-bs-toggle="collapse"]',(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();const e=K.getDataAttributes(this),s=r(this);i.find(s).forEach(t=>{const s=A.get(t,"bs.collapse");let i;s?(null===s._parent&&"string"==typeof e.parent&&(s._config.parent=e.parent,s._parent=s._getParent()),i="toggle"):i=e,st.collapseInterface(t,i)})})),w(st);const it=new RegExp("ArrowUp|ArrowDown|Escape"),nt=y()?"top-end":"top-start",ot=y()?"top-start":"top-end",rt=y()?"bottom-end":"bottom-start",at=y()?"bottom-start":"bottom-end",lt=y()?"left-start":"right-start",ct=y()?"right-start":"left-start",ht={offset:[0,2],boundary:"clippingParents",reference:"toggle",display:"dynamic",popperConfig:null,autoClose:!0},dt={offset:"(array|string|function)",boundary:"(string|element)",reference:"(string|element|object)",display:"string",popperConfig:"(null|object|function)",autoClose:"(boolean|string)"};class ut extends z{constructor(t,e){super(t),this._popper=null,this._config=this._getConfig(e),this._menu=this._getMenuElement(),this._inNavbar=this._detectNavbar(),this._addEventListeners()}static get Default(){return ht}static get DefaultType(){return dt}static get NAME(){return"dropdown"}toggle(){p(this._element)||(this._element.classList.contains("show")?this.hide():this.show())}show(){if(p(this._element)||this._menu.classList.contains("show"))return;const t=ut.getParentFromElement(this._element),e={relatedTarget:this._element};if(!$.trigger(this._element,"show.bs.dropdown",e).defaultPrevented){if(this._inNavbar)K.setDataAttribute(this._menu,"popper","none");else{if(void 0===s)throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");let e=this._element;"parent"===this._config.reference?e=t:h(this._config.reference)?e=d(this._config.reference):"object"==typeof this._config.reference&&(e=this._config.reference);const i=this._getPopperConfig(),n=i.modifiers.find(t=>"applyStyles"===t.name&&!1===t.enabled);this._popper=s.createPopper(e,this._menu,i),n&&K.setDataAttribute(this._menu,"popper","static")}"ontouchstart"in document.documentElement&&!t.closest(".navbar-nav")&&[].concat(...document.body.children).forEach(t=>$.on(t,"mouseover",_)),this._element.focus(),this._element.setAttribute("aria-expanded",!0),this._menu.classList.toggle("show"),this._element.classList.toggle("show"),$.trigger(this._element,"shown.bs.dropdown",e)}}hide(){if(p(this._element)||!this._menu.classList.contains("show"))return;const t={relatedTarget:this._element};this._completeHide(t)}dispose(){this._popper&&this._popper.destroy(),super.dispose()}update(){this._inNavbar=this._detectNavbar(),this._popper&&this._popper.update()}_addEventListeners(){$.on(this._element,"click.bs.dropdown",t=>{t.preventDefault(),this.toggle()})}_completeHide(t){$.trigger(this._element,"hide.bs.dropdown",t).defaultPrevented||("ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach(t=>$.off(t,"mouseover",_)),this._popper&&this._popper.destroy(),this._menu.classList.remove("show"),this._element.classList.remove("show"),this._element.setAttribute("aria-expanded","false"),K.removeDataAttribute(this._menu,"popper"),$.trigger(this._element,"hidden.bs.dropdown",t))}_getConfig(t){if(t={...this.constructor.Default,...K.getDataAttributes(this._element),...t},g("dropdown",t,this.constructor.DefaultType),"object"==typeof t.reference&&!h(t.reference)&&"function"!=typeof t.reference.getBoundingClientRect)throw new TypeError("dropdown".toUpperCase()+': Option "reference" provided type "object" without a required "getBoundingClientRect" method.');return t}_getMenuElement(){return i.next(this._element,".dropdown-menu")[0]}_getPlacement(){const t=this._element.parentNode;if(t.classList.contains("dropend"))return lt;if(t.classList.contains("dropstart"))return ct;const e="end"===getComputedStyle(this._menu).getPropertyValue("--bs-position").trim();return t.classList.contains("dropup")?e?ot:nt:e?at:rt}_detectNavbar(){return null!==this._element.closest(".navbar")}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map(t=>Number.parseInt(t,10)):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return"static"===this._config.display&&(t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,..."function"==typeof this._config.popperConfig?this._config.popperConfig(t):this._config.popperConfig}}_selectMenuItem(t){const e=i.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter(f);if(!e.length)return;let s=e.indexOf(t.target);"ArrowUp"===t.key&&s>0&&s--,"ArrowDown"===t.key&&sthis.matches('[data-bs-toggle="dropdown"]')?this:i.prev(this,'[data-bs-toggle="dropdown"]')[0];if("Escape"===t.key)return s().focus(),void ut.clearMenus();e||"ArrowUp"!==t.key&&"ArrowDown"!==t.key?e&&"Space"!==t.key?ut.getInstance(s())._selectMenuItem(t):ut.clearMenus():s().click()}}$.on(document,"keydown.bs.dropdown.data-api",'[data-bs-toggle="dropdown"]',ut.dataApiKeydownHandler),$.on(document,"keydown.bs.dropdown.data-api",".dropdown-menu",ut.dataApiKeydownHandler),$.on(document,"click.bs.dropdown.data-api",ut.clearMenus),$.on(document,"keyup.bs.dropdown.data-api",ut.clearMenus),$.on(document,"click.bs.dropdown.data-api",'[data-bs-toggle="dropdown"]',(function(t){t.preventDefault(),ut.dropdownInterface(this)})),w(ut);const gt=()=>{const t=document.documentElement.clientWidth;return Math.abs(window.innerWidth-t)},ft=(t=gt())=>{pt(),mt("body","paddingRight",e=>e+t),mt(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top","paddingRight",e=>e+t),mt(".sticky-top","marginRight",e=>e-t)},pt=()=>{const t=document.body.style.overflow;t&&K.setDataAttribute(document.body,"overflow",t),document.body.style.overflow="hidden"},mt=(t,e,s)=>{const n=gt();i.find(t).forEach(t=>{if(t!==document.body&&window.innerWidth>t.clientWidth+n)return;const i=t.style[e],o=window.getComputedStyle(t)[e];K.setDataAttribute(t,e,i),t.style[e]=s(Number.parseFloat(o))+"px"})},_t=()=>{bt("body","overflow"),bt("body","paddingRight"),bt(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top","paddingRight"),bt(".sticky-top","marginRight")},bt=(t,e)=>{i.find(t).forEach(t=>{const s=K.getDataAttribute(t,e);void 0===s?t.style.removeProperty(e):(K.removeDataAttribute(t,e),t.style[e]=s)})},vt={isVisible:!0,isAnimated:!1,rootElement:document.body,clickCallback:null},yt={isVisible:"boolean",isAnimated:"boolean",rootElement:"element",clickCallback:"(function|null)"};class wt{constructor(t){this._config=this._getConfig(t),this._isAppended=!1,this._element=null}show(t){this._config.isVisible?(this._append(),this._config.isAnimated&&b(this._getElement()),this._getElement().classList.add("show"),this._emulateAnimation(()=>{E(t)})):E(t)}hide(t){this._config.isVisible?(this._getElement().classList.remove("show"),this._emulateAnimation(()=>{this.dispose(),E(t)})):E(t)}_getElement(){if(!this._element){const t=document.createElement("div");t.className="modal-backdrop",this._config.isAnimated&&t.classList.add("fade"),this._element=t}return this._element}_getConfig(t){return(t={...vt,..."object"==typeof t?t:{}}).rootElement=t.rootElement||document.body,g("backdrop",t,yt),t}_append(){this._isAppended||(this._config.rootElement.appendChild(this._getElement()),$.on(this._getElement(),"mousedown.bs.backdrop",()=>{E(this._config.clickCallback)}),this._isAppended=!0)}dispose(){this._isAppended&&($.off(this._element,"mousedown.bs.backdrop"),this._getElement().parentNode.removeChild(this._element),this._isAppended=!1)}_emulateAnimation(t){if(!this._config.isAnimated)return void E(t);const e=l(this._getElement());$.one(this._getElement(),"transitionend",()=>E(t)),u(this._getElement(),e)}}const Et={backdrop:!0,keyboard:!0,focus:!0},Tt={backdrop:"(boolean|string)",keyboard:"boolean",focus:"boolean"};class At extends z{constructor(t,e){super(t),this._config=this._getConfig(e),this._dialog=i.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._isShown=!1,this._ignoreBackdropClick=!1,this._isTransitioning=!1}static get Default(){return Et}static get NAME(){return"modal"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){if(this._isShown||this._isTransitioning)return;this._isAnimated()&&(this._isTransitioning=!0);const e=$.trigger(this._element,"show.bs.modal",{relatedTarget:t});this._isShown||e.defaultPrevented||(this._isShown=!0,ft(),document.body.classList.add("modal-open"),this._adjustDialog(),this._setEscapeEvent(),this._setResizeEvent(),$.on(this._element,"click.dismiss.bs.modal",'[data-bs-dismiss="modal"]',t=>this.hide(t)),$.on(this._dialog,"mousedown.dismiss.bs.modal",()=>{$.one(this._element,"mouseup.dismiss.bs.modal",t=>{t.target===this._element&&(this._ignoreBackdropClick=!0)})}),this._showBackdrop(()=>this._showElement(t)))}hide(t){if(t&&t.preventDefault(),!this._isShown||this._isTransitioning)return;if($.trigger(this._element,"hide.bs.modal").defaultPrevented)return;this._isShown=!1;const e=this._isAnimated();e&&(this._isTransitioning=!0),this._setEscapeEvent(),this._setResizeEvent(),$.off(document,"focusin.bs.modal"),this._element.classList.remove("show"),$.off(this._element,"click.dismiss.bs.modal"),$.off(this._dialog,"mousedown.dismiss.bs.modal"),this._queueCallback(()=>this._hideModal(),this._element,e)}dispose(){[window,this._dialog].forEach(t=>$.off(t,".bs.modal")),this._backdrop.dispose(),super.dispose(),$.off(document,"focusin.bs.modal")}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new wt({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_getConfig(t){return t={...Et,...K.getDataAttributes(this._element),...t},g("modal",t,Tt),t}_showElement(t){const e=this._isAnimated(),s=i.findOne(".modal-body",this._dialog);this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.appendChild(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0,s&&(s.scrollTop=0),e&&b(this._element),this._element.classList.add("show"),this._config.focus&&this._enforceFocus(),this._queueCallback(()=>{this._config.focus&&this._element.focus(),this._isTransitioning=!1,$.trigger(this._element,"shown.bs.modal",{relatedTarget:t})},this._dialog,e)}_enforceFocus(){$.off(document,"focusin.bs.modal"),$.on(document,"focusin.bs.modal",t=>{document===t.target||this._element===t.target||this._element.contains(t.target)||this._element.focus()})}_setEscapeEvent(){this._isShown?$.on(this._element,"keydown.dismiss.bs.modal",t=>{this._config.keyboard&&"Escape"===t.key?(t.preventDefault(),this.hide()):this._config.keyboard||"Escape"!==t.key||this._triggerBackdropTransition()}):$.off(this._element,"keydown.dismiss.bs.modal")}_setResizeEvent(){this._isShown?$.on(window,"resize.bs.modal",()=>this._adjustDialog()):$.off(window,"resize.bs.modal")}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide(()=>{document.body.classList.remove("modal-open"),this._resetAdjustments(),_t(),$.trigger(this._element,"hidden.bs.modal")})}_showBackdrop(t){$.on(this._element,"click.dismiss.bs.modal",t=>{this._ignoreBackdropClick?this._ignoreBackdropClick=!1:t.target===t.currentTarget&&(!0===this._config.backdrop?this.hide():"static"===this._config.backdrop&&this._triggerBackdropTransition())}),this._backdrop.show(t)}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if($.trigger(this._element,"hidePrevented.bs.modal").defaultPrevented)return;const t=this._element.scrollHeight>document.documentElement.clientHeight;t||(this._element.style.overflowY="hidden"),this._element.classList.add("modal-static");const e=l(this._dialog);$.off(this._element,"transitionend"),$.one(this._element,"transitionend",()=>{this._element.classList.remove("modal-static"),t||($.one(this._element,"transitionend",()=>{this._element.style.overflowY=""}),u(this._element,e))}),u(this._element,e),this._element.focus()}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=gt(),s=e>0;(!s&&t&&!y()||s&&!t&&y())&&(this._element.style.paddingLeft=e+"px"),(s&&!t&&!y()||!s&&t&&y())&&(this._element.style.paddingRight=e+"px")}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const s=At.getInstance(this)||new At(this,"object"==typeof t?t:{});if("string"==typeof t){if(void 0===s[t])throw new TypeError(`No method named "${t}"`);s[t](e)}}))}}$.on(document,"click.bs.modal.data-api",'[data-bs-toggle="modal"]',(function(t){const e=a(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),$.one(e,"show.bs.modal",t=>{t.defaultPrevented||$.one(e,"hidden.bs.modal",()=>{f(this)&&this.focus()})}),(At.getInstance(e)||new At(e)).toggle(this)})),w(At);const kt={backdrop:!0,keyboard:!0,scroll:!1},Lt={backdrop:"boolean",keyboard:"boolean",scroll:"boolean"};class Ct extends z{constructor(t,e){super(t),this._config=this._getConfig(e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._addEventListeners()}static get NAME(){return"offcanvas"}static get Default(){return kt}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||$.trigger(this._element,"show.bs.offcanvas",{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._element.style.visibility="visible",this._backdrop.show(),this._config.scroll||(ft(),this._enforceFocusOnElement(this._element)),this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add("show"),this._queueCallback(()=>{$.trigger(this._element,"shown.bs.offcanvas",{relatedTarget:t})},this._element,!0))}hide(){this._isShown&&($.trigger(this._element,"hide.bs.offcanvas").defaultPrevented||($.off(document,"focusin.bs.offcanvas"),this._element.blur(),this._isShown=!1,this._element.classList.remove("show"),this._backdrop.hide(),this._queueCallback(()=>{this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._element.style.visibility="hidden",this._config.scroll||_t(),$.trigger(this._element,"hidden.bs.offcanvas")},this._element,!0)))}dispose(){this._backdrop.dispose(),super.dispose(),$.off(document,"focusin.bs.offcanvas")}_getConfig(t){return t={...kt,...K.getDataAttributes(this._element),..."object"==typeof t?t:{}},g("offcanvas",t,Lt),t}_initializeBackDrop(){return new wt({isVisible:this._config.backdrop,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:()=>this.hide()})}_enforceFocusOnElement(t){$.off(document,"focusin.bs.offcanvas"),$.on(document,"focusin.bs.offcanvas",e=>{document===e.target||t===e.target||t.contains(e.target)||t.focus()}),t.focus()}_addEventListeners(){$.on(this._element,"click.dismiss.bs.offcanvas",'[data-bs-dismiss="offcanvas"]',()=>this.hide()),$.on(this._element,"keydown.dismiss.bs.offcanvas",t=>{this._config.keyboard&&"Escape"===t.key&&this.hide()})}static jQueryInterface(t){return this.each((function(){const e=A.get(this,"bs.offcanvas")||new Ct(this,"object"==typeof t?t:{});if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}$.on(document,"click.bs.offcanvas.data-api",'[data-bs-toggle="offcanvas"]',(function(t){const e=a(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),p(this))return;$.one(e,"hidden.bs.offcanvas",()=>{f(this)&&this.focus()});const s=i.findOne(".offcanvas.show");s&&s!==e&&Ct.getInstance(s).hide(),(A.get(e,"bs.offcanvas")||new Ct(e)).toggle(this)})),$.on(window,"load.bs.offcanvas.data-api",()=>{i.find(".offcanvas.show").forEach(t=>(A.get(t,"bs.offcanvas")||new Ct(t)).show())}),w(Ct);const Dt=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),Nt=/^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/i,St=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i,Ot=(t,e)=>{const s=t.nodeName.toLowerCase();if(e.includes(s))return!Dt.has(s)||Boolean(Nt.test(t.nodeValue)||St.test(t.nodeValue));const i=e.filter(t=>t instanceof RegExp);for(let t=0,e=i.length;t{Ot(t,a)||s.removeAttribute(t.nodeName)})}return i.body.innerHTML}const xt=new RegExp("(^|\\s)bs-tooltip\\S+","g"),jt=new Set(["sanitize","allowList","sanitizeFn"]),Pt={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(array|string|function)",container:"(string|element|boolean)",fallbackPlacements:"array",boundary:"(string|element)",customClass:"(string|function)",sanitize:"boolean",sanitizeFn:"(null|function)",allowList:"object",popperConfig:"(null|object|function)"},Mt={AUTO:"auto",TOP:"top",RIGHT:y()?"left":"right",BOTTOM:"bottom",LEFT:y()?"right":"left"},Ht={animation:!0,template:'',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:[0,0],container:!1,fallbackPlacements:["top","right","bottom","left"],boundary:"clippingParents",customClass:"",sanitize:!0,sanitizeFn:null,allowList:{"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},popperConfig:null},Rt={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"};class Bt extends z{constructor(t,e){if(void 0===s)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(t),this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this._config=this._getConfig(e),this.tip=null,this._setListeners()}static get Default(){return Ht}static get NAME(){return"tooltip"}static get Event(){return Rt}static get DefaultType(){return Pt}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(t){if(this._isEnabled)if(t){const e=this._initializeOnDelegatedTarget(t);e._activeTrigger.click=!e._activeTrigger.click,e._isWithActiveTrigger()?e._enter(null,e):e._leave(null,e)}else{if(this.getTipElement().classList.contains("show"))return void this._leave(null,this);this._enter(null,this)}}dispose(){clearTimeout(this._timeout),$.off(this._element.closest(".modal"),"hide.bs.modal",this._hideModalHandler),this.tip&&this.tip.parentNode&&this.tip.parentNode.removeChild(this.tip),this._popper&&this._popper.destroy(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this.isWithContent()||!this._isEnabled)return;const t=$.trigger(this._element,this.constructor.Event.SHOW),e=m(this._element),i=null===e?this._element.ownerDocument.documentElement.contains(this._element):e.contains(this._element);if(t.defaultPrevented||!i)return;const o=this.getTipElement(),r=n(this.constructor.NAME);o.setAttribute("id",r),this._element.setAttribute("aria-describedby",r),this.setContent(),this._config.animation&&o.classList.add("fade");const a="function"==typeof this._config.placement?this._config.placement.call(this,o,this._element):this._config.placement,l=this._getAttachment(a);this._addAttachmentClass(l);const{container:c}=this._config;A.set(o,this.constructor.DATA_KEY,this),this._element.ownerDocument.documentElement.contains(this.tip)||(c.appendChild(o),$.trigger(this._element,this.constructor.Event.INSERTED)),this._popper?this._popper.update():this._popper=s.createPopper(this._element,o,this._getPopperConfig(l)),o.classList.add("show");const h="function"==typeof this._config.customClass?this._config.customClass():this._config.customClass;h&&o.classList.add(...h.split(" ")),"ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach(t=>{$.on(t,"mouseover",_)});const d=this.tip.classList.contains("fade");this._queueCallback(()=>{const t=this._hoverState;this._hoverState=null,$.trigger(this._element,this.constructor.Event.SHOWN),"out"===t&&this._leave(null,this)},this.tip,d)}hide(){if(!this._popper)return;const t=this.getTipElement();if($.trigger(this._element,this.constructor.Event.HIDE).defaultPrevented)return;t.classList.remove("show"),"ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach(t=>$.off(t,"mouseover",_)),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1;const e=this.tip.classList.contains("fade");this._queueCallback(()=>{this._isWithActiveTrigger()||("show"!==this._hoverState&&t.parentNode&&t.parentNode.removeChild(t),this._cleanTipClass(),this._element.removeAttribute("aria-describedby"),$.trigger(this._element,this.constructor.Event.HIDDEN),this._popper&&(this._popper.destroy(),this._popper=null))},this.tip,e),this._hoverState=""}update(){null!==this._popper&&this._popper.update()}isWithContent(){return Boolean(this.getTitle())}getTipElement(){if(this.tip)return this.tip;const t=document.createElement("div");return t.innerHTML=this._config.template,this.tip=t.children[0],this.tip}setContent(){const t=this.getTipElement();this.setElementContent(i.findOne(".tooltip-inner",t),this.getTitle()),t.classList.remove("fade","show")}setElementContent(t,e){if(null!==t)return h(e)?(e=d(e),void(this._config.html?e.parentNode!==t&&(t.innerHTML="",t.appendChild(e)):t.textContent=e.textContent)):void(this._config.html?(this._config.sanitize&&(e=It(e,this._config.allowList,this._config.sanitizeFn)),t.innerHTML=e):t.textContent=e)}getTitle(){let t=this._element.getAttribute("data-bs-original-title");return t||(t="function"==typeof this._config.title?this._config.title.call(this._element):this._config.title),t}updateAttachment(t){return"right"===t?"end":"left"===t?"start":t}_initializeOnDelegatedTarget(t,e){const s=this.constructor.DATA_KEY;return(e=e||A.get(t.delegateTarget,s))||(e=new this.constructor(t.delegateTarget,this._getDelegateConfig()),A.set(t.delegateTarget,s,e)),e}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map(t=>Number.parseInt(t,10)):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"onChange",enabled:!0,phase:"afterWrite",fn:t=>this._handlePopperPlacementChange(t)}],onFirstUpdate:t=>{t.options.placement!==t.placement&&this._handlePopperPlacementChange(t)}};return{...e,..."function"==typeof this._config.popperConfig?this._config.popperConfig(e):this._config.popperConfig}}_addAttachmentClass(t){this.getTipElement().classList.add("bs-tooltip-"+this.updateAttachment(t))}_getAttachment(t){return Mt[t.toUpperCase()]}_setListeners(){this._config.trigger.split(" ").forEach(t=>{if("click"===t)$.on(this._element,this.constructor.Event.CLICK,this._config.selector,t=>this.toggle(t));else if("manual"!==t){const e="hover"===t?this.constructor.Event.MOUSEENTER:this.constructor.Event.FOCUSIN,s="hover"===t?this.constructor.Event.MOUSELEAVE:this.constructor.Event.FOCUSOUT;$.on(this._element,e,this._config.selector,t=>this._enter(t)),$.on(this._element,s,this._config.selector,t=>this._leave(t))}}),this._hideModalHandler=()=>{this._element&&this.hide()},$.on(this._element.closest(".modal"),"hide.bs.modal",this._hideModalHandler),this._config.selector?this._config={...this._config,trigger:"manual",selector:""}:this._fixTitle()}_fixTitle(){const t=this._element.getAttribute("title"),e=typeof this._element.getAttribute("data-bs-original-title");(t||"string"!==e)&&(this._element.setAttribute("data-bs-original-title",t||""),!t||this._element.getAttribute("aria-label")||this._element.textContent||this._element.setAttribute("aria-label",t),this._element.setAttribute("title",""))}_enter(t,e){e=this._initializeOnDelegatedTarget(t,e),t&&(e._activeTrigger["focusin"===t.type?"focus":"hover"]=!0),e.getTipElement().classList.contains("show")||"show"===e._hoverState?e._hoverState="show":(clearTimeout(e._timeout),e._hoverState="show",e._config.delay&&e._config.delay.show?e._timeout=setTimeout(()=>{"show"===e._hoverState&&e.show()},e._config.delay.show):e.show())}_leave(t,e){e=this._initializeOnDelegatedTarget(t,e),t&&(e._activeTrigger["focusout"===t.type?"focus":"hover"]=e._element.contains(t.relatedTarget)),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState="out",e._config.delay&&e._config.delay.hide?e._timeout=setTimeout(()=>{"out"===e._hoverState&&e.hide()},e._config.delay.hide):e.hide())}_isWithActiveTrigger(){for(const t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1}_getConfig(t){const e=K.getDataAttributes(this._element);return Object.keys(e).forEach(t=>{jt.has(t)&&delete e[t]}),(t={...this.constructor.Default,...e,..."object"==typeof t&&t?t:{}}).container=!1===t.container?document.body:d(t.container),"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),g("tooltip",t,this.constructor.DefaultType),t.sanitize&&(t.template=It(t.template,t.allowList,t.sanitizeFn)),t}_getDelegateConfig(){const t={};if(this._config)for(const e in this._config)this.constructor.Default[e]!==this._config[e]&&(t[e]=this._config[e]);return t}_cleanTipClass(){const t=this.getTipElement(),e=t.getAttribute("class").match(xt);null!==e&&e.length>0&&e.map(t=>t.trim()).forEach(e=>t.classList.remove(e))}_handlePopperPlacementChange(t){const{state:e}=t;e&&(this.tip=e.elements.popper,this._cleanTipClass(),this._addAttachmentClass(this._getAttachment(e.placement)))}static jQueryInterface(t){return this.each((function(){let e=A.get(this,"bs.tooltip");const s="object"==typeof t&&t;if((e||!/dispose|hide/.test(t))&&(e||(e=new Bt(this,s)),"string"==typeof t)){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}w(Bt);const $t=new RegExp("(^|\\s)bs-popover\\S+","g"),zt={...Bt.Default,placement:"right",offset:[0,8],trigger:"click",content:"",template:''},Ut={...Bt.DefaultType,content:"(string|element|function)"},qt={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"};class Ft extends Bt{static get Default(){return zt}static get NAME(){return"popover"}static get Event(){return qt}static get DefaultType(){return Ut}isWithContent(){return this.getTitle()||this._getContent()}setContent(){const t=this.getTipElement();this.setElementContent(i.findOne(".popover-header",t),this.getTitle());let e=this._getContent();"function"==typeof e&&(e=e.call(this._element)),this.setElementContent(i.findOne(".popover-body",t),e),t.classList.remove("fade","show")}_addAttachmentClass(t){this.getTipElement().classList.add("bs-popover-"+this.updateAttachment(t))}_getContent(){return this._element.getAttribute("data-bs-content")||this._config.content}_cleanTipClass(){const t=this.getTipElement(),e=t.getAttribute("class").match($t);null!==e&&e.length>0&&e.map(t=>t.trim()).forEach(e=>t.classList.remove(e))}static jQueryInterface(t){return this.each((function(){let e=A.get(this,"bs.popover");const s="object"==typeof t?t:null;if((e||!/dispose|hide/.test(t))&&(e||(e=new Ft(this,s),A.set(this,"bs.popover",e)),"string"==typeof t)){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}w(Ft);const Wt={offset:10,method:"auto",target:""},Kt={offset:"number",method:"string",target:"(string|element)"};class Vt extends z{constructor(t,e){super(t),this._scrollElement="BODY"===this._element.tagName?window:this._element,this._config=this._getConfig(e),this._selector=`${this._config.target} .nav-link, ${this._config.target} .list-group-item, ${this._config.target} .dropdown-item`,this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,$.on(this._scrollElement,"scroll.bs.scrollspy",()=>this._process()),this.refresh(),this._process()}static get Default(){return Wt}static get NAME(){return"scrollspy"}refresh(){const t=this._scrollElement===this._scrollElement.window?"offset":"position",e="auto"===this._config.method?t:this._config.method,s="position"===e?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),i.find(this._selector).map(t=>{const n=r(t),o=n?i.findOne(n):null;if(o){const t=o.getBoundingClientRect();if(t.width||t.height)return[K[e](o).top+s,n]}return null}).filter(t=>t).sort((t,e)=>t[0]-e[0]).forEach(t=>{this._offsets.push(t[0]),this._targets.push(t[1])})}dispose(){$.off(this._scrollElement,".bs.scrollspy"),super.dispose()}_getConfig(t){if("string"!=typeof(t={...Wt,...K.getDataAttributes(this._element),..."object"==typeof t&&t?t:{}}).target&&h(t.target)){let{id:e}=t.target;e||(e=n("scrollspy"),t.target.id=e),t.target="#"+e}return g("scrollspy",t,Kt),t}_getScrollTop(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop}_getScrollHeight(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)}_getOffsetHeight(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height}_process(){const t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),s=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=s){const t=this._targets[this._targets.length-1];this._activeTarget!==t&&this._activate(t)}else{if(this._activeTarget&&t0)return this._activeTarget=null,void this._clear();for(let e=this._offsets.length;e--;)this._activeTarget!==this._targets[e]&&t>=this._offsets[e]&&(void 0===this._offsets[e+1]||t`${e}[data-bs-target="${t}"],${e}[href="${t}"]`),s=i.findOne(e.join(","));s.classList.contains("dropdown-item")?(i.findOne(".dropdown-toggle",s.closest(".dropdown")).classList.add("active"),s.classList.add("active")):(s.classList.add("active"),i.parents(s,".nav, .list-group").forEach(t=>{i.prev(t,".nav-link, .list-group-item").forEach(t=>t.classList.add("active")),i.prev(t,".nav-item").forEach(t=>{i.children(t,".nav-link").forEach(t=>t.classList.add("active"))})})),$.trigger(this._scrollElement,"activate.bs.scrollspy",{relatedTarget:t})}_clear(){i.find(this._selector).filter(t=>t.classList.contains("active")).forEach(t=>t.classList.remove("active"))}static jQueryInterface(t){return this.each((function(){const e=Vt.getInstance(this)||new Vt(this,"object"==typeof t?t:{});if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}$.on(window,"load.bs.scrollspy.data-api",()=>{i.find('[data-bs-spy="scroll"]').forEach(t=>new Vt(t))}),w(Vt);class Qt extends z{static get NAME(){return"tab"}show(){if(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&this._element.classList.contains("active"))return;let t;const e=a(this._element),s=this._element.closest(".nav, .list-group");if(s){const e="UL"===s.nodeName||"OL"===s.nodeName?":scope > li > .active":".active";t=i.find(e,s),t=t[t.length-1]}const n=t?$.trigger(t,"hide.bs.tab",{relatedTarget:this._element}):null;if($.trigger(this._element,"show.bs.tab",{relatedTarget:t}).defaultPrevented||null!==n&&n.defaultPrevented)return;this._activate(this._element,s);const o=()=>{$.trigger(t,"hidden.bs.tab",{relatedTarget:this._element}),$.trigger(this._element,"shown.bs.tab",{relatedTarget:t})};e?this._activate(e,e.parentNode,o):o()}_activate(t,e,s){const n=(!e||"UL"!==e.nodeName&&"OL"!==e.nodeName?i.children(e,".active"):i.find(":scope > li > .active",e))[0],o=s&&n&&n.classList.contains("fade"),r=()=>this._transitionComplete(t,n,s);n&&o?(n.classList.remove("show"),this._queueCallback(r,t,!0)):r()}_transitionComplete(t,e,s){if(e){e.classList.remove("active");const t=i.findOne(":scope > .dropdown-menu .active",e.parentNode);t&&t.classList.remove("active"),"tab"===e.getAttribute("role")&&e.setAttribute("aria-selected",!1)}t.classList.add("active"),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!0),b(t),t.classList.contains("fade")&&t.classList.add("show");let n=t.parentNode;if(n&&"LI"===n.nodeName&&(n=n.parentNode),n&&n.classList.contains("dropdown-menu")){const e=t.closest(".dropdown");e&&i.find(".dropdown-toggle",e).forEach(t=>t.classList.add("active")),t.setAttribute("aria-expanded",!0)}s&&s()}static jQueryInterface(t){return this.each((function(){const e=A.get(this,"bs.tab")||new Qt(this);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}$.on(document,"click.bs.tab.data-api",'[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),p(this)||(A.get(this,"bs.tab")||new Qt(this)).show()})),w(Qt);const Xt={animation:"boolean",autohide:"boolean",delay:"number"},Yt={animation:!0,autohide:!0,delay:5e3};class Gt extends z{constructor(t,e){super(t),this._config=this._getConfig(e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get DefaultType(){return Xt}static get Default(){return Yt}static get NAME(){return"toast"}show(){$.trigger(this._element,"show.bs.toast").defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add("fade"),this._element.classList.remove("hide"),b(this._element),this._element.classList.add("showing"),this._queueCallback(()=>{this._element.classList.remove("showing"),this._element.classList.add("show"),$.trigger(this._element,"shown.bs.toast"),this._maybeScheduleHide()},this._element,this._config.animation))}hide(){this._element.classList.contains("show")&&($.trigger(this._element,"hide.bs.toast").defaultPrevented||(this._element.classList.remove("show"),this._queueCallback(()=>{this._element.classList.add("hide"),$.trigger(this._element,"hidden.bs.toast")},this._element,this._config.animation)))}dispose(){this._clearTimeout(),this._element.classList.contains("show")&&this._element.classList.remove("show"),super.dispose()}_getConfig(t){return t={...Yt,...K.getDataAttributes(this._element),..."object"==typeof t&&t?t:{}},g("toast",t,this.constructor.DefaultType),t}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout(()=>{this.hide()},this._config.delay)))}_onInteraction(t,e){switch(t.type){case"mouseover":case"mouseout":this._hasMouseInteraction=e;break;case"focusin":case"focusout":this._hasKeyboardInteraction=e}if(e)return void this._clearTimeout();const s=t.relatedTarget;this._element===s||this._element.contains(s)||this._maybeScheduleHide()}_setListeners(){$.on(this._element,"click.dismiss.bs.toast",'[data-bs-dismiss="toast"]',()=>this.hide()),$.on(this._element,"mouseover.bs.toast",t=>this._onInteraction(t,!0)),$.on(this._element,"mouseout.bs.toast",t=>this._onInteraction(t,!1)),$.on(this._element,"focusin.bs.toast",t=>this._onInteraction(t,!0)),$.on(this._element,"focusout.bs.toast",t=>this._onInteraction(t,!1))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){let e=A.get(this,"bs.toast");if(e||(e=new Gt(this,"object"==typeof t&&t)),"string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}return w(Gt),{Alert:U,Button:q,Carousel:J,Collapse:st,Dropdown:ut,Modal:At,Offcanvas:Ct,Popover:Ft,ScrollSpy:Vt,Tab:Qt,Toast:Gt,Tooltip:Bt}}));
7 | //# sourceMappingURL=bootstrap.min.js.map


--------------------------------------------------------------------------------
/custom_theme/keyboard-modal.html:
--------------------------------------------------------------------------------
 1 | 


--------------------------------------------------------------------------------
/custom_theme/main.html:
--------------------------------------------------------------------------------
 1 | {% extends "base.html" %}
 2 | 
 3 | {%- block styles %}
 4 |     
 5 |     
 6 |     
 7 |     
 8 | 
 9 |     {%- for path in config['extra_css'] %}
10 |     
11 |     {%- endfor %}
12 | {%- endblock %}
13 | 
14 | {%- block libs %}
15 |     
16 |     
20 |     
21 |     
22 | {%- endblock %}


--------------------------------------------------------------------------------
/custom_theme/mkdocs_theme.yml:
--------------------------------------------------------------------------------
 1 | # Config options for 'bootstrap4' theme
 2 | 
 3 | extends: mkdocs
 4 | suppress_nextprev: true
 5 | hljs_style: github
 6 | shortcuts:
 7 |   help: 191    # ?
 8 |   next: 78     # n
 9 |   previous: 80 # p
10 |   search: 83   # s


--------------------------------------------------------------------------------
/custom_theme/nav-toggle.html:
--------------------------------------------------------------------------------
 1 | 


--------------------------------------------------------------------------------
/custom_theme/nav.html:
--------------------------------------------------------------------------------
 1 | 


--------------------------------------------------------------------------------
/custom_theme/search-modal.html:
--------------------------------------------------------------------------------
 1 | 


--------------------------------------------------------------------------------
/custom_theme/secondary-nav.html:
--------------------------------------------------------------------------------
 1 | 


--------------------------------------------------------------------------------
/custom_theme/toc.html:
--------------------------------------------------------------------------------
 1 | 
2 | On this page 3 | 23 |
-------------------------------------------------------------------------------- /custom_theme/twitter-nav-item.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCan-io/opencan/7f224bad5e2a7fdbace3df012ad7713efac4ec9c/docs/.DS_Store -------------------------------------------------------------------------------- /docs/Cycles.md: -------------------------------------------------------------------------------- 1 | # Wrapped ICP Cycles (WIC) 2 | 3 | Motoko canister code for wrapped ICP cycles as erc20 style tokens. This canister utilizes a standard ERC20 style token with additional "burn" and "mint" functions. We hope to deploy a version of this canister to the ICP as soon as we can. 4 | 5 | In theory, WIC should essentially be a stablecoin (1WIC = 1XDR). 6 | 7 | ## Minting 8 | Tokens are minted by using the cycles wallet `wallet_call` feature which allows us to forward cycles to the WIC canister which is converted to WIC (1T cycles = 1WIC). We can then continue to trade these tokens like any other token on exchanges. 9 | 10 | ## Burning 11 | Tokens can be returned to the WIC canister via a burn mechanism, which then returns an equal amount of cycles to a user defined canister (1WIC = 1T cycles). This allows developers to easily purchase WIC from secondary markets and have it easily send to their canisters. To burn tokens, the user must provide a canister ID and method (the **callback** function) which can accept the returned cycles. 12 | 13 | The callback must be of the following type: 14 |

15 | type Callback = shared () -> async ();
16 | 
17 | 18 | An example function that can be included in your canister is as follows: 19 |

20 | public func accept() : async () {
21 |     let available = Cycles.available();
22 |     let accepted = Cycles.accept(available);
23 |     assert (accepted == available);
24 | };
25 | 
26 | 27 | This can be submitted to the burn function in the following form: 28 |

29 | //Where ryjl3-tyaaa-aaaaa-aaaba-cai is the principal/canister id of your canister
30 | (func ryjl3-tyaaa-aaaaa-aaaba-cai.accept)
31 | 
32 | 33 | ## Testing 34 | We create two canisters, our WIC canister which handles the burning/minting/token logic and a test canister which can receive returned cycles (via burning). 35 | 36 |

37 | //Clean start (if you want)
38 | dfx start --clean --background
39 | 
40 | //Set identity if you need to
41 | dfx identity new me && dfx identity use me
42 | 
43 | //Deploy all
44 | dfx deploy --all
45 | 
46 | //Set WIC Canister ID and test canister
47 | WICCAN=$(dfx canister id wrapped_cycles)
48 | TESTCAN=$(dfx canister id test)
49 | 
50 | //Check available cycles in canister and current balance
51 | dfx canister call $WICCAN availableCycles
52 | dfx canister call $WICCAN myBalance
53 | 
54 | //Mint some WIC from cycles wallet (1T cycles == 1WIC)
55 | dfx canister --no-wallet call $(dfx identity get-wallet) wallet_call "(record { canister = principal \"$WICCAN\"; method_name = \"mint\"; args = blob \"DIDL\00\00\"; cycles = (1_000_000_000_000:nat64); } )"
56 | 
57 | //Check new balance and available cycles (both should have increased by 1T)
58 | dfx canister call $WICCAN myBalance
59 | dfx canister call $WICCAN availableCycles
60 | 
61 | //Burn WIC and send to TEST canister. 
62 | dfx canister call $TESTCAN availableCycles
63 | dfx canister call $WICCAN burn "(500_000_000_000:nat, (func \"$TESTCAN\".accept))"
64 | 
65 | //Check balances again
66 | dfx canister call $WICCAN myBalance
67 | dfx canister call $TESTCAN availableCycles
68 | dfx canister call $WICCAN availableCycles
69 | 
70 | 71 | ##Preset Cycles Canister 72 | [Cycles](https://github.com/ALLiDoizCode/wrapped_cycles) 73 | 74 | This canister is ready to deploy without having to write any Motoko code. It can be used as-is for quick prototyping and testing, but is also suitable for production environments. -------------------------------------------------------------------------------- /docs/ICIP-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | icip: 1 3 | title: Internet Computer Token Standard 4 | status: Draft 5 | type: Financial 6 | author: Norton Wang (@floorlamp) 7 | created: 2020-09-24 8 | --- 9 | 10 | Since official "Internet Computer Improvement Proposals" (ICIPs) do not 11 | exist yet, this document refers to "ICIP-1" for convenience only. 12 | 13 | ## Table Of Contents 14 | 15 | - [Summary](#summary) 16 | - [Motivation](#motivation) 17 | - [Abstract](#abstract) 18 | - [General](#general) 19 | - [Interface Specification](#interface-specification) 20 | - [Entrypoint Semantics](#entrypoint-semantics) 21 | - [`transfer`](#transfer) 22 | - [Core Transfer Behavior](#core-transfer-behavior) 23 | - [Default Transfer Permission Policy](#default-transfer-permission-policy) 24 | - [`getBalance`](#getBalance) 25 | - [Operators](#operators) 26 | - [`updateOperator`](#updateOperator) 27 | - [`isAuthorized`](#isAuthorized) 28 | - [`getMetadata`](#getMetadata) 29 | - [Implementing Different Token Types with ICIP-1](#implementing-different-token-types-with-ICIP-1) 30 | - [Single Fungible Token](#single-fungible-token) 31 | - [Multiple Fungible Tokens](#multiple-fungible-tokens) 32 | - [Non-fungible Tokens](#non-fungible-tokens) 33 | - [Mixing Fungible and Non-fungible Tokens](#mixing-fungible-and-non-fungible-tokens) 34 | - [Non-transferable Tokens](#non-transferable-tokens) 35 | - [Additional Ideas](#additional-ideas) 36 | - [References](#references) 37 | - [Copyright](#copyright) 38 | 39 | ## Summary 40 | 41 | ICIP-1 proposes a standard for a unified token canister interface, supporting a 42 | wide range of token types and implementations. This document provides an 43 | overview and rationale for the interface, token transfer semantics, and support 44 | for various transfer permission policies. 45 | 46 | **PLEASE NOTE:** This API specification is a work-in-progress. 47 | 48 | ## Motivation 49 | 50 | There are multiple dimensions and considerations while implementing a particular 51 | token canister. Tokens might be fungible or non-fungible. A variety of transfer 52 | permission policies can be used to define how many tokens can be transferred, 53 | who can perform a transfer, and who can receive tokens. A token canister can be 54 | designed to support a single token type (e.g. ERC-20 or ERC-721) or multiple 55 | token types (e.g. ERC-1155) to optimize batch transfers and atomic swaps of the 56 | tokens. 57 | 58 | Such considerations can easily lead to the proliferation of many token 59 | standards, each optimized for a particular token type or use case. This 60 | situation is apparent in the Ethereum ecosystem, where many standards have been 61 | proposed, but ERC-20 (fungible tokens) and ERC-721 (non-fungible tokens) are 62 | dominant. 63 | 64 | Token wallets, token exchanges, and other clients then need to support multiple 65 | standards and multiple token APIs. The ICIP-1 standard proposes a unified token 66 | canister interface that accommodates all mentioned concerns. It aims to provide 67 | significant expressivity to canister developers to create new types of tokens 68 | while maintaining a common interface standard for wallet integrators and 69 | external developers. 70 | 71 | ## Abstract 72 | 73 | This standard defines the unified canister interface and its behavior to support 74 | a wide range of token types and implementations. The particular ICIP-1 75 | implementation may support either a single token type per canister or multiple 76 | tokens per canister, including hybrid implementations where multiple token kinds 77 | (fungible, non-fungible, non-transferable etc) are supported. 78 | 79 | All of the entrypoints are batch operations that allow querying or transfer of 80 | multiple token types atomically. 81 | 82 | Most token standards specify logic that validates a transfer transaction and can 83 | either approve or reject a transfer. Such logic could validate who can perform a 84 | transfer, the transfer amount and who can receive tokens. This standard calls 85 | such logic a _transfer permission policy_. The ICIP-1 standard defines the 86 | [default `TransferRequest` permission policy](#default-transfer-permission-policy) 87 | that specify who can transfer tokens. The default policy allows transfers by 88 | either token owner (an principal that holds token balance) or by an operator (an 89 | principal that is permitted to manage tokens on behalf of the token owner). 90 | 91 | Transfer permission policies can be customized. 92 | 93 | This specification defines some standard error variants to be used when 94 | implementing ICIP-1. However, some implementations MAY introduce their custom 95 | errors that MUST follow the same pattern as standard ones. 96 | 97 | ## General 98 | 99 | The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, 100 | “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be 101 | interpreted as described in [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt). 102 | 103 | - Tokens are uniquely identified by a pair composed of the token canister ID and 104 | token ID, a natural number (`Nat`). If the underlying canister implementation 105 | supports only a single token type (e.g. ERC-20-like contract), the token ID 106 | MUST be `0n`. In the case when multiple token types are supported within the 107 | same ICIP-1 token canister (e. g. ERC-1155-like contract), the canister is 108 | fully responsible for assigning and managing token IDs. 109 | 110 | - The ICIP-1 batch entrypoints accept a list (batch) of parameters describing a 111 | single operation or a query. The batch MUST NOT be reordered or deduplicated 112 | and MUST be processed in the same order it is received. 113 | 114 | - Empty batch is a valid input and MUST be processed as a non-empty one. For 115 | example, an empty transfer batch will not affect token balances, but 116 | applicable transfer core behavior and permission policy MUST be applied. 117 | 118 | - If the underlying token implementation supports only a single token type, the 119 | batch may contain zero or multiple entries where token ID is a fixed `0n` 120 | value. Likewise, if multiple token types are supported, the batch may contain 121 | zero or more entries and there may be duplicate token IDs. 122 | 123 | - The choice of `Nat32` for a `tokenId` type implies each canister can store 124 | `2**32` individual tokens 125 | 126 | ## Interface Specification 127 | 128 | Token canisters implementing the ICIP-1 standard MUST have the following 129 | entrypoints. Notation is given in 130 | [Motoko](https://sdk.dfinity.org/docs/language-guide/motoko.html). Candid 131 | specifications can be generated as needed. 132 | 133 | ``` 134 | type Token = actor { 135 | getBalance: query (requests: [BalanceRequest]) -> async BalanceResponse; 136 | 137 | getMetadata: query (tokenIds: [TokenId]) -> async MetadataResponse; 138 | 139 | transfer: shared (requests: [TransferRequest]) -> async TransferResponse; 140 | 141 | updateOperator: shared (requests: [OperatorRequest]) -> async OperatorResponse; 142 | 143 | isAuthorized: query (requests: [IsAuthorizedRequest]) -> async IsAuthorizedResponse; 144 | }; 145 | ``` 146 | 147 | ### Entrypoint Semantics 148 | 149 | #### `transfer` 150 | 151 | ``` 152 | type User = Principal; 153 | 154 | type TokenId = Nat32; 155 | 156 | type Balance = Nat; 157 | 158 | type TransferRequest = { 159 | from: User; 160 | to: User; 161 | tokenId: TokenId; 162 | amount: Balance; 163 | }; 164 | 165 | type TransferResponse = Result.Result<(), { 166 | #Unauthorized; 167 | #InvalidDestination: User; 168 | #InvalidToken: TokenId; 169 | #InsufficientBalance; 170 | }>; 171 | 172 | type transfer = (requests: [TransferRequest]) -> async TransferResponse; 173 | ``` 174 | 175 | Each transfer in the batch is specified between one source (`from`) and 176 | destination (`to`) pair. Each `TransferRequest` specifies token ID and the 177 | amount to be transferred from the source principal to the destination principal. 178 | 179 | ICIP-1 does NOT specify an interface for mint and burn operations; however, if 180 | an ICIP-1 token canister implements mint and burn operations, it SHOULD, when 181 | possible, enforce the same logic (core transfer behavior and transfer permission 182 | logic) applied to the token transfer operation. Mint and burn can be considered 183 | special cases of the transfer. Although, it is possible that mint and burn have 184 | more or less restrictive rules than the regular transfer. For instance, mint and 185 | burn operations may be invoked by a special privileged administrative principal 186 | only. In this case, regular operator restrictions may not be applicable. 187 | 188 | ##### Core Transfer Behavior 189 | 190 | ICIP-1 token canisters MUST always implement this behavior. 191 | 192 | - Every batch transfer operation MUST happen atomically and in order. If at 193 | least one transfer in the batch cannot be completed, the whole transaction 194 | MUST fail, all token transfers MUST be reverted, and token balances MUST 195 | remain unchanged. 196 | 197 | - Each transfer in the batch MUST decrement token balance of the source (`from`) 198 | principal by the amount of the transfer and increment token balance of the 199 | destination (`to`) principal by the amount of the transfer. 200 | 201 | - If the transfer amount exceeds current token balance of the source principal, 202 | the whole transfer operation MUST fail with the error variant 203 | `InsufficientBalance`. 204 | 205 | - If the token owner does not hold any tokens of type `tokenId`, the owner's 206 | balance is interpreted as zero. No token owner can have a negative balance. 207 | 208 | - The transfer MUST update token balances exactly as the operation parameters 209 | specify it. Transfer operations MUST NOT try to adjust transfer amounts or try 210 | to add/remove additional transfers like transaction fees. 211 | 212 | - Transfers of zero amount MUST be treated as normal transfers. 213 | 214 | - Transfers with the same principal (`from` equals `to`) MUST be treated as 215 | normal transfers. 216 | 217 | - If one of the specified `tokenId`s is not defined within the ICIP-1 contract, 218 | the entrypoint MUST fail with the error variant `InvalidToken`. 219 | 220 | - Transfer implementations MUST apply transfer permission logic (either 221 | [default transfer permission policy](#default-transfer-permission-policy) or a 222 | custom one). If permission logic rejects a transfer, the whole operation MUST 223 | fail. 224 | 225 | - Core transfer behavior MAY be extended. If additional constraints on tokens 226 | transfer are required, ICIP-1 token canister implementation MAY invoke 227 | additional permission policies. If the additional permission fails, the whole 228 | transfer operation MUST fail with a custom error variant. 229 | 230 | ##### Default Transfer Permission Policy 231 | 232 | - Token owner principal MUST be able to perform a transfer of its own tokens (e. 233 | g. `caller` equals to `from` parameter in the `TransferRequest`). 234 | 235 | - An operator (a principal that performs token transfer operation on behalf of 236 | the owner) MUST be permitted to manage the specified owner's tokens before it 237 | invokes a transfer transaction (see [`updateOperator`](#updateOperator)). 238 | 239 | - If the principal that invokes a transfer operation is neither a token owner 240 | nor one of the permitted operators, the transaction MUST fail with the error 241 | variant `Unauthorized`. If at least one of the `TransferRequest`s in the batch 242 | is not permitted, the whole transaction MUST fail. 243 | 244 | #### `getBalance` 245 | 246 | ``` 247 | type BalanceRequest = { 248 | user: User; 249 | tokenId: TokenId 250 | }; 251 | 252 | type BalanceResponse = Result.Result<[Balance], { 253 | #InvalidToken: TokenId; 254 | }>; 255 | 256 | type getBalance = query (requests: [BalanceRequest]) -> async BalanceResponse; 257 | ``` 258 | 259 | Gets the balance of multiple principal/token pairs. Accepts a list of 260 | `BalanceRequest`s and returns a `BalanceResponse`. 261 | 262 | - There may be duplicate `BalanceRequest`'s, in which case they should not be 263 | deduplicated nor reordered. 264 | 265 | - If the principal does not hold any tokens, the principal balance is 266 | interpreted as zero. 267 | 268 | - If one of the specified `tokenId`s is not defined within the ICIP-1 contract, 269 | the entrypoint MUST fail with the error variant `InvalidToken`. 270 | 271 | #### Operators 272 | 273 | **Owner** is a principal which can hold tokens. 274 | 275 | **Operator** is a principal that originates token transfer operation on behalf 276 | of the owner. 277 | 278 | An operator, other than the owner, CAN be approved to manage specific tokens 279 | held by the owner to transfer them from the owner principal. 280 | 281 | ICIP-1 interface specifies an entrypoint to update operators. Operators are 282 | permitted per specific token owner and token ID (token type). Once permitted, an 283 | operator can transfer tokens of that type belonging to the owner. 284 | 285 | ##### `updateOperator` 286 | 287 | ``` 288 | type TokenIds = { 289 | #All; 290 | #Some: (TokenId, ?Balance); 291 | }; 292 | 293 | type OperatorAction = { 294 | #SetOperator: TokenIds; 295 | #RemoveOperator: ?[TokenId]; 296 | }; 297 | 298 | type OperatorRequest = { 299 | owner: User; 300 | operators: [(User, OperatorAction)] 301 | }; 302 | 303 | type OperatorResponse = Result.Result<(), { 304 | #Unauthorized; 305 | #InvalidOwner: User; 306 | }>; 307 | 308 | type updateOperator = (requests: [OperatorRequest]) -> async OperatorResponse; 309 | ``` 310 | 311 | Update or Remove token operators for the specified token owners, token IDs and balances. 312 | 313 | - The entrypoint accepts a list of `OperatorRequest`s. If two different requests 314 | in the list add and remove an operator for the same token owner and token ID, 315 | the last command in the list MUST take effect. 316 | 317 | - Adding an operator for `#All` token IDs MUST grant permissions to all current 318 | and future tokens owned by the owner for ALL balances. Similarly, removing an operator for 319 | `#All` token IDs MUST remove permissions for all current and future tokens. 320 | 321 | - It is possible to update operators for a token owner that does not hold any 322 | token balances yet. 323 | 324 | - Operator relation is not transitive. If C is an operator of B and if B is an 325 | operator of A, C cannot transfer tokens that are owned by A, on behalf of B. 326 | 327 | The standard does not specify who is permitted to update operators on behalf of 328 | the token owner. Depending on the business use case, the particular 329 | implementation of the ICIP-1 contract MAY limit operator updates to a token 330 | owner (`owner == caller`) or be limited to an administrator. If so, the 331 | `Unauthorized` error variant MUST be used. 332 | 333 | ##### `isAuthorized` 334 | 335 | ``` 336 | type IsAuthorizedRequest = { 337 | owner: User; 338 | operator: User; 339 | tokenId: TokenId; 340 | amount: Balance; 341 | }; 342 | 343 | type IsAuthorizedResponse = [Bool]; 344 | 345 | type isAuthorized = query (requests: [IsAuthorizedRequest]) -> async IsAuthorizedResponse; 346 | ``` 347 | 348 | Checks whether the specified `operator` principal is authorized to transfer on 349 | behalf of the `owner` principal the token `tokenId` of `amount`. 350 | 351 | - Results MUST be consistent with authorization checks in `transfer` operations. 352 | If `isAuthorized` returns `True` for a given operator and owner pair, then 353 | that operator must be able perform `transfer`s without receiving an 354 | `Unauthorized` error. Likewise, if `isAuthorized` returns `False`, then that 355 | operator MUST NOT be able to `transfer` and should receive an `Unauthorized` 356 | error. 357 | 358 | ##### `getMetadata` 359 | 360 | ``` 361 | type Metadata = Blob; 362 | 363 | type MetadataResponse = Result.Result<[Metadata], { 364 | #InvalidToken: TokenId; 365 | }>; 366 | 367 | type getMetadata = query (tokenIds: [TokenId]) -> async MetadataResponse; 368 | ``` 369 | 370 | Returns token metadata for the given `tokenId`s. 371 | 372 | Token metadata is primarily useful in user-facing contexts (e.g. wallets, 373 | explorers, marketplaces). Some attributes that are commonly defined are symbol, 374 | name, description, and decimals. The specification for the metadata format is a 375 | work-in-progress. 376 | 377 | ## Implementing Different Token Types With ICIP-1 378 | 379 | The ICIP-1 interface is designed to support a wide range of token types and 380 | implementations. This section gives examples of how different types of the 381 | ICIP-1 contracts MAY be implemented and what are the expected properties of such 382 | an implementation. 383 | 384 | ### Single Fungible Token 385 | 386 | An ICIP-1 contract represents a single token similar to the ERC-20 standard. 387 | 388 | | Property | Constraints | 389 | | ----------------- | ----------- | 390 | | `tokenId` | Always `0n` | 391 | | transfer amount | Nat | 392 | | principal balance | Nat | 393 | 394 | ### Multiple Fungible Tokens 395 | 396 | An ICIP-1 contract may represent multiple tokens similar to ERC-1155 standard. 397 | The implementation can have a fixed predefined set of supported tokens or tokens 398 | can be created dynamically. 399 | 400 | | Property | Constraints | 401 | | ----------------- | ----------- | 402 | | `tokenId` | Nat | 403 | | transfer amount | Nat | 404 | | principal balance | Nat | 405 | 406 | ### Non-fungible Tokens 407 | 408 | An ICIP-1 contract may represent non-fungible tokens (NFT) similar to ERC-721 409 | standard. For each individual non-fungible token the implementation assigns a 410 | unique `tokenId`. The implementation MAY support either a single kind of NFTs or 411 | multiple kinds. If multiple kinds of NFT is supported, each kind MAY be assigned 412 | a continuous range of natural number (that does not overlap with other ranges) 413 | and have its own associated metadata. 414 | 415 | | Property | Constraints | 416 | | ----------------- | ------------ | 417 | | `tokenId` | Nat | 418 | | transfer amount | `0n` or `1n` | 419 | | principal balance | `0n` or `1n` | 420 | 421 | For any valid `tokenId` only one principal CAN hold the balance of one token 422 | (`1n`). The rest of the principals MUST hold zero balance (`0n`) for that 423 | `tokenId`. 424 | 425 | ### Mixing Fungible and Non-fungible Tokens 426 | 427 | An ICIP-1 contract MAY mix multiple fungible and non-fungible tokens within the 428 | same contract similar to ERC-1155. The implementation MAY chose to select 429 | individual natural numbers to represent `tokenId` for fungible tokens and 430 | continuous natural number ranges to represent `tokenId`s for NFTs. 431 | 432 | | Property | Constraints | 433 | | ----------------- | ------------------------------------------------ | 434 | | `tokenId` | Nat | 435 | | transfer amount | `0n` or `1n` for NFT and Nat for fungible tokens | 436 | | principal balance | `0n` or `1n` for NFT and Nat for fungible tokens | 437 | 438 | ### Non-transferable Tokens 439 | 440 | Either fungible and non-fungible tokens can be non-transferable. 441 | Non-transferable tokens can be represented by the ICIP-1 token that has custom 442 | permission logic. Tokens cannot be transferred either by the token owner or by 443 | any operator. Only privileged operations like mint and burn can assign tokens to 444 | owner principals. 445 | 446 | ## Additional Ideas 447 | 448 | The following are some other features for consideration that could offer more 449 | flexibility and UX improvements. 450 | 451 | - Receiver hooks, for token receivers to perform operations immediately after 452 | receiving tokens 453 | - More detailed transfer permission policies, such as setting a token to only be 454 | transferrable by an operator 455 | - A `Decimal` type instead of `Nat` for balances, removing the complexity of 456 | emulating precision with large exponents 457 | 458 | ## Motoko Types 459 | 460 | ```motoko 461 | import Hash "mo:base/Hash"; 462 | import Nat32 "mo:base/Nat32"; 463 | import Principal "mo:base/Principal"; 464 | import Result "mo:base/Result"; 465 | import Word32 "mo:base/Word32"; 466 | 467 | // A user can be any principal or canister 468 | type User = Principal; 469 | 470 | // A Nat32 implies each canister can store 2**32 individual tokens 471 | type TokenId = Nat32; 472 | 473 | // Token amounts are unbounded 474 | type Balance = Nat; 475 | 476 | // Details for a token, eg. name, symbol, description, decimals. 477 | // Metadata format TBD, possible option is JSON blob 478 | type Metadata = Blob; 479 | type MetadataResponse = Result.Result<[Metadata], { 480 | #InvalidToken: TokenId; 481 | }>; 482 | 483 | // Request and responses for getBalance 484 | type BalanceRequest = { 485 | user: User; 486 | tokenId: TokenId; 487 | }; 488 | type BalanceResponse = Result.Result<[Balance], { 489 | #InvalidToken: TokenId; 490 | }>; 491 | 492 | // Request and responses for transfer 493 | type TransferRequest = { 494 | from: User; 495 | to: User; 496 | tokenId: TokenId; 497 | amount: Balance; 498 | }; 499 | type TransferResponse = Result.Result<(), { 500 | #Unauthorized; 501 | #InvalidDestination: User; 502 | #InvalidToken: TokenId; 503 | #InsufficientBalance; 504 | }>; 505 | 506 | // Request and responses for updateOperator 507 | type TokenIds = { 508 | #All; 509 | #Some: (TokenId, ?Balance); 510 | }; 511 | type OperatorAction = { 512 | #SetOperator: TokenIds; 513 | #RemoveOperator: ?[TokenId]; 514 | }; 515 | type OperatorRequest = { 516 | owner: User; 517 | operators: [(User, OperatorAction)]; 518 | }; 519 | type OperatorResponse = Result.Result<(), { 520 | #Unauthorized; 521 | #InvalidOwner: User; 522 | }>; 523 | 524 | // Request and responses for isAuthorized 525 | type IsAuthorizedRequest = { 526 | owner: User; 527 | operator: User; 528 | tokenId: TokenId; 529 | amount: Balance; 530 | }; 531 | type IsAuthorizedResponse = [Bool]; 532 | 533 | // Utility functions for User and TokenId, useful when implementing containers 534 | module User = { 535 | public let equal = Principal.equal; 536 | public let hash = Principal.hash; 537 | }; 538 | 539 | module TokenId = { 540 | public func equal(id1 : TokenId, id2 : TokenId) : Bool { id1 == id2 }; 541 | public func hash(id : TokenId) : Hash.Hash { Word32.fromNat(Nat32.toNat(id)) }; 542 | }; 543 | 544 | // Uniquely identifies a token 545 | type TokenIdentifier = { 546 | canister: Token; 547 | tokenId: TokenId; 548 | }; 549 | 550 | // Utility functions for TokenIdentifier 551 | module TokenIdentifier = { 552 | // Tokens are equal if the canister and tokenId are equal 553 | public func equal(id1 : TokenIdentifier, id2 : TokenIdentifier) : Bool { 554 | Principal.fromActor(id1.canister) == Principal.fromActor(id2.canister) 555 | and id1.tokenId == id2.tokenId 556 | }; 557 | // Hash the canister and xor with tokenId 558 | public func hash(id : TokenIdentifier) : Hash.Hash { 559 | Principal.hash(Principal.fromActor(id.canister)) ^ Word32.fromNat(Nat32.toNat(id.tokenId)) 560 | }; 561 | // Join the principal and id with a '_' 562 | public func toText(id : TokenIdentifier) : Text { 563 | Principal.toText(Principal.fromActor(id.canister)) # "_" # Nat32.toText(id.tokenId) 564 | }; 565 | }; 566 | 567 | /** 568 | A token canister that can hold many tokens. 569 | */ 570 | type Token = actor { 571 | /** 572 | Batch get balances. 573 | Any request with an invalid tokenId should cause the entire batch to fail. 574 | A user that has no token should default to 0. 575 | */ 576 | getBalance: query (requests: [BalanceRequest]) -> async BalanceResponse; 577 | 578 | /** 579 | Batch get metadata. 580 | Any request with an invalid tokenId should cause the entire batch to fail. 581 | */ 582 | getMetadata: query (tokenIds: [TokenId]) -> async MetadataResponse; 583 | 584 | /** 585 | Batch transfer. 586 | A request should fail if: 587 | - the caller is not authorized to transfer for the sender 588 | - the sender has insufficient balance 589 | Any request that fails should cause the entire batch to fail, and to 590 | rollback to the initial state. 591 | */ 592 | transfer: shared (requests: [TransferRequest]) -> async TransferResponse; 593 | 594 | /** 595 | Batch update operator. 596 | A request should fail if the caller is not authorized to update operators 597 | for the owner. 598 | Any request that fails should cause the entire batch to fail, and to 599 | rollback to the initial state. 600 | */ 601 | updateOperator: shared (requests: [OperatorRequest]) -> async OperatorResponse; 602 | 603 | /** 604 | Batch function to check if a user is authorized to transfer for an owner. 605 | */ 606 | isAuthorized: query (requests: [IsAuthorizedRequest]) -> async IsAuthorizedResponse; 607 | }; 608 | ``` 609 | 610 | ## References 611 | 612 | **Standards** 613 | 614 | - [ERC-20 Token Standard](https://eips.ethereum.org/EIPS/eip-20) 615 | - [ERC-721 Non-Fungible Token Standard](https://eips.ethereum.org/EIPS/eip-721) 616 | - [ERC-1155 Multi Token Standard](https://eips.ethereum.org/EIPS/eip-1155) 617 | 618 | ## Copyright 619 | 620 | Copyright and related rights waived via 621 | [CC0](https://creativecommons.org/publicdomain/zero/1.0/). 622 | -------------------------------------------------------------------------------- /docs/ICIP-20.md: -------------------------------------------------------------------------------- 1 | ## ICIP-20 2 | --- 3 | ICIP-20 token canisters manage and track *[fungible tokens](https://www.markdownguide.org)*. fungible tokens are completely interchangeable with each other. They hold the same value and are used for making payments and tracking balances. This is the vast majority of crypto currencies like BTC, and ETH. 4 | 5 | ### Creating an ICIP-20 Token Canister 6 | --- 7 | *[Canisters](https://www.markdownguide.org)* allow us to easliy create our own DIP20 Token, 8 | 9 | 10 | ![Screenshot](img/DIP20Init.png#zoom#shadow) 11 | 12 | 13 | Here is how it might look minting your tokens 14 |

15 | dfx canister call token initialize "'(\"test token\", \"TT\", 0, 1000)'"
16 | true
17 | 
18 | 19 | We're creating an inital supply of tokens that will be deposited to the *[Caller](https://www.markdownguide.org)* of the initialize method. 20 | 21 | That’s it! Once initialized, we will be able to query the total supply: 22 |

23 | dfx canister call token totalSupply '()'
24 | (1_000)
25 | 
26 | 27 | We can also transfer these tokens to other accounts and query balances: 28 | 29 |

30 | dfx canister call token transfer (Principle, amount)
31 | dfx canister call token balanceOf (Principle)
32 | 
33 | 34 | ##Preset DIP20 Canister 35 | [DIP20](https://github.com/ALLiDoizCode/DIP20) 36 | 37 | This canister is ready to deploy without having to write any Motoko code. It can be used as-is for quick prototyping and testing, but is also suitable for production environments. -------------------------------------------------------------------------------- /docs/ICIP-721.md: -------------------------------------------------------------------------------- 1 | # ICIP-721 2 | --- -------------------------------------------------------------------------------- /docs/Sudograph.md: -------------------------------------------------------------------------------- 1 | ![Screenshot](img/sudograph.png) 2 | 3 | # Sudograph 4 | 5 | Sudograph is a [GraphQL](https://graphql.org/) database for the [Internet Computer](https://dfinity.org/). 6 | 7 | It greatly simplifies [CRUD](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete) development by providing GraphQL queries and mutations derived directly from your [GraphQL schema](https://graphql.org/learn/schema/). All you have to do is define your schema using the [GraphQL SDL](https://www.digitalocean.com/community/tutorials/graphql-graphql-sdl). 8 | 9 | For example, if you created the following schema: 10 | 11 | # As an example, you might define the following types in a file called schema.graphql 12 |

 13 | type BlogPost {
 14 |     id: String!
 15 |     body: String!
 16 |     created_at: Date!
 17 |     live: Boolean!
 18 |     num_words: Int!
 19 |     published_at: Date
 20 |     title: String!
 21 |     updated_at: Date!
 22 | }
 23 | 
24 | 25 | Then Sudograph would create the following queries and mutations for you: 26 | 27 |

 28 | type Query {
 29 |   readBlogPost(input: ReadBlogPostInput!): [BlogPost!]!
 30 | }
 31 | 
 32 | type Mutation {
 33 |   createBlogPost(input: CreateBlogPostInput!): [BlogPost!]!
 34 |   updateBlogPost(input: UpdateBlogPostInput!): [BlogPost!]!
 35 |   deleteBlogPost(input: DeleteBlogPostInput!): [BlogPost!]!
 36 |   initBlogPost: Boolean!
 37 | }
 38 | 
39 | 40 | There's a lot more being generated for you to get the above to work, but you're seeing the most important parts (the queries and mutations themselves). 41 | 42 | With the generated queries/mutations above, you could start writing code like this in any of your clients: 43 | 44 |

 45 | query {
 46 |     readBlogPost(input: {
 47 |         live: {
 48 |             eq: true
 49 |         }
 50 |     }) {
 51 |         id
 52 |         body
 53 |         created_at
 54 |         live
 55 |         num_words
 56 |         published_at
 57 |         title
 58 |         updated_at
 59 |     }
 60 | }
 61 | 
62 | 63 | The query above will return all blog posts that are "live" (have been published). 64 | 65 | Creating a blog post would look something like this: 66 | 67 |

 68 | mutation {
 69 |     createBlogPost(input: {
 70 |         id: "0"
 71 |         body: "This is my blog post!"
 72 |         created_at: "2021-03-21T05:34:31.127Z"
 73 |         live: false
 74 |         num_words: 5
 75 |         published_at: null
 76 |         title: "My Blog Post"
 77 |         updated_at: "2021-03-21T05:34:31.127Z"
 78 |     }) {
 79 |         id
 80 |     }
 81 | }
 82 | 
83 | 84 | ## Quick Start 85 | 86 | Sudograph is a Rust crate, and thus (for now) you must create a Rust IC canister to use it. You should generally follow the official DFINITY guidance for the [Rust CDK](https://sdk.dfinity.org/docs/rust-guide/rust-intro.html). 87 | 88 | If you ever want to see a concrete example of how to implement Sudograph, simply take a look at the examples directory. 89 | 90 | Let's imagine you've created a Rust canister called `graphql` in a directory called `graphql`. In the `graphql` directory you should have a `Cargo.toml` file. You'll need to add Sudograph as a dependency. For example: 91 | 92 |

 93 | [package]
 94 | name = "graphql"
 95 | version = "0.0.0"
 96 | authors = ["Jordan Last "]
 97 | edition = "2018"
 98 | 
 99 | [lib]
100 | path = "src/graphql.rs"
101 | crate-type = ["cdylib"]
102 | 
103 | [dependencies]
104 | sudograph = "0.1.0"
105 | 
106 | 107 | Next let's define our schema. In the `graphql/src` directory, let's add a file called `schema.graphql`: 108 | 109 |

110 | # graphql/src/schema.graphql
111 | type BlogPost {
112 |     id: String!
113 |     body: String!
114 |     created_at: Date!
115 |     live: Boolean!
116 |     num_words: Int!
117 |     published_at: Date
118 |     title: String!
119 |     updated_at: Date!
120 | }
121 | 
122 | 123 | Your canister should be implemented as a Rust library crate, in this case the source code for our canister is found in `graphql/src/graphql.rs`. You only need to add two lines of code to this file to bootstrap your GraphQL database: 124 | 125 |

126 | // graphql/src/graphql.rs
127 | use sudograph::graphql_database;
128 | 
129 | graphql_database!("canisters/graphql/src/schema.graphql");
130 | 
131 | 132 | You will also need to add a [Candid](https://sdk.dfinity.org/docs/candid-guide/candid-intro.html) file to `graphql/src`. Let's call it `graphql.did`: 133 | 134 |

135 | # graphql/src/graphql.did
136 | service : {
137 |     "graphql_query": (text) -> (text) query;
138 |     "graphql_mutation": (text) -> (text);
139 | }
140 | 
141 | 142 | Sudograph will automatically create two methods on your canister, the first is called `graphql_query`, which is a query method (will return quickly). The second is called `graphql_mutation`, which is an update method (will return more slowly). You should send all queries to `graphql_query` and all mutations to `graphql_mutation`. If you want the highest security guarantees, you can send all queries to `graphql_mutation`, they will simply take a few seconds to return. 143 | 144 | If you have setup your `dfx.json` correctly, then you should be able to deploy your Sudograph canister. Open up a terminal in the root directory of your IC project and start up an IC replica with `dfx start`. Open another terminal, and from the same directory run `dfx deploy`. 145 | 146 | You should now have a GraphQL database running inside of your `graphql` canister. 147 | 148 | ##Preset Sudograph Canister 149 | [Sudograph](https://github.com/ALLiDoizCode/sudograph) 150 | 151 | This canister is ready to deploy without having to write any Motoko code. It can be used as-is for quick prototyping and testing, but is also suitable for production environments. -------------------------------------------------------------------------------- /docs/fungible-tokens.md: -------------------------------------------------------------------------------- 1 | # Fungible Tokens 2 | --- -------------------------------------------------------------------------------- /docs/getting-started.md: -------------------------------------------------------------------------------- 1 | ![Screenshot](img/dfinity-logo.svg) 2 | 3 | ## Getting Started 4 | 5 | ## Requirements 6 | 7 | Install the beta version of the DFINITY Canister SDK 8 | 9 |

10 | DFX_VERSION=0.7.0-beta.8 sh -ci "$(curl -fsSL https://sdk.dfinity.org/install.sh)" 
11 | 
12 | 13 | 14 | ## Get Started 15 | 16 | With NPM: 17 | 18 |

19 | npx create-ic-app
20 | 
21 | 22 | 23 | ![Screenshot](img/setup.png) 24 | 25 | After the setup is done 26 |

27 | cd test-project
28 | npm install
29 | 
30 | Start the backend 31 |

32 | dfx start --background
33 | dfx canister create --all
34 | dfx build
35 | dfx canister install --all
36 | 
37 | Start the frontend 38 |

39 | npm run dev
40 | 
41 | Thats it! The counter demo is persisted on your local Internet Computer. 42 | 43 | ![Screenshot](img/example.png) 44 | 45 | ## [Experimental] Watch mode for canisters 46 | This will auto build and install your canisters whenever you make a change to them 47 |

48 | npm run watch
49 | 
50 | 51 | ![Screenshot](img/create-ic-app.gif) 52 | 53 | ## Adding / Removing / Renaming Canisters 54 | 55 | You will have to edit 3 files: 56 | 57 | * dfx.json 58 | * tsconfig.json 59 | * src/agent.ts 60 | 61 | More detailed instructions later. For now see how it's done in those files for the example counter canister. 62 | 63 | ## Deploying Asset Canister 64 | 65 | Run the following commands 66 |

67 | dfx build
68 | dfx canister install --all --mode=reinstall
69 | 
70 | Then grab the asset canister ID from the output. Shown here: 71 | ![Screenshot](img/deployCanister.png) 72 | 73 | Now you can visit the following url in your browser to see it running on your local internet computer: 74 | 75 | http://localhost:8000?canisterId= 76 | 77 | ## Community templates / Contributions 78 | Want to contribute your own template? Find something that could be improved? Repo is open for PRs! Happy to assist you in this. You'll receive full credit for your contribution of course. 79 | 80 | ### Contributions 81 | @ferMartz (React JS + Tailwind template) -------------------------------------------------------------------------------- /docs/img/DIP20Init.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCan-io/opencan/7f224bad5e2a7fdbace3df012ad7713efac4ec9c/docs/img/DIP20Init.png -------------------------------------------------------------------------------- /docs/img/create-ic-app.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCan-io/opencan/7f224bad5e2a7fdbace3df012ad7713efac4ec9c/docs/img/create-ic-app.gif -------------------------------------------------------------------------------- /docs/img/deployCanister.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCan-io/opencan/7f224bad5e2a7fdbace3df012ad7713efac4ec9c/docs/img/deployCanister.png -------------------------------------------------------------------------------- /docs/img/dfinity-logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/img/example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCan-io/opencan/7f224bad5e2a7fdbace3df012ad7713efac4ec9c/docs/img/example.png -------------------------------------------------------------------------------- /docs/img/opencantrailer.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCan-io/opencan/7f224bad5e2a7fdbace3df012ad7713efac4ec9c/docs/img/opencantrailer.mp4 -------------------------------------------------------------------------------- /docs/img/setup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCan-io/opencan/7f224bad5e2a7fdbace3df012ad7713efac4ec9c/docs/img/setup.png -------------------------------------------------------------------------------- /docs/img/sudograph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCan-io/opencan/7f224bad5e2a7fdbace3df012ad7713efac4ec9c/docs/img/sudograph.png -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 |
2 | 5 |
6 | 7 | 13 | 14 | ## Introduction 15 | 16 | Although revolutionary in many ways, the Internet Computer will always have a need for new improvement proposals and left to our own devices, getting a proposal voted on by the NNS will be costly if rejected at best and difficult to find developer adoption if accepted at worst. 17 | 18 | Say we all have our own method for minting tokens or NFTs, should we all individually make "motion" proposals for new standards to the NNS? How will other developers know to use that standard if the motion passes? And why should so many of us pay NNS fees on trying to solve the same problem if they get rejected? 19 | 20 | OpenCan aims to provide developers with a mechanism for drafting, collaborating, and agreeing on such proposals so that we can align on them prior to the step of actually making the final proposal to the NNS. 21 | 22 | Once accepted, guides and examples to integrate these new standards in your applications will be posted here as a central source of truth for further Internet Computer development. 23 | 24 | ## What we need help with 25 | 26 | We are currently a small team of volunteers. Please help make development easier on the Internet Computer by contributing to this repo any of these items: 27 |
    28 |
  • Standards you think should be included
  • 29 |
  • Methods of collaboration on reviewing developer-proposed standards
  • 30 |
  • Methods of decentralizing OpenCan process & governance (how will developer-proposed standards move to the NNS, how can incentives be aligned for developer-proposers, editors, and reviewers)
  • 31 |
-------------------------------------------------------------------------------- /docs/learn.md: -------------------------------------------------------------------------------- 1 | ![Screenshot](img/dfinity-logo.svg) 2 | 3 | # Learn 4 | 5 | [Creating a new IC app](getting-started.md) 6 | [Developing smart contracts](getting-started.md) 7 | [Deploying and interacting](getting-started.md) -------------------------------------------------------------------------------- /docs/motoko-token.md: -------------------------------------------------------------------------------- 1 | ## ERC20 style token template for Dfinity 2 | 3 | Source code: https://github.com/dfinance-tech/motoko-token 4 | 5 | ## Features 6 | 7 | * ERC20 style standard token interface 8 | * Store every transaction record 9 | * Support query of history records 10 | 11 | ## Env 12 | 13 | 1. dfx 0.7.0-beta.6 14 | 2. [vessel 0.6.1](https://github.com/dfinity/vessel) 15 | 16 | ## Docs 17 | 18 | https://dfinance.ai/motoko-token/ 19 | 20 | ## Types 21 | ### AccountIdentifier 22 | Account Identifier, refer to [Ledger canister](https://github.com/dfinity/ic/blob/master/rs/rosetta-api/ledger_canister/src/account_identifier.rs#L24-L26). 23 | ```mo 24 | /// Account Identitier type. 25 | type AccountIdentifier = { hash : [Nat8] } 26 | ``` 27 | 28 | ![](https://github.com/dfinance-tech/motoko-token/blob/ledger/images/public-key-principal-account.png) 29 | 30 | ### Operation 31 | ```mo 32 | /// Update call operations 33 | type Operation = {#mint; #burn; #transfer; #approve; #init} 34 | ``` 35 | 36 | ### Status 37 | ```mo 38 | /// Update call status 39 | type Status = {#success; #failed} 40 | ``` 41 | 42 | ### OpRecord 43 | ```mo 44 | /// Update call record fields 45 | type OpRecord = { caller : Text; op : Operation; status : Status; index : Nat; hash : Text; from : ?Text; to : ?Text; amount : Nat64; fee : ?Nat64; memo : ?Nat64; timestamp : Time.Time } 46 | ``` 47 | ### OpRecordIn 48 | ```mo 49 | /// OpRecord without hash. 50 | type OpRecordIn = { caller : Text; op : Operation; status : Status; index : Nat; from : ?Text; to : ?Text; amount : Nat64; fee : ?Nat64; memo : ?Nat64; timestamp : Time.Time } 51 | ``` 52 | 53 | ## Interface Specification 54 | ```motoko 55 | /// Update call 56 | /// Transfers `value` amount of tokens to Account `to`. `value` is the number of minimum units. 57 | /// Return whether the result is successful and transaction hash. 58 | public func transfer(to : Text, value : Nat64) : async (Bool, Text) 59 | 60 | /// Transfers `value` amount of tokens from Account `from` to Account `to`. `value` is the number of minimum units. 61 | /// Return whether the result is successful and transaction hash. 62 | public func transferFrom( 63 | from : Text, 64 | to : Text, 65 | value : Nat64 66 | ) : async (Bool, Text) 67 | 68 | /// Allows `spender` to withdraw from your account multiple times, up to the `value` amount. 69 | /// If this function is called again it overwrites the current allowance with value. 70 | /// `value` is the number of minimum units. 71 | /// the `value` of `approve` is has **nothing** to do with your `balance` 72 | /// Return whether the result is successful and transaction hash. 73 | public func approve(spender : Text, value : Nat64) : async (Bool, Text) 74 | 75 | /// Creates `value` tokens and assigns them to Account `to`, increasing the total supply. 76 | /// Return whether the result is successful and transaction hash. 77 | public func mint(to : Text, value : Nat64) : async (Bool, Text) 78 | 79 | /// Burn `value` tokens of Account `to`, decreasing the total supply. 80 | /// Return whether the result is successful and transaction hash. 81 | public func burn(from : Text, value : Nat64) : async (Bool, Text) 82 | 83 | 84 | /// Query call 85 | /// Get the balance of Account who, in the number of minimum units. 86 | public func balanceOf(who : Text) : async Nat64 87 | 88 | /// Get the amount which `spender` is still allowed to withdraw from `owner`, in the number of minimum units. 89 | public func allowance(owner : Text, spender : Text) : async Nat64 90 | 91 | /// Get the total token supply, in the number of minimum units. 92 | public func totalSupply() : async Nat64 93 | 94 | /// Get the name of the token. 95 | public func name() : async Text 96 | 97 | /// Get the number of decimals the token uses. 98 | public func decimals() : async Nat64 99 | 100 | /// Get the number of decimals the token uses. 101 | public func symbol() : async Text 102 | 103 | /// Get the owner of the token 104 | public func owner() : async Text 105 | 106 | /// Get update call History index by hash. 107 | public func getHistoryByHash(hash : Text) : async ?OpRecord 108 | Get update call History index by hash. 109 | 110 | /// Get update call history by account. 111 | public func getHistoryByAccount(a : Text) : async ?[OpRecord] 112 | 113 | /// Get all update call history. 114 | public func allHistory() : async [OpRecord] 115 | ``` 116 | 117 | ## Examples 118 | 119 | See [demo.sh](./demo.sh). 120 | 121 | ## Reference 122 | 123 | * https://github.com/enzoh/motoko-token 124 | * https://github.com/flyq/motoko_token 125 | * https://github.com/enzoh/motoko-sha 126 | * https://github.com/stephenandrews/motoko-crc 127 | * https://github.com/flyq/motoko-sha224 128 | -------------------------------------------------------------------------------- /docs/non-fungible-tokens.md: -------------------------------------------------------------------------------- 1 | ![Screenshot](img/dfinity-logo.svg) 2 | 3 | # Non-Fungible Tokens 4 | --- 5 | -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: OpenCan 2 | nav: 3 | - 'Start': 4 | - 'Introduction': 'index.md' 5 | - 'Learn': 6 | - 'Overview': 'learn.md' 7 | - 'Creating a new IC app': 'getting-started.md' 8 | - 'Sudograph': 'Sudograph.md' 9 | - 'In-review': 10 | - 'ICIP-20': 'ICIP-20.md' 11 | - 'ICIP-721': 'ICIP-721.md' 12 | - "Cycles": 'Cycles.md' 13 | - "ICIP-1": 'ICIP-1.md' 14 | - "Motoko-Token": 'motoko-token.md' 15 | - 'Tools': 16 | - 'fungible-tokens.md' 17 | - 'non-fungible-tokens.md' 18 | theme: 19 | name: 'mkdocs' 20 | custom_dir: 'custom_theme/' 21 | --------------------------------------------------------------------------------